Completed
Push — master ( fa62a0...64cd69 )
by Guillaume
04:06
created

Time::isConfigured()   A

Complexity

Conditions 2
Paths 2

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 2
eloc 2
nc 2
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  $timerId
76
     * @return string
77
     */
78
    public function deleteTimer($timerId)
79
    {
80
        $message = '';
81
82
        $atLeastOneTimerDeleted = false;
83
84 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...
85
            if ($this->$service->deleteTimer($timerId) === true) {
86
                if ($timerId === $this->config->get('workflow', 'timer_' . $service . '_id')) {
87
                    $this->config->update('workflow', 'timer_' . $service . '_id', null);
88
                    $atLeastOneTimerDeleted = true;
89
                }
90
            }
91
92
            $message .= $this->$service->getLastMessage() . "\r\n";
93
        }
94
95
        if ($atLeastOneTimerDeleted === true) {
96
            $this->config->update('workflow', 'is_timer_running', false);
97
        }
98
99
        return $message;
100
    }
101
102
    public function generateDefaultConfigurationFile()
103
    {
104
        $this->config->generateDefaultConfigurationFile();
105
    }
106
107
    /**
108
     * @param  $projectId
109
     * @return mixed
110
     */
111
    public function getProjectName($projectId)
112
    {
113
        $projectName = '';
114
115
        $projects = $this->getProjects();
116
117
        foreach ($projects as $project) {
118
            if ($project['id'] === $projectId) {
119
                $projectName = $project['name'];
120
                break;
121
            }
122
        }
123
124
        return $projectName;
125
    }
126
127
    /**
128
     * @return mixed
129
     */
130
    public function getProjects()
131
    {
132
        $projects = [];
133
134
        if ($this->isTogglActive() === true) {
0 ignored issues
show
Bug introduced by
The method isTogglActive() does not seem to exist on object<AlfredTime\Time>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
135
            $projects = array_merge($projects, $this->getTogglProjects());
136
        }
137
138
        return $projects;
139
    }
140
141
    /**
142
     * @return mixed
143
     */
144
    public function getRecentTimers()
145
    {
146
        $timers = [];
147
148
        if ($this->isTogglActive() === true) {
0 ignored issues
show
Bug introduced by
The method isTogglActive() does not seem to exist on object<AlfredTime\Time>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
149
            $timers = array_merge($timers, $this->getRecentTogglTimers());
150
        }
151
152
        return $timers;
153
    }
154
155
    /**
156
     * @return mixed
157
     */
158
    public function getTags()
159
    {
160
        $tags = [];
161
162
        if ($this->isTogglActive() === true) {
0 ignored issues
show
Bug introduced by
The method isTogglActive() does not seem to exist on object<AlfredTime\Time>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
163
            $tags = array_merge($tags, $this->getTogglTags());
164
        }
165
166
        return $tags;
167
    }
168
169
    /**
170
     * @return mixed
171
     */
172
    public function getTimerDescription()
173
    {
174
        return $this->config->get('workflow', 'timer_description');
175
    }
176
177
    /**
178
     * @return mixed
179
     */
180
    public function hasTimerRunning()
181
    {
182
        return $this->config->get('workflow', 'is_timer_running') === false ? false : true;
183
    }
184
185
    /**
186
     * @param  $feature
187
     * @return mixed
188
     */
189
    public function implementedServicesForFeature($feature = null)
190
    {
191
        $services = [];
192
193
        if (isset($this->currentImplementation[$feature]) === true) {
194
            $services = $this->currentImplementation[$feature];
195
        }
196
197
        return $services;
198
    }
199
200
    /**
201
     * @return mixed
202
     */
203
    public function isConfigured()
204
    {
205
        return $this->config === null ? false : true;
206
    }
207
208
    /**
209
     * @param  $service
210
     * @return mixed
211
     */
212
    public function isServiceActive($service)
213
    {
214
        return $this->config->get($service, 'is_active');
215
    }
216
217
    /**
218
     * @return mixed
219
     */
220
    public function servicesToUndo()
221
    {
222
        $services = [];
223
224
        foreach ($this->activatedServices() as $service) {
225
            if ($this->config->get('workflow', 'timer_' . $service . '_id') !== null) {
226
                array_push($services, $service);
227
            }
228
        }
229
230
        return $services;
231
    }
232
233
    /**
234
     * @param  $description
235
     * @param  $projectsDefault
236
     * @param  null               $tagsDefault
237
     * @param  boolean            $startDefault
238
     * @return mixed
239
     */
240
    public function startTimer($description = '', $projectsDefault = null, $tagsDefault = null, $startDefault = false)
241
    {
242
        $message = '';
243
        $startType = $startDefault === true ? 'start_default' : 'start';
244
        $atLeastOneServiceStarted = false;
245
        $implementedServices = $this->implementedServicesForFeature($startType);
246
247
/*
248
 * When starting a new timer, all the services timer IDs have to be put to null
249
 * so that when the user uses the UNDO feature, it doesn't delete old previous
250
 * other services timers. The timer IDs are used for the UNDO feature and
251
 * should then contain the IDs of the last starts through the workflow, not
252
 * through each individual sefrvice
253
 */
254
        if (empty($implementedServices) === false) {
255
            foreach ($this->activatedServices() as $service) {
256
                $this->config->update('workflow', 'timer_' . $service . '_id', null);
257
            }
258
        }
259
260
        foreach ($implementedServices as $service) {
261
            $defaultProjectId = isset($projectsDefault[$service]) ? $projectsDefault[$service] : null;
262
            $defaultTags = isset($tagsDefault[$service]) ? $tagsDefault[$service] : null;
263
264
            $timerId = $this->$service->startTimer($description, $defaultProjectId, $defaultTags);
265
            $this->config->update('workflow', 'timer_' . $service . '_id', $timerId);
266
267
            if ($timerId !== null) {
268
                $atLeastOneServiceStarted = true;
269
            }
270
271
            $message .= $this->$service->getLastMessage() . "\r\n";
272
        }
273
274
        if ($atLeastOneServiceStarted === true) {
275
            $this->config->update('workflow', 'timer_description', $description);
276
            $this->config->update('workflow', 'is_timer_running', true);
277
        }
278
279
        return $message;
280
    }
281
282
    /**
283
     * @param  $description
284
     * @return mixed
285
     */
286
    public function startTimerWithDefaultOptions($description)
287
    {
288
        $projectsDefault = [
289
            'toggl'   => $this->config->get('toggl', 'default_project_id'),
290
            'harvest' => $this->config->get('harvest', 'default_project_id'),
291
        ];
292
293
        $tagsDefault = [
294
            'toggl'   => $this->config->get('toggl', 'default_tags'),
295
            'harvest' => $this->config->get('harvest', 'default_task_id'),
296
        ];
297
298
        return $this->startTimer($description, $projectsDefault, $tagsDefault, true);
299
    }
300
301
    /**
302
     * @return mixed
303
     */
304
    public function stopRunningTimer()
305
    {
306
        $message = '';
307
        $atLeastOneServiceStopped = false;
308
309
        foreach ($this->activatedServices() as $service) {
310
            $timerId = $this->config->get('workflow', 'timer_' . $service . '_id');
311
312
            if ($this->$service->stopTimer($timerId) === true) {
313
                $atLeastOneServiceStopped = true;
314
            }
315
316
            $message .= $this->$service->getLastMessage() . "\r\n";
317
        }
318
319
        if ($atLeastOneServiceStopped === true) {
320
            $this->config->update('workflow', 'is_timer_running', false);
321
        }
322
323
        return $message;
324
    }
325
326
    /**
327
     * @return mixed
328
     */
329
    public function syncOnlineDataToLocalCache()
330
    {
331
        $message = '';
332
333
        if ($this->isTogglActive() === true) {
0 ignored issues
show
Bug introduced by
The method isTogglActive() does not seem to exist on object<AlfredTime\Time>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
334
            $message .= $this->syncTogglOnlineDataToLocalCache();
335
        }
336
337
        return $message;
338
    }
339
340
    /**
341
     * @return mixed
342
     */
343
    public function undoTimer()
344
    {
345
        $message = '';
346
347
        if ($this->hasTimerRunning() === true) {
348
            $this->stopRunningTimer();
349
        }
350
351
        $atLeastOneTimerDeleted = false;
352
353 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...
354
            if ($this->$service->deleteTimer($this->config->get('workflow', 'timer_' . $service . '_id')) === true) {
355
                $this->config->update('workflow', 'timer_' . $service . '_id', null);
356
                $atLeastOneTimerDeleted = true;
357
            }
358
359
            $message .= $this->$service->getLastMessage() . "\r\n";
360
        }
361
362
        if ($atLeastOneTimerDeleted === true) {
363
            $this->config->update('workflow', 'is_timer_running', false);
364
        }
365
366
        return $message;
367
    }
368
369
    /**
370
     * @return mixed
371
     */
372
    private function getRecentTogglTimers()
373
    {
374
        return $this->toggl->getRecentTimers();
375
    }
376
377
    /**
378
     * @return mixed
379
     */
380
    private function getTogglProjects()
381
    {
382
        $cacheData = [];
383
        $cacheFile = getenv('alfred_workflow_data') . '/toggl_cache.json';
384
385
        if (file_exists($cacheFile)) {
386
            $cacheData = json_decode(file_get_contents($cacheFile), true);
387
        }
388
389
/*
390
 * To only show projects that are currently active
391
 * The Toggl API is slightly weird on that
392
 */
393
        foreach ($cacheData['data']['projects'] as $key => $project) {
394
            if (isset($project['server_deleted_at']) === true) {
395
                unset($cacheData['data']['projects'][$key]);
396
            }
397
        }
398
399
        return $cacheData['data']['projects'];
400
    }
401
402
    /**
403
     * @return mixed
404
     */
405
    private function getTogglTags()
406
    {
407
        $cacheFile = getenv('alfred_workflow_data') . '/toggl_cache.json';
408
        $cacheData = [];
409
410
        if (file_exists($cacheFile)) {
411
            $cacheData = json_decode(file_get_contents($cacheFile), true);
412
        }
413
414
        return $cacheData['data']['tags'];
415
    }
416
417
    /**
418
     * @param $data
419
     */
420
    private function saveTogglDataCache($data)
421
    {
422
        $cacheFile = getenv('alfred_workflow_data') . '/toggl_cache.json';
423
        file_put_contents($cacheFile, json_encode($data));
424
    }
425
426
    /**
427
     * @return mixed
428
     */
429
    private function syncTogglOnlineDataToLocalCache()
430
    {
431
        $data = $this->toggl->getOnlineData();
432
433
        $this->message = $this->toggl->getLastMessage();
434
435
        if (empty($data) === false) {
436
            $this->saveTogglDataCache($data);
437
        }
438
439
        return $this->message;
440
    }
441
}
442