Completed
Push — master ( 508f99...169e5d )
by Guillaume
02:21
created

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