Completed
Push — master ( df44ca...d60b64 )
by Guillaume
02:23
created

Time::getProjects()   B

Complexity

Conditions 6
Paths 6

Size

Total Lines 35
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 35
rs 8.439
cc 6
eloc 14
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
    ];
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
        $services = ['toggl'];
0 ignored issues
show
Unused Code introduced by
$services is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

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