Completed
Push — master ( 43a919...57d452 )
by Guillaume
02:08
created

Time::startTimer()   C

Complexity

Conditions 8
Paths 37

Size

Total Lines 43
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 7
Bugs 0 Features 0
Metric Value
c 7
b 0
f 0
dl 0
loc 43
rs 5.3846
cc 8
eloc 22
nc 37
nop 4
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 mixed
18
     */
19
    private $harvest;
20
21
    /**
22
     * @var mixed
23
     */
24
    private $toggl;
25
26
    /**
27
     * @param Config $config
28
     */
29
    public function __construct(Config $config = null)
30
    {
31
        $this->config = $config;
32
        $this->harvest = new Harvest($this->config->get('harvest', 'domain'), $this->config->get('harvest', 'api_token'));
33
        $this->toggl = new Toggl($this->config->get('toggl', 'api_token'));
34
    }
35
36
    /**
37
     * @param  $service
38
     * @param  $timerId
39
     * @return boolean
40
     */
41
    public function deleteServiceTimer($service, $timerId)
42
    {
43
        if ($this->$service->deleteTimer($timerId) === false) {
44
            return false;
45
        }
46
47
        if ($timerId === $this->config->get('workflow', 'timer_' . $service . '_id')) {
48
            $this->config->update('workflow', 'timer_' . $service . '_id', null);
49
        }
50
51
        return true;
52
    }
53
54
    /**
55
     * @param  $timerId
56
     * @return string
57
     */
58
    public function deleteTimer($timerId)
59
    {
60
        $message = '';
61
62
        foreach ($this->config->implementedServicesForFeature('delete') as $service) {
63
            if ($this->deleteServiceTimer($service, $timerId) === true) {
64
                $message .= '- ' . ucfirst($service) . ': deleted' . "\r\n";
65
            } else {
66
                $message .= '- ' . ucfirst($service) . ': cannot delete' . "\r\n";
67
            }
68
        }
69
70
        return $message;
71
    }
72
73
    /**
74
     * @param  $projectId
75
     * @return mixed
76
     */
77
    public function getProjectName($projectId)
78
    {
79
        $projectName = '';
80
81
        $projects = $this->getProjects();
82
83
        foreach ($projects as $project) {
84
            if ($project['id'] === $projectId) {
85
                $projectName = $project['name'];
86
                break;
87
            }
88
        }
89
90
        return $projectName;
91
    }
92
93
    /**
94
     * @return mixed
95
     */
96 View Code Duplication
    public function getProjects()
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...
97
    {
98
        $projects = [];
99
100
/*
101
 * Temporary, only get the projects of Toggl
102
 * Later, we will get Harvest ones too
103
 */
104
        foreach ($this->config->implementedServicesForFeature('get_projects') as $service) {
105
            if ($this->config->isServiceActive($service) === true) {
106
                $projects = $this->$service->getProjects($this->getServiceDataCache($service));
107
            }
108
        }
109
110
        return $projects;
111
    }
112
113
    /**
114
     * @return mixed
115
     */
116 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...
117
    {
118
        $timers = [];
119
120
        foreach ($this->config->implementedServicesForFeature('get_timers') as $service) {
121
            if ($this->config->isServiceActive($service) === true) {
122
                $timers = array_merge($timers, $this->getRecentServiceTimers($service));
123
            }
124
        }
125
126
        return $timers;
127
    }
128
129
    /**
130
     * @param  $service
131
     * @return mixed
132
     */
133
    public function getServiceDataCache($service)
134
    {
135
        $data = [];
136
        $cacheFile = getenv('alfred_workflow_data') . '/' . $service . '_cache.json';
137
138
        if (file_exists($cacheFile)) {
139
            $data = json_decode(file_get_contents($cacheFile), true);
140
        }
141
142
        return $data;
143
    }
144
145
    /**
146
     * @return mixed
147
     */
148 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...
149
    {
150
        $tags = [];
151
152
/*
153
 * Temporary, only get the tags of Toggl
154
 * Later, we will get Harvest ones too
155
 */
156
        foreach ($this->config->implementedServicesForFeature('get_tags') as $service) {
157
            if ($this->config->isServiceActive($service) === true) {
158
                $tags = $this->$service->getTags($this->getServiceDataCache($service));
159
            }
160
        }
161
162
        return $tags;
163
    }
164
165
    /**
166
     * @param  $description
167
     * @param  $projectsDefault
168
     * @param  null               $tagsDefault
169
     * @param  string             $startType
170
     * @return string
171
     */
172
    public function startTimer($description = '', array $projectsDefault = [], array $tagsDefault = [], $startType = 'start')
173
    {
174
        $message = '';
175
        $oneServiceStarted = false;
176
        $implementedServices = $this->config->implementedServicesForFeature($startType);
177
178
/*
179
 * When starting a new timer, all the services timer IDs have to be put to null
180
 * so that when the user uses the UNDO feature, it doesn't delete old previous
181
 * other services timers. The timer IDs are used for the UNDO feature and
182
 * should then contain the IDs of the last starts through the workflow, not
183
 * through each individual sefrvice
184
 */
185
        if (empty($implementedServices) === true) {
186
            return '';
187
        }
188
189
        foreach ($this->config->activatedServices() as $service) {
190
            $this->config->update('workflow', 'timer_' . $service . '_id', null);
191
        }
192
193
        foreach ($implementedServices as $service) {
194
            $defaultProjectId = isset($projectsDefault[$service]) ? $projectsDefault[$service] : null;
195
            $defaultTags = isset($tagsDefault[$service]) ? $tagsDefault[$service] : null;
196
197
            $timerId = $this->$service->startTimer($description, $defaultProjectId, $defaultTags);
198
            $this->config->update('workflow', 'timer_' . $service . '_id', $timerId);
199
200
            if ($timerId !== null) {
201
                $oneServiceStarted = true;
202
                $message .= '- ' . ucfirst($service) . ': started' . "\r\n";
203
            } else {
204
                $message .= '- ' . ucfirst($service) . ': cannot start' . "\r\n";
205
            }
206
        }
207
208
        if ($oneServiceStarted === true) {
209
            $this->config->update('workflow', 'timer_description', $description);
210
            $this->config->update('workflow', 'is_timer_running', true);
211
        }
212
213
        return $message;
214
    }
215
216
    /**
217
     * @param  $description
218
     * @return string
219
     */
220
    public function startTimerWithDefaultOptions($description)
221
    {
222
        $projectsDefault = [
223
            'toggl'   => $this->config->get('toggl', 'default_project_id'),
224
            'harvest' => $this->config->get('harvest', 'default_project_id'),
225
        ];
226
227
        $tagsDefault = [
228
            'toggl'   => $this->config->get('toggl', 'default_tags'),
229
            'harvest' => $this->config->get('harvest', 'default_task_id'),
230
        ];
231
232
        return $this->startTimer($description, $projectsDefault, $tagsDefault, 'start_default');
233
    }
234
235
    /**
236
     * @return string
237
     */
238
    public function stopRunningTimer()
239
    {
240
        $message = '';
241
        $oneServiceStopped = false;
242
243 View Code Duplication
        foreach ($this->config->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...
244
            $timerId = $this->config->get('workflow', 'timer_' . $service . '_id');
245
246
            if ($this->$service->stopTimer($timerId) === true) {
247
                $oneServiceStopped = true;
248
                $message .= '- ' . ucfirst($service) . ': stopped' . "\r\n";
249
            } else {
250
                $message .= '- ' . ucfirst($service) . ': cannot stop' . "\r\n";
251
            }
252
        }
253
254
        if ($oneServiceStopped === true) {
255
            $this->config->update('workflow', 'is_timer_running', false);
256
        }
257
258
        return $message;
259
    }
260
261
    /**
262
     * @return string
263
     */
264 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...
265
    {
266
        $message = '';
267
268
        foreach ($this->config->implementedServicesForFeature('sync_data') as $service) {
269
            if ($this->config->isServiceActive($service) === true) {
270
                $message .= $this->syncServiceOnlineDataToLocalCache($service);
271
            }
272
        }
273
274
        return $message;
275
    }
276
277
    /**
278
     * @return string
279
     */
280
    public function undoTimer()
281
    {
282
        $message = '';
283
284
        if ($this->config->hasTimerRunning() === true) {
285
            $this->stopRunningTimer();
286
        }
287
288
        $oneTimerDeleted = false;
289
290 View Code Duplication
        foreach ($this->config->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...
291
            if ($this->deleteServiceTimer($service, $this->config->get('workflow', 'timer_' . $service . '_id')) === true) {
292
                $oneTimerDeleted = true;
293
                $message .= '- ' . ucfirst($service) . ': undid' . "\r\n";
294
            } else {
295
                $message .= '- ' . ucfirst($service) . ': cannot undo' . "\r\n";
296
            }
297
        }
298
299
        if ($oneTimerDeleted === true) {
300
            $this->config->update('workflow', 'is_timer_running', false);
301
        }
302
303
        return $message;
304
    }
305
306
    /**
307
     * @return mixed
308
     */
309
    private function getRecentServiceTimers($service)
310
    {
311
        return $this->$service->getRecentTimers();
312
    }
313
314
    /**
315
     * @param $data
316
     * @param string  $service
317
     */
318
    private function saveServiceDataCache($service, $data)
319
    {
320
        $cacheFile = getenv('alfred_workflow_data') . '/' . $service . '_cache.json';
321
        file_put_contents($cacheFile, json_encode($data));
322
    }
323
324
    /**
325
     * @param  string   $service
326
     * @return string
327
     */
328
    private function syncServiceOnlineDataToLocalCache($service)
329
    {
330
        $data = $this->$service->getOnlineData();
331
332
        if (empty($data) === true) {
333
            return '- ' . ucfirst($service) . ': cannot cache data' . "\r\n";
334
        }
335
336
        $this->saveServiceDataCache($service, $data);
337
338
        return '- ' . ucfirst($service) . ': data cached' . "\r\n";
339
    }
340
}
341