Completed
Push — master ( 700cfb...d47114 )
by Guillaume
02:09
created

AlfredTime::generateDefaultConfigurationFile()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

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