Passed
Push — clockify ( ab4086...e26db1 )
by Guillaume
03:41
created

Clockify::deleteTimer()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
ccs 1
cts 1
cp 1
crap 1
rs 10
c 1
b 0
f 1
1
<?php
2
3
namespace Godbout\Alfred\Time\Services;
4
5
use Carbon\Carbon;
6
use Godbout\Alfred\Time\Workflow;
7
use GuzzleHttp\Client;
8
9
class Clockify extends TimerService
10
{
11
    private $client;
12
13
14
    public function __construct($apiToken)
15 78
    {
16
        $this->client = new Client([
17 78
            'base_uri' => 'https://api.clockify.me/api/v1/',
18 78
            'headers' => [
19
                'content-type' => 'application/json',
20 78
                'X-Api-Key' => $apiToken
21 78
            ]
22
        ]);
23
    }
24 78
25
    public function projects()
26 12
    {
27
        try {
28
            $user = json_decode(
29 12
                $this->client->get("user")->getBody()->getContents()
30 6
            );
31
32 6
            Workflow::getConfig()->write('clockify.active_workspace_id', $user->activeWorkspace);
33 6
34 6
            $response = $this->client->get("workspaces/{$user->activeWorkspace}/projects");
35
36
            $projects = json_decode($response->getBody()->getContents());
37
38 18
            return array_column($projects, 'name', 'id');
39
        } catch (\Exception $e) {
40
            return [];
41 18
        }
42 18
    }
43
44
    public function tags()
45 12
    {
46
        try {
47 12
            $workspaceId = Workflow::getConfig()->read('clockify.active_workspace_id');
48
49 12
            $response = $this->client->get("workspaces/$workspaceId/tags");
50 6
            $tags = json_decode($response->getBody()->getContents());
51 6
52
            return array_column($tags, 'name', 'id');
53
        } catch (\Exception $e) {
54
            return [];
55 18
        }
56
    }
57
58 18
    public function startTimer()
59
    {
60 18
        try {
61 12
            $workspaceId = Workflow::getConfig()->read('clockify.active_workspace_id');
62
63 12
            $response = $this->client->post("workspaces/$workspaceId/time-entries", [
64 6
                'json' => [
65 6
                    'start' => (new \DateTime())->format('Y-m-d\TH:i:s\Z'),
66
                    'description' => getenv('timer_description'),
67
                    'projectId' => getenv('timer_project_id'),
68
                    'tagIds' => getenv('timer_tag_id') ? [getenv('timer_tag_id')] : [''],
69 30
                ]
70
            ]);
71
72 30
            $timer = json_decode($response->getBody()->getContents());
73
74 30
            if (! isset($timer->id)) {
75 10
                return false;
76 30
            }
77 30
        } catch (Exception $e) {
0 ignored issues
show
Bug introduced by
The type Godbout\Alfred\Time\Services\Exception was not found. Did you mean Exception? If so, make sure to prefix the type with \.
Loading history...
78 30
            return false;
79 30
        }
80
81
        return $timer->id;
82
    }
83 30
84
    public function stopCurrentTimer()
85 30
    {
86 30
        $user = json_decode(
87
            $this->client->get("user")->getBody()->getContents()
88
        );
89
90
        if ($this->runningTimer()) {
91
            $response = $this->client->patch("workspaces/{$user->activeWorkspace}/user/{$user->id}/time-entries", [
92 30
                'json' => [
93
                    'end' => (new \DateTime())->format('Y-m-d\TH:i:s\Z'),
94
                ]
95 30
            ]) ;
96
97 30
            $timer = json_decode($response->getBody()->getContents());
98 30
99
            if (! isset($timer->timeInterval->end)) {
100 30
                throw new Exception("Can't stop current running timer.", 1);
101 30
            }
102
103 30
            return true;
104
        }
105
106
        return false;
107 30
    }
108
109 30
    public function runningTimer()
110
    {
111
        try {
112
            $user = json_decode(
113
                $this->client->get("user")->getBody()->getContents()
114
            );
115 30
116
            $response = $this->client->get(
117
                "workspaces/{$user->activeWorkspace}/user/{$user->id}/time-entries?in-progress=true"
118 6
            );
119
120
            $timer = json_decode($response->getBody()->getContents());
121 78
122
            return $timer[0]->id ?? false;
123
        } catch (\Exception $e) {
124 78
            return false;
125 78
        }
126
127 78
        return true;
0 ignored issues
show
Unused Code introduced by
return true is not reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
128
    }
129 78
130
    public function pastTimers()
131 78
    {
132
        try {
133
            $user = json_decode(
134
                $this->client->get("user")->getBody()->getContents()
135
            );
136
137
            $response = $this->client->get("workspaces/{$user->activeWorkspace}/user/{$user->id}/time-entries", [
138
                'start' => Carbon::today(),
139 6
                'end' => Carbon::today()->subDays(30),
140
            ]);
141
            $clockifyTimers = json_decode($response->getBody()->getContents());
142 6
143
            return $this->convertToPastTimers($clockifyTimers);
144 6
        } catch (Exception $e) {
145 6
            return [];
146
        }
147 6
    }
148 6
149 6
    public function continueTimer($timerId = null)
150
    {
151 6
        /**
152
         * Timer attributes are stored in env variables
153 6
         * gathered in startTimer.
154
         */
155
        return $this->startTimer();
156
    }
157
158
    protected function convertToPastTimers($clockifyTimers)
159 6
    {
160
        $projects = $this->projects();
161
        $tags = $this->tags();
162
163
        return array_map(function ($clockifyTimer) use ($projects, $tags) {
164
            return $this->buildPastTimerObject($clockifyTimer, $projects, $tags);
165 6
        }, $clockifyTimers);
166
    }
167
168 6
    protected function buildPastTimerObject($clockifyTimer, $projects, $tags)
169
    {
170 6
        $pastTimer = [];
171
172
        $pastTimer['id'] = $clockifyTimer->id;
173 6
        $pastTimer['description'] = $clockifyTimer->description;
174
175 6
        if (isset($clockifyTimer->projectId)) {
176 6
            $pastTimer['project_id'] = $clockifyTimer->projectId;
177
            $pastTimer['project_name'] = $projects[$clockifyTimer->projectId];
178
        }
179 6
180 6
        if (isset($clockifyTimer->tagIds[0])) {
181
            $pastTimer['tag_id'] = $clockifyTimer->tagIds[0];
182
            $pastTimer['tags'] = $tags[$clockifyTimer->tagIds[0]];
183 6
        }
184
185 6
        $pastTimer['duration'] = $clockifyTimer->timeInterval->duration;
186 6
187
        return (object) $pastTimer;
188 6
    }
189
}
190