1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* @file |
5
|
|
|
* Class AbstractEvent |
6
|
|
|
*/ |
7
|
|
|
|
8
|
|
|
namespace Roomify\Bat\Event; |
9
|
|
|
|
10
|
|
|
use Roomify\Bat\Event\EventInterface; |
11
|
|
|
use Roomify\Bat\Store\Store; |
12
|
|
|
|
13
|
|
|
abstract class AbstractEvent implements EventInterface { |
14
|
|
|
|
15
|
|
|
const BAT_DAY = 'bat_day'; |
16
|
|
|
const BAT_HOUR = 'bat_hour'; |
17
|
|
|
const BAT_MINUTE = 'bat_minute'; |
18
|
|
|
const BAT_HOURLY = 'bat_hourly'; |
19
|
|
|
const BAT_DAILY = 'bat_daily'; |
20
|
|
|
|
21
|
|
|
/** |
22
|
|
|
* The booking unit the event is relevant to |
23
|
|
|
* @var int |
24
|
|
|
*/ |
25
|
|
|
protected $unit_id; |
26
|
|
|
|
27
|
|
|
/** |
28
|
|
|
* The start date for the event. |
29
|
|
|
* |
30
|
|
|
* @var DateTime |
31
|
|
|
*/ |
32
|
|
|
protected $start_date; |
33
|
|
|
|
34
|
|
|
/** |
35
|
|
|
* The end date for the event. |
36
|
|
|
* |
37
|
|
|
* @var DateTime |
38
|
|
|
*/ |
39
|
|
|
protected $end_date; |
40
|
|
|
|
41
|
|
|
/** |
42
|
|
|
* The value associated with this event. |
43
|
|
|
* This can represent an availability state or a pricing value |
44
|
|
|
* |
45
|
|
|
* @var int |
46
|
|
|
*/ |
47
|
|
|
protected $value; |
48
|
|
|
|
49
|
|
|
/** |
50
|
|
|
* Returns the value. |
51
|
|
|
* |
52
|
|
|
* @return int |
53
|
|
|
*/ |
54
|
|
|
public function getValue() { |
55
|
|
|
return $this->value; |
56
|
|
|
} |
57
|
|
|
|
58
|
|
|
/** |
59
|
|
|
* Set the value. |
60
|
|
|
* |
61
|
|
|
* @param int $value |
62
|
|
|
*/ |
63
|
|
|
public function setValue($value) { |
64
|
|
|
$this->value = $value; |
65
|
|
|
} |
66
|
|
|
|
67
|
|
|
/** |
68
|
|
|
* Returns the unit id. |
69
|
|
|
* |
70
|
|
|
* @return int |
71
|
|
|
*/ |
72
|
|
|
public function getUnitId() { |
73
|
|
|
return $this->unit_id; |
74
|
|
|
} |
75
|
|
|
|
76
|
|
|
/** |
77
|
|
|
* Set the unit id. |
78
|
|
|
* |
79
|
|
|
* @param int $unit_id |
80
|
|
|
*/ |
81
|
|
|
public function setUnitId($unit_id) { |
82
|
|
|
$this->unit_id = $unit_id; |
83
|
|
|
} |
84
|
|
|
|
85
|
|
|
/** |
86
|
|
|
* Returns the start date. |
87
|
|
|
* |
88
|
|
|
* @return DateTime |
89
|
|
|
*/ |
90
|
|
|
public function getStartDate() { |
91
|
|
|
return clone($this->start_date); |
|
|
|
|
92
|
|
|
} |
93
|
|
|
|
94
|
|
|
/** |
95
|
|
|
* Utility function to always give us a standard format for viewing the start date. |
96
|
|
|
* @return mixed |
97
|
|
|
*/ |
98
|
|
|
public function startDateToString($format = 'Y-m-d H:i') { |
99
|
|
|
return $this->start_date->format($format); |
100
|
|
|
} |
101
|
|
|
|
102
|
|
|
/** |
103
|
|
|
* Set the start date. |
104
|
|
|
* |
105
|
|
|
* @param DateTime $start_date |
106
|
|
|
*/ |
107
|
|
|
public function setStartDate(\DateTime $start_date) { |
108
|
|
|
$this->start_date = clone($start_date); |
|
|
|
|
109
|
|
|
} |
110
|
|
|
|
111
|
|
|
/** |
112
|
|
|
* Returns the end date. |
113
|
|
|
* |
114
|
|
|
* @return DateTime |
115
|
|
|
*/ |
116
|
|
|
public function getEndDate() { |
117
|
|
|
return clone($this->end_date); |
|
|
|
|
118
|
|
|
} |
119
|
|
|
|
120
|
|
|
/** |
121
|
|
|
* Utility function to always give us a standard format for viewing the end date. |
122
|
|
|
* @return mixed |
123
|
|
|
*/ |
124
|
|
|
public function endDateToString($format = 'Y-m-d H:i') { |
125
|
|
|
return $this->end_date->format($format); |
126
|
|
|
} |
127
|
|
|
|
128
|
|
|
/** |
129
|
|
|
* Set the end date. |
130
|
|
|
* |
131
|
|
|
* @param DateTime $end_date |
132
|
|
|
*/ |
133
|
|
|
public function setEndDate(\DateTime $end_date) { |
134
|
|
|
$this->end_date = clone($end_date); |
|
|
|
|
135
|
|
|
} |
136
|
|
|
|
137
|
|
|
/** |
138
|
|
|
* {@inheritdoc} |
139
|
|
|
*/ |
140
|
|
|
public function startDay($format = 'j') { |
141
|
|
|
return $this->start_date->format($format); |
142
|
|
|
} |
143
|
|
|
|
144
|
|
|
/** |
145
|
|
|
* {@inheritdoc} |
146
|
|
|
*/ |
147
|
|
|
public function endDay($format = 'j') { |
148
|
|
|
return $this->end_date->format($format); |
149
|
|
|
} |
150
|
|
|
|
151
|
|
|
/** |
152
|
|
|
* {@inheritdoc} |
153
|
|
|
*/ |
154
|
|
|
public function startMonth($format = 'n') { |
155
|
|
|
return $this->start_date->format($format); |
156
|
|
|
} |
157
|
|
|
|
158
|
|
|
/** |
159
|
|
|
* {@inheritdoc} |
160
|
|
|
*/ |
161
|
|
|
public function endMonth($format = 'n') { |
162
|
|
|
return $this->end_date->format($format); |
163
|
|
|
} |
164
|
|
|
|
165
|
|
|
/** |
166
|
|
|
*{@inheritdoc) |
167
|
|
|
*/ |
168
|
|
|
public function endMonthDate(\DateTime $date) { |
169
|
|
|
// The time is added so that the end date is included |
170
|
|
|
$date_format = $date->format('Y-n-t 23:59:59'); |
171
|
|
|
return new \DateTime($date_format); |
172
|
|
|
} |
173
|
|
|
|
174
|
|
|
/** |
175
|
|
|
* {@inheritdoc} |
176
|
|
|
*/ |
177
|
|
|
public function startYear($format = 'Y') { |
178
|
|
|
return $this->start_date->format($format); |
179
|
|
|
} |
180
|
|
|
|
181
|
|
|
/** |
182
|
|
|
* {@inheritdoc} |
183
|
|
|
*/ |
184
|
|
|
public function endYear($format = 'Y') { |
185
|
|
|
return $this->end_date->format($format); |
186
|
|
|
} |
187
|
|
|
|
188
|
|
|
/** |
189
|
|
|
* {@inheritdoc} |
190
|
|
|
*/ |
191
|
|
|
public function startWeek($format = 'W') { |
192
|
|
|
return $this->start_date->format($format); |
193
|
|
|
} |
194
|
|
|
|
195
|
|
|
/** |
196
|
|
|
* {@inheritdoc} |
197
|
|
|
*/ |
198
|
|
|
public function endWeek($format = 'W') { |
199
|
|
|
return $this->end_date->format($format); |
200
|
|
|
} |
201
|
|
|
|
202
|
|
|
/** |
203
|
|
|
* {@inheritdoc} |
204
|
|
|
*/ |
205
|
|
|
public function startHour($format = 'G') { |
206
|
|
|
return $this->start_date->format($format); |
207
|
|
|
} |
208
|
|
|
|
209
|
|
|
/** |
210
|
|
|
* {@inheritdoc} |
211
|
|
|
*/ |
212
|
|
|
public function endHour($format = 'G') { |
213
|
|
|
return $this->end_date->format($format); |
214
|
|
|
} |
215
|
|
|
|
216
|
|
|
/** |
217
|
|
|
* {@inheritdoc} |
218
|
|
|
*/ |
219
|
|
|
public function startMinute($format = 'i') { |
220
|
|
|
return $this->start_date->format($format); |
221
|
|
|
} |
222
|
|
|
|
223
|
|
|
/** |
224
|
|
|
* {@inheritdoc} |
225
|
|
|
*/ |
226
|
|
|
public function endMinute($format = 'i') { |
227
|
|
|
return $this->end_date->format($format); |
228
|
|
|
} |
229
|
|
|
|
230
|
|
|
/** |
231
|
|
|
* {@inheritdoc} |
232
|
|
|
*/ |
233
|
|
|
public function isFirstMonth($date) { |
234
|
|
|
if ($date->format("n") == $this->startMonth() && $date->format("Y") == $this->startYear()) { |
235
|
|
|
return TRUE; |
236
|
|
|
} |
237
|
|
|
|
238
|
|
|
return FALSE; |
239
|
|
|
} |
240
|
|
|
|
241
|
|
|
/** |
242
|
|
|
* {@inheritdoc} |
243
|
|
|
*/ |
244
|
|
|
public function isLastMonth($date) { |
245
|
|
|
if ($date->format("n") == $this->endMonth() && $date->format("Y") == $this->endYear()) { |
246
|
|
|
return TRUE; |
247
|
|
|
} |
248
|
|
|
|
249
|
|
|
return FALSE; |
250
|
|
|
} |
251
|
|
|
|
252
|
|
|
/** |
253
|
|
|
* {@inheritdoc} |
254
|
|
|
*/ |
255
|
|
|
public function isFirstDay($date) { |
256
|
|
|
if (($date->format('j') == $this->startDay()) && ($this->isFirstMonth($date))) { |
257
|
|
|
return TRUE; |
258
|
|
|
} |
259
|
|
|
|
260
|
|
|
return FALSE; |
261
|
|
|
} |
262
|
|
|
|
263
|
|
|
/** |
264
|
|
|
* {@inheritdoc} |
265
|
|
|
*/ |
266
|
|
|
public function isFirstHour($date) { |
267
|
|
|
if ($date->format('G') == $this->startHour() && $this->isFirstDay($date)) { |
268
|
|
|
return TRUE; |
269
|
|
|
} |
270
|
|
|
|
271
|
|
|
return FALSE; |
272
|
|
|
} |
273
|
|
|
|
274
|
|
|
/** |
275
|
|
|
* {@inheritdoc} |
276
|
|
|
*/ |
277
|
|
|
public function isSameYear() { |
278
|
|
|
if ($this->startYear() == $this->endYear()) { |
279
|
|
|
return TRUE; |
280
|
|
|
} |
281
|
|
|
|
282
|
|
|
return FALSE; |
283
|
|
|
} |
284
|
|
|
|
285
|
|
|
/** |
286
|
|
|
* {@inheritdoc} |
287
|
|
|
*/ |
288
|
|
|
public function isSameMonth() { |
289
|
|
|
if (($this->startMonth() == $this->endMonth()) && $this->isSameYear()) { |
290
|
|
|
return TRUE; |
291
|
|
|
} |
292
|
|
|
|
293
|
|
|
return FALSE; |
294
|
|
|
} |
295
|
|
|
|
296
|
|
|
/** |
297
|
|
|
* {@inheritdoc} |
298
|
|
|
*/ |
299
|
|
|
public function isSameDay() { |
300
|
|
|
if (($this->startDay() == $this->endDay()) && $this->isSameMonth()) { |
301
|
|
|
return TRUE; |
302
|
|
|
} |
303
|
|
|
|
304
|
|
|
return FALSE; |
305
|
|
|
} |
306
|
|
|
|
307
|
|
|
/** |
308
|
|
|
* {@inheritdoc} |
309
|
|
|
*/ |
310
|
|
|
public function isSameHour() { |
311
|
|
|
if (($this->startHour() == $this->endHour()) && $this->isSameDay()) { |
312
|
|
|
return TRUE; |
313
|
|
|
} |
314
|
|
|
|
315
|
|
|
return FALSE; |
316
|
|
|
} |
317
|
|
|
|
318
|
|
|
/** |
319
|
|
|
* {@inheritdoc} |
320
|
|
|
*/ |
321
|
|
|
public function diff() { |
322
|
|
|
$interval = $this->start_date->diff($this->end_date); |
323
|
|
|
return $interval; |
324
|
|
|
} |
325
|
|
|
|
326
|
|
|
/** |
327
|
|
|
* Returns true if the event overlaps at all with the time period within |
328
|
|
|
* the start and end time. |
329
|
|
|
* |
330
|
|
|
* @param \DateTime $start |
331
|
|
|
* @param \DateTime $end |
332
|
|
|
* @return bool |
333
|
|
|
*/ |
334
|
|
|
public function overlaps(\DateTime $start, \DateTime $end) { |
335
|
|
|
$overlaps = FALSE; |
336
|
|
|
|
337
|
|
|
if ($this->dateIsEarlier($start) && |
338
|
|
|
($this->dateIsInRange($end) || $this->dateIsLater($end))) { |
339
|
|
|
$overlaps = TRUE; |
340
|
|
|
} |
341
|
|
|
elseif ($this->dateIsInRange($start) && |
342
|
|
|
($this->dateIsInRange($end) || $this->dateIsLater($end))) { |
343
|
|
|
$overlaps = TRUE; |
344
|
|
|
} |
345
|
|
|
|
346
|
|
|
return $overlaps; |
347
|
|
|
} |
348
|
|
|
|
349
|
|
|
/** |
350
|
|
|
* Checks if date supplied is in range of event |
351
|
|
|
* |
352
|
|
|
* @param \DateTime $date |
353
|
|
|
* @return bool |
354
|
|
|
*/ |
355
|
|
|
public function dateIsInRange(\DateTime $date) { |
356
|
|
|
$dateInRange = FALSE; |
357
|
|
|
|
358
|
|
|
$t1 = $this->start_date->getTimeStamp(); |
359
|
|
|
$t2 = $this->end_date->getTimeStamp(); |
360
|
|
|
|
361
|
|
|
$t3 = $date->getTimeStamp(); |
362
|
|
|
|
363
|
|
|
if (($t3 >= $t1) && ($t3 <= $t2)) { |
364
|
|
|
$dateInRange = TRUE; |
365
|
|
|
} |
366
|
|
|
|
367
|
|
|
return $dateInRange; |
368
|
|
|
} |
369
|
|
|
|
370
|
|
|
/** |
371
|
|
|
* Checks if the date supplied starts earlier than our event |
372
|
|
|
* @param \DateTime $date |
373
|
|
|
* @return bool |
374
|
|
|
*/ |
375
|
|
View Code Duplication |
public function dateIsEarlier(\DateTime $date) { |
|
|
|
|
376
|
|
|
$dateEarlier = FALSE; |
377
|
|
|
|
378
|
|
|
$t1 = $this->start_date->getTimeStamp(); |
379
|
|
|
|
380
|
|
|
$t3 = $date->getTimeStamp(); |
381
|
|
|
|
382
|
|
|
if ($t3 < $t1) { |
383
|
|
|
$dateEarlier = TRUE; |
384
|
|
|
} |
385
|
|
|
|
386
|
|
|
return $dateEarlier; |
387
|
|
|
} |
388
|
|
|
|
389
|
|
|
/** |
390
|
|
|
* Checks if the date supplied ends after our event ends |
391
|
|
|
* @param \DateTime $date |
392
|
|
|
* @return bool |
393
|
|
|
*/ |
394
|
|
View Code Duplication |
public function dateIsLater(\DateTime $date) { |
|
|
|
|
395
|
|
|
$dateLater = FALSE; |
396
|
|
|
|
397
|
|
|
$t2 = $this->end_date->getTimeStamp(); |
398
|
|
|
|
399
|
|
|
$t4 = $date->getTimestamp(); |
400
|
|
|
|
401
|
|
|
if ($t2 < $t4) { |
402
|
|
|
$dateLater = TRUE; |
403
|
|
|
} |
404
|
|
|
|
405
|
|
|
return $dateLater; |
406
|
|
|
} |
407
|
|
|
|
408
|
|
|
/** |
409
|
|
|
* Checks if our event ends after the date supplied |
410
|
|
|
* @param \DateTime $date |
411
|
|
|
* @return bool |
412
|
|
|
*/ |
413
|
|
View Code Duplication |
public function endsLater(\DateTime $date) { |
|
|
|
|
414
|
|
|
$later = FALSE; |
415
|
|
|
|
416
|
|
|
$t2 = $this->end_date->getTimeStamp(); |
417
|
|
|
|
418
|
|
|
$t4 = $date->getTimestamp(); |
419
|
|
|
|
420
|
|
|
if ($t2 > $t4) { |
421
|
|
|
$later = TRUE; |
422
|
|
|
} |
423
|
|
|
|
424
|
|
|
return $later; |
425
|
|
|
} |
426
|
|
|
|
427
|
|
|
/** |
428
|
|
|
* Checks if our event starts earlier than the date supplied |
429
|
|
|
* @param \DateTime $date |
430
|
|
|
* @return bool |
431
|
|
|
*/ |
432
|
|
View Code Duplication |
public function startsEarlier(\DateTime $date) { |
|
|
|
|
433
|
|
|
$earlier = FALSE; |
434
|
|
|
|
435
|
|
|
$t1 = $this->start_date->getTimeStamp(); |
436
|
|
|
|
437
|
|
|
$t3 = $date->getTimestamp(); |
438
|
|
|
|
439
|
|
|
if ($t1 < $t3) { |
440
|
|
|
$earlier = TRUE; |
441
|
|
|
} |
442
|
|
|
|
443
|
|
|
return $earlier; |
444
|
|
|
} |
445
|
|
|
|
446
|
|
|
/** |
447
|
|
|
* Based on the start and end dates of the event it creates the appropriate granular events |
448
|
|
|
* and adds them to an array suitable for manipulating easily or storing in the database. |
449
|
|
|
* |
450
|
|
|
* @param array $itemized |
451
|
|
|
* @return array |
452
|
|
|
*/ |
453
|
|
|
public function createDayGranural($itemized = array()) { |
454
|
|
|
$interval = new \DateInterval('PT1M'); |
455
|
|
|
|
456
|
|
|
$sy = $this->start_date->format('Y'); |
457
|
|
|
$sm = $this->start_date->format('n'); |
458
|
|
|
$sd = $this->start_date->format('j'); |
459
|
|
|
|
460
|
|
|
$ey = $this->end_date->format('Y'); |
461
|
|
|
$em = $this->end_date->format('n'); |
462
|
|
|
$ed = $this->end_date->format('j'); |
463
|
|
|
|
464
|
|
|
// Clone the dates otherwise changes will change the event itself |
465
|
|
|
$start_date = clone($this->start_date); |
466
|
|
|
$end_date = clone($this->end_date); |
467
|
|
|
|
468
|
|
|
if ($this->isSameDay()) { |
469
|
|
|
if (!($this->end_date->format('H:i') == '23:59')) { |
470
|
|
|
$period = new \DatePeriod($start_date, $interval, $end_date->add(new \DateInterval('PT1M'))); |
471
|
|
|
$itemized_same_day = $this->createHourlyGranular($period, $start_date); |
472
|
|
|
$itemized[AbstractEvent::BAT_DAY][$sy][$sm]['d' . $sd] = -1; |
473
|
|
|
$itemized[AbstractEvent::BAT_HOUR][$sy][$sm]['d' . $sd] = $itemized_same_day[AbstractEvent::BAT_HOUR][$sy][$sm]['d' . $sd]; |
474
|
|
|
$itemized[AbstractEvent::BAT_MINUTE][$sy][$sm]['d' . $sd] = $itemized_same_day[AbstractEvent::BAT_MINUTE][$sy][$sm]['d' . $sd]; |
475
|
|
|
} |
476
|
|
|
} |
477
|
|
|
else { |
478
|
|
|
// Deal with the start day unless it starts on midnight precisely at which point the whole day is booked |
479
|
|
|
if (!($this->start_date->format('H:i') == '00:00')) { |
480
|
|
|
$start_period = new \DatePeriod($start_date, $interval, new \DateTime($start_date->format("Y-n-j 23:59:59"))); |
481
|
|
|
$itemized_start = $this->createHourlyGranular($start_period, $start_date); |
482
|
|
|
$itemized[AbstractEvent::BAT_DAY][$sy][$sm]['d' . $sd] = -1; |
483
|
|
|
$itemized[AbstractEvent::BAT_HOUR][$sy][$sm]['d' . $sd] = $itemized_start[AbstractEvent::BAT_HOUR][$sy][$sm]['d' . $sd]; |
484
|
|
|
$itemized[AbstractEvent::BAT_MINUTE][$sy][$sm]['d' . $sd] = $itemized_start[AbstractEvent::BAT_MINUTE][$sy][$sm]['d' . $sd]; |
485
|
|
|
} |
486
|
|
|
else { |
487
|
|
|
// Just set an empty hour and minute |
488
|
|
|
$itemized[AbstractEvent::BAT_HOUR][$sy][$sm]['d' . $sd] = array(); |
489
|
|
|
$itemized[AbstractEvent::BAT_MINUTE][$sy][$sm]['d' . $sd] = array(); |
490
|
|
|
} |
491
|
|
|
|
492
|
|
|
// Deal with the end date unless it ends just before midnight at which point we don't need to go further |
493
|
|
|
if ($this->end_date->format('H:i') == '23:59' ) { |
494
|
|
|
$itemized[AbstractEvent::BAT_HOUR][$ey][$em]['d' . $ed] = array(); |
495
|
|
|
$itemized[AbstractEvent::BAT_MINUTE][$ey][$em]['d' . $ed] = array(); |
496
|
|
|
} else { |
497
|
|
|
$end_period = new \DatePeriod(new \DateTime($end_date->format("Y-n-j 00:00:00")), $interval, $end_date->add(new \DateInterval('PT1M'))); |
498
|
|
|
$itemized_end = $this->createHourlyGranular($end_period, new \DateTime($end_date->format("Y-n-j 00:00:00"))); |
499
|
|
|
$itemized[AbstractEvent::BAT_DAY][$ey][$em]['d' . $ed] = -1; |
500
|
|
|
$itemized[AbstractEvent::BAT_HOUR][$ey][$em]['d' . $ed] = $itemized_end[AbstractEvent::BAT_HOUR][$ey][$em]['d' . $ed]; |
501
|
|
|
$itemized[AbstractEvent::BAT_MINUTE][$ey][$em]['d' . $ed] = $itemized_end[AbstractEvent::BAT_MINUTE][$ey][$em]['d' . $ed]; |
502
|
|
|
} |
503
|
|
|
} |
504
|
|
|
|
505
|
|
|
return $itemized; |
506
|
|
|
} |
507
|
|
|
|
508
|
|
|
/** |
509
|
|
|
* Given a DatePeriod it transforms it in hours and minutes. Used to break the first and |
510
|
|
|
* last days of an event into more granular events. |
511
|
|
|
* |
512
|
|
|
* @param \DatePeriod $period |
513
|
|
|
* @return array |
514
|
|
|
*/ |
515
|
|
|
public function createHourlyGranular(\DatePeriod $period, \DateTime $period_start) { |
516
|
|
|
$interval = new \DateInterval('PT1M'); |
|
|
|
|
517
|
|
|
$itemized = array(); |
518
|
|
|
|
519
|
|
|
$counter = (int)$period_start->format('i'); |
520
|
|
|
$start_minute = $counter; |
521
|
|
|
foreach($period as $minute) { |
522
|
|
|
// Doing minutes so set the values in the minute array |
523
|
|
|
$itemized[AbstractEvent::BAT_MINUTE][$minute->format('Y')][$minute->format('n')]['d'. $minute->format('j')]['h'. $minute->format('G')]['m' .$minute->format('i')] = $this->getValue(); |
524
|
|
|
// Let the hours know that it cannot determine availability |
525
|
|
|
$itemized[AbstractEvent::BAT_HOUR][$minute->format('Y')][$minute->format('n')]['d'. $minute->format('j')]['h'. $minute->format('G')] = -1; |
526
|
|
|
$counter++; |
527
|
|
|
|
528
|
|
|
if ($counter == 60 && $start_minute!==0) { |
529
|
|
|
// Not a real hour - leave as is and move on |
530
|
|
|
$counter = 0; |
531
|
|
|
$start_minute = 0; |
532
|
|
|
} |
533
|
|
|
elseif ($counter == 60 && $start_minute == 0) { |
534
|
|
|
// Did a real whole hour so initialize the hour |
535
|
|
|
$itemized[AbstractEvent::BAT_HOUR][$minute->format('Y')][$minute->format('n')]['d' . $minute->format('j')]['h' . $minute->format('G')] = $this->getValue(); |
536
|
|
|
// We have a whole hour so get rid of the minute info |
537
|
|
|
unset($itemized[AbstractEvent::BAT_MINUTE][$minute->format('Y')][$minute->format('n')]['d'. $minute->format('j')]['h'. $minute->format('G')]); |
538
|
|
|
$counter = 0; |
539
|
|
|
$start_minute = 0; |
540
|
|
|
} |
541
|
|
|
} |
542
|
|
|
|
543
|
|
|
return $itemized; |
544
|
|
|
} |
545
|
|
|
|
546
|
|
|
/** |
547
|
|
|
* Transforms the event in a breakdown of days, hours and minutes with associated states. |
548
|
|
|
* |
549
|
|
|
* @return array |
550
|
|
|
*/ |
551
|
|
|
public function itemizeEvent($granularity = AbstractEvent::BAT_HOURLY) { |
552
|
|
|
// The largest interval we deal with are months (a row in the *_state/*_event tables) |
553
|
|
|
$interval = new \DateInterval('P1M'); |
554
|
|
|
|
555
|
|
|
// Set the end date to the last day of the month so that we are sure to get that last month |
556
|
|
|
$adjusted_end_day = new \DateTime($this->end_date->format('Y-n-t')); |
557
|
|
|
|
558
|
|
|
$daterange = new \DatePeriod($this->start_date, $interval ,$adjusted_end_day); |
559
|
|
|
|
560
|
|
|
$itemized = array(); |
561
|
|
|
|
562
|
|
|
// Cycle through each month |
563
|
|
|
foreach($daterange as $date) { |
564
|
|
|
|
565
|
|
|
$year = $date->format("Y"); |
566
|
|
|
$dayinterval = new \DateInterval('P1D'); |
567
|
|
|
$dayrange = null; |
|
|
|
|
568
|
|
|
|
569
|
|
|
// Handle the first month |
570
|
|
|
if ($this->isFirstMonth($date)) { |
571
|
|
|
// If we are in the same month the end date is the end date of the event |
572
|
|
|
if ($this->isSameMonth()) { |
573
|
|
|
$dayrange = new \DatePeriod($this->start_date, $dayinterval, new \DateTime($this->end_date->format("Y-n-j 23:59:59"))); |
574
|
|
|
} |
575
|
|
|
else { // alternatively it is the last day of the start month |
576
|
|
|
$dayrange = new \DatePeriod($this->start_date, $dayinterval, $this->endMonthDate($this->start_date)); |
577
|
|
|
} |
578
|
|
View Code Duplication |
foreach ($dayrange as $day) { |
|
|
|
|
579
|
|
|
$itemized[AbstractEvent::BAT_DAY][$year][$day->format('n')]['d' . $day->format('j')] = $this->getValue(); |
580
|
|
|
} |
581
|
|
|
} |
582
|
|
|
|
583
|
|
|
// Handle the last month (will be skipped if event is same month) |
584
|
|
|
elseif ($this->isLastMonth($date)) { |
585
|
|
|
$dayrange = new \DatePeriod(new \DateTime($date->format("Y-n-1")), $dayinterval, $this->end_date); |
586
|
|
View Code Duplication |
foreach ($dayrange as $day) { |
|
|
|
|
587
|
|
|
$itemized[AbstractEvent::BAT_DAY][$year][$day->format('n')]['d' . $day->format('j')] = $this->getValue(); |
588
|
|
|
} |
589
|
|
|
} |
590
|
|
|
|
591
|
|
|
// We are in an in-between month - just cycle through and set dates (time on end date set to ensure it is included) |
592
|
|
|
else { |
593
|
|
|
$dayrange = new \DatePeriod(new \DateTime($date->format("Y-n-1")), $dayinterval, new \DateTime($date->format("Y-n-t 23:59:59"))); |
594
|
|
View Code Duplication |
foreach ($dayrange as $day) { |
|
|
|
|
595
|
|
|
$itemized[AbstractEvent::BAT_DAY][$year][$day->format('n')]['d' . $day->format('j')] = $this->getValue(); |
596
|
|
|
} |
597
|
|
|
} |
598
|
|
|
} |
599
|
|
|
|
600
|
|
|
if ($granularity == AbstractEvent::BAT_HOURLY) { |
601
|
|
|
// Add granural info in |
602
|
|
|
$itemized = $this->createDayGranural($itemized); |
603
|
|
|
} |
604
|
|
|
|
605
|
|
|
return $itemized; |
606
|
|
|
} |
607
|
|
|
|
608
|
|
|
/** |
609
|
|
|
* Saves an event to whatever Drupal tables are defined in the store array |
610
|
|
|
* |
611
|
|
|
* @param \ROomify\Bat\\Store\Store $store |
612
|
|
|
* @param string $granularity |
613
|
|
|
* |
614
|
|
|
* @throws \Exception |
615
|
|
|
* @throws \InvalidMergeQueryException |
616
|
|
|
*/ |
617
|
|
|
public function saveEvent(Store $store, $granularity = AbstractEvent::BAT_HOURLY) { |
618
|
|
|
return $store->storeEvent($this, $granularity); |
|
|
|
|
619
|
|
|
} |
620
|
|
|
|
621
|
|
|
} |
622
|
|
|
|
If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.
Let’s take a look at an example:
Our function
my_function
expects aPost
object, and outputs the author of the post. The base classPost
returns a simple string and outputting a simple string will work just fine. However, the child classBlogPost
which is a sub-type ofPost
instead decided to return anobject
, and is therefore violating the SOLID principles. If aBlogPost
were passed tomy_function
, PHP would not complain, but ultimately fail when executing thestrtoupper
call in its body.