Completed
Push — master ( 8a9213...8197b4 )
by Guillaume
02:13
created

Time::stopRunningTimer()   B

Complexity

Conditions 4
Paths 6

Size

Total Lines 22
Code Lines 11

Duplication

Lines 10
Ratio 45.45 %

Importance

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

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
486
            } else {
487
                $message .= '- ' . ucfirst($service) .': cannot cache data'."\r\n";
488
        }
489
490
        return $this->message;
491
    }
492
}
493