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