Completed
Push — master ( 7668c7...bd1406 )
by Guillaume
02:28
created

Time::startTimerWithDefaultOptions()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

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