Completed
Push — master ( a257b4...97bdbf )
by Guillaume
02:15
created

Timer::getItems()   B

Complexity

Conditions 5
Paths 9

Size

Total Lines 19
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

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