Completed
Push — master ( 945b79...1bf282 )
by Guillaume
03:07 queued 52s
created

Time::isServiceActive()   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 1
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 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...
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
                $projects = $this->getServiceProjects($service);
157
            }
158
        }
159
160
        return $projects;
161
    }
162
163
    /**
164
     * @return mixed
165
     */
166 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...
167
    {
168
        $tempServices = ['toggl'];
169
        $timers = [];
170
171
        foreach ($tempServices as $service) {
172
            if ($this->isServiceActive($service) === true) {
173
                $timers = array_merge($timers, $this->getRecentServiceTimers($service));
174
            }
175
        }
176
177
        return $timers;
178
    }
179
180
    /**
181
     * @param  $service
182
     * @return mixed
183
     */
184
    public function getServiceDataCache($service)
185
    {
186
        $data = [];
187
        $cacheFile = getenv('alfred_workflow_data') . '/' . $service . '_cache.json';
188
189
        if (file_exists($cacheFile)) {
190
            $data = json_decode(file_get_contents($cacheFile), true);
191
        }
192
193
        return $data;
194
    }
195
196
    /**
197
     * @param $service
198
     */
199
    public function getServiceProjects($service)
200
    {
201
        $projects = $this->getServiceDataCache($service);
202
203
        if (isset($projects['data']['projects']) === true) {
204
/*
205
 * To only show projects that are currently active
206
 * The Toggl API is slightly weird on that
207
 */
208
            foreach ($projects['data']['projects'] as $key => $project) {
209
                if (isset($project['server_deleted_at']) === true) {
210
                    unset($projects['data']['projects'][$key]);
211
                }
212
            }
213
214
            $projects = $projects['data']['projects'];
215
        }
216
217
        return $projects;
218
    }
219
220
    /**
221
     * @return mixed
222
     */
223 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...
224
    {
225
        $tempServices = ['toggl'];
226
        $tags = [];
227
228
        foreach ($tempServices as $service) {
229
            if ($this->isServiceActive($service) === true) {
230
                $tags = array_merge($tags, $this->getServiceTags($service));
231
            }
232
        }
233
234
        return $tags;
235
    }
236
237
    /**
238
     * @return mixed
239
     */
240
    public function getTimerDescription()
241
    {
242
        return $this->config->get('workflow', 'timer_description');
243
    }
244
245
    /**
246
     * @return boolean
247
     */
248
    public function hasTimerRunning()
249
    {
250
        return $this->config->get('workflow', 'is_timer_running') === false ? false : true;
251
    }
252
253
    /**
254
     * @param  string  $feature
255
     * @return mixed
256
     */
257
    public function implementedServicesForFeature($feature = null)
258
    {
259
        $services = [];
260
261
        if (isset($this->currentImplementation[$feature]) === true) {
262
            $services = $this->currentImplementation[$feature];
263
        }
264
265
        return $services;
266
    }
267
268
    /**
269
     * @return boolean
270
     */
271
    public function isConfigured()
272
    {
273
        return $this->config === null ? false : true;
274
    }
275
276
    /**
277
     * @param  $service
278
     * @return mixed
279
     */
280
    public function isServiceActive($service)
281
    {
282
        return $this->config->get($service, 'is_active');
283
    }
284
285
    /**
286
     * @return mixed
287
     */
288
    public function servicesToUndo()
289
    {
290
        $services = [];
291
292
        foreach ($this->activatedServices() as $service) {
293
            if ($this->config->get('workflow', 'timer_' . $service . '_id') !== null) {
294
                array_push($services, $service);
295
            }
296
        }
297
298
        return $services;
299
    }
300
301
    /**
302
     * @param  $description
303
     * @param  $projectsDefault
304
     * @param  null               $tagsDefault
305
     * @param  boolean            $startDefault
306
     * @return string
307
     */
308
    public function startTimer($description = '', $projectsDefault = null, $tagsDefault = null, $startDefault = false)
309
    {
310
        $message = '';
311
        $startType = $startDefault === true ? 'start_default' : 'start';
312
        $atLeastOneServiceStarted = false;
313
        $implementedServices = $this->implementedServicesForFeature($startType);
314
315
/*
316
 * When starting a new timer, all the services timer IDs have to be put to null
317
 * so that when the user uses the UNDO feature, it doesn't delete old previous
318
 * other services timers. The timer IDs are used for the UNDO feature and
319
 * should then contain the IDs of the last starts through the workflow, not
320
 * through each individual sefrvice
321
 */
322
        if (empty($implementedServices) === false) {
323
            foreach ($this->activatedServices() as $service) {
324
                $this->config->update('workflow', 'timer_' . $service . '_id', null);
325
            }
326
327
            foreach ($implementedServices as $service) {
328
                $defaultProjectId = isset($projectsDefault[$service]) ? $projectsDefault[$service] : null;
329
                $defaultTags = isset($tagsDefault[$service]) ? $tagsDefault[$service] : null;
330
331
                $timerId = $this->$service->startTimer($description, $defaultProjectId, $defaultTags);
332
                $this->config->update('workflow', 'timer_' . $service . '_id', $timerId);
333
334
                if ($timerId !== null) {
335
                    $atLeastOneServiceStarted = true;
336
                }
337
338
                $message .= $this->$service->getLastMessage() . "\r\n";
339
            }
340
        }
341
342
        if ($atLeastOneServiceStarted === true) {
343
            $this->config->update('workflow', 'timer_description', $description);
344
            $this->config->update('workflow', 'is_timer_running', true);
345
        }
346
347
        return $message;
348
    }
349
350
    /**
351
     * @param  $description
352
     * @return string
353
     */
354
    public function startTimerWithDefaultOptions($description)
355
    {
356
        $projectsDefault = [
357
            'toggl'   => $this->config->get('toggl', 'default_project_id'),
358
            'harvest' => $this->config->get('harvest', 'default_project_id'),
359
        ];
360
361
        $tagsDefault = [
362
            'toggl'   => $this->config->get('toggl', 'default_tags'),
363
            'harvest' => $this->config->get('harvest', 'default_task_id'),
364
        ];
365
366
        return $this->startTimer($description, $projectsDefault, $tagsDefault, true);
367
    }
368
369
    /**
370
     * @return string
371
     */
372
    public function stopRunningTimer()
373
    {
374
        $message = '';
375
        $atLeastOneServiceStopped = false;
376
377 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...
378
            $timerId = $this->config->get('workflow', 'timer_' . $service . '_id');
379
380
            if ($this->$service->stopTimer($timerId) === true) {
381
                $atLeastOneServiceStopped = true;
382
            }
383
384
            $message .= $this->$service->getLastMessage() . "\r\n";
385
        }
386
387
        if ($atLeastOneServiceStopped === true) {
388
            $this->config->update('workflow', 'is_timer_running', false);
389
        }
390
391
        return $message;
392
    }
393
394
    /**
395
     * @return string
396
     */
397 View Code Duplication
    public function syncOnlineDataToLocalCache()
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...
398
    {
399
        $tempServices = ['toggl'];
400
        $message = '';
401
402
        foreach ($tempServices as $service) {
403
            if ($this->isServiceActive($service) === true) {
404
                $message .= $this->syncServiceOnlineDataToLocalCache($service);
405
            }
406
        }
407
408
        return $message;
409
    }
410
411
    /**
412
     * @return string
413
     */
414
    public function undoTimer()
415
    {
416
        $message = '';
417
418
        if ($this->hasTimerRunning() === true) {
419
            $this->stopRunningTimer();
420
        }
421
422
        $atLeastOneTimerDeleted = false;
423
424 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...
425
            if ($this->deleteServiceTimer($service, $this->config->get('workflow', 'timer_' . $service . '_id')) === true) {
426
                $atLeastOneTimerDeleted = true;
427
            }
428
429
            $message .= $this->$service->getLastMessage() . "\r\n";
430
        }
431
432
        if ($atLeastOneTimerDeleted === true) {
433
            $this->config->update('workflow', 'is_timer_running', false);
434
        }
435
436
        return $message;
437
    }
438
439
    /**
440
     * @return mixed
441
     */
442
    private function getRecentServiceTimers($service)
443
    {
444
        return $this->$service->getRecentTimers();
445
    }
446
447
    /**
448
     * @return mixed
449
     */
450
    private function getServiceTags($service)
451
    {
452
        $tags = $this->getServiceDataCache($service);
453
454
        if (isset($tags['data']['tags']) === true) {
455
            $tags = $tags['data']['tags'];
456
        }
457
458
        return $tags;
459
    }
460
461
    /**
462
     * @param $data
463
     * @param string  $service
464
     */
465
    private function saveServiceDataCache($service, $data)
466
    {
467
        $cacheFile = getenv('alfred_workflow_data') . '/' . $service . '_cache.json';
468
        file_put_contents($cacheFile, json_encode($data));
469
    }
470
471
    /**
472
     * @param  string  $service
473
     * @return mixed
474
     */
475
    private function syncServiceOnlineDataToLocalCache($service)
476
    {
477
        $data = $this->$service->getOnlineData();
478
        $this->message .= $this->$service->getLastMessage();
479
480
        if (empty($data) === false) {
481
            $this->saveServiceDataCache($service, $data);
482
        }
483
484
        return $this->message;
485
    }
486
}
487