Completed
Push — master ( 169e5d...b608d5 )
by Guillaume
02:16
created

Timer::undo()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 10
rs 9.4285
cc 2
eloc 5
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 Timer
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->getProperty($service . '_id')) {
48
            $this->updateProperty($service . '_id', null);
49
        }
50
51
        return true;
52
    }
53
54
    /**
55
     * @param  $timerId
56
     * @return string
57
     */
58
    public function delete(array $timerData = [])
59
    {
60
        $message = '';
61
        $oneTimerDeleted = false;
62
63
        foreach ($timerData as $service => $id) {
64
            $res = $this->deleteServiceTimer($service, $id);
65
            $message .= $this->setNotificationForService($service, 'delete', $res);
66
            $oneTimerDeleted = $oneTimerDeleted || $res;
67
        }
68
69
        if ($oneTimerDeleted === true) {
70
            $this->updateProperty('is_running', false);
71
        }
72
73
        return $message;
74
    }
75
76
    public function getDescription()
77
    {
78
        return $this->getProperty('description');
79
    }
80
81
    /**
82
     * @return mixed
83
     */
84
    public function getPrimaryService()
85
    {
86
        return $this->getProperty('primary_service');
87
    }
88
89
    /**
90
     * @param  $projectId
91
     * @return mixed
92
     */
93
    public function getProjectName($projectId)
94
    {
95
        $projectName = '';
96
97
        $projects = $this->getProjects();
98
99
        foreach ($projects as $project) {
100
            if ($project['id'] === $projectId) {
101
                $projectName = $project['name'];
102
                break;
103
            }
104
        }
105
106
        return $projectName;
107
    }
108
109
    /**
110
     * @return mixed
111
     */
112 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...
113
    {
114
        $projects = [];
115
        $services = [];
116
117
        foreach ($this->config->implementedServicesForFeature('get_projects') as $service) {
118
            if ($this->config->isServiceActive($service) === true) {
119
                $services[$service] = $this->$service->getProjects($this->getServiceDataCache($service));
120
            }
121
        }
122
123
        foreach ($services as $serviceName => $serviceProjects) {
124
            foreach ($serviceProjects as $serviceProject) {
125
                $projects[$serviceProject['name']][$serviceName . '_id'] = $serviceProject['id'];
126
            }
127
        }
128
129
        return $projects;
130
    }
131
132
    /**
133
     * @return mixed
134
     */
135 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...
136
    {
137
        $timers = [];
138
139
        foreach ($this->config->implementedServicesForFeature('get_timers') as $service) {
140
            if ($this->config->isServiceActive($service) === true) {
141
                $timers = array_merge($timers, $this->getRecentServiceTimers($service));
142
            }
143
        }
144
145
        return $timers;
146
    }
147
148
    /**
149
     * @param  $service
150
     * @return mixed
151
     */
152
    public function getServiceDataCache($service)
153
    {
154
        $cacheFile = getenv('alfred_workflow_data') . '/' . $service . '_cache.json';
155
156
        if (file_exists($cacheFile) === false) {
157
            $this->syncServiceOnlineDataToLocalCache($service);
158
        }
159
160
        return json_decode(file_get_contents($cacheFile), true);
161
    }
162
163
    /**
164
     * @return mixed
165
     */
166 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...
167
    {
168
        $tags = [];
169
        $services = [];
170
171
        foreach ($this->config->implementedServicesForFeature('get_tags') as $service) {
172
            if ($this->config->isServiceActive($service) === true) {
173
                $services[$service] = $this->$service->getTags($this->getServiceDataCache($service));
174
            }
175
        }
176
177
        foreach ($services as $serviceName => $serviceTags) {
178
            foreach ($serviceTags as $serviceTag) {
179
                $tags[$serviceTag['name']][$serviceName . '_id'] = $serviceTag['id'];
180
            }
181
        }
182
183
        return $tags;
184
    }
185
186
    /**
187
     * @return mixed
188
     */
189
    public function isRunning()
190
    {
191
        return $this->getProperty('is_running');
192
    }
193
194
    /**
195
     * @param $service
196
     * @param null       $action
197
     * @param null       $success
198
     */
199
    public function setNotificationForService($service = null, $action = null, $success = null)
200
    {
201
        if (empty($success) === true) {
202
            return '- ' . ucfirst($service) . ': cannot ' . $action . ' [' . $this->$service->getLastMessage() . ']' . "\r\n";
203
        }
204
205
        return '- ' . ucfirst($service) . ': ' . $action . "\r\n";
206
    }
207
208
    /**
209
     * @param  $description
210
     * @param  $projectsData
211
     * @param  $tagData
212
     * @return string
213
     */
214
    public function start($description = '', array $projectData = [], array $tagData = [], $specificService = null)
215
    {
216
        $message = '';
217
        $oneServiceStarted = false;
218
219
        $servicesToRun = ($specificService === null) ? $this->config->implementedServicesForFeature('start') : [$specificService];
220
221
        /**
222
         * When starting a new timer, all the services timer IDs have to be put to null
223
         * so that when the user uses the UNDO feature, it doesn't delete old previous
224
         * other services timers. The timer IDs are used for the UNDO feature and
225
         * should then contain the IDs of the last starts through the workflow, not
226
         * through each individual sefrvice
227
         */
228
        if (empty($servicesToRun) === true) {
229
            return '';
230
        }
231
232
        foreach ($this->config->activatedServices() as $service) {
233
            $this->updateProperty($service . '_id', null);
234
        }
235
236
        foreach ($servicesToRun as $service) {
237
            $timerId = $this->$service->startTimer($description, $projectData[$service . '_id'], $tagData[$service . '_id']);
238
            $this->updateProperty($service . '_id', $timerId);
239
            $message .= $this->setNotificationForService($service, 'start', $timerId);
240
            $oneServiceStarted = $oneServiceStarted || ($timerId !== null);
241
        }
242
243
        if ($oneServiceStarted === true) {
244
            $this->updateProperty('description', $description);
245
            $this->updateProperty('is_running', true);
246
        }
247
248
        return $message;
249
    }
250
251
    /**
252
     * @return string
253
     */
254
    public function stop()
255
    {
256
        $message = '';
257
        $oneServiceStopped = false;
258
259
        foreach ($this->config->runningServices() as $service) {
260
            $timerId = $this->getProperty($service . '_id');
261
262
            $res = $this->$service->stopTimer($timerId);
263
            $message .= $this->setNotificationForService($service, 'stop', $res);
264
            $oneServiceStopped = $oneServiceStopped || $res;
265
        }
266
267
        if ($oneServiceStopped === true) {
268
            $this->updateProperty('is_running', false);
269
        }
270
271
        return $message;
272
    }
273
274
    /**
275
     * @return string
276
     */
277 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...
278
    {
279
        $message = '';
280
281
        foreach ($this->config->implementedServicesForFeature('sync_data') as $service) {
282
            if ($this->config->isServiceActive($service) === true) {
283
                $message .= $this->syncServiceOnlineDataToLocalCache($service);
284
            }
285
        }
286
287
        return $message;
288
    }
289
290
    /**
291
     * @return string
292
     */
293
    public function undo()
294
    {
295
        $timerData = [];
296
297
        foreach ($this->config->runningServices() as $service) {
298
            $timerData[$service] = $this->getProperty($service .'_id');
299
        }
300
301
        return $this->delete($timerData);
302
    }
303
304
    /**
305
     * @param $name
306
     * @param $value
307
     */
308
    public function updateProperty($name, $value)
309
    {
310
        $this->config->update('timer', $name, $value);
311
    }
312
313
    /**
314
     * @param  $name
315
     * @return mixed
316
     */
317
    private function getProperty($name)
318
    {
319
        return $this->config->get('timer', $name);
320
    }
321
322
    /**
323
     * @return mixed
324
     */
325
    private function getRecentServiceTimers($service)
326
    {
327
        return $this->$service->getRecentTimers();
328
    }
329
330
    /**
331
     * @param $data
332
     * @param string  $service
333
     */
334
    private function saveServiceDataCache($service, $data)
335
    {
336
        $cacheFile = getenv('alfred_workflow_data') . '/' . $service . '_cache.json';
337
        file_put_contents($cacheFile, json_encode($data));
338
    }
339
340
    /**
341
     * @param  string   $service
342
     * @return string
343
     */
344
    private function syncServiceOnlineDataToLocalCache($service)
345
    {
346
        $data = $this->$service->getOnlineData();
347
348
        if (empty($data) === true) {
349
            return $this->setNotificationForService($service, 'data', false);
350
        }
351
352
        $this->saveServiceDataCache($service, $data);
353
354
        return $this->setNotificationForService($service, 'data', true);
355
    }
356
}
357