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