Passed
Push — master ( 34d55a...7b347a )
by Guillaume
24:04
created

Toggl::stopCurrentTimer()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 13
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 3.2098

Importance

Changes 0
Metric Value
cc 3
eloc 6
nc 3
nop 0
dl 0
loc 13
ccs 5
cts 7
cp 0.7143
crap 3.2098
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Godbout\Alfred\Time\Services;
4
5
use Carbon\Carbon;
6
use Carbon\CarbonInterval;
7
use Exception;
8
use MorningTrain\TogglApi\TogglApi;
9
10
class Toggl extends TimerService
11
{
12
    private $client;
13
14
    private $data = null;
15
16
17 100
    public function __construct($apiToken)
18
    {
19 100
        $this->client = new TogglApi($apiToken);
20 100
    }
21
22 28
    public function projects()
23
    {
24 28
        return $this->extractFromData('projects');
25
    }
26
27 16
    public function tags()
28
    {
29 16
        return $this->extractFromData('tags');
30
    }
31
32 4
    public function pastTimers()
33
    {
34
        try {
35 4
            $togglTimers = $this->client->getTimeEntriesInRange(Carbon::today(), Carbon::today()->subDays(30));
36
37 4
            return $this->convertToPastTimers($togglTimers);
38
        } catch (Exception $e) {
39
            return [];
40
        }
41
    }
42
43 28
    public function startTimer()
44
    {
45
        try {
46 28
            $timer = $this->client->startTimeEntry([
47 28
                'description' => getenv('timer_description'),
48 28
                'pid' => getenv('timer_project_id'),
49 28
                'tags' => getenv('timer_tag') ? [getenv('timer_tag')] : '',
50 28
                'created_with' => 'Alfred Time'
51
            ]);
52
53 28
            if (! isset($timer->id)) {
54 28
                return false;
55
            }
56
        } catch (Exception $e) {
57
            return false;
58
        }
59
60 28
        return $timer->id;
61
    }
62
63 20
    public function stopCurrentTimer()
64
    {
65 20
        if ($timerId = $this->runningTimer()) {
66 20
            $response = $this->client->stopTimeEntry($timerId);
67
68 20
            if (! isset($response->id)) {
69
                throw new Exception("Can't stop current running timer.", 1);
70
            }
71
72 20
            return true;
73
        }
74
75
        return false;
76
    }
77
78 76
    public function runningTimer()
79
    {
80 76
        $timer = $this->client->getRunningTimeEntry();
81
82 76
        return $timer->id ?? false;
83
    }
84
85 4
    public function continueTimer($timerId)
86
    {
87
        /**
88
         * Timer attributes are stored in env variables
89
         * gathered in startTimer.
90
         */
91 4
        return $this->startTimer();
92
    }
93
94 28
    public function deleteTimer($timerId)
95
    {
96
        try {
97 28
            $this->client->deleteTimeEntry($timerId);
98
        } catch (Exception $e) {
99
            return false;
100
        }
101
102 28
        return true;
103
    }
104
105 44
    private function extractFromData($needle)
106
    {
107 44
        $data = $this->getData();
108
109 44
        if (! isset($data->$needle)) {
110 24
            return [];
111
        }
112
113 20
        $choosableData = $this->filterOutServerwiseDeletedAndArchivedItemsFromData($data->$needle);
114
115 20
        return array_column($choosableData, 'name', 'id');
116
    }
117
118 44
    private function getData()
119
    {
120 44
        if (is_null($this->data)) {
121 44
            return $this->client->getMe(true);
122
        }
123
124
        return $this->data;
125
    }
126
127 20
    private function filterOutServerwiseDeletedAndArchivedItemsFromData($items = [])
128
    {
129
        return array_filter($items, function ($item) {
130
            return
131 20
                ! $this->itemIsDeletedServerwise($item)
132 20
                && ! $this->itemIsArchivedServerwise($item);
133 20
        });
134
    }
135
136 20
    private function itemIsDeletedServerwise($item)
137
    {
138 20
        return isset($item->server_deleted_at);
139
    }
140
141 20
    private function itemIsArchivedServerwise($item)
142
    {
143
        return
144 20
            isset($item->active)
145 20
            && $item->active === false;
146
    }
147
148 4
    protected function convertToPastTimers($togglTimers)
149
    {
150 4
        $projects = $this->projects();
151
152 4
        return array_reverse(
153
            array_map(function ($togglTimer) use ($projects) {
154 4
                return $this->buildPastTimerObject($togglTimer, $projects);
155 4
            }, $togglTimers)
156
        );
157
    }
158
159 4
    protected function buildPastTimerObject($togglTimer, $projects)
160
    {
161 4
        $pastTimer['id'] = $togglTimer->id;
0 ignored issues
show
Comprehensibility Best Practice introduced by
$pastTimer was never initialized. Although not strictly required by PHP, it is generally a good practice to add $pastTimer = array(); before regardless.
Loading history...
162 4
        $pastTimer['description'] = $togglTimer->description ?? '';
163 4
        $pastTimer['duration'] = CarbonInterval::seconds($togglTimer->duration)->cascade()->format('%H:%I:%S');
164
165 4
        if (isset($togglTimer->pid)) {
166 4
            $pastTimer['project_id'] = $togglTimer->pid;
167 4
            $pastTimer['project_name'] = $projects[$togglTimer->pid] ?? $togglTimer->pid;
168
        }
169
170 4
        if (isset($togglTimer->tags)) {
171 4
            $pastTimer['tags'] = implode(', ', (array) $togglTimer->tags);
172
        }
173
174 4
        return (object) $pastTimer;
175
    }
176
}
177