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

Clockify   A

Complexity

Total Complexity 21

Size/Duplication

Total Lines 177
Duplicated Lines 0 %

Test Coverage

Coverage 91.76%

Importance

Changes 2
Bugs 0 Features 1
Metric Value
wmc 21
eloc 84
c 2
b 0
f 1
dl 0
loc 177
ccs 78
cts 85
cp 0.9176
rs 10

10 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 7 1
A projects() 0 16 2
A stopCurrentTimer() 0 23 3
A tags() 0 11 2
A startTimer() 0 24 4
A runningTimer() 0 16 2
A convertToPastTimers() 0 8 1
A pastTimers() 0 16 2
A continueTimer() 0 7 1
A buildPastTimerObject() 0 20 3
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 54
    public function startTimer()
59
    {
60
        try {
61 54
            $workspaceId = Workflow::getConfig()->read('clockify.active_workspace_id');
62
63 54
            $response = $this->client->post("workspaces/$workspaceId/time-entries", [
64 20
                'json' => [
65 54
                    'start' => (new \DateTime())->format('Y-m-d\TH:i:s\Z'),
66 54
                    'description' => getenv('timer_description'),
67 54
                    'projectId' => getenv('timer_project_id'),
68 54
                    'tagIds' => getenv('timer_tag_id') ? [getenv('timer_tag_id')] : [''],
69
                ]
70
            ]);
71
72 54
            $timer = json_decode($response->getBody()->getContents());
73
74 54
            if (! isset($timer->id)) {
75 54
                return false;
76
            }
77
        } catch (\Exception $e) {
78
            return false;
79
        }
80
81 54
        return $timer->id;
82
    }
83
84 56
    public function stopCurrentTimer()
85
    {
86 56
        $user = json_decode(
87 56
            $this->client->get("user")->getBody()->getContents()
88
        );
89
90 56
        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 12
        return false;
107
    }
108
109 81
    public function runningTimer()
110
    {
111
        try {
112 81
            $user = json_decode(
113 81
                $this->client->get("user")->getBody()->getContents()
114
            );
115
116 81
            $response = $this->client->get(
117 81
                "workspaces/{$user->activeWorkspace}/user/{$user->id}/time-entries?in-progress=true"
118
            );
119
120 81
            $timer = json_decode($response->getBody()->getContents());
121
122 81
            return $timer[0]->id ?? false;
123
        } catch (\Exception $e) {
124
            return false;
125
        }
126
    }
127
128 11
    public function pastTimers()
129
    {
130
        try {
131 11
            $user = json_decode(
132 11
                $this->client->get("user")->getBody()->getContents()
133
            );
134
135 11
            $response = $this->client->get("workspaces/{$user->activeWorkspace}/user/{$user->id}/time-entries", [
136 11
                'start' => Carbon::today(),
137 11
                'end' => Carbon::today()->subDays(30),
138
            ]);
139 11
            $clockifyTimers = json_decode($response->getBody()->getContents());
140
141 11
            return $this->convertToPastTimers($clockifyTimers);
142
        } catch (\Exception $e) {
143
            return [];
144
        }
145
    }
146
147 11
    public function continueTimer($timerId = null)
148
    {
149
        /**
150
         * Timer attributes are stored in env variables
151
         * gathered in startTimer.
152
         */
153 11
        return $this->startTimer();
154
    }
155
156 11
    protected function convertToPastTimers($clockifyTimers)
157
    {
158 11
        $projects = $this->projects();
159 11
        $tags = $this->tags();
160
161
        return array_map(function ($clockifyTimer) use ($projects, $tags) {
162 11
            return $this->buildPastTimerObject($clockifyTimer, $projects, $tags);
163 11
        }, $clockifyTimers);
164
    }
165
166 11
    protected function buildPastTimerObject($clockifyTimer, $projects, $tags)
167
    {
168 11
        $pastTimer = [];
169
170 11
        $pastTimer['id'] = $clockifyTimer->id;
171 11
        $pastTimer['description'] = $clockifyTimer->description;
172
173 11
        if (isset($clockifyTimer->projectId)) {
174 11
            $pastTimer['project_id'] = $clockifyTimer->projectId;
175 11
            $pastTimer['project_name'] = $projects[$clockifyTimer->projectId];
176
        }
177
178 11
        if (isset($clockifyTimer->tagIds[0])) {
179 11
            $pastTimer['tag_id'] = $clockifyTimer->tagIds[0];
180 11
            $pastTimer['tags'] = $tags[$clockifyTimer->tagIds[0]];
181
        }
182
183 11
        $pastTimer['duration'] = $clockifyTimer->timeInterval->duration;
184
185 11
        return (object) $pastTimer;
186
    }
187
}
188