Passed
Pull Request — master (#30)
by Guillaume
34:24 queued 30:24
created

Clockify::projects()   A

Complexity

Conditions 2
Paths 5

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 2
eloc 7
nc 5
nop 0
dl 0
loc 12
ccs 7
cts 7
cp 1
crap 2
rs 10
c 1
b 0
f 1
1
<?php
2
3
namespace Godbout\Alfred\Time\Services;
4
5
use Carbon\Carbon;
6
use GuzzleHttp\Client;
7
8
class Clockify extends TimerService
9
{
10
    private $client;
11
12
    private $data = null;
0 ignored issues
show
introduced by
The private property $data is not used, and could be removed.
Loading history...
13
14
15 80
    public function __construct($apiToken)
16
    {
17 80
        $this->client = new Client([
18 80
            'base_uri' => 'https://api.clockify.me/api/v1/',
19
            'headers' => [
20 80
                'content-type' => 'application/json',
21 80
                'X-Api-Key' => $apiToken
22
            ]
23
        ]);
24 80
    }
25
26 12
    public function workspaces()
27
    {
28
        try {
29 12
            $response = $this->client->get('workspaces');
30 10
            $workspaces = json_decode($response->getBody()->getContents());
31
32 10
            return array_column($workspaces, 'name', 'id');
33 2
        } catch (\Exception $e) {
34 2
            return [];
35
        }
36
    }
37
38 22
    public function projects()
39
    {
40
        try {
41 22
            $workspaceId = getenv('timer_workspace_id');
42
43 22
            $response = $this->client->get("workspaces/$workspaceId/projects");
44
45 20
            $projects = json_decode($response->getBody()->getContents());
46
47 20
            return array_column($projects, 'name', 'id');
48 2
        } catch (\Exception $e) {
49 2
            return [];
50
        }
51
    }
52
53 22
    public function tags()
54
    {
55
        try {
56 22
            $workspaceId = getenv('timer_workspace_id');
57
58 22
            $response = $this->client->get("workspaces/$workspaceId/tags");
59 20
            $tags = json_decode($response->getBody()->getContents());
60
61 20
            return array_column($tags, 'name', 'id');
62 2
        } catch (\Exception $e) {
63 2
            return [];
64
        }
65
    }
66
67 40
    public function startTimer()
68
    {
69
        try {
70 40
            $workspaceId = getenv('timer_workspace_id');
71
72 40
            $response = $this->client->post("workspaces/$workspaceId/time-entries", [
73 16
                'json' => [
74 40
                    'start' => (new \DateTime())->format('Y-m-d\TH:i:s\Z'),
75 40
                    'description' => getenv('timer_description'),
76 40
                    'projectId' => getenv('timer_project_id'),
77 40
                    'tagIds' => getenv('timer_tag_id') ? [getenv('timer_tag_id')] : [''],
78
                ]
79
            ]);
80
81 40
            $timer = json_decode($response->getBody()->getContents());
82
83 40
            if (! isset($timer->id)) {
84 40
                return false;
85
            }
86
        } 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...
87
            return false;
88
        }
89
90 40
        return $timer->id;
91
    }
92
93 41
    public function stopCurrentTimer()
94
    {
95 41
        $workspaceId = getenv('timer_workspace_id');
96 41
        $userId = getenv('timer_user_id');
97
98 41
        if ($timerId = $this->runningTimer()) {
0 ignored issues
show
Unused Code introduced by
The assignment to $timerId is dead and can be removed.
Loading history...
99 40
            $response = $this->client->patch("workspaces/$workspaceId/user/$userId/time-entries", [
100
                'json' => [
101 40
                    'end' => (new \DateTime())->format('Y-m-d\TH:i:s\Z'),
102
                ]
103
            ]) ;
104
105 40
            $timer = json_decode($response->getBody()->getContents());
106
107 40
            if (! isset($timer->timeInterval->end)) {
108
                throw new Exception("Can't stop current running timer.", 1);
109
110
                return false;
0 ignored issues
show
Unused Code introduced by
return false 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...
111
            }
112
113 40
            return true;
114
        }
115
116 11
        return false;
117
    }
118
119 80
    public function runningTimer()
120
    {
121
        try {
122 80
            $workspaceId = getenv('timer_workspace_id');
123 80
            $userId = getenv('timer_user_id');
124
125 80
            $response = $this->client->get("workspaces/$workspaceId/user/$userId/time-entries?in-progress=true");
126
127 80
            $timer = json_decode($response->getBody()->getContents());
128
129 80
            return $timer[0]->id ?? false;
130
        } catch (\Exception $e) {
131
            return false;
132
        }
133
134
        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...
135
    }
136
137 10
    public function pastTimers()
138
    {
139
        try {
140 10
            $pastTimers = [];
0 ignored issues
show
Unused Code introduced by
The assignment to $pastTimers is dead and can be removed.
Loading history...
141
142 10
            $workspaceId = getenv('timer_workspace_id');
143 10
            $userId = getenv('timer_user_id');
144
145 10
            $response = $this->client->get("workspaces/$workspaceId/user/$userId/time-entries", [
146 10
                'start' => Carbon::today(),
147 10
                'end' => Carbon::today()->subDays(30),
148
            ]);
149 10
            $clockifyTimers = json_decode($response->getBody()->getContents());
150
151 10
            return $this->convertToPastTimers($clockifyTimers);
152
        } catch (Exception $e) {
153
            return [];
154
        }
155
    }
156
157
    public function continueTimer($timerId = null)
158
    {
159
        return false;
160
    }
161
162 1
    public function deleteTimer($timerId)
163
    {
164 1
        return false;
165
    }
166
167 10
    protected function convertToPastTimers($clockifyTimers)
168
    {
169 10
        $projects = $this->projects();
170 10
        $tags = $this->tags();
171
172
        return array_map(function ($clockifyTimer) use ($projects, $tags) {
173 10
            return $this->buildPastTimerObject($clockifyTimer, $projects, $tags);
174 10
        }, $clockifyTimers);
175
    }
176
177 10
    protected function buildPastTimerObject($clockifyTimer, $projects, $tags)
178
    {
179 10
        $pastTimer['id'] = $clockifyTimer->id;
0 ignored issues
show
Comprehensibility Best Practice introduced by
$pastTimer was never initialized. Although not strictly required by PHP, it is generally a good practice to add $pastTimer = array(); before regardless.
Loading history...
180 10
        $pastTimer['description'] = $clockifyTimer->description;
181
182 10
        if (isset($clockifyTimer->projectId)) {
183 10
            $pastTimer['project_id'] = $clockifyTimer->projectId;
184 10
            $pastTimer['project_name'] = $projects[$clockifyTimer->projectId];
185
        }
186
187 10
        if (isset($clockifyTimer->tagIds[0])) {
188 10
            $pastTimer['tag_id'] = $clockifyTimer->tagIds[0];
189 10
            $pastTimer['tags'] = $tags[$clockifyTimer->tagIds[0]];
190
        }
191
192 10
        $pastTimer['duration'] = $clockifyTimer->timeInterval->duration;
193
194 10
        return (object) $pastTimer;
195
    }
196
}
197