Passed
Pull Request — master (#30)
by Guillaume
38:02 queued 36:39
created

Clockify::buildPastTimerObject()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 20
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 11
c 0
b 0
f 0
nc 4
nop 3
dl 0
loc 20
ccs 12
cts 12
cp 1
crap 3
rs 9.9
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 81
    public function __construct($apiToken)
15
    {
16 81
        $this->client = new Client([
17 81
            'base_uri' => 'https://api.clockify.me/api/v1/',
18
            'headers' => [
19 81
                'content-type' => 'application/json',
20 81
                'X-Api-Key' => $apiToken
21
            ]
22
        ]);
23 81
    }
24
25 23
    public function projects()
26
    {
27
        try {
28 23
            $user = json_decode(
29 23
                $this->client->get("user")->getBody()->getContents()
30
            );
31
32 22
            Workflow::getConfig()->write('clockify.active_workspace_id', $user->activeWorkspace);
33
34 22
            $response = $this->client->get("workspaces/{$user->activeWorkspace}/projects");
35
36 22
            $projects = json_decode($response->getBody()->getContents());
37
38 22
            return array_column($projects, 'name', 'id');
39 1
        } catch (\Exception $e) {
40 1
            return [];
41
        }
42
    }
43
44 23
    public function tags()
45
    {
46
        try {
47 23
            $workspaceId = Workflow::getConfig()->read('clockify.active_workspace_id');
48
49 23
            $response = $this->client->get("workspaces/$workspaceId/tags");
50 22
            $tags = json_decode($response->getBody()->getContents());
51
52 22
            return array_column($tags, 'name', 'id');
53 1
        } catch (\Exception $e) {
54 1
            return [];
55
        }
56
    }
57
58 55
    public function startTimer()
59
    {
60
        try {
61 55
            $workspaceId = Workflow::getConfig()->read('clockify.active_workspace_id');
62
63 55
            $response = $this->client->post("workspaces/$workspaceId/time-entries", [
64 20
                'json' => [
65 55
                    'start' => (new \DateTime())->format('Y-m-d\TH:i:s\Z'),
66 55
                    'description' => getenv('timer_description'),
67 55
                    'projectId' => getenv('timer_project_id'),
68 55
                    'tagIds' => getenv('timer_tag_id') ? [getenv('timer_tag_id')] : [''],
69
                ]
70
            ]);
71
72 55
            $timer = json_decode($response->getBody()->getContents());
73
74 55
            if (! isset($timer->id)) {
75 55
                return false;
76
            }
77
        } 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
            return false;
79
        }
80
81 55
        return $timer->id;
82
    }
83
84 55
    public function stopCurrentTimer()
85
    {
86 55
        $user = json_decode(
87 55
            $this->client->get("user")->getBody()->getContents()
88
        );
89
90 55
        if ($this->runningTimer()) {
91 55
            $response = $this->client->patch("workspaces/{$user->activeWorkspace}/user/{$user->id}/time-entries", [
92
                'json' => [
93 55
                    'end' => (new \DateTime())->format('Y-m-d\TH:i:s\Z'),
94
                ]
95
            ]) ;
96
97 55
            $timer = json_decode($response->getBody()->getContents());
98
99 55
            if (! isset($timer->timeInterval->end)) {
100
                throw new Exception("Can't stop current running timer.", 1);
101
            }
102
103 55
            return true;
104
        }
105
106 11
        return false;
107
    }
108
109 55
    public function runningTimer()
110
    {
111
        try {
112 55
            $user = json_decode(
113 55
                $this->client->get("user")->getBody()->getContents()
114
            );
115
116 55
            $response = $this->client->get(
117 55
                "workspaces/{$user->activeWorkspace}/user/{$user->id}/time-entries?in-progress=true"
118
            );
119
120 55
            $timer = json_decode($response->getBody()->getContents());
121
122 55
            return $timer[0]->id ?? false;
123
        } catch (\Exception $e) {
124
            return false;
125
        }
126
127
        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
130 11
    public function pastTimers()
131
    {
132
        try {
133 11
            $user = json_decode(
134 11
                $this->client->get("user")->getBody()->getContents()
135
            );
136
137 11
            $response = $this->client->get("workspaces/{$user->activeWorkspace}/user/{$user->id}/time-entries", [
138 11
                'start' => Carbon::today(),
139 11
                'end' => Carbon::today()->subDays(30),
140
            ]);
141 11
            $clockifyTimers = json_decode($response->getBody()->getContents());
142
143 11
            return $this->convertToPastTimers($clockifyTimers);
144
        } catch (Exception $e) {
145
            return [];
146
        }
147
    }
148
149 11
    public function continueTimer($timerId = null)
150
    {
151
        /**
152
         * Timer attributes are stored in env variables
153
         * gathered in startTimer.
154
         */
155 11
        return $this->startTimer();
156
    }
157
158 11
    protected function convertToPastTimers($clockifyTimers)
159
    {
160 11
        $projects = $this->projects();
161 11
        $tags = $this->tags();
162
163
        return array_map(function ($clockifyTimer) use ($projects, $tags) {
164 11
            return $this->buildPastTimerObject($clockifyTimer, $projects, $tags);
165 11
        }, $clockifyTimers);
166
    }
167
168 11
    protected function buildPastTimerObject($clockifyTimer, $projects, $tags)
169
    {
170 11
        $pastTimer = [];
171
172 11
        $pastTimer['id'] = $clockifyTimer->id;
173 11
        $pastTimer['description'] = $clockifyTimer->description;
174
175 11
        if (isset($clockifyTimer->projectId)) {
176 11
            $pastTimer['project_id'] = $clockifyTimer->projectId;
177 11
            $pastTimer['project_name'] = $projects[$clockifyTimer->projectId];
178
        }
179
180 11
        if (isset($clockifyTimer->tagIds[0])) {
181 11
            $pastTimer['tag_id'] = $clockifyTimer->tagIds[0];
182 11
            $pastTimer['tags'] = $tags[$clockifyTimer->tagIds[0]];
183
        }
184
185 11
        $pastTimer['duration'] = $clockifyTimer->timeInterval->duration;
186
187 11
        return (object) $pastTimer;
188
    }
189
}
190