]> Raphaël G. Git Repositories - airbundle/blob - Entity/Session.php
Protect from infinite remove recursion
[airbundle] / Entity / Session.php
1 <?php declare(strict_types=1);
2
3 /*
4 * this file is part of the rapsys packbundle package.
5 *
6 * (c) raphaël gertz <symfony@rapsys.eu>
7 *
8 * for the full copyright and license information, please view the license
9 * file that was distributed with this source code.
10 */
11
12 namespace Rapsys\AirBundle\Entity;
13
14 use Doctrine\Common\Collections\ArrayCollection;
15 use Doctrine\ORM\Event\PreUpdateEventArgs;
16
17 /**
18 * Session
19 */
20 class Session {
21 /**
22 * @var integer
23 */
24 private $id;
25
26 /**
27 * @var \DateTime
28 */
29 private $date;
30
31 /**
32 * @var \DateTime
33 */
34 private $begin;
35
36 /**
37 * @var \DateTime
38 */
39 private $start;
40
41 /**
42 * @var \DateTime
43 */
44 private $length;
45
46 /**
47 * @var \DateTime
48 */
49 private $stop;
50
51 /**
52 * @var bool
53 */
54 private $premium;
55
56 /**
57 * @var float
58 */
59 private $rainfall;
60
61 /**
62 * @var float
63 */
64 private $rainrisk;
65
66 /**
67 * @var float
68 */
69 private $realfeel;
70
71 /**
72 * @var float
73 */
74 private $realfeelmin;
75
76 /**
77 * @var float
78 */
79 private $realfeelmax;
80
81 /**
82 * @var float
83 */
84 private $temperature;
85
86 /**
87 * @var float
88 */
89 private $temperaturemin;
90
91 /**
92 * @var float
93 */
94 private $temperaturemax;
95
96 /**
97 * @var \DateTime
98 */
99 private $locked;
100
101 /**
102 * @var \DateTime
103 */
104 private $created;
105
106 /**
107 * @var \DateTime
108 */
109 private $updated;
110
111 /**
112 * @var Application
113 */
114 private $application;
115
116 /**
117 * @var Location
118 */
119 private $location;
120
121 /**
122 * @var Slot
123 */
124 private $slot;
125
126 /**
127 * @var ArrayCollection
128 */
129 private $applications;
130
131 /**
132 * Constructor
133 */
134 public function __construct() {
135 //Set defaults
136 $this->begin = null;
137 $this->start = null;
138 $this->length = null;
139 $this->stop = null;
140 $this->premium = null;
141 $this->rainfall = null;
142 $this->rainrisk = null;
143 $this->realfeel = null;
144 $this->realfeelmin = null;
145 $this->realfeelmax = null;
146 $this->temperature = null;
147 $this->temperaturemin = null;
148 $this->temperaturemax = null;
149 $this->locked = null;
150 $this->created = new \DateTime('now');
151 $this->updated = new \DateTime('now');
152 $this->application = null;
153 $this->applications = new ArrayCollection();
154 }
155
156 /**
157 * Get id
158 *
159 * @return integer
160 */
161 public function getId(): int {
162 return $this->id;
163 }
164
165 /**
166 * Set date
167 *
168 * @param \DateTime $date
169 *
170 * @return Session
171 */
172 public function setDate(\DateTime $date): Session {
173 $this->date = $date;
174
175 return $this;
176 }
177
178 /**
179 * Get date
180 *
181 * @return \DateTime
182 */
183 public function getDate(): \DateTime {
184 return $this->date;
185 }
186
187 /**
188 * Set begin
189 *
190 * @param \DateTime $begin
191 *
192 * @return Session
193 */
194 public function setBegin(?\DateTime $begin): Session {
195 $this->begin = $begin;
196
197 return $this;
198 }
199
200 /**
201 * Get begin
202 *
203 * @return \DateTime
204 */
205 public function getBegin(): ?\DateTime {
206 return $this->begin;
207 }
208
209 /**
210 * Get start
211 *
212 * @return \DateTime
213 */
214 public function getStart(): \DateTime {
215 //With start
216 if ($this->start !== null) {
217 return $this->start;
218 }
219
220 //Clone date
221 $this->start = clone $this->date;
222
223 //Check if after slot
224 //XXX: id=4 <=> title=After
225 if ($this->slot->getId() == 4) {
226 //Add one day
227 $this->start->add(new \DateInterval('P1D'));
228 }
229
230 //With begin
231 if ($this->begin !== null) {
232 //Set start time
233 $this->start->setTime(intval($this->begin->format('H')), intval($this->begin->format('i')), intval($this->begin->format('s')));
234 }
235
236 //Return start
237 return $this->start;
238 }
239
240 /**
241 * Set length
242 *
243 * @param \DateTime $length
244 *
245 * @return Session
246 */
247 public function setLength(?\DateTime $length): Session {
248 $this->length = $length;
249
250 return $this;
251 }
252
253 /**
254 * Get length
255 *
256 * @return \DateTime
257 */
258 public function getLength(): ?\DateTime {
259 return $this->length;
260 }
261
262 /**
263 * Get stop
264 *
265 * @return \DateTime
266 */
267 public function getStop(): \DateTime {
268 //Check start
269 if ($this->stop !== null) {
270 return $this->stop;
271 }
272
273 //Get start clone
274 $this->stop = clone $this->getStart();
275
276 //With length
277 if ($this->length !== null) {
278 //Set stop time
279 $this->stop->add(new \DateInterval('PT'.$this->length->format('H').'H'.$this->length->format('i').'M'.$this->length->format('s').'S'));
280 }
281
282 //Return date
283 return $this->stop;
284 }
285
286 /**
287 * Set premium
288 *
289 * @param bool $premium
290 *
291 * @return Session
292 */
293 public function setPremium(bool $premium): Session {
294 $this->premium = $premium;
295
296 return $this;
297 }
298
299 /**
300 * Get premium
301 *
302 * @return bool
303 */
304 public function getPremium(): bool {
305 return $this->premium;
306 }
307
308 /**
309 * Set rainfall
310 *
311 * @param float $rainfall
312 *
313 * @return Session
314 */
315 public function setRainfall(?float $rainfall): Session {
316 $this->rainfall = $rainfall;
317
318 return $this;
319 }
320
321 /**
322 * Get rainfall
323 *
324 * @return float
325 */
326 public function getRainfall(): ?float {
327 return $this->rainfall;
328 }
329
330 /**
331 * Set rainrisk
332 *
333 * @param float $rainrisk
334 *
335 * @return Session
336 */
337 public function setRainrisk(?float $rainrisk): Session {
338 $this->rainrisk = $rainrisk;
339
340 return $this;
341 }
342
343 /**
344 * Get rainrisk
345 *
346 * @return float
347 */
348 public function getRainrisk(): ?float {
349 return $this->rainrisk;
350 }
351
352 /**
353 * Set realfeel
354 *
355 * @param float $realfeel
356 *
357 * @return Session
358 */
359 public function setRealfeel(?float $realfeel): Session {
360 $this->realfeel = $realfeel;
361
362 return $this;
363 }
364
365 /**
366 * Get realfeel
367 *
368 * @return float
369 */
370 public function getRealfeel(): ?float {
371 return $this->realfeel;
372 }
373
374 /**
375 * Set realfeelmin
376 *
377 * @param float $realfeelmin
378 *
379 * @return Session
380 */
381 public function setRealfeelmin(?float $realfeelmin): Session {
382 $this->realfeelmin = $realfeelmin;
383
384 return $this;
385 }
386
387 /**
388 * Get realfeelmin
389 *
390 * @return float
391 */
392 public function getRealfeelmin(): ?float {
393 return $this->realfeelmin;
394 }
395
396 /**
397 * Set realfeelmax
398 *
399 * @param float $realfeelmax
400 *
401 * @return Session
402 */
403 public function setRealfeelmax(?float $realfeelmax): Session {
404 $this->realfeelmax = $realfeelmax;
405
406 return $this;
407 }
408
409 /**
410 * Get realfeelmax
411 *
412 * @return float
413 */
414 public function getRealfeelmax(): ?float {
415 return $this->realfeelmax;
416 }
417
418 /**
419 * Set temperature
420 *
421 * @param float $temperature
422 *
423 * @return Session
424 */
425 public function setTemperature(?float $temperature): Session {
426 $this->temperature = $temperature;
427
428 return $this;
429 }
430
431 /**
432 * Get temperature
433 *
434 * @return float
435 */
436 public function getTemperature(): ?float {
437 return $this->temperature;
438 }
439
440 /**
441 * Set temperaturemin
442 *
443 * @param float $temperaturemin
444 *
445 * @return Session
446 */
447 public function setTemperaturemin(?float $temperaturemin): Session {
448 $this->temperaturemin = $temperaturemin;
449
450 return $this;
451 }
452
453 /**
454 * Get temperaturemin
455 *
456 * @return float
457 */
458 public function getTemperaturemin(): ?float {
459 return $this->temperaturemin;
460 }
461
462 /**
463 * Set temperaturemax
464 *
465 * @param float $temperaturemax
466 *
467 * @return Session
468 */
469 public function setTemperaturemax(?float $temperaturemax): Session {
470 $this->temperaturemax = $temperaturemax;
471
472 return $this;
473 }
474
475 /**
476 * Get temperaturemax
477 *
478 * @return float
479 */
480 public function getTemperaturemax(): ?float {
481 return $this->temperaturemax;
482 }
483
484 /**
485 * Set locked
486 *
487 * @param \DateTime $locked
488 *
489 * @return Session
490 */
491 public function setLocked(?\DateTime $locked): Session {
492 $this->locked = $locked;
493
494 return $this;
495 }
496
497 /**
498 * Get locked
499 *
500 * @return \DateTime
501 */
502 public function getLocked(): ?\DateTime {
503 return $this->locked;
504 }
505
506 /**
507 * Set created
508 *
509 * @param \DateTime $created
510 *
511 * @return Session
512 */
513 public function setCreated(\DateTime $created): Session {
514 $this->created = $created;
515
516 return $this;
517 }
518
519 /**
520 * Get created
521 *
522 * @return \DateTime
523 */
524 public function getCreated(): \DateTime {
525 return $this->created;
526 }
527
528 /**
529 * Set updated
530 *
531 * @param \DateTime $updated
532 *
533 * @return Session
534 */
535 public function setUpdated(\DateTime $updated): Session {
536 $this->updated = $updated;
537
538 return $this;
539 }
540
541 /**
542 * Get updated
543 *
544 * @return \DateTime
545 */
546 public function getUpdated(): \DateTime {
547 return $this->updated;
548 }
549
550 /**
551 * Add application
552 *
553 * @param Application $application
554 *
555 * @return Session
556 */
557 public function addApplication(Application $application): Session {
558 $this->applications[] = $application;
559
560 return $this;
561 }
562
563 /**
564 * Remove application
565 *
566 * @param Application $application
567 */
568 public function removeApplication(Application $application): bool {
569 return $this->applications->removeElement($application);
570 }
571
572 /**
573 * Get applications
574 *
575 * @return ArrayCollection
576 */
577 public function getApplications(): ArrayCollection {
578 return $this->applications;
579 }
580
581 /**
582 * Set location
583 *
584 * @param Location $location
585 *
586 * @return Session
587 */
588 public function setLocation(Location $location): Session {
589 $this->location = $location;
590
591 return $this;
592 }
593
594 /**
595 * Get location
596 *
597 * @return Location
598 */
599 public function getLocation(): Location {
600 return $this->location;
601 }
602
603 /**
604 * Set slot
605 *
606 * @param Slot $slot
607 *
608 * @return Session
609 */
610 public function setSlot(Slot $slot): Session {
611 $this->slot = $slot;
612
613 return $this;
614 }
615
616 /**
617 * Get slot
618 *
619 * @return Slot
620 */
621 public function getSlot(): Slot {
622 return $this->slot;
623 }
624
625 /**
626 * Set application
627 *
628 * @param Application $application
629 *
630 * @return Session
631 */
632 public function setApplication(?Application $application): Session {
633 $this->application = $application;
634
635 return $this;
636 }
637
638 /**
639 * Get application
640 *
641 * @return Application
642 */
643 public function getApplication(): ?Application {
644 return $this->application;
645 }
646
647 /**
648 * {@inheritdoc}
649 */
650 public function preUpdate(PreUpdateEventArgs $eventArgs) {
651 //Check that we have a session instance
652 if (($session = $eventArgs->getEntity()) instanceof Session) {
653 //Set updated value
654 $session->setUpdated(new \DateTime('now'));
655 }
656 }
657
658 /**
659 * Wether if session is a premium day
660 *
661 * Consider as premium a day off for afternoon, the eve for evening and after
662 * Store computed result in premium member for afternoon and evening
663 *
664 * @return bool Whether the date is day off or not
665 */
666 public function isPremium(): bool {
667 //Without date
668 if (empty($date = $this->date)) {
669 throw new \LogicException('Property date is empty');
670 }
671
672 //Without slot
673 if (empty($slot = $this->slot) || empty($slotTitle = $slot->getTitle())) {
674 throw new \LogicException('Property slot is empty');
675 }
676
677 //With evening and after slot
678 if ($slotTitle == 'Evening' || $slotTitle == 'After') {
679 //Evening and after session is considered premium when the eve is a day off
680 $date = (clone $date)->add(new \DateInterval('P1D'));
681 }
682
683 //Get day number
684 $w = $date->format('w');
685
686 //Check if weekend day
687 if ($w == 0 || $w == 6) {
688 //With afternoon and evening slot
689 if ($slotTitle == 'Afternoon' || $slotTitle == 'Evening') {
690 //Save premium
691 $this->premium = true;
692 }
693
694 //Date is weekend day
695 return true;
696 }
697
698 //Get date day
699 $d = $date->format('d');
700
701 //Get date month
702 $m = $date->format('m');
703
704 //Check if fixed holiday
705 if (
706 //Check if 1st january
707 ($d == 1 && $m == 1) ||
708 //Check if 1st may
709 ($d == 1 && $m == 5) ||
710 //Check if 8st may
711 ($d == 8 && $m == 5) ||
712 //Check if 14st july
713 ($d == 14 && $m == 7) ||
714 //Check if 15st august
715 ($d == 15 && $m == 8) ||
716 //Check if 1st november
717 ($d == 1 && $m == 11) ||
718 //Check if 11st november
719 ($d == 11 && $m == 11) ||
720 //Check if 25st december
721 ($d == 25 && $m == 12)
722 ) {
723 //With afternoon and evening slot
724 if ($slotTitle == 'Afternoon' || $slotTitle == 'Evening') {
725 //Save premium
726 $this->premium = true;
727 }
728
729 //Date is a fixed holiday
730 return true;
731 }
732
733 //Get eastern
734 $eastern = $this->getEastern($date->format('Y'));
735
736 //Check dynamic holidays
737 if (
738 (clone $eastern)->add(new \DateInterval('P1D')) == $date ||
739 (clone $eastern)->add(new \DateInterval('P39D')) == $date ||
740 (clone $eastern)->add(new \DateInterval('P50D')) == $date
741 ) {
742 //With afternoon and evening slot
743 if ($slotTitle == 'Afternoon' || $slotTitle == 'Evening') {
744 //Save premium
745 $this->premium = true;
746 }
747
748 //Date is a dynamic holiday
749 return true;
750 }
751
752 //With afternoon and evening slot
753 if ($slotTitle == 'Afternoon' || $slotTitle == 'Evening') {
754 //Save premium
755 $this->premium = false;
756 }
757
758 //Date is not a holiday and week day
759 return false;
760 }
761
762 /**
763 * Compute eastern for selected year
764 *
765 * @param string $year The eastern year
766 *
767 * @return DateTime The eastern date
768 */
769 private function getEastern(string $year): \DateTime {
770 //Set static
771 static $data = null;
772
773 //Check if already computed
774 if (isset($data[$year])) {
775 //Return computed eastern
776 return $data[$year];
777 //Check if data is null
778 } elseif (is_null($data)) {
779 //Init data array
780 $data = [];
781 }
782
783 $d = (19 * ($year % 19) + 24) % 30;
784
785 $e = (2 * ($year % 4) + 4 * ($year % 7) + 6 * $d + 5) % 7;
786
787 $day = 22 + $d + $e;
788
789 $month = 3;
790
791 if ($day > 31) {
792 $day = $d + $e - 9;
793 $month = 4;
794 } elseif ($d == 29 && $e == 6) {
795 $day = 10;
796 $month = 4;
797 } elseif ($d == 28 && $e == 6) {
798 $day = 18;
799 $month = 4;
800 }
801
802 //Store eastern in data
803 return ($data[$year] = new \DateTime(sprintf('%04d-%02d-%02d', $year, $month, $day)));
804 }
805 }