1 | <?php |
||||
2 | |||||
3 | namespace Godbout\Alfred\Time\Services; |
||||
4 | |||||
5 | use Exception; |
||||
6 | use Carbon\Carbon; |
||||
7 | use Carbon\CarbonInterval; |
||||
8 | use MorningTrain\TogglApi\TogglApi; |
||||
9 | |||||
10 | class Toggl extends TimerService |
||||
11 | { |
||||
12 | private $client; |
||||
13 | |||||
14 | private $data = null; |
||||
15 | |||||
16 | |||||
17 | 28 | public function __construct($apiToken) |
|||
18 | { |
||||
19 | 28 | $this->client = new TogglApi($apiToken); |
|||
20 | 28 | } |
|||
21 | |||||
22 | 6 | public function projects() |
|||
23 | { |
||||
24 | 6 | return $this->extractFromData('projects'); |
|||
25 | } |
||||
26 | |||||
27 | 4 | public function tags() |
|||
28 | { |
||||
29 | 4 | return $this->extractFromData('tags'); |
|||
30 | } |
||||
31 | |||||
32 | 1 | public function pastTimers() |
|||
33 | { |
||||
34 | try { |
||||
35 | 1 | $pastTimers = []; |
|||
0 ignored issues
–
show
Unused Code
introduced
by
Loading history...
|
|||||
36 | |||||
37 | 1 | $togglTimers = $this->client->getTimeEntriesInRange(Carbon::today(), Carbon::today()->subDays(30)); |
|||
38 | |||||
39 | 1 | return $this->convertToPastTimers($togglTimers); |
|||
40 | } catch (Exception $e) { |
||||
41 | return []; |
||||
42 | } |
||||
43 | } |
||||
44 | |||||
45 | 11 | public function startTimer() |
|||
46 | { |
||||
47 | try { |
||||
48 | 11 | $timer = $this->client->startTimeEntry([ |
|||
49 | 11 | 'description' => getenv('timer_description'), |
|||
50 | 11 | 'pid' => getenv('timer_project_id'), |
|||
51 | 11 | 'tags' => getenv('timer_tag') ? [getenv('timer_tag')] : '', |
|||
52 | 11 | 'created_with' => 'Alfred Time' |
|||
53 | ]); |
||||
54 | |||||
55 | 11 | if (! isset($timer->id)) { |
|||
56 | 11 | return false; |
|||
57 | } |
||||
58 | } catch (Exception $e) { |
||||
59 | return false; |
||||
60 | } |
||||
61 | |||||
62 | 11 | return $timer->id; |
|||
63 | } |
||||
64 | |||||
65 | 9 | public function stopCurrentTimer() |
|||
66 | { |
||||
67 | 9 | if ($timerId = $this->runningTimer()) { |
|||
68 | 9 | $response = $this->client->stopTimeEntry($timerId); |
|||
69 | |||||
70 | 9 | if (! isset($response->id)) { |
|||
71 | throw new Exception("Can't stop current running timer.", 1); |
||||
72 | |||||
73 | return false; |
||||
0 ignored issues
–
show
return false is not reachable.
This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed. Unreachable code is most often the result of function fx() {
try {
doSomething();
return true;
}
catch (\Exception $e) {
return false;
}
return false;
}
In the above example, the last
Loading history...
|
|||||
74 | } |
||||
75 | |||||
76 | 9 | return true; |
|||
77 | } |
||||
78 | |||||
79 | 1 | return false; |
|||
80 | } |
||||
81 | |||||
82 | 22 | public function runningTimer() |
|||
83 | { |
||||
84 | 22 | $timer = $this->client->getRunningTimeEntry(); |
|||
85 | |||||
86 | 22 | return $timer->id ?? false; |
|||
87 | } |
||||
88 | |||||
89 | 2 | public function continueTimer($timerId) |
|||
90 | { |
||||
91 | /** |
||||
92 | * Timer attributes are stored in env variables |
||||
93 | * gathered in startTimer. |
||||
94 | */ |
||||
95 | 2 | return $this->startTimer(); |
|||
96 | } |
||||
97 | |||||
98 | 11 | public function deleteTimer($timerId) |
|||
99 | { |
||||
100 | try { |
||||
101 | 11 | $this->client->deleteTimeEntry($timerId); |
|||
102 | } catch (Exception $e) { |
||||
103 | return false; |
||||
104 | } |
||||
105 | |||||
106 | 11 | return true; |
|||
107 | } |
||||
108 | |||||
109 | 10 | private function extractFromData($needle) |
|||
110 | { |
||||
111 | 10 | $data = $this->getData(); |
|||
112 | |||||
113 | 10 | if (! isset($data->$needle)) { |
|||
114 | 6 | return []; |
|||
115 | } |
||||
116 | |||||
117 | 4 | $nonDeletedData = $this->filterOutServerwiseDeletedItemsFromData($data->$needle); |
|||
118 | |||||
119 | 4 | return array_column($nonDeletedData, 'name', 'id'); |
|||
120 | } |
||||
121 | |||||
122 | 10 | private function getData() |
|||
123 | { |
||||
124 | 10 | if (is_null($this->data)) { |
|||
125 | 10 | return $this->client->getMe(true); |
|||
126 | } |
||||
127 | |||||
128 | return $this->data; |
||||
129 | } |
||||
130 | |||||
131 | 4 | private function filterOutServerwiseDeletedItemsFromData($items = []) |
|||
132 | { |
||||
133 | return array_filter($items, function ($item) { |
||||
134 | 4 | return ! isset($item->server_deleted_at); |
|||
135 | 4 | }); |
|||
136 | } |
||||
137 | |||||
138 | 1 | protected function convertToPastTimers($togglTimers) |
|||
139 | { |
||||
140 | 1 | $projects = $this->projects(); |
|||
141 | |||||
142 | 1 | return array_reverse( |
|||
143 | array_map(function ($togglTimer) use ($projects) { |
||||
144 | 1 | return $this->buildPastTimerObject($togglTimer, $projects); |
|||
145 | 1 | }, $togglTimers) |
|||
146 | ); |
||||
147 | } |
||||
148 | |||||
149 | 1 | protected function buildPastTimerObject($togglTimer, $projects) |
|||
150 | { |
||||
151 | 1 | $pastTimer['id'] = $togglTimer->id; |
|||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||||
152 | 1 | $pastTimer['description'] = $togglTimer->description ?? ''; |
|||
153 | 1 | $pastTimer['duration'] = CarbonInterval::seconds($togglTimer->duration)->cascade()->format('%H:%I:%S'); |
|||
0 ignored issues
–
show
The method
Carbon\CarbonInterval::seconds() is not static, but was called statically.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||
154 | |||||
155 | 1 | if (isset($togglTimer->pid)) { |
|||
156 | 1 | $pastTimer['project_id'] = $togglTimer->pid; |
|||
157 | 1 | $pastTimer['project_name'] = $projects[$togglTimer->pid]; |
|||
158 | } |
||||
159 | |||||
160 | 1 | if (isset($togglTimer->tags)) { |
|||
161 | 1 | $pastTimer['tags'] = implode(', ', (array) $togglTimer->tags); |
|||
162 | } |
||||
163 | |||||
164 | 1 | return (object) $pastTimer; |
|||
165 | } |
||||
166 | } |
||||
167 |