PluginProbe ʕ •ᴥ•ʔ
Booking for Appointments and Events Calendar – Amelia / trunk
Booking for Appointments and Events Calendar – Amelia vtrunk
2.4.4 2.4.3 2.4.2 2.4.1 2.4 trunk 1.2.1 1.2.10 1.2.11 1.2.12 1.2.13 1.2.14 1.2.15 1.2.16 1.2.17 1.2.18 1.2.19 1.2.2 1.2.20 1.2.21 1.2.22 1.2.23 1.2.24 1.2.25 1.2.26 1.2.27 1.2.28 1.2.29 1.2.3 1.2.30 1.2.31 1.2.32 1.2.33 1.2.34 1.2.35 1.2.36 1.2.37 1.2.38 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 2.0 2.0.1 2.0.2 2.1 2.1.1 2.1.2 2.1.3 2.2 2.2.1 2.3
ameliabooking / src / Domain / Services / Booking / EventDomainService.php
ameliabooking / src / Domain / Services / Booking Last commit date
AppointmentDomainService.php 6 months ago EventDomainService.php 6 months ago
EventDomainService.php
538 lines
1 <?php
2
3 namespace AmeliaBooking\Domain\Services\Booking;
4
5 use AmeliaBooking\Domain\Collection\Collection;
6 use AmeliaBooking\Domain\Entity\Booking\Event\Event;
7 use AmeliaBooking\Domain\Entity\Booking\Event\EventPeriod;
8 use AmeliaBooking\Domain\Entity\Booking\Event\EventTicket;
9 use AmeliaBooking\Domain\Entity\Gallery\GalleryImage;
10 use AmeliaBooking\Domain\Factory\Booking\Event\EventTicketFactory;
11 use AmeliaBooking\Domain\Factory\Gallery\GalleryImageFactory;
12 use AmeliaBooking\Domain\Services\DateTime\DateTimeService;
13 use AmeliaBooking\Domain\Services\Settings\SettingsService;
14 use AmeliaBooking\Domain\ValueObjects\DateTime\DateTimeValue;
15 use AmeliaBooking\Domain\ValueObjects\Json;
16 use AmeliaBooking\Domain\ValueObjects\Number\Integer\Id;
17 use AmeliaBooking\Domain\ValueObjects\Number\Integer\IntegerValue;
18 use AmeliaBooking\Domain\ValueObjects\Recurring;
19 use AmeliaBooking\Domain\ValueObjects\String\Cycle;
20 use AmeliaBooking\Infrastructure\Common\Container;
21 use DateTime as DateTime;
22
23 /**
24 * Class EventDomainService
25 *
26 * @package AmeliaBooking\Domain\Services\Booking
27 */
28 class EventDomainService
29 {
30 /**
31 * @param DateTime $periodStart
32 * @param DateTime $periodEnd
33 *
34 * @return void
35 */
36 public function fixPeriod($periodStart, $periodEnd)
37 {
38 if ($periodStart->format('Y-m-d H:i') === $periodEnd->format('Y-m-d H:i')) {
39 $periodEnd->modify('60 minutes');
40 }
41 }
42
43 /**
44 * @param Recurring $recurring
45 * @param Collection $eventPeriods
46 *
47 * @return array
48 *
49 * @throws \AmeliaBooking\Domain\Common\Exceptions\InvalidArgumentException
50 */
51 public function getRecurringEventsPeriods($recurring, $eventPeriods)
52 {
53 $recurringPeriods = [];
54
55 if (!($recurring && $recurring->getCycle() && $recurring->getUntil())) {
56 return $recurringPeriods;
57 }
58
59 $recurringMonthDate = false;
60 $modifyCycle = 'days';
61 $modifyBaseValue = $recurring->getCycleInterval()->getValue();
62
63 switch ($recurring->getCycle()->getValue()) {
64 case (Cycle::DAILY):
65 $modifyCycle = 'days';
66 break;
67
68 case (Cycle::WEEKLY):
69 $modifyCycle = 'days';
70 $modifyBaseValue = 7 * $modifyBaseValue;
71 break;
72
73 case (Cycle::MONTHLY):
74 if ($recurring->getMonthlyRepeat() === 'on') {
75 $repeatPeriod = $recurring->getMonthlyOnRepeat() . ' ' . $recurring->getMonthlyOnDay();
76 } else {
77 $recurringMonthDate = true;
78 }
79 $modifyCycle = 'months';
80 break;
81
82 case (Cycle::YEARLY):
83 $modifyCycle = 'years';
84 break;
85 }
86
87 $hasMoreRecurringPeriods = true;
88
89 $recurringOrder = 1;
90
91 $recurringOrderEvent = 2;
92
93 while ($hasMoreRecurringPeriods) {
94 $periods = new Collection();
95
96 $modifyValue = $recurringOrder * $modifyBaseValue;
97
98 $periodStartDate0 = DateTimeService::getCustomDateTimeObject($eventPeriods->getItem(0)->getPeriodStart()->getValue()->format('Y-m-d H:i:s'));
99 $periodEndDate0 = DateTimeService::getCustomDateTimeObject($eventPeriods->getItem(0)->getPeriodEnd()->getValue()->format('Y-m-d H:i:s'));
100
101 $periodStart0 = null;
102 $dayDifference = null;
103
104 if (isset($repeatPeriod)) {
105 $periodStart0 = $this->getNextPeriodStartDate($periodStartDate0, $modifyValue, $repeatPeriod);
106 if ($periodStart0 === null) {
107 if ($periodStart0 > $recurring->getUntil()->getValue()) {
108 break;
109 }
110 $recurringOrder++;
111 $recurringOrderEvent++;
112 continue;
113 }
114 $dayDifference = $periodStartDate0->diff($periodStart0);
115 }
116
117 for ($i = 0; $i < count($eventPeriods->getItems()); $i++) {
118 $periodStartDate = DateTimeService::getCustomDateTimeObject($eventPeriods->getItem($i)->getPeriodStart()->getValue()->format('Y-m-d H:i:s'));
119 $periodEndDate = DateTimeService::getCustomDateTimeObject($eventPeriods->getItem($i)->getPeriodEnd()->getValue()->format('Y-m-d H:i:s'));
120
121 if (isset($repeatPeriod)) {
122 if ($i === 0) {
123 $periodStart = $periodStart0;
124 $periodEnd = $periodEndDate0->add($dayDifference);
125 } else {
126 $periodStart = $periodStartDate->add($dayDifference);
127 $periodEnd = $periodEndDate->add($dayDifference);
128 }
129 } else {
130 $originalDate = clone $periodStartDate;
131 $periodStart = $periodStartDate->modify("+{$modifyValue} {$modifyCycle}");
132 $periodEnd = $periodEndDate->modify("+{$modifyValue} {$modifyCycle}");
133 if (
134 $i === 0 && $recurringMonthDate &&
135 $originalDate && $originalDate->format('d') != $periodStart->format('d')
136 ) {
137 $day = $originalDate->format('j');
138 $originalDate->modify("first day of +{$modifyValue} month");
139 $periodStart = $originalDate->modify('+' . (min($day, $originalDate->format('t')) - 1) . ' days');
140 }
141 }
142
143 $newEventPeriod = new EventPeriod();
144
145 $newEventPeriod->setPeriodStart(new DateTimeValue($periodStart));
146 $newEventPeriod->setPeriodEnd(new DateTimeValue($periodEnd));
147
148 $periods->addItem($newEventPeriod);
149
150 if ($periodStart > $recurring->getUntil()->getValue()) {
151 $hasMoreRecurringPeriods = false;
152 }
153 }
154
155 if ($hasMoreRecurringPeriods) {
156 $recurringPeriods[] = ['order' => $recurringOrderEvent, 'periods' => $periods];
157 $recurringOrderEvent++;
158 $recurringOrder++;
159 }
160 }
161
162 return $recurringPeriods;
163 }
164
165 /**
166 * @param Collection $eventPeriods
167 * @param bool $setId
168 *
169 * @return Collection
170 *
171 * @throws \AmeliaBooking\Domain\Common\Exceptions\InvalidArgumentException
172 */
173 public function getClonedEventPeriods($eventPeriods, $setId = false)
174 {
175 $clonedPeriods = new Collection();
176
177 /** @var EventPeriod $eventPeriod **/
178 foreach ($eventPeriods->getItems() as $eventPeriod) {
179 $periodStart = DateTimeService::getCustomDateTimeObject(
180 $eventPeriod->getPeriodStart()->getValue()->format('Y-m-d H:i:s')
181 );
182
183 $periodEnd = DateTimeService::getCustomDateTimeObject(
184 $eventPeriod->getPeriodEnd()->getValue()->format('Y-m-d H:i:s')
185 );
186
187 $newEventPeriod = new EventPeriod();
188
189 $newEventPeriod->setPeriodStart(new DateTimeValue($periodStart));
190 $newEventPeriod->setPeriodEnd(new DateTimeValue($periodEnd));
191
192 if ($eventPeriod->getZoomMeeting()) {
193 $newEventPeriod->setZoomMeeting($eventPeriod->getZoomMeeting());
194 }
195
196 if ($setId) {
197 $newEventPeriod->setId(new Id($eventPeriod->getId()->getValue()));
198 }
199
200 $clonedPeriods->addItem($newEventPeriod);
201 }
202
203 return $clonedPeriods;
204 }
205
206
207 /**
208 * @param Collection $eventTickets
209 *
210 * @return Collection
211 *
212 * @throws \AmeliaBooking\Domain\Common\Exceptions\InvalidArgumentException
213 */
214 public function getClonedEventTickets($eventTickets)
215 {
216 $clonedTickets = new Collection();
217
218 /** @var EventTicket $eventTicket **/
219 foreach ($eventTickets->getItems() as $eventTicket) {
220 $newEventTicket = EventTicketFactory::create($eventTicket->toArray());
221 $clonedTickets->addItem($newEventTicket);
222 }
223
224 return $clonedTickets;
225 }
226
227
228 /**
229 * @param Event $followingEvent
230 * @param Event $originEvent
231 * @param Collection $clonedOriginEventPeriods
232 *
233 * @return boolean
234 *
235 * @throws \Slim\Exception\ContainerValueNotFoundException
236 * @throws \AmeliaBooking\Domain\Common\Exceptions\InvalidArgumentException
237 */
238 public function buildFollowingEvent($followingEvent, $originEvent, $clonedOriginEventPeriods)
239 {
240 $followingEvent->setName($originEvent->getName());
241 $followingEvent->setPrice($originEvent->getPrice());
242 $followingEvent->setMaxCapacity($originEvent->getMaxCapacity());
243 $followingEvent->setTags($originEvent->getTags());
244 $followingEvent->setProviders($originEvent->getProviders());
245 $followingEvent->setBringingAnyone($originEvent->getBringingAnyone());
246 $followingEvent->setBookMultipleTimes($originEvent->getBookMultipleTimes());
247 $followingEvent->setOrganizerId($originEvent->getOrganizerId());
248 $followingEvent->setCustomPricing($originEvent->getCustomPricing());
249 $followingEvent->setCloseAfterMin($originEvent->getCloseAfterMin());
250 $followingEvent->setMaxCustomCapacity($originEvent->getMaxCustomCapacity());
251 $followingEvent->setCloseAfterMinBookings($originEvent->getCloseAfterMinBookings());
252 $followingEvent->setAggregatedPrice($originEvent->getAggregatedPrice());
253 $followingEvent->setMaxExtraPeople($originEvent->getMaxExtraPeople());
254 $followingEvent->setNotifyParticipants($originEvent->isNotifyParticipants());
255
256 if ($originEvent->getPicture()) {
257 $followingEvent->setPicture($originEvent->getPicture());
258 }
259
260 if ($originEvent->getCustomPricing() && $originEvent->getCustomPricing()->getValue() && $followingEvent->getBookings()->length() === 0) {
261 $newEventTickets = new Collection();
262 /** @var EventTicket $eventTicket */
263 foreach ($originEvent->getCustomTickets()->getItems() as $ticketIndex => $eventTicket) {
264 if (!empty($followingEvent->getCustomTickets()->toArray()[$ticketIndex])) {
265 $editedTicket = EventTicketFactory::create($followingEvent->getCustomTickets()->toArray()[$ticketIndex]);
266 $editedTicket->setName($eventTicket->getName());
267 $editedTicket->setEnabled($eventTicket->getEnabled());
268 $editedTicket->setPrice($eventTicket->getPrice());
269 if ($eventTicket->getTranslations()) {
270 $editedTicket->setTranslations($eventTicket->getTranslations());
271 }
272 $editedTicket->setSpots($eventTicket->getSpots());
273 $newEventTickets->addItem($editedTicket);
274 } else {
275 $newTicket = EventTicketFactory::create($eventTicket->toArray());
276 $newTicket->setId(new Id(0));
277 $newTicket->setEventId($followingEvent->getId() ? new Id($followingEvent->getId()->getValue()) : null);
278 $newTicket->setSold(new IntegerValue(0));
279 $newTicket->setDateRanges(new Json('[]'));
280 $newEventTickets->addItem($newTicket);
281 }
282 }
283 $followingEvent->setCustomTickets($newEventTickets);
284 }
285
286 if ($originEvent->getTranslations()) {
287 $followingEvent->setTranslations($originEvent->getTranslations());
288 }
289
290 if ($originEvent->getDeposit()) {
291 $followingEvent->setDeposit($originEvent->getDeposit());
292 }
293
294 if ($originEvent->getDepositPayment()) {
295 $followingEvent->setDepositPayment($originEvent->getDepositPayment());
296 }
297
298 if ($originEvent->getDepositPerPerson()) {
299 $followingEvent->setDepositPerPerson($originEvent->getDepositPerPerson());
300 }
301
302 $followingEventGallery = new Collection();
303
304 /** @var GalleryImage $image **/
305 foreach ($originEvent->getGallery()->getItems() as $image) {
306 $followingEventGallery->addItem(
307 GalleryImageFactory::create(
308 [
309 'id' => null,
310 'entityId' => $followingEvent->getId() ? $followingEvent->getId()->getValue() : null,
311 'entityType' => $image->getEntityType()->getValue(),
312 'pictureFullPath' => $image->getPicture()->getFullPath(),
313 'pictureThumbPath' => $image->getPicture()->getThumbPath(),
314 'position' => $image->getPosition()->getValue(),
315 ]
316 )
317 );
318 }
319
320 $followingEvent->setGallery($followingEventGallery);
321
322 if ($originEvent->getSettings()) {
323 $followingEvent->setSettings($originEvent->getSettings());
324 }
325
326 $followingEvent->setBookingOpens($originEvent->getBookingOpens());
327
328 $followingEvent->setBookingCloses($originEvent->getBookingCloses());
329
330 $followingEvent->setBookingOpensRec($originEvent->getBookingOpensRec());
331
332 $followingEvent->setBookingClosesRec($originEvent->getBookingClosesRec());
333
334 if ($originEvent->getLocationId()) {
335 $followingEvent->setLocationId($originEvent->getLocationId());
336 }
337
338 if ($originEvent->getCustomLocation()) {
339 $followingEvent->setCustomLocation($originEvent->getCustomLocation());
340 }
341
342 if ($originEvent->getTags()) {
343 $followingEvent->setTags($originEvent->getTags());
344 }
345
346 if ($originEvent->getDescription()) {
347 $followingEvent->setDescription($originEvent->getDescription());
348 }
349
350 if ($originEvent->getColor()) {
351 $followingEvent->setColor($originEvent->getColor());
352 }
353
354 if ($originEvent->getShow()) {
355 $followingEvent->setShow($originEvent->getShow());
356 }
357
358 if ($originEvent->getZoomUserId()) {
359 $followingEvent->setZoomUserId($originEvent->getZoomUserId());
360 }
361
362 $modifyCycle = 'days';
363 $modifyBaseValue = $originEvent->getRecurring()->getCycleInterval()->getValue();
364 $recurringMonthDate = false;
365
366 switch ($originEvent->getRecurring()->getCycle()->getValue()) {
367 case (Cycle::DAILY):
368 $modifyCycle = 'days';
369 break;
370
371 case (Cycle::WEEKLY):
372 $modifyCycle = 'days';
373 $modifyBaseValue = 7 * $modifyBaseValue;
374 break;
375
376 case (Cycle::MONTHLY):
377 if ($followingEvent->getRecurring()->getMonthlyRepeat() === 'on') {
378 $repeatPeriod = $followingEvent->getRecurring()->getMonthlyOnRepeat() . ' ' . $followingEvent->getRecurring()->getMonthlyOnDay();
379 } else {
380 $recurringMonthDate = true;
381 }
382 $modifyCycle = 'months';
383 break;
384
385 case (Cycle::YEARLY):
386 $modifyCycle = 'years';
387 break;
388 }
389
390 $modifyValue = $modifyBaseValue * ($followingEvent->getRecurring()->getOrder()->getValue() - 1);
391
392 $periodStartDate0 =
393 DateTimeService::getCustomDateTimeObject($clonedOriginEventPeriods->getItem(0)->getPeriodStart()->getValue()->format('Y-m-d H:i:s'));
394 $periodEndDate0 =
395 DateTimeService::getCustomDateTimeObject($clonedOriginEventPeriods->getItem(0)->getPeriodEnd()->getValue()->format('Y-m-d H:i:s'));
396
397 $periodStart0 = null;
398 $dayDifference = null;
399 if (isset($repeatPeriod)) {
400 $periodStart0 = $this->getNextPeriodStartDate($periodStartDate0, $modifyValue, $repeatPeriod);
401 if ($periodStart0 === null) {
402 // for added events
403 return false;
404 }
405 $dayDifference = $periodStartDate0->diff($periodStart0);
406 }
407
408 /** @var EventPeriod $followingEventPeriod */
409 foreach ($followingEvent->getPeriods()->getItems() as $key => $followingEventPeriod) {
410 if ($clonedOriginEventPeriods->keyExists($key)) {
411 /** @var EventPeriod $clonedOriginEventPeriod */
412 $clonedOriginEventPeriod = $clonedOriginEventPeriods->getItem($key);
413
414 $periodStartDate = DateTimeService::getCustomDateTimeObject($clonedOriginEventPeriod->getPeriodStart()->getValue()->format('Y-m-d H:i:s'));
415 $periodEndDate = DateTimeService::getCustomDateTimeObject($clonedOriginEventPeriod->getPeriodEnd()->getValue()->format('Y-m-d H:i:s'));
416
417 if (isset($repeatPeriod)) {
418 if ($key === 0) {
419 $periodStart = $periodStart0;
420 $periodEnd = $periodEndDate0->add($dayDifference);
421 } else {
422 $periodStart = $periodStartDate->add($dayDifference);
423 $periodEnd = $periodEndDate->add($dayDifference);
424 }
425 } else {
426 $periodStartDateCloned = clone $periodStartDate;
427 $periodStart = $periodStartDate->modify("+{$modifyValue} {$modifyCycle}");
428 $periodEnd = $periodEndDate->modify("+{$modifyValue} {$modifyCycle}");
429 if (
430 $key === 0 && $recurringMonthDate &&
431 $periodStartDateCloned && $periodStartDateCloned->format('d') != $periodStart->format('d')
432 ) {
433 $day = $periodStartDateCloned->format('j');
434 $periodStartDateCloned->modify("first day of +{$modifyValue} month");
435 $periodStart = $periodStartDateCloned->modify('+' . (min($day, $periodStartDateCloned->format('t')) - 1) . ' days');
436 }
437 }
438
439 $followingEventPeriod->setPeriodStart(new DateTimeValue($periodStart));
440 $followingEventPeriod->setPeriodEnd(new DateTimeValue($periodEnd));
441 } else {
442 $followingEvent->getPeriods()->deleteItem($key);
443 }
444 }
445
446 /** @var EventPeriod $originEventPeriod */
447 foreach ($originEvent->getPeriods()->getItems() as $key => $originEventPeriod) {
448 if (!$followingEvent->getPeriods()->keyExists($key)) {
449
450 /** @var EventPeriod $followingEventPeriod */
451 $newFollowingEventPeriod = new EventPeriod();
452
453 $newPeriodStart = DateTimeService::getCustomDateTimeObject(
454 $originEventPeriod->getPeriodStart()->getValue()->format('Y-m-d H:i:s')
455 );
456
457 $newPeriodEnd = DateTimeService::getCustomDateTimeObject(
458 $originEventPeriod->getPeriodEnd()->getValue()->format('Y-m-d H:i:s')
459 );
460
461 if (isset($repeatPeriod)) {
462 $periodStart = $newPeriodStart->add($dayDifference);
463 $periodEnd = $newPeriodEnd->add($dayDifference);
464 } else {
465 $periodStartDateCloned = clone $newPeriodStart;
466 $periodStart = $newPeriodStart->modify("+{$modifyValue} {$modifyCycle}");
467 $periodEnd = $newPeriodEnd->modify("+{$modifyValue} {$modifyCycle}");
468 if (
469 $key === 0 && $recurringMonthDate &&
470 $periodStartDateCloned && $periodStartDateCloned->format('d') != $periodStart->format('d')
471 ) {
472 $day = $periodStartDateCloned->format('j');
473 $periodStartDateCloned->modify("first day of +{$modifyValue} month");
474 $periodStart = $periodStartDateCloned->modify('+' . (min($day, $periodStartDateCloned->format('t')) - 1) . ' days');
475 }
476 }
477
478 $newFollowingEventPeriod->setPeriodStart(new DateTimeValue($periodStart));
479
480 $newFollowingEventPeriod->setPeriodEnd(new DateTimeValue($periodEnd));
481
482 $newFollowingEventPeriod->setEventId(new Id($followingEvent->getId()->getValue()));
483
484 $followingEvent->getPeriods()->addItem($newFollowingEventPeriod);
485 }
486 }
487
488 return true;
489 }
490
491 /**
492 * @param Container $container
493 * @param array $events
494 *
495 * @return array
496 *
497 * @throws \AmeliaBooking\Domain\Common\Exceptions\InvalidArgumentException
498 */
499 public function getShortcodeForEventList($container, $events)
500 {
501
502 /** @var SettingsService $settingsService */
503 $settingsService = $container->get('domain.settings.service');
504 $dateFormat = $settingsService->getSetting('wordpress', 'dateFormat');
505
506 for ($i = 0; $i < count($events); $i++) {
507 $dateString = explode(" ", $events[$i]['periods'][0]['periodStart'])[0];
508 $newDate = date_i18n($dateFormat, strtotime($dateString));
509 $events[$i]['formattedPeriodStart'] = $newDate;
510 }
511 return $events;
512 }
513
514 /**
515 * @param \DateTime $periodStartDate0
516 * @param int $modifyValue
517 * @param string $repeatPeriod
518 *
519 * @return \DateTime
520 *
521 * @throws \AmeliaBooking\Domain\Common\Exceptions\InvalidArgumentException
522 * @throws \Exception
523 */
524 public function getNextPeriodStartDate($periodStartDate0, $modifyValue, $repeatPeriod)
525 {
526 $month = (int)$periodStartDate0->format('m') + $modifyValue;
527 $year = (int)$periodStartDate0->format('Y');
528
529 $year += floor($month / 12);
530 $month -= 12 * floor($month / 12);
531 $time = (int)$periodStartDate0->format('H') * 60 + (int)$periodStartDate0->format('i');
532
533 $periodStart0 = DateTimeService::getCustomDateTimeObject($repeatPeriod . " of $year-$month");
534 return explode(' ', $repeatPeriod)[0] === 'fifth'
535 && (int)$periodStart0->format('m') !== (int)$month ? null : $periodStart0->add(new \DateInterval('PT' . $time . 'M'));
536 }
537 }
538