Completed
Push — master ( cbd605...af7e3b )
by Guillaume
02:17
created

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