Passed
Pull Request — master (#30)
by Guillaume
36:15 queued 34:05
created

Clockify::pastTimers()   A

Complexity

Conditions 2
Paths 6

Size

Total Lines 17
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 2.024

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 2
eloc 11
nc 6
nop 0
dl 0
loc 17
ccs 9
cts 11
cp 0.8182
crap 2.024
rs 9.9
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 66
    public function __construct($apiToken)
16
    {
17 66
        $this->client = new Client([
18 66
            'base_uri' => 'https://api.clockify.me/api/v1/',
19
            'headers' => [
20 66
                'content-type' => 'application/json',
21 66
                'X-Api-Key' => $apiToken
22
            ]
23
        ]);
24 66
    }
25
26 12
    public function workspaces()
27
    {
28
        try {
29 12
            $response = $this->client->get('workspaces');
30 2
            $workspaces = json_decode($response->getBody()->getContents());
31
32 2
            return array_column($workspaces, 'name', 'id');
33 10
        } catch (\Exception $e) {
34 10
            return [];
35
        }
36
    }
37
38 14
    public function projects()
39
    {
40
        try {
41 14
            $workspaceId = getenv('timer_workspace_id');
42
43 14
            $response = $this->client->get("workspaces/$workspaceId/projects");
44
45 4
            $projects = json_decode($response->getBody()->getContents());
46
47 4
            return array_column($projects, 'name', 'id');
48 10
        } catch (\Exception $e) {
49 10
            return [];
50
        }
51
    }
52
53 14
    public function tags()
54
    {
55
        try {
56 14
            $workspaceId = getenv('timer_workspace_id');
57
58 14
            $response = $this->client->get("workspaces/$workspaceId/tags");
59 4
            $tags = json_decode($response->getBody()->getContents());
60
61 4
            return array_column($tags, 'name', 'id');
62 10
        } catch (\Exception $e) {
63 10
            return [];
64
        }
65
    }
66
67 10
    public function startTimer()
68
    {
69
        try {
70 10
            $workspaceId = getenv('timer_workspace_id');
71
72 10
            $response = $this->client->post("workspaces/$workspaceId/time-entries", [
73 5
                'json' => [
74 10
                    'start' => (new \DateTime())->format('Y-m-d\TH:i:s\Z'),
75 10
                    'description' => getenv('timer_description'),
76 10
                    'projectId' => getenv('timer_project_id'),
77 10
                    'tagIds' => getenv('timer_tag_id') ? [getenv('timer_tag_id')] : [''],
78
                ]
79
            ]);
80
81 10
            $timer = json_decode($response->getBody()->getContents());
82
83 10
            if (! isset($timer->id)) {
84 10
                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 10
        return $timer->id;
91
    }
92
93 11
    public function stopCurrentTimer()
94
    {
95 11
        $workspaceId = getenv('timer_workspace_id');
96 11
        $userId = getenv('timer_user_id');
97
98 11
        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 11
            $response = $this->client->patch("workspaces/$workspaceId/user/$userId/time-entries", [
100
                'json' => [
101 11
                    'end' => (new \DateTime())->format('Y-m-d\TH:i:s\Z'),
102
                ]
103
            ]) ;
104
105 10
            $timer = json_decode($response->getBody()->getContents());
106
107 10
            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 10
            return true;
114
        }
115
116 2
        return false;
117
    }
118
119 66
    public function runningTimer()
120
    {
121
        try {
122 66
            $workspaceId = getenv('timer_workspace_id');
123 66
            $userId = getenv('timer_user_id');
124
125 66
            $response = $this->client->get("workspaces/$workspaceId/user/$userId/time-entries?in-progress=true");
126
127 66
            $timer = json_decode($response->getBody()->getContents());
128
129 66
            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 2
    public function pastTimers()
138
    {
139
        try {
140 2
            $pastTimers = [];
0 ignored issues
show
Unused Code introduced by
The assignment to $pastTimers is dead and can be removed.
Loading history...
141
142 2
            $workspaceId = getenv('timer_workspace_id');
143 2
            $userId = getenv('timer_user_id');
144
145 2
            $response = $this->client->get("workspaces/$workspaceId/user/$userId/time-entries", [
146 2
                'start' => Carbon::today(),
147 2
                'end' => Carbon::today()->subDays(30),
148
            ]);
149 2
            $clockifyTimers = json_decode($response->getBody()->getContents());
150
151 2
            return $this->convertToPastTimers($clockifyTimers);
152
        } catch (Exception $e) {
153
            return [];
154
        }
155
    }
156
157 2
    public function continueTimer($timerId = null)
158
    {
159
        /**
160
         * Timer attributes are stored in env variables
161
         * gathered in startTimer.
162
         */
163 2
        return $this->startTimer();
164
    }
165
166 2
    public function deleteTimer($timerId)
167
    {
168 2
        return false;
169
    }
170
171 2
    protected function convertToPastTimers($clockifyTimers)
172
    {
173 2
        $projects = $this->projects();
174 2
        $tags = $this->tags();
175
176
        return array_map(function ($clockifyTimer) use ($projects, $tags) {
177 2
            return $this->buildPastTimerObject($clockifyTimer, $projects, $tags);
178 2
        }, $clockifyTimers);
179
    }
180
181 2
    protected function buildPastTimerObject($clockifyTimer, $projects, $tags)
182
    {
183 2
        $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...
184 2
        $pastTimer['description'] = $clockifyTimer->description;
185
186 2
        if (isset($clockifyTimer->projectId)) {
187 2
            $pastTimer['project_id'] = $clockifyTimer->projectId;
188 2
            $pastTimer['project_name'] = $projects[$clockifyTimer->projectId];
189
        }
190
191 2
        if (isset($clockifyTimer->tagIds[0])) {
192 2
            $pastTimer['tag_id'] = $clockifyTimer->tagIds[0];
193 2
            $pastTimer['tags'] = $tags[$clockifyTimer->tagIds[0]];
194
        }
195
196 2
        $pastTimer['duration'] = $clockifyTimer->timeInterval->duration;
197
198 2
        return (object) $pastTimer;
199
    }
200
}
201