Completed
Push — master ( fcda40...c34931 )
by Guillaume
02:05
created

Time::getTimerDescription()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
3
namespace AlfredTime;
4
5
use AlfredTime\Toggl;
6
use AlfredTime\Config;
7
use AlfredTime\Harvest;
8
9
class Time
10
{
11
    /**
12
     * @var mixed
13
     */
14
    private $config;
15
16
    /**
17
     * @var mixed
18
     */
19
    private $harvest;
20
21
    /**
22
     * @var mixed
23
     */
24
    private $toggl;
25
26
    /**
27
     * @param Config $config
28
     */
29
    public function __construct(Config $config = null)
30
    {
31
        $this->config = $config;
32
        $this->harvest = new Harvest($this->config->get('harvest', 'domain'), $this->config->get('harvest', 'api_token'));
33
        $this->toggl = new Toggl($this->config->get('toggl', 'api_token'));
34
    }
35
36
    /**
37
     * @param  $service
38
     * @param  $timerId
39
     * @return boolean
40
     */
41
    public function deleteServiceTimer($service, $timerId)
42
    {
43
        $res = false;
44
45
        if ($this->$service->deleteTimer($timerId) === true) {
46
            if ($timerId === $this->config->get('workflow', 'timer_' . $service . '_id')) {
47
                $this->config->update('workflow', 'timer_' . $service . '_id', null);
48
                $res = true;
49
            }
50
        }
51
52
        return $res;
53
    }
54
55
    /**
56
     * @param  $timerId
57
     * @return string
58
     */
59
    public function deleteTimer($timerId)
60
    {
61
        $message = '';
62
        $atLeastOneTimerDeleted = false;
63
64
        foreach ($this->config->implementedServicesForFeature('delete') as $service) {
65
            if ($this->deleteServiceTimer($service, $timerId) === true) {
66
                $atLeastOneTimerDeleted = true;
67
                $message .= '- ' . ucfirst($service) . ': deleted' . "\r\n";
68
            } else {
69
                $message .= '- ' . ucfirst($service) . ': cannot delete' . "\r\n";
70
            }
71
        }
72
73
        if ($atLeastOneTimerDeleted === true) {
74
            $this->config->update('workflow', 'is_timer_running', false);
75
        }
76
77
        return $message;
78
    }
79
80
    /**
81
     * @param  $projectId
82
     * @return mixed
83
     */
84
    public function getProjectName($projectId)
85
    {
86
        $projectName = '';
87
88
        $projects = $this->getProjects();
89
90
        foreach ($projects as $project) {
91
            if ($project['id'] === $projectId) {
92
                $projectName = $project['name'];
93
                break;
94
            }
95
        }
96
97
        return $projectName;
98
    }
99
100
    /**
101
     * @return mixed
102
     */
103 View Code Duplication
    public function getProjects()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
104
    {
105
        $projects = [];
106
107
/*
108
 * Temporary, only get the projects of Toggl
109
 * Later, we will get Harvest ones too
110
 */
111
        foreach ($this->config->implementedServicesForFeature('get_projects') as $service) {
112
            if ($this->config->isServiceActive($service) === true) {
113
                $projects = $this->getServiceProjects($service);
114
            }
115
        }
116
117
        return $projects;
118
    }
119
120
    /**
121
     * @return mixed
122
     */
123 View Code Duplication
    public function getRecentTimers()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
124
    {
125
        $timers = [];
126
127
        foreach ($this->config->implementedServicesForFeature('get_timers') as $service) {
128
            if ($this->config->isServiceActive($service) === true) {
129
                $timers = array_merge($timers, $this->getRecentServiceTimers($service));
130
            }
131
        }
132
133
        return $timers;
134
    }
135
136
    /**
137
     * @param  $service
138
     * @return mixed
139
     */
140
    public function getServiceDataCache($service)
141
    {
142
        $data = [];
143
        $cacheFile = getenv('alfred_workflow_data') . '/' . $service . '_cache.json';
144
145
        if (file_exists($cacheFile)) {
146
            $data = json_decode(file_get_contents($cacheFile), true);
147
        }
148
149
        return $data;
150
    }
151
152
    /**
153
     * @param $service
154
     */
155
    public function getServiceProjects($service)
156
    {
157
        $projects = $this->getServiceDataCache($service);
158
159
        if (isset($projects['data']['projects']) === true) {
160
/*
161
 * To only show projects that are currently active
162
 * The Toggl API is slightly weird on that
163
 */
164
            foreach ($projects['data']['projects'] as $key => $project) {
165
                if (isset($project['server_deleted_at']) === true) {
166
                    unset($projects['data']['projects'][$key]);
167
                }
168
            }
169
170
            $projects = $projects['data']['projects'];
171
        }
172
173
        return $projects;
174
    }
175
176
    /**
177
     * @return mixed
178
     */
179 View Code Duplication
    public function getTags()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
180
    {
181
        $tags = [];
182
183
        foreach ($this->config->implementedServicesForFeature('get_tags') as $service) {
184
            if ($this->config->isServiceActive($service) === true) {
185
                $tags = array_merge($tags, $this->getServiceTags($service));
186
            }
187
        }
188
189
        return $tags;
190
    }
191
192
    /**
193
     * @return mixed
194
     */
195
    public function getTimerDescription()
196
    {
197
        return $this->config->get('workflow', 'timer_description');
198
    }
199
200
    /**
201
     * @return boolean
202
     */
203
    public function hasTimerRunning()
204
    {
205
        return $this->config->get('workflow', 'is_timer_running') === false ? false : true;
206
    }
207
208
    /**
209
     * @param  $description
210
     * @param  $projectsDefault
211
     * @param  null               $tagsDefault
212
     * @param  boolean            $startDefault
213
     * @return string
214
     */
215
    public function startTimer($description = '', $projectsDefault = null, $tagsDefault = null, $startDefault = false)
216
    {
217
        $message = '';
218
        $startType = $startDefault === true ? 'start_default' : 'start';
219
        $atLeastOneServiceStarted = false;
220
        $implementedServices = $this->config->implementedServicesForFeature($startType);
221
222
/*
223
 * When starting a new timer, all the services timer IDs have to be put to null
224
 * so that when the user uses the UNDO feature, it doesn't delete old previous
225
 * other services timers. The timer IDs are used for the UNDO feature and
226
 * should then contain the IDs of the last starts through the workflow, not
227
 * through each individual sefrvice
228
 */
229
        if (empty($implementedServices) === false) {
230
            foreach ($this->config->activatedServices() as $service) {
231
                $this->config->update('workflow', 'timer_' . $service . '_id', null);
232
            }
233
234
            foreach ($implementedServices as $service) {
235
                $defaultProjectId = isset($projectsDefault[$service]) ? $projectsDefault[$service] : null;
236
                $defaultTags = isset($tagsDefault[$service]) ? $tagsDefault[$service] : null;
237
238
                $timerId = $this->$service->startTimer($description, $defaultProjectId, $defaultTags);
239
                $this->config->update('workflow', 'timer_' . $service . '_id', $timerId);
240
241
                if ($timerId !== null) {
242
                    $atLeastOneServiceStarted = true;
243
                    $message .= '- ' . ucfirst($service) . ': started' . "\r\n";
244
                } else {
245
                    $message .= '- ' . ucfirst($service) . ': cannot start' . "\r\n";
246
                }
247
            }
248
        }
249
250
        if ($atLeastOneServiceStarted === true) {
251
            $this->config->update('workflow', 'timer_description', $description);
252
            $this->config->update('workflow', 'is_timer_running', true);
253
        }
254
255
        return $message;
256
    }
257
258
    /**
259
     * @param  $description
260
     * @return string
261
     */
262
    public function startTimerWithDefaultOptions($description)
263
    {
264
        $projectsDefault = [
265
            'toggl'   => $this->config->get('toggl', 'default_project_id'),
266
            'harvest' => $this->config->get('harvest', 'default_project_id'),
267
        ];
268
269
        $tagsDefault = [
270
            'toggl'   => $this->config->get('toggl', 'default_tags'),
271
            'harvest' => $this->config->get('harvest', 'default_task_id'),
272
        ];
273
274
        return $this->startTimer($description, $projectsDefault, $tagsDefault, true);
275
    }
276
277
    /**
278
     * @return string
279
     */
280
    public function stopRunningTimer()
281
    {
282
        $message = '';
283
        $atLeastOneServiceStopped = false;
284
285 View Code Duplication
        foreach ($this->config->activatedServices() as $service) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
286
            $timerId = $this->config->get('workflow', 'timer_' . $service . '_id');
287
288
            if ($this->$service->stopTimer($timerId) === true) {
289
                $atLeastOneServiceStopped = true;
290
                $message .= '- ' . ucfirst($service) . ': stopped' . "\r\n";
291
            } else {
292
                $message .= '- ' . ucfirst($service) . ': cannot stop' . "\r\n";
293
            }
294
        }
295
296
        if ($atLeastOneServiceStopped === true) {
297
            $this->config->update('workflow', 'is_timer_running', false);
298
        }
299
300
        return $message;
301
    }
302
303
    /**
304
     * @return string
305
     */
306
    public function syncOnlineDataToLocalCache()
307
    {
308
        $message = '';
309
310
        foreach ($this->implementedServicesForFeature('sync_data') as $service) {
0 ignored issues
show
Bug introduced by
The method implementedServicesForFeature() does not seem to exist on object<AlfredTime\Time>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
311
            if ($this->isServiceActive($service) === true) {
0 ignored issues
show
Bug introduced by
The method isServiceActive() does not seem to exist on object<AlfredTime\Time>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
312
                $message .= $this->syncServiceOnlineDataToLocalCache($service);
313
            }
314
        }
315
316
        return $message;
317
    }
318
319
    /**
320
     * @return string
321
     */
322
    public function undoTimer()
323
    {
324
        $message = '';
325
326
        if ($this->hasTimerRunning() === true) {
327
            $this->stopRunningTimer();
328
        }
329
330
        $atLeastOneTimerDeleted = false;
331
332 View Code Duplication
        foreach ($this->config->servicesToUndo() as $service) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
333
            if ($this->deleteServiceTimer($service, $this->config->get('workflow', 'timer_' . $service . '_id')) === true) {
334
                $atLeastOneTimerDeleted = true;
335
                $message .= '- ' . ucfirst($service) . ': undid' . "\r\n";
336
            } else {
337
                $message .= '- ' . ucfirst($service) . ': cannot undo' . "\r\n";
338
            }
339
        }
340
341
        if ($atLeastOneTimerDeleted === true) {
342
            $this->config->update('workflow', 'is_timer_running', false);
343
        }
344
345
        return $message;
346
    }
347
348
    /**
349
     * @return mixed
350
     */
351
    private function getRecentServiceTimers($service)
352
    {
353
        return $this->$service->getRecentTimers();
354
    }
355
356
    /**
357
     * @return mixed
358
     */
359
    private function getServiceTags($service)
360
    {
361
        $tags = $this->getServiceDataCache($service);
362
363
        if (isset($tags['data']['tags']) === true) {
364
            $tags = $tags['data']['tags'];
365
        }
366
367
        return $tags;
368
    }
369
370
    /**
371
     * @param $data
372
     * @param string  $service
373
     */
374
    private function saveServiceDataCache($service, $data)
375
    {
376
        $cacheFile = getenv('alfred_workflow_data') . '/' . $service . '_cache.json';
377
        file_put_contents($cacheFile, json_encode($data));
378
    }
379
380
    /**
381
     * @param  string   $service
382
     * @return string
383
     */
384
    private function syncServiceOnlineDataToLocalCache($service)
385
    {
386
        $message = '';
387
        $data = $this->$service->getOnlineData();
388
389
        if (empty($data) === false) {
390
            $this->saveServiceDataCache($service, $data);
391
            $message .= '- ' . ucfirst($service) . ': data cached' . "\r\n";
392
        } else {
393
            $message .= '- ' . ucfirst($service) . ': cannot cache data' . "\r\n";
394
        }
395
396
        return $message;
397
    }
398
}
399