Completed
Push — master ( fb6de7...e6e877 )
by Guillaume
05:24
created

Time::deleteServiceTimer()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 13
Code Lines 7

Duplication

Lines 6
Ratio 46.15 %

Importance

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