Completed
Push — master ( d60b64...cbd605 )
by Guillaume
02:13
created

Time::saveServiceDataCache()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 5
rs 9.4285
cc 1
eloc 3
nc 1
nop 2
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 array
18
     */
19
    private $currentImplementation = [
20
        'start'         => ['toggl'],
21
        'start_default' => ['toggl', 'harvest'],
22
        'stop'          => ['toggl', 'harvest'],
23
        'delete'        => ['toggl'],
24
    ];
25
26
    /**
27
     * @var mixed
28
     */
29
    private $harvest;
30
31
    /**
32
     * @var mixed
33
     */
34
    private $message;
35
36
    /**
37
     * @var array
38
     */
39
    private $services = [
40
        'toggl',
41
        'harvest',
42
    ];
43
44
    /**
45
     * @var mixed
46
     */
47
    private $toggl;
48
49
    public function __construct()
50
    {
51
        $this->config = new Config(getenv('alfred_workflow_data') . '/config.json');
52
53
        $this->harvest = new Harvest($this->config->get('harvest', 'domain'), $this->config->get('harvest', 'api_token'));
54
        $this->toggl = new Toggl($this->config->get('toggl', 'api_token'));
55
        $this->message = '';
56
    }
57
58
    /**
59
     * @return mixed
60
     */
61
    public function activatedServices()
62
    {
63
        $activatedServices = [];
64
65
        foreach ($this->services as $service) {
66
            if ($this->isServiceActive($service) === true) {
67
                array_push($activatedServices, $service);
68
            }
69
        }
70
71
        return $activatedServices;
72
    }
73
74
    /**
75
     * @param  $service
76
     * @param  $timerId
77
     * @return boolean
78
     */
79
    public function deleteServiceTimer($service, $timerId)
80
    {
81
        $res = false;
82
83
        if ($this->$service->deleteTimer($timerId) === true) {
84
            if ($timerId === $this->config->get('workflow', 'timer_' . $service . '_id')) {
85
                $this->config->update('workflow', 'timer_' . $service . '_id', null);
86
                $res = true;
87
            }
88
        }
89
90
        return $res;
91
    }
92
93
    /**
94
     * @param  $timerId
95
     * @return string
96
     */
97
    public function deleteTimer($timerId)
98
    {
99
        $message = '';
100
        $atLeastOneTimerDeleted = false;
101
102
        foreach ($this->implementedServicesForFeature('delete') as $service) {
103
            if ($this->deleteServiceTimer($service, $timerId) === true) {
104
                $atLeastOneTimerDeleted = true;
105
            }
106
107
            $message .= $this->$service->getLastMessage() . "\r\n";
108
        }
109
110
        if ($atLeastOneTimerDeleted === true) {
111
            $this->config->update('workflow', 'is_timer_running', false);
112
        }
113
114
        return $message;
115
    }
116
117
    public function generateDefaultConfigurationFile()
118
    {
119
        $this->config->generateDefaultConfigurationFile();
120
    }
121
122
    /**
123
     * @param  $projectId
124
     * @return mixed
125
     */
126
    public function getProjectName($projectId)
127
    {
128
        $projectName = '';
129
130
        $projects = $this->getProjects();
131
132
        foreach ($projects as $project) {
133
            if ($project['id'] === $projectId) {
134
                $projectName = $project['name'];
135
                break;
136
            }
137
        }
138
139
        return $projectName;
140
    }
141
142
    /**
143
     * @return mixed
144
     */
145
    public function getProjects()
146
    {
147
        $tempServices = ['toggl'];
148
        $projects = [];
149
150
/*
151
 * Temporary, only get the projects of Toggl
152
 * Later, we will get Harvest ones too
153
 */
154
        foreach ($tempServices as $service) {
155
            if ($this->isServiceActive($service) === true) {
156
                $cacheFile = getenv('alfred_workflow_data') . '/' . $service . '_cache.json';
157
158
                if (file_exists($cacheFile)) {
159
                    $projects = json_decode(file_get_contents($cacheFile), true);
160
161
/*
162
 * To only show projects that are currently active
163
 * The Toggl API is slightly weird on that
164
 */
165
                    foreach ($projects['data']['projects'] as $key => $project) {
166
                        if (isset($project['server_deleted_at']) === true) {
167
                            unset($projects['data']['projects'][$key]);
168
                        }
169
                    }
170
171
                    $projects = $projects['data']['projects'];
172
                }
173
            }
174
        }
175
176
        return $projects;
177
    }
178
179
    /**
180
     * @return mixed
181
     */
182
    public function getRecentTimers()
183
    {
184
        $timers = [];
185
186
        if ($this->isServiceActive('toggl') === true) {
187
            $timers = array_merge($timers, $this->getRecentTogglTimers());
188
        }
189
190
        return $timers;
191
    }
192
193
    /**
194
     * @return mixed
195
     */
196
    public function getTags()
197
    {
198
        $tags = [];
199
200
        if ($this->isServiceActive('toggl') === true) {
201
            $tags = array_merge($tags, $this->getTogglTags());
202
        }
203
204
        return $tags;
205
    }
206
207
    /**
208
     * @return mixed
209
     */
210
    public function getTimerDescription()
211
    {
212
        return $this->config->get('workflow', 'timer_description');
213
    }
214
215
    /**
216
     * @return boolean
217
     */
218
    public function hasTimerRunning()
219
    {
220
        return $this->config->get('workflow', 'is_timer_running') === false ? false : true;
221
    }
222
223
    /**
224
     * @param  string  $feature
225
     * @return mixed
226
     */
227
    public function implementedServicesForFeature($feature = null)
228
    {
229
        $services = [];
230
231
        if (isset($this->currentImplementation[$feature]) === true) {
232
            $services = $this->currentImplementation[$feature];
233
        }
234
235
        return $services;
236
    }
237
238
    /**
239
     * @return boolean
240
     */
241
    public function isConfigured()
242
    {
243
        return $this->config === null ? false : true;
244
    }
245
246
    /**
247
     * @param  $service
248
     * @return mixed
249
     */
250
    public function isServiceActive($service)
251
    {
252
        return $this->config->get($service, 'is_active');
253
    }
254
255
    /**
256
     * @return mixed
257
     */
258
    public function servicesToUndo()
259
    {
260
        $services = [];
261
262
        foreach ($this->activatedServices() as $service) {
263
            if ($this->config->get('workflow', 'timer_' . $service . '_id') !== null) {
264
                array_push($services, $service);
265
            }
266
        }
267
268
        return $services;
269
    }
270
271
    /**
272
     * @param  $description
273
     * @param  $projectsDefault
274
     * @param  null               $tagsDefault
275
     * @param  boolean            $startDefault
276
     * @return string
277
     */
278
    public function startTimer($description = '', $projectsDefault = null, $tagsDefault = null, $startDefault = false)
279
    {
280
        $message = '';
281
        $startType = $startDefault === true ? 'start_default' : 'start';
282
        $atLeastOneServiceStarted = false;
283
        $implementedServices = $this->implementedServicesForFeature($startType);
284
285
/*
286
 * When starting a new timer, all the services timer IDs have to be put to null
287
 * so that when the user uses the UNDO feature, it doesn't delete old previous
288
 * other services timers. The timer IDs are used for the UNDO feature and
289
 * should then contain the IDs of the last starts through the workflow, not
290
 * through each individual sefrvice
291
 */
292
        if (empty($implementedServices) === false) {
293
            foreach ($this->activatedServices() as $service) {
294
                $this->config->update('workflow', 'timer_' . $service . '_id', null);
295
            }
296
297
            foreach ($implementedServices as $service) {
298
                $defaultProjectId = isset($projectsDefault[$service]) ? $projectsDefault[$service] : null;
299
                $defaultTags = isset($tagsDefault[$service]) ? $tagsDefault[$service] : null;
300
301
                $timerId = $this->$service->startTimer($description, $defaultProjectId, $defaultTags);
302
                $this->config->update('workflow', 'timer_' . $service . '_id', $timerId);
303
304
                if ($timerId !== null) {
305
                    $atLeastOneServiceStarted = true;
306
                }
307
308
                $message .= $this->$service->getLastMessage() . "\r\n";
309
            }
310
        }
311
312
        if ($atLeastOneServiceStarted === true) {
313
            $this->config->update('workflow', 'timer_description', $description);
314
            $this->config->update('workflow', 'is_timer_running', true);
315
        }
316
317
        return $message;
318
    }
319
320
    /**
321
     * @param  $description
322
     * @return string
323
     */
324
    public function startTimerWithDefaultOptions($description)
325
    {
326
        $projectsDefault = [
327
            'toggl'   => $this->config->get('toggl', 'default_project_id'),
328
            'harvest' => $this->config->get('harvest', 'default_project_id'),
329
        ];
330
331
        $tagsDefault = [
332
            'toggl'   => $this->config->get('toggl', 'default_tags'),
333
            'harvest' => $this->config->get('harvest', 'default_task_id'),
334
        ];
335
336
        return $this->startTimer($description, $projectsDefault, $tagsDefault, true);
337
    }
338
339
    /**
340
     * @return string
341
     */
342
    public function stopRunningTimer()
343
    {
344
        $message = '';
345
        $atLeastOneServiceStopped = false;
346
347 View Code Duplication
        foreach ($this->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...
348
            $timerId = $this->config->get('workflow', 'timer_' . $service . '_id');
349
350
            if ($this->$service->stopTimer($timerId) === true) {
351
                $atLeastOneServiceStopped = true;
352
            }
353
354
            $message .= $this->$service->getLastMessage() . "\r\n";
355
        }
356
357
        if ($atLeastOneServiceStopped === true) {
358
            $this->config->update('workflow', 'is_timer_running', false);
359
        }
360
361
        return $message;
362
    }
363
364
    /**
365
     * @return string
366
     */
367
    public function syncOnlineDataToLocalCache()
368
    {
369
        $message = '';
370
371
        if ($this->isServiceActive('toggl') === true) {
372
            $message .= $this->syncServiceOnlineDataToLocalCache('toggl');
373
        }
374
375
        return $message;
376
    }
377
378
    /**
379
     * @return string
380
     */
381
    public function undoTimer()
382
    {
383
        $message = '';
384
385
        if ($this->hasTimerRunning() === true) {
386
            $this->stopRunningTimer();
387
        }
388
389
        $atLeastOneTimerDeleted = false;
390
391 View Code Duplication
        foreach ($this->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...
392
            if ($this->deleteServiceTimer($service, $this->config->get('workflow', 'timer_' . $service . '_id')) === true) {
393
                $atLeastOneTimerDeleted = true;
394
            }
395
396
            $message .= $this->$service->getLastMessage() . "\r\n";
397
        }
398
399
        if ($atLeastOneTimerDeleted === true) {
400
            $this->config->update('workflow', 'is_timer_running', false);
401
        }
402
403
        return $message;
404
    }
405
406
    /**
407
     * @return mixed
408
     */
409
    private function getRecentTogglTimers()
410
    {
411
        return $this->toggl->getRecentTimers();
412
    }
413
414
    /**
415
     * @return mixed
416
     */
417
    private function getTogglTags()
418
    {
419
        $cacheFile = getenv('alfred_workflow_data') . '/toggl_cache.json';
420
        $cacheData = [];
421
422
        if (file_exists($cacheFile)) {
423
            $cacheData = json_decode(file_get_contents($cacheFile), true);
424
        }
425
426
        return $cacheData['data']['tags'];
427
    }
428
429
    /**
430
     * @param $data
431
     */
432
    private function saveServiceDataCache($service, $data)
433
    {
434
        $cacheFile = getenv('alfred_workflow_data') . '/' . $service . '_cache.json';
435
        file_put_contents($cacheFile, json_encode($data));
436
    }
437
438
    /**
439
     * @return mixed
440
     */
441
    private function syncServiceOnlineDataToLocalCache($service)
0 ignored issues
show
Unused Code introduced by
The parameter $service is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
442
    {
443
        $tempServices = ['toggl'];
444
445
        foreach ($tempServices as $service) {
446
            $data = $this->$service->getOnlineData();
447
            $this->message .= $this->$service->getLastMessage();
448
449
            if (empty($data) === false) {
450
                $this->saveServiceDataCache($service, $data);
451
            }
452
        }
453
454
        return $this->message;
455
    }
456
}
457