1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* \Wicked\Timely\Entities\Task |
5
|
|
|
* |
6
|
|
|
* NOTICE OF LICENSE |
7
|
|
|
* |
8
|
|
|
* This source file is subject to the Open Software License (OSL 3.0) |
9
|
|
|
* that is available through the world-wide-web at this URL: |
10
|
|
|
* http://opensource.org/licenses/osl-3.0.php |
11
|
|
|
* |
12
|
|
|
* PHP version 5 |
13
|
|
|
* |
14
|
|
|
* @author wick-ed |
15
|
|
|
* @copyright 2020 Bernhard Wick |
16
|
|
|
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) |
17
|
|
|
* @link https://github.com/wick-ed/timely |
18
|
|
|
*/ |
19
|
|
|
|
20
|
|
|
namespace Wicked\Timely\Entities; |
21
|
|
|
|
22
|
|
|
/** |
23
|
|
|
* Task entity |
24
|
|
|
* |
25
|
|
|
* @author wick-ed |
26
|
|
|
* @copyright 2020 Bernhard Wick |
27
|
|
|
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) |
28
|
|
|
* @link https://github.com/wick-ed/timely |
29
|
|
|
*/ |
30
|
|
|
class Task |
31
|
|
|
{ |
32
|
|
|
|
33
|
|
|
/** |
34
|
|
|
* First booking of this task |
35
|
|
|
* |
36
|
|
|
* @var \Wicked\Timely\Entities\Booking $startBooking |
37
|
|
|
*/ |
38
|
|
|
protected $startBooking; |
39
|
|
|
|
40
|
|
|
/** |
41
|
|
|
* Last booking of this task |
42
|
|
|
* |
43
|
|
|
* @var \Wicked\Timely\Entities\Booking $endBooking |
44
|
|
|
*/ |
45
|
|
|
protected $endBooking; |
46
|
|
|
|
47
|
|
|
/** |
48
|
|
|
* Bookings within this task |
49
|
|
|
* |
50
|
|
|
* @var \Wicked\Timely\Entities\Booking[] $intermediateBookings |
51
|
|
|
*/ |
52
|
|
|
protected $intermediateBookings; |
53
|
|
|
|
54
|
|
|
/** |
55
|
|
|
* Intermediate tasks, done within this task instance |
56
|
|
|
* |
57
|
|
|
* @var \Wicked\Timely\Entities\Task[] $intermediateTasks |
58
|
|
|
*/ |
59
|
|
|
protected $intermediateTasks; |
60
|
|
|
|
61
|
|
|
/** |
62
|
|
|
* The task's duration |
63
|
|
|
* |
64
|
|
|
* @var integer $duration |
65
|
|
|
*/ |
66
|
|
|
protected $duration; |
67
|
|
|
|
68
|
|
|
/** |
69
|
|
|
* Whether or not the task is being clipped due to filtering |
70
|
|
|
* |
71
|
|
|
* @var boolean $isClipped |
72
|
|
|
*/ |
73
|
|
|
protected $isClipped = false; |
74
|
|
|
|
75
|
|
|
/** |
76
|
|
|
* Default constructor |
77
|
|
|
* |
78
|
|
|
* @param \Wicked\Timely\Entities\Booking $startBooking The first booking of the task |
79
|
|
|
* @param \Wicked\Timely\Entities\Booking $endBooking The last booking of the task |
80
|
|
|
* @param \Wicked\Timely\Entities\Booking[] $intermediateBookings Bookings within this task |
81
|
|
|
*/ |
82
|
9 |
|
public function __construct($startBooking, $endBooking, $intermediateBookings) |
83
|
|
|
{ |
84
|
|
|
// set the properties |
85
|
9 |
|
$this->startBooking = $startBooking; |
86
|
9 |
|
$this->endBooking = $endBooking; |
87
|
9 |
|
$this->intermediateBookings = $intermediateBookings; |
88
|
|
|
// calculate the duration |
89
|
9 |
|
$this->duration = $this->calculateDuration($startBooking, $endBooking, $intermediateBookings); |
90
|
|
|
// determine if we are being clipped |
91
|
9 |
|
foreach ($intermediateBookings as $intermediateBooking) { |
92
|
6 |
|
if ($intermediateBooking instanceof Clipping) { |
93
|
4 |
|
$this->isClipped = true; |
94
|
4 |
|
break; |
95
|
|
|
} |
96
|
|
|
} |
97
|
9 |
|
} |
98
|
|
|
|
99
|
|
|
/** |
100
|
|
|
* Getter for the first booking of the task instance |
101
|
|
|
* |
102
|
|
|
* @return \Wicked\Timely\Entities\Booking |
103
|
|
|
*/ |
104
|
4 |
|
public function getStartBooking() |
105
|
|
|
{ |
106
|
4 |
|
return $this->startBooking; |
107
|
|
|
} |
108
|
|
|
|
109
|
|
|
/** |
110
|
|
|
* Getter for the first booking of the task instance |
111
|
|
|
* |
112
|
|
|
* @return string |
113
|
|
|
*/ |
114
|
|
View Code Duplication |
public function getStartTime() |
|
|
|
|
115
|
|
|
{ |
116
|
|
|
$firstIntermediate = reset($this->intermediateBookings); |
117
|
|
|
if ($this->isClipped() && $firstIntermediate instanceof Pause && $firstIntermediate->isPauseEnd()) { |
118
|
|
|
return $firstIntermediate->getTime(); |
119
|
|
|
} |
120
|
|
|
return $this->getStartBooking()->getTime(); |
121
|
|
|
} |
122
|
|
|
|
123
|
|
|
/** |
124
|
|
|
* Getter for the first booking of the task instance |
125
|
|
|
* |
126
|
|
|
* @return string |
127
|
|
|
*/ |
128
|
|
|
public function getComment() |
129
|
|
|
{ |
130
|
|
|
return $this->getStartBooking()->getComment(); |
131
|
|
|
} |
132
|
|
|
|
133
|
|
|
/** |
134
|
|
|
* Getter for the first booking of the task instance |
135
|
|
|
* |
136
|
|
|
* @return string |
137
|
|
|
*/ |
138
|
|
View Code Duplication |
public function isPushed() |
|
|
|
|
139
|
|
|
{ |
140
|
|
|
$firstIntermediate = reset($this->intermediateBookings); |
141
|
|
|
if ($this->isClipped() && $firstIntermediate instanceof Pause && $firstIntermediate->isPauseEnd()) { |
142
|
|
|
return $firstIntermediate->isPushed(); |
143
|
|
|
} |
144
|
|
|
return $this->getStartBooking()->isPushed(); |
145
|
|
|
} |
146
|
|
|
|
147
|
|
|
/** |
148
|
|
|
* Getter for the last booking of the task instance |
149
|
|
|
* |
150
|
|
|
* @return \Wicked\Timely\Entities\Booking |
151
|
|
|
*/ |
152
|
|
|
public function getEndBooking() |
153
|
|
|
{ |
154
|
|
|
return $this->endBooking; |
155
|
|
|
} |
156
|
|
|
|
157
|
|
|
/** |
158
|
|
|
* Getter for the first booking of the task instance |
159
|
|
|
* |
160
|
|
|
* @return string |
161
|
|
|
*/ |
162
|
|
|
public function getEndTime() |
163
|
|
|
{ |
164
|
|
|
return $this->getEndBooking()->getTime(); |
165
|
|
|
} |
166
|
|
|
|
167
|
|
|
/** |
168
|
|
|
* Getter for the intermediate bookings |
169
|
|
|
* |
170
|
|
|
* @return \Wicked\Timely\Entities\Booking[] |
171
|
|
|
*/ |
172
|
|
|
public function getIntermediateBookings() |
173
|
|
|
{ |
174
|
|
|
return $this->intermediateBookings; |
175
|
|
|
} |
176
|
|
|
|
177
|
|
|
/** |
178
|
|
|
* Getter for the task's ticket id |
179
|
|
|
* |
180
|
|
|
* @return string |
181
|
|
|
*/ |
182
|
|
|
public function getTicketId() |
183
|
|
|
{ |
184
|
|
|
return $this->getStartBooking()->getTicketId(); |
185
|
|
|
} |
186
|
|
|
|
187
|
|
|
/** |
188
|
|
|
* Getter for the task duration |
189
|
|
|
* |
190
|
|
|
* @return integer |
191
|
|
|
*/ |
192
|
8 |
|
public function getDuration() |
193
|
|
|
{ |
194
|
8 |
|
return $this->duration; |
195
|
|
|
} |
196
|
|
|
|
197
|
|
|
/** |
198
|
|
|
* Getter for the task duration |
199
|
|
|
* |
200
|
|
|
* @return bool |
201
|
|
|
*/ |
202
|
|
|
protected function isClipped() |
203
|
|
|
{ |
204
|
|
|
return $this->isClipped; |
205
|
|
|
} |
206
|
|
|
|
207
|
|
|
/** |
208
|
|
|
* Whether or not the task is still ongoing |
209
|
|
|
* |
210
|
|
|
* @return bool |
211
|
|
|
*/ |
212
|
|
|
public function isOngoing() |
213
|
|
|
{ |
214
|
|
|
return ($this->getEndBooking()->getTicketId() === Clipping::CLIPPING_TAG_REAR); |
215
|
|
|
} |
216
|
|
|
|
217
|
|
|
/** |
218
|
|
|
* Whether or not the task is currently paused |
219
|
|
|
* |
220
|
|
|
* @return bool |
221
|
|
|
*/ |
222
|
|
|
public function isPaused() |
223
|
|
|
{ |
224
|
|
|
// search for the first occurrence of a pause in the intermediate bookings |
225
|
|
|
foreach ($this->getIntermediateBookings() as $intermediateBooking) { |
226
|
|
|
if ($intermediateBooking instanceof Pause) { |
227
|
|
|
if ($intermediateBooking->getTicketId() === Pause::PAUSE_TAG_START) { |
228
|
|
|
return true; |
229
|
|
|
} elseif ($intermediateBooking->getTicketId() === Pause::PAUSE_TAG_END) { |
230
|
|
|
return false; |
231
|
|
|
} |
232
|
|
|
} |
233
|
|
|
} |
234
|
|
|
} |
235
|
|
|
|
236
|
|
|
/** |
237
|
|
|
* Calculates the duration of a task by given bookings |
238
|
|
|
* |
239
|
|
|
* @param \Wicked\Timely\Entities\Booking $startBooking The first booking of the task |
240
|
|
|
* @param \Wicked\Timely\Entities\Booking $endBooking The last booking of the task |
241
|
|
|
* @param \Wicked\Timely\Entities\Booking[] $intermediateBookings Bookings within this task |
242
|
|
|
* |
243
|
|
|
* @return integer |
244
|
|
|
*/ |
245
|
9 |
|
protected function calculateDuration($startBooking, $endBooking, array $intermediateBookings) |
246
|
|
|
{ |
247
|
|
|
// get any potential clippings and include them as task borders |
248
|
9 |
|
foreach ($intermediateBookings as $intermediateBooking) { |
249
|
6 |
|
if ($intermediateBooking->canStartTask()) { |
250
|
2 |
|
$startBooking = $intermediateBooking; |
251
|
6 |
|
} elseif ($intermediateBooking->getTicketId() === Clipping::CLIPPING_TAG_REAR) { |
252
|
4 |
|
$endBooking = $intermediateBooking; |
253
|
|
|
} |
254
|
|
|
} |
255
|
|
|
|
256
|
|
|
// get the raw time without breaks and such |
257
|
9 |
|
$rawTime = strtotime($endBooking->getTime()) - strtotime($startBooking->getTime()); |
258
|
|
|
|
259
|
|
|
// subtract the breaks |
260
|
9 |
|
if (count($intermediateBookings) > 1) { |
261
|
6 |
|
$this->intermediateTasks = TaskFactory::getTasksFromBookings(array_merge(array($endBooking), $intermediateBookings), false, true); |
262
|
6 |
|
foreach ($this->intermediateTasks as $intermediateTask) { |
263
|
6 |
|
$rawTime -= $intermediateTask->getDuration(); |
264
|
|
|
} |
265
|
|
|
} |
266
|
|
|
// return what we got |
267
|
9 |
|
return $rawTime; |
268
|
|
|
} |
269
|
|
|
} |
270
|
|
|
|
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.