PluginProbe ʕ •ᴥ•ʔ
Booking for Appointments and Events Calendar – Amelia / 1.2.31
Booking for Appointments and Events Calendar – Amelia v1.2.31
2.4.9 2.4.8 2.4.7 2.4.6 2.4.5 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 / Infrastructure / Repository / Booking / Event / EventRepository.php
ameliabooking / src / Infrastructure / Repository / Booking / Event Last commit date
CustomerBookingEventPeriodRepository.php 1 year ago CustomerBookingEventTicketRepository.php 1 year ago EventPeriodsRepository.php 1 year ago EventProvidersRepository.php 1 year ago EventRepository.php 1 year ago EventTagsRepository.php 1 year ago EventTicketRepository.php 1 year ago
EventRepository.php
1804 lines
1 <?php
2
3 namespace AmeliaBooking\Infrastructure\Repository\Booking\Event;
4
5 use AmeliaBooking\Domain\Collection\Collection;
6 use AmeliaBooking\Domain\Common\Exceptions\InvalidArgumentException;
7 use AmeliaBooking\Domain\Entity\Booking\Event\Event;
8 use AmeliaBooking\Domain\Factory\Booking\Appointment\CustomerBookingFactory;
9 use AmeliaBooking\Domain\Factory\Booking\Event\EventFactory;
10 use AmeliaBooking\Domain\Repository\Booking\Event\EventRepositoryInterface;
11 use AmeliaBooking\Domain\Services\DateTime\DateTimeService;
12 use AmeliaBooking\Infrastructure\Common\Exceptions\QueryExecutionException;
13 use AmeliaBooking\Infrastructure\Licence;
14 use AmeliaBooking\Infrastructure\Repository\AbstractRepository;
15 use AmeliaBooking\Infrastructure\WP\InstallActions\DB\Booking\CustomerBookingsTable;
16 use AmeliaBooking\Infrastructure\WP\InstallActions\DB\Booking\CustomerBookingsToEventsPeriodsTable;
17 use AmeliaBooking\Infrastructure\WP\InstallActions\DB\Booking\CustomerBookingToEventsTicketsTable;
18 use AmeliaBooking\Infrastructure\WP\InstallActions\DB\Booking\EventsPeriodsTable;
19 use AmeliaBooking\Infrastructure\WP\InstallActions\DB\Booking\EventsProvidersTable;
20 use AmeliaBooking\Infrastructure\WP\InstallActions\DB\Booking\EventsTagsTable;
21 use AmeliaBooking\Infrastructure\WP\InstallActions\DB\Booking\EventsTicketsTable;
22 use AmeliaBooking\Infrastructure\WP\InstallActions\DB\Coupon\CouponsTable;
23 use AmeliaBooking\Infrastructure\WP\InstallActions\DB\Gallery\GalleriesTable;
24 use AmeliaBooking\Infrastructure\WP\InstallActions\DB\Payment\PaymentsTable;
25 use AmeliaBooking\Infrastructure\WP\InstallActions\DB\User\UsersTable;
26
27 /**
28 * Class EventRepository
29 *
30 * @package AmeliaBooking\Infrastructure\Repository\Booking\Event
31 */
32 class EventRepository extends AbstractRepository implements EventRepositoryInterface
33 {
34 public const FACTORY = EventFactory::class;
35
36 /**
37 * @param Event $entity
38 *
39 * @return bool
40 * @throws QueryExecutionException
41 */
42 public function add($entity)
43 {
44 $data = $entity->toArray();
45
46 $params = [
47 ':bookingOpens' => $data['bookingOpens'] ? DateTimeService::getCustomDateTimeInUtc($data['bookingOpens']) : null,
48 ':bookingCloses' => $data['bookingCloses'] ? DateTimeService::getCustomDateTimeInUtc($data['bookingCloses']) : null,
49 ':bookingOpensRec' => $data['bookingOpensRec'],
50 ':bookingClosesRec' => $data['bookingClosesRec'],
51 ':status' => $data['status'],
52 ':name' => $data['name'],
53 ':description' => $data['description'],
54 ':color' => $data['color'],
55 ':price' => $data['price'],
56 ':bringingAnyone' => $data['bringingAnyone'] ? 1 : 0,
57 ':bookMultipleTimes' => $data['bookMultipleTimes'] ? 1 : 0,
58 ':maxCapacity' => $data['maxCapacity'],
59 ':maxCustomCapacity' => $data['maxCustomCapacity'],
60 ':maxExtraPeople' => $data['maxExtraPeople'],
61 ':show' => $data['show'] ? 1 : 0,
62 ':notifyParticipants' => $data['notifyParticipants'],
63 ':customLocation' => $data['customLocation'],
64 ':parentId' => $data['parentId'],
65 ':created' => $data['created'],
66 ':closeAfterMin' => $data['closeAfterMin'],
67 ':closeAfterMinBookings' => $data['closeAfterMinBookings'] ? 1 : 0,
68 ':aggregatedPrice' => $data['aggregatedPrice'] ? 1 : 0,
69 ':error' => '',
70 ];
71
72 $additionalData = Licence\DataModifier::getEventRepositoryData($data);
73
74 $params = array_merge($params, $additionalData['values'], $additionalData['addValues']);
75
76 try {
77 $statement = $this->connection->prepare(
78 "INSERT INTO {$this->table}
79 (
80 {$additionalData['columns']}
81 `bookingOpens`,
82 `bookingCloses`,
83 `bookingOpensRec`,
84 `bookingClosesRec`,
85 `status`,
86 `name`,
87 `description`,
88 `color`,
89 `price`,
90 `bringingAnyone`,
91 `bookMultipleTimes`,
92 `maxCapacity`,
93 `maxCustomCapacity`,
94 `maxExtraPeople`,
95 `show`,
96 `notifyParticipants`,
97 `customLocation`,
98 `parentId`,
99 `created`,
100 `closeAfterMin`,
101 `closeAfterMinBookings`,
102 `aggregatedPrice`,
103 `error`
104 )
105 VALUES (
106 {$additionalData['placeholders']}
107 :bookingOpens,
108 :bookingCloses,
109 :bookingOpensRec,
110 :bookingClosesRec,
111 :status,
112 :name,
113 :description,
114 :color,
115 :price,
116 :bringingAnyone,
117 :bookMultipleTimes,
118 :maxCapacity,
119 :maxCustomCapacity,
120 :maxExtraPeople,
121 :show,
122 :notifyParticipants,
123 :customLocation,
124 :parentId,
125 :created,
126 :closeAfterMin,
127 :closeAfterMinBookings,
128 :aggregatedPrice,
129 :error
130 )"
131 );
132
133 $res = $statement->execute($params);
134
135 if (!$res) {
136 throw new QueryExecutionException('Unable to add data in ' . __CLASS__);
137 }
138
139 return $this->connection->lastInsertId();
140 } catch (\Exception $e) {
141 throw new QueryExecutionException('Unable to add data in ' . __CLASS__, $e->getCode(), $e);
142 }
143 }
144
145 /**
146 * @param int $id
147 * @param Event $entity
148 *
149 * @return mixed
150 * @throws QueryExecutionException
151 */
152 public function update($id, $entity)
153 {
154 $data = $entity->toArray();
155
156 $params = [
157 ':id' => $id,
158 ':bookingOpens' => $data['bookingOpens'] ? DateTimeService::getCustomDateTimeInUtc($data['bookingOpens']) : null,
159 ':bookingCloses' => $data['bookingCloses'] ? DateTimeService::getCustomDateTimeInUtc($data['bookingCloses']) : null,
160 ':bookingOpensRec' => $data['bookingOpensRec'],
161 ':bookingClosesRec' => $data['bookingClosesRec'],
162 ':status' => $data['status'],
163 ':name' => $data['name'],
164 ':description' => $data['description'],
165 ':color' => $data['color'],
166 ':price' => $data['price'],
167 ':bringingAnyone' => $data['bringingAnyone'] ? 1 : 0,
168 ':bookMultipleTimes' => $data['bookMultipleTimes'] ? 1 : 0,
169 ':maxCapacity' => $data['maxCapacity'],
170 ':maxCustomCapacity' => $data['maxCustomCapacity'],
171 ':maxExtraPeople' => $data['maxExtraPeople'],
172 ':show' => $data['show'] ? 1 : 0,
173 ':notifyParticipants' => $data['notifyParticipants'] ? 1 : 0,
174 ':customLocation' => $data['customLocation'],
175 ':parentId' => $data['parentId'],
176 ':closeAfterMin' => $data['closeAfterMin'],
177 ':closeAfterMinBookings' => $data['closeAfterMinBookings'] ? 1 : 0,
178 ':aggregatedPrice' => $data['aggregatedPrice'] ? 1 : 0
179 ];
180
181 $additionalData = Licence\DataModifier::getEventRepositoryData($data);
182
183 $params = array_merge($params, $additionalData['values']);
184
185 try {
186 $statement = $this->connection->prepare(
187 "UPDATE {$this->table}
188 SET
189 {$additionalData['columnsPlaceholders']}
190 `bookingOpens` = :bookingOpens,
191 `bookingCloses` = :bookingCloses,
192 `bookingOpensRec` = :bookingOpensRec,
193 `bookingClosesRec` = :bookingClosesRec,
194 `status` = :status,
195 `name` = :name,
196 `description` = :description,
197 `color` = :color,
198 `price` = :price,
199 `bringingAnyone` = :bringingAnyone,
200 `bookMultipleTimes` = :bookMultipleTimes,
201 `maxCapacity` = :maxCapacity,
202 `maxCustomCapacity` = :maxCustomCapacity,
203 `maxExtraPeople` = :maxExtraPeople,
204 `show` = :show,
205 `notifyParticipants` = :notifyParticipants,
206 `customLocation` = :customLocation,
207 `parentId` = :parentId,
208 `closeAfterMin` = :closeAfterMin,
209 `closeAfterMinBookings` = :closeAfterMinBookings,
210 `aggregatedPrice` = :aggregatedPrice
211 WHERE id = :id"
212 );
213
214 $res = $statement->execute($params);
215
216 if (!$res) {
217 throw new QueryExecutionException('Unable to save data in ' . __CLASS__);
218 }
219
220 return $res;
221 } catch (\Exception $e) {
222 throw new QueryExecutionException('Unable to save data in ' . __CLASS__, $e->getCode(), $e);
223 }
224 }
225
226 /**
227 * @param int $id
228 * @param int $status
229 *
230 * @return mixed
231 * @throws QueryExecutionException
232 */
233 public function updateStatusById($id, $status)
234 {
235 $params = [
236 ':id' => $id,
237 ':status' => $status
238 ];
239
240 try {
241 $statement = $this->connection->prepare(
242 "UPDATE {$this->table}
243 SET
244 `status` = :status
245 WHERE id = :id"
246 );
247
248 $res = $statement->execute($params);
249
250 if (!$res) {
251 throw new QueryExecutionException('Unable to save data in ' . __CLASS__);
252 }
253
254 return $res;
255 } catch (\Exception $e) {
256 throw new QueryExecutionException('Unable to save data in ' . __CLASS__, $e->getCode(), $e);
257 }
258 }
259
260 /**
261 * @param int $id
262 * @param int|null $parentId
263 *
264 * @return mixed
265 * @throws QueryExecutionException
266 */
267 public function updateParentId($id, $parentId)
268 {
269 $params = [
270 ':id' => $id,
271 ':parentId' => $parentId,
272 ];
273
274 try {
275 $statement = $this->connection->prepare(
276 "UPDATE {$this->table}
277 SET
278 `parentId` = :parentId
279 WHERE id = :id"
280 );
281
282 $res = $statement->execute($params);
283
284 if (!$res) {
285 throw new QueryExecutionException('Unable to save data in ' . __CLASS__);
286 }
287
288 return $res;
289 } catch (\Exception $e) {
290 throw new QueryExecutionException('Unable to save data in ' . __CLASS__, $e->getCode(), $e);
291 }
292 }
293
294 /**
295 * @param array $criteria
296 *
297 * @return Collection
298 * @throws QueryExecutionException
299 * @throws InvalidArgumentException
300 */
301 public function getProvidersEvents($criteria)
302 {
303 $eventsPeriodsTable = EventsPeriodsTable::getTableName();
304 $eventsProvidersTable = EventsProvidersTable::getTableName();
305 $usersTable = UsersTable::getTableName();
306
307 $params = [];
308 $where = [];
309
310 if (!empty($criteria['dates'])) {
311 if (isset($criteria['dates'][0], $criteria['dates'][1])) {
312 $whereStart = "(ep.periodStart BETWEEN :eventFrom AND :eventTo)";
313 $params[':eventFrom'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][0]);
314 $params[':eventTo'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][1]);
315
316 $whereEnd = "(ep.periodEnd BETWEEN :bookingFrom2 AND :bookingTo2)";
317 $params[':bookingFrom2'] = $params[':eventFrom'];
318 $params[':bookingTo2'] = $params[':eventTo'];
319
320 $where[] = "({$whereStart} OR {$whereEnd})";
321 } elseif (isset($criteria['dates'][0])) {
322 $where[] = "(ep.periodStart >= :eventFrom)";
323 $params[':eventFrom'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][0]);
324 } elseif (isset($criteria['dates'][1])) {
325 $where[] = "(ep.periodStart <= :eventTo)";
326 $params[':eventTo'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][1]);
327 } else {
328 $where[] = "(ep.periodStart > :eventFrom)";
329 $params[':eventFrom'] = DateTimeService::getNowDateTimeInUtc();
330 }
331 }
332
333 if (!empty($criteria['providers'])) {
334 $queryProviders = [];
335
336 foreach ((array)$criteria['providers'] as $index => $value) {
337 $param = ':provider' . $index;
338 $queryProviders[] = $param;
339 $params[$param] = $value;
340 }
341
342 $where[] = 'epr.userId IN (' . implode(', ', $queryProviders) . ')';
343 }
344
345 if (!empty($criteria['status'])) {
346 $params[':status'] = $criteria['status'];
347
348 $where[] = 'e.status = :status';
349 }
350
351 $where = $where ? 'WHERE ' . implode(' AND ', $where) : '';
352
353 try {
354 $statement = $this->connection->prepare(
355 "SELECT
356 e.id AS event_id,
357 e.name AS event_name,
358 e.status AS event_status,
359 e.bookingOpens AS event_bookingOpens,
360 e.bookingCloses AS event_bookingCloses,
361 e.recurringCycle AS event_recurringCycle,
362 e.recurringOrder AS event_recurringOrder,
363 e.recurringInterval AS event_recurringInterval,
364 e.recurringUntil AS event_recurringUntil,
365 e.recurringMonthly AS event_recurringMonthly,
366 e.monthlyDate AS event_monthlyDate,
367 e.monthlyOnRepeat AS event_monthlyOnRepeat,
368 e.monthlyOnDay AS event_monthlyOnDay,
369 e.bringingAnyone AS event_bringingAnyone,
370 e.bookMultipleTimes AS event_bookMultipleTimes,
371 e.maxCapacity AS event_maxCapacity,
372 e.maxCustomCapacity AS event_maxCustomCapacity,
373 e.maxExtraPeople AS event_maxExtraPeople,
374 e.price AS event_price,
375 e.description AS event_description,
376 e.color AS event_color,
377 e.show AS event_show,
378 e.locationId AS event_locationId,
379 e.customLocation AS event_customLocation,
380 e.parentId AS event_parentId,
381 e.created AS event_created,
382 e.notifyParticipants AS event_notifyParticipants,
383 e.translations AS event_translations,
384 e.deposit AS event_deposit,
385 e.depositPayment AS event_depositPayment,
386 e.depositPerPerson AS event_depositPerPerson,
387 e.fullPayment AS event_fullPayment,
388 e.customPricing AS event_customPricing,
389 e.aggregatedPrice AS event_aggregatedPrice,
390
391 ep.id AS event_periodId,
392 ep.periodStart AS event_periodStart,
393 ep.periodEnd AS event_periodEnd,
394
395 pu.id AS provider_id,
396 pu.firstName AS provider_firstName,
397 pu.lastName AS provider_lastName,
398 pu.email AS provider_email,
399 pu.note AS provider_note,
400 pu.description AS provider_description,
401 pu.phone AS provider_phone,
402 pu.gender AS provider_gender,
403 pu.pictureFullPath AS provider_pictureFullPath,
404 pu.pictureThumbPath AS provider_pictureThumbPath,
405 pu.translations AS provider_translations
406 FROM {$this->table} e
407 INNER JOIN {$eventsPeriodsTable} ep ON ep.eventId = e.id
408 INNER JOIN {$eventsProvidersTable} epr ON epr.eventId = e.id
409 INNER JOIN {$usersTable} pu ON pu.id = epr.userId
410 {$where}
411 ORDER BY ep.periodStart"
412 );
413
414 $statement->execute($params);
415
416 $rows = $statement->fetchAll();
417 } catch (\Exception $e) {
418 throw new QueryExecutionException('Unable to find by id in ' . __CLASS__, $e->getCode(), $e);
419 }
420
421 return call_user_func([static::FACTORY, 'createCollection'], $rows);
422 }
423
424 /**
425 * @param array $criteria
426 * @param int $itemsPerPage
427 *
428 * @return array
429 * @throws QueryExecutionException
430 * @throws InvalidArgumentException
431 */
432 public function getFilteredIds($criteria, $itemsPerPage)
433 {
434 $eventsPeriodsTable = EventsPeriodsTable::getTableName();
435 $eventsTagsTable = EventsTagsTable::getTableName();
436 $customerBookingsTable = CustomerBookingsTable::getTableName();
437 $customerBookingsEventsPeriods = CustomerBookingsToEventsPeriodsTable::getTableName();
438 $eventsProvidersTable = EventsProvidersTable::getTableName();
439 $usersTable = UsersTable::getTableName();
440
441 $params = [];
442
443 $where = [];
444
445 if (isset($criteria['parentId'])) {
446 $params[':parentId'] = $criteria['parentId'];
447
448 $params[':originParentId'] = $criteria['parentId'];
449
450 $where[] = 'e.parentId = :parentId OR e.id = :originParentId';
451 }
452
453 if (!empty($criteria['search'])) {
454 $where[] = "(e.name LIKE '%" . $criteria['search'] . "%'
455 OR e.translations LIKE '{\"name\":{%" . $criteria['search'] . "%\"description\":{%'
456 OR e.translations LIKE '{\"description\":{%\"name\":{%" . $criteria['search'] . "%'
457 OR (e.translations LIKE '{\"name\":{%" . $criteria['search'] . "%' AND e.translations NOT LIKE '%\"description\":{%'))";
458 }
459
460
461 if (isset($criteria['show'])) {
462 $where[] = 'e.show = 1';
463 }
464
465 if (!empty($criteria['dates'])) {
466 if (isset($criteria['dates'][0], $criteria['dates'][1])) {
467 $where[] = "((ep.periodStart BETWEEN :eventFrom1 AND :eventTo1)
468 OR (ep.periodEnd BETWEEN :eventFrom2 AND :eventTo2)
469 OR (:eventFrom3 BETWEEN ep.periodStart AND ep.periodEnd)
470 OR (:eventTo3 BETWEEN ep.periodStart AND ep.periodEnd))";
471
472 $params[':eventFrom1'] = $params[':eventFrom2'] = $params[':eventFrom3'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][0]);
473 $params[':eventTo1'] = $params[':eventTo2'] = $params[':eventTo3'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][1]);
474 } elseif (isset($criteria['dates'][0])) {
475 $where[] = "(ep.periodStart >= :eventFrom OR (ep.periodEnd >= :eventTo))";
476 $params[':eventFrom'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][0]);
477 $params[':eventTo'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][0]);
478 } elseif (isset($criteria['dates'][1])) {
479 $where[] = "(ep.periodStart <= :eventTo)";
480
481 $params[':eventTo'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][1]);
482 } else {
483 $where[] = "(ep.periodStart > :eventFrom)";
484 $params[':eventFrom'] = DateTimeService::getNowDateTimeInUtc();
485 }
486 }
487
488 $tagJoin = '';
489
490 if (isset($criteria['tag'])) {
491 $queryTags = [];
492
493 $tags = $criteria['tag'];
494 foreach ((array)$tags as $index => $value) {
495 $param = ':tag' . $index;
496
497 $queryTags[] = $param;
498
499 $params[$param] = $value;
500 }
501
502 $where[] = 'et.name IN (' . implode(', ', $queryTags) . ')';
503
504 $tagJoin = "INNER JOIN {$eventsTagsTable} et ON et.eventId = e.id";
505 }
506
507 if (!empty($criteria['id'])) {
508 if (!empty($criteria['recurring'])) {
509 $whereOr = [];
510 foreach ((array)$criteria['id'] as $index => $value) {
511 $param = 'id' . $index;
512
513 $params[':rec1' . $param] = (int)$value;
514 $params[':rec2' . $param] = (int)$value;
515 $params[':rec3' . $param] = (int)$value;
516 $params[':rec4' . $param] = (int)$value;
517
518 $whereOr[] = "((e.id = :rec1id" . $index . " AND e.parentId IS NULL) OR
519 (e.parentId IN (SELECT parentId FROM {$this->table} WHERE parentId IS NOT NULL AND parentId = :rec2id" . $index . ")) OR
520 (e.id >= :rec3id" . $index . " AND e.parentId IN (SELECT parentId FROM {$this->table} WHERE id = :rec4id" . $index . ")))";
521 }
522 $where[] = '(' . implode(' OR ', $whereOr) . ')';
523 } else {
524 $queryIds = [];
525
526 foreach ((array)$criteria['id'] as $index => $value) {
527 $param = ':id' . $index;
528
529 $queryIds[] = $param;
530
531 $params[$param] = (int)$value;
532 }
533
534 $where[] = 'e.id IN (' . implode(', ', $queryIds) . ')';
535 }
536 }
537
538 $customerJoin = '';
539
540 if (!empty($criteria['customerId']) || !empty($criteria['customerBookingsIds'])) {
541 $customerJoin = "
542 LEFT JOIN {$customerBookingsEventsPeriods} cbe ON cbe.eventPeriodId = ep.id
543 LEFT JOIN {$customerBookingsTable} cb ON cb.id = cbe.customerBookingId";
544
545 if (!empty($criteria['customerId'])) {
546 $params[':customerId'] = $criteria['customerId'];
547
548 $where[] = 'cb.customerId = :customerId';
549 }
550
551 if (!empty($criteria['customerBookingsIds'])) {
552 $queryBookingsIds = [];
553
554 foreach ($criteria['customerBookingsIds'] as $index => $value) {
555 $param = ':customerBookingId' . $index;
556
557 $queryBookingsIds[] = $param;
558
559 $params[$param] = $value;
560 }
561
562 $where[] = 'cb.id IN (' . implode(', ', $queryBookingsIds) . ')';
563 }
564
565 if (!empty($criteria['customerBookingStatus'])) {
566 $params[':customerBookingStatus'] = $criteria['customerBookingStatus'];
567
568 $where[] = 'cb.status = :customerBookingStatus';
569 }
570
571 if (!empty($criteria['customerBookingCouponId'])) {
572 $params[':customerBookingCouponId'] = $criteria['customerBookingCouponId'];
573
574 $where[] = 'cb.couponId = :customerBookingCouponId';
575 }
576 }
577
578 if (!empty($criteria['locationId'])) {
579 $params[':locationId'] = $criteria['locationId'];
580
581 $where[] = 'e.locationId = :locationId';
582 }
583
584 if (!empty($criteria['locations'])) {
585 $queryLocations = [];
586
587 foreach ((array)$criteria['locations'] as $index => $value) {
588 $param = ':location' . $index;
589 $queryLocations[] = $param;
590 $params[$param] = $value;
591 }
592
593 $where3 = 'e.locationId IN (' . implode(', ', $queryLocations) . ')';
594
595 $where[] = '(' . $where3 . ')';
596 }
597
598 $providerJoin = '';
599
600 if (!empty($criteria['providers'])) {
601 $providerJoin = "
602 LEFT JOIN {$eventsProvidersTable} epr ON epr.eventId = e.id
603 INNER JOIN {$usersTable} pu ON pu.id = epr.userId OR pu.id = e.organizerId";
604 $queryProviders = [];
605
606 foreach ((array)$criteria['providers'] as $index => $value) {
607 $param = ':provider' . $index;
608 $queryProviders[] = $param;
609 $params[$param] = $value;
610 }
611
612 $where1 = 'epr.userId IN (' . implode(', ', $queryProviders) . ')';
613
614 $queryProviders = [];
615 foreach ((array)$criteria['providers'] as $index => $value) {
616 $param = ':organizer' . $index;
617 $queryProviders[] = $param;
618 $params[$param] = $value;
619 }
620
621 $where2 = 'e.organizerId IN (' . implode(', ', $queryProviders) . ')';
622
623 $where[] = '(' . $where1 . ' OR ' . $where2 . ')';
624 }
625
626 $where = $where ? 'WHERE ' . implode(' AND ', $where) : '';
627
628 $limit = $this->getLimit(
629 !empty($criteria['page']) ? (int)$criteria['page'] : 0,
630 (int)$itemsPerPage
631 );
632
633 try {
634 $statement = $this->connection->prepare(
635 "SELECT
636 e.id
637 FROM {$this->table} e
638 INNER JOIN {$eventsPeriodsTable} ep ON ep.eventId = e.id
639 {$tagJoin}
640 {$providerJoin}
641 {$customerJoin}
642 {$where}
643 GROUP BY e.id
644 ORDER BY ep.periodStart, e.id
645 {$limit}"
646 );
647
648 $statement->execute($params);
649
650 $rows = $statement->fetchAll();
651 } catch (\Exception $e) {
652 throw new QueryExecutionException('Unable to find by id in ' . __CLASS__, $e->getCode(), $e);
653 }
654
655 return array_column($rows, 'id');
656 }
657
658 /**
659 * @param array $criteria
660 *
661 * @return int
662 * @throws QueryExecutionException
663 * @throws InvalidArgumentException
664 */
665 public function getFilteredIdsCount($criteria)
666 {
667 $eventsPeriodsTable = EventsPeriodsTable::getTableName();
668 $eventsTagsTable = EventsTagsTable::getTableName();
669 $eventsProvidersTable = EventsProvidersTable::getTableName();
670 $usersTable = UsersTable::getTableName();
671
672
673 $params = [];
674 $where = [];
675
676 if (isset($criteria['parentId'])) {
677 $params[':parentId'] = $criteria['parentId'];
678
679 $params[':originParentId'] = $criteria['parentId'];
680
681 $where[] = 'e.parentId = :parentId OR e.id = :originParentId';
682 }
683
684 if (!empty($criteria['search'])) {
685 $where[] = "(e.name LIKE '%" . $criteria['search'] . "%'
686 OR e.translations LIKE '{\"name\":{%" . $criteria['search'] . "%\"description\":{%'
687 OR e.translations LIKE '{\"description\":{%\"name\":{%" . $criteria['search'] . "%'
688 OR (e.translations LIKE '{\"name\":{%" . $criteria['search'] . "%' AND e.translations NOT LIKE '%\"description\":{%'))";
689 }
690
691 if (isset($criteria['show'])) {
692 $where[] = 'e.show = 1';
693 }
694
695 if (!empty($criteria['dates'])) {
696 if (isset($criteria['dates'][0], $criteria['dates'][1])) {
697 $where[] = "((ep.periodStart BETWEEN :eventFrom1 AND :eventTo1)
698 OR (ep.periodEnd BETWEEN :eventFrom2 AND :eventTo2)
699 OR (:eventFrom3 BETWEEN ep.periodStart AND ep.periodEnd)
700 OR (:eventTo3 BETWEEN ep.periodStart AND ep.periodEnd))";
701
702 $params[':eventFrom1'] = $params[':eventFrom2'] = $params[':eventFrom3'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][0]);
703 $params[':eventTo1'] = $params[':eventTo2'] = $params[':eventTo3'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][1]);
704 } elseif (isset($criteria['dates'][0])) {
705 $where[] = "(ep.periodStart >= :eventFrom OR (ep.periodEnd >= :eventTo))";
706
707 $params[':eventFrom'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][0]);
708
709 $params[':eventTo'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][0]);
710 } elseif (isset($criteria['dates'][1])) {
711 $where[] = "(ep.periodStart <= :eventTo)";
712
713 $params[':eventTo'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][1]);
714 } else {
715 $where[] = "(ep.periodStart > :eventFrom)";
716
717 $params[':eventFrom'] = DateTimeService::getNowDateTimeInUtc();
718 }
719 }
720
721 if (!empty($criteria['locationId'])) {
722 $params[':locationId'] = $criteria['locationId'];
723
724 $where[] = 'e.locationId = :locationId';
725 }
726
727 if (!empty($criteria['locations'])) {
728 $queryLocations = [];
729
730 foreach ((array)$criteria['locations'] as $index => $value) {
731 $param = ':location' . $index;
732 $queryLocations[] = $param;
733 $params[$param] = $value;
734 }
735
736 $where3 = 'e.locationId IN (' . implode(', ', $queryLocations) . ')';
737
738 $where[] = '(' . $where3 . ')';
739 }
740
741
742 $tagJoin = '';
743
744 if (isset($criteria['tag'])) {
745 $queryTags = [];
746
747 $tags = $criteria['tag'];//explode(',', $criteria['tag']);
748 foreach ((array)$tags as $index => $value) {
749 $param = ':tag' . $index;
750
751 $queryTags[] = $param;
752
753 $params[$param] = $value;//trim($value, '{}');
754 }
755
756 $where[] = 'et.name IN (' . implode(', ', $queryTags) . ')';
757
758 $tagJoin = "INNER JOIN {$eventsTagsTable} et ON et.eventId = e.id";
759 }
760
761 if (!empty($criteria['id'])) {
762 if (!empty($criteria['recurring'])) {
763 $whereOr = [];
764 foreach ((array)$criteria['id'] as $index => $value) {
765 $param = 'id' . $index;
766
767 $params[':rec1' . $param] = (int)$value;
768 $params[':rec2' . $param] = (int)$value;
769 $params[':rec3' . $param] = (int)$value;
770 $params[':rec4' . $param] = (int)$value;
771
772 $whereOr[] = "((e.id = :rec1id" . $index . " AND e.parentId IS NULL) OR
773 (e.parentId IN (SELECT parentId FROM {$this->table} WHERE parentId IS NOT NULL AND parentId = :rec2id" . $index . ")) OR
774 (e.id >= :rec3id" . $index . " AND e.parentId IN (SELECT parentId FROM {$this->table} WHERE id = :rec4id" . $index . ")))";
775 }
776 $where[] = '(' . implode(' OR ', $whereOr) . ')';
777 } else {
778 $queryIds = [];
779
780 foreach ((array)$criteria['id'] as $index => $value) {
781 $param = ':id' . $index;
782
783 $queryIds[] = $param;
784
785 $params[$param] = (int)$value;
786 }
787
788 $where[] = 'e.id IN (' . implode(', ', $queryIds) . ')';
789 }
790 }
791
792 $providerJoin = '';
793
794 if (!empty($criteria['providers'])) {
795 $providerJoin = "
796 LEFT JOIN {$eventsProvidersTable} epr ON epr.eventId = e.id
797 INNER JOIN {$usersTable} pu ON pu.id = epr.userId OR pu.id = e.organizerId";
798
799 $queryProviders = [];
800
801 foreach ((array)$criteria['providers'] as $index => $value) {
802 $param = ':provider' . $index;
803 $queryProviders[] = $param;
804 $params[$param] = $value;
805 }
806 $where1 = 'epr.userId IN (' . implode(', ', $queryProviders) . ')';
807
808 $queryProviders = [];
809 foreach ((array)$criteria['providers'] as $index => $value) {
810 $param = ':organizer' . $index;
811 $queryProviders[] = $param;
812 $params[$param] = $value;
813 }
814 $where2 = 'e.organizerId IN (' . implode(', ', $queryProviders) . ')';
815
816 $where[] = '(' . $where1 . ' OR ' . $where2 . ')';
817 }
818
819 $customerJoin = '';
820
821 $customerBookingsTable = CustomerBookingsTable::getTableName();
822 $customerBookingsEventsPeriods = CustomerBookingsToEventsPeriodsTable::getTableName();
823
824 if (!empty($criteria['customerId']) || !empty($criteria['customerBookingsIds'])) {
825 $customerJoin = "
826 LEFT JOIN {$customerBookingsEventsPeriods} cbe ON cbe.eventPeriodId = ep.id
827 LEFT JOIN {$customerBookingsTable} cb ON cb.id = cbe.customerBookingId";
828
829 if (!empty($criteria['customerId'])) {
830 $params[':customerId'] = $criteria['customerId'];
831
832 $where[] = 'cb.customerId = :customerId';
833 }
834
835 if (!empty($criteria['customerBookingsIds'])) {
836 $queryBookingsIds = [];
837
838 foreach ($criteria['customerBookingsIds'] as $index => $value) {
839 $param = ':customerBookingId' . $index;
840
841 $queryBookingsIds[] = $param;
842
843 $params[$param] = $value;
844 }
845
846 $where[] = 'cb.id IN (' . implode(', ', $queryBookingsIds) . ')';
847 }
848
849 if (!empty($criteria['customerBookingStatus'])) {
850 $params[':customerBookingStatus'] = $criteria['customerBookingStatus'];
851
852 $where[] = 'cb.status = :customerBookingStatus';
853 }
854
855 if (!empty($criteria['customerBookingCouponId'])) {
856 $params[':customerBookingCouponId'] = $criteria['customerBookingCouponId'];
857
858 $where[] = 'cb.couponId = :customerBookingCouponId';
859 }
860 }
861
862 $where = $where ? 'WHERE ' . implode(' AND ', $where) : '';
863
864 try {
865 $statement = $this->connection->prepare(
866 "SELECT e.id
867 FROM {$this->table} e
868 INNER JOIN {$eventsPeriodsTable} ep ON ep.eventId = e.id
869 {$tagJoin}
870 {$providerJoin}
871 {$customerJoin}
872 {$where}
873 GROUP BY e.id
874 ORDER BY ep.periodStart"
875 );
876
877 $statement->execute($params);
878
879 $rows = $statement->fetchAll();
880 } catch (\Exception $e) {
881 throw new QueryExecutionException('Unable to find by id in ' . __CLASS__, $e->getCode(), $e);
882 }
883
884 return sizeOf($rows);
885 }
886
887 /**
888 * @param int $id
889 *
890 * @return Event
891 * @throws QueryExecutionException
892 * @throws InvalidArgumentException
893 */
894 public function getById($id, $criteria = [])
895 {
896 $eventsPeriodsTable = EventsPeriodsTable::getTableName();
897 $eventsTagsTable = EventsTagsTable::getTableName();
898 $eventsTicketTable = EventsTicketsTable::getTableName();
899
900 $customerBookingsTable = CustomerBookingsTable::getTableName();
901 $paymentsTable = PaymentsTable::getTableName();
902 $usersTable = UsersTable::getTableName();
903 $customerBookingsEventsPeriods = CustomerBookingsToEventsPeriodsTable::getTableName();
904 $galleriesTable = GalleriesTable::getTableName();
905 $eventsProvidersTable = EventsProvidersTable::getTableName();
906 $couponsTable = CouponsTable::getTableName();
907
908 $fields = '';
909
910 $joins = "INNER JOIN {$eventsPeriodsTable} ep ON ep.eventId = e.id
911 LEFT JOIN {$eventsTagsTable} et ON et.eventId = e.id
912 LEFT JOIN {$customerBookingsEventsPeriods} cbe ON cbe.eventPeriodId = ep.id
913 LEFT JOIN {$customerBookingsTable} cb ON cb.id = cbe.customerBookingId
914 LEFT JOIN {$usersTable} cu ON cu.id = cb.customerId
915 LEFT JOIN {$eventsProvidersTable} epr ON epr.eventId = e.id
916 LEFT JOIN {$usersTable} pu ON pu.id = epr.userId
917 LEFT JOIN {$paymentsTable} p ON p.customerBookingId = cb.id
918 LEFT JOIN {$galleriesTable} g ON g.entityId = e.id AND g.entityType = 'event'
919 LEFT JOIN {$couponsTable} c ON c.id = cb.couponId
920 LEFT JOIN {$eventsTicketTable} t ON t.eventId = e.id";
921
922 if (!empty($criteria['fetchBookingsTickets'])) {
923 $bookingsTicketsTable = CustomerBookingToEventsTicketsTable::getTableName();
924
925 $fields .= '
926 cbt.id AS booking_ticket_id,
927 cbt.eventTicketId AS booking_ticket_eventTicketId,
928 cbt.price AS booking_ticket_price,
929 cbt.persons AS booking_ticket_persons,
930 ';
931
932 $joins .= "
933 LEFT JOIN {$bookingsTicketsTable} cbt ON cbt.customerBookingId = cb.id
934 ";
935 }
936
937 $fields .= 'e.id AS event_id,
938 e.name AS event_name,
939 e.status AS event_status,
940 e.bookingOpens AS event_bookingOpens,
941 e.bookingCloses AS event_bookingCloses,
942 e.bookingOpensRec AS event_bookingOpensRec,
943 e.bookingClosesRec AS event_bookingClosesRec,
944 e.ticketRangeRec AS event_ticketRangeRec,
945 e.recurringCycle AS event_recurringCycle,
946 e.recurringOrder AS event_recurringOrder,
947 e.recurringInterval AS event_recurringInterval,
948 e.recurringMonthly AS event_recurringMonthly,
949 e.monthlyDate AS event_monthlyDate,
950 e.monthlyOnRepeat AS event_monthlyOnRepeat,
951 e.monthlyOnDay AS event_monthlyOnDay,
952 e.recurringUntil AS event_recurringUntil,
953 e.bringingAnyone AS event_bringingAnyone,
954 e.bookMultipleTimes AS event_bookMultipleTimes,
955 e.maxCapacity AS event_maxCapacity,
956 e.maxCustomCapacity AS event_maxCustomCapacity,
957 e.maxExtraPeople AS event_maxExtraPeople,
958 e.price AS event_price,
959 e.description AS event_description,
960 e.color AS event_color,
961 e.show AS event_show,
962 e.notifyParticipants AS event_notifyParticipants,
963 e.locationId AS event_locationId,
964 e.customLocation AS event_customLocation,
965 e.parentId AS event_parentId,
966 e.created AS event_created,
967 e.settings AS event_settings,
968 e.zoomUserId AS event_zoomUserId,
969 e.organizerId AS event_organizerId,
970 e.translations AS event_translations,
971 e.deposit AS event_deposit,
972 e.depositPayment AS event_depositPayment,
973 e.depositPerPerson AS event_depositPerPerson,
974 e.fullPayment AS event_fullPayment,
975 e.customPricing AS event_customPricing,
976 e.aggregatedPrice AS event_aggregatedPrice,
977
978 ep.id AS event_periodId,
979 ep.periodStart AS event_periodStart,
980 ep.periodEnd AS event_periodEnd,
981 ep.zoomMeeting AS event_periodZoomMeeting,
982 ep.lessonSpace AS event_periodLessonSpace,
983 ep.googleCalendarEventId AS event_googleCalendarEventId,
984 ep.googleMeetUrl AS event_googleMeetUrl,
985 ep.outlookCalendarEventId AS event_outlookCalendarEventId,
986 ep.microsoftTeamsUrl AS event_microsoftTeamsUrl,
987 ep.appleCalendarEventId AS event_appleCalendarEventId,
988
989 et.id AS event_tagId,
990 et.name AS event_tagName,
991
992 cb.id AS booking_id,
993 cb.customerId AS booking_customerId,
994 cb.status AS booking_status,
995 cb.price AS booking_price,
996 cb.persons AS booking_persons,
997 cb.customFields AS booking_customFields,
998 cb.info AS booking_info,
999 cb.aggregatedPrice AS booking_aggregatedPrice,
1000 cb.token AS booking_token,
1001 cb.utcOffset AS booking_utcOffset,
1002 cb.couponId AS booking_couponId,
1003
1004 cu.id AS customer_id,
1005 cu.firstName AS customer_firstName,
1006 cu.lastName AS customer_lastName,
1007 cu.email AS customer_email,
1008 cu.note AS customer_note,
1009 cu.phone AS customer_phone,
1010 cu.gender AS customer_gender,
1011 cu.birthday AS customer_birthday,
1012
1013 p.id AS payment_id,
1014 p.amount AS payment_amount,
1015 p.dateTime AS payment_dateTime,
1016 p.status AS payment_status,
1017 p.gateway AS payment_gateway,
1018 p.gatewayTitle AS payment_gatewayTitle,
1019 p.transactionId AS payment_transactionId,
1020 p.data AS payment_data,
1021 p.wcOrderId AS payment_wcOrderId,
1022 p.wcOrderItemId AS payment_wcOrderItemId,
1023 p.invoiceNumber AS payment_invoiceNumber,
1024
1025 pu.id AS provider_id,
1026 pu.firstName AS provider_firstName,
1027 pu.lastName AS provider_lastName,
1028 pu.email AS provider_email,
1029 pu.note AS provider_note,
1030 pu.description AS provider_description,
1031 pu.phone AS provider_phone,
1032 pu.gender AS provider_gender,
1033 pu.translations AS provider_translations,
1034 pu.timeZone AS provider_timeZone,
1035
1036 g.id AS gallery_id,
1037 g.pictureFullPath AS gallery_picture_full,
1038 g.pictureThumbPath AS gallery_picture_thumb,
1039 g.position AS gallery_position,
1040
1041 c.id AS coupon_id,
1042 c.code AS coupon_code,
1043 c.discount AS coupon_discount,
1044 c.deduction AS coupon_deduction,
1045 c.limit AS coupon_limit,
1046 c.customerLimit AS coupon_customerLimit,
1047 c.status AS coupon_status,
1048
1049 t.id AS ticket_id,
1050 t.name AS ticket_name,
1051 t.enabled AS ticket_enabled,
1052 t.price AS ticket_price,
1053 t.spots AS ticket_spots,
1054 t.waitingListSpots AS ticket_waiting_list_spots,
1055 t.dateRanges AS ticket_dateRanges,
1056 t.translations AS ticket_translations';
1057
1058 try {
1059 $statement = $this->connection->prepare(
1060 "SELECT
1061 {$fields}
1062 FROM {$this->table} e
1063 {$joins}
1064
1065 WHERE e.id = :eventId"
1066 );
1067
1068 $statement->bindParam(':eventId', $id);
1069
1070 $statement->execute();
1071
1072 $rows = $statement->fetchAll();
1073 } catch (\Exception $e) {
1074 throw new QueryExecutionException('Unable to find event by id in ' . __CLASS__, $e->getCode(), $e);
1075 }
1076
1077 return call_user_func([static::FACTORY, 'createCollection'], $rows)->getItem($id);
1078 }
1079
1080
1081 /**
1082 * @param int $id
1083 *
1084 * @return mixed
1085 * @throws QueryExecutionException
1086 */
1087 public function isRecurring($id)
1088 {
1089 try {
1090 $statement = $this->connection->prepare(
1091 "SELECT
1092 e.recurringOrder AS event_recurringOrder,
1093 e.parentId AS event_parentId
1094 FROM {$this->table} e
1095 WHERE e.id = :eventId"
1096 );
1097
1098 $statement->bindParam(':eventId', $id);
1099
1100 $statement->execute();
1101
1102 return $statement->fetch();
1103 } catch (\Exception $e) {
1104 throw new QueryExecutionException('Unable to find event by id in ' . __CLASS__, $e->getCode(), $e);
1105 }
1106 }
1107
1108
1109 /**
1110 * @param int $id
1111 * @param int $parentId
1112 *
1113 * @return mixed
1114 * @throws QueryExecutionException
1115 */
1116 public function getRecurringIds($id, $parentId)
1117 {
1118 $whereParent = empty($parentId) ? '' : ' OR e.parentId = :parentId';
1119 try {
1120 $statement = $this->connection->prepare(
1121 "SELECT
1122 e.id AS eventId
1123 FROM {$this->table} e
1124 WHERE e.parentId = :eventId" . $whereParent
1125 );
1126
1127 $statement->bindParam(':eventId', $id);
1128 if ($parentId) {
1129 $statement->bindParam(':parentId', $parentId);
1130 }
1131
1132 $statement->execute();
1133
1134 $events = $statement->fetchAll();
1135
1136 return array_column($events, 'eventId');
1137 } catch (\Exception $e) {
1138 throw new QueryExecutionException('Unable to find event by id in ' . __CLASS__, $e->getCode(), $e);
1139 }
1140 }
1141
1142 /**
1143 * @param int $bookingId
1144 * @param array $criteria
1145 *
1146 * @return Event
1147 * @throws QueryExecutionException
1148 * @throws InvalidArgumentException
1149 */
1150 public function getByBookingId($bookingId, $criteria = [])
1151 {
1152 $eventsPeriodsTable = EventsPeriodsTable::getTableName();
1153
1154 $customerBookingsEventsPeriods = CustomerBookingsToEventsPeriodsTable::getTableName();
1155
1156 $fields = '';
1157
1158 $joins = '';
1159
1160 if (!empty($criteria['fetchEventsCoupons'])) {
1161 $couponsTable = CouponsTable::getTableName();
1162
1163 $fields .= '
1164 ec.id AS coupon_id,
1165 ec.code AS coupon_code,
1166 ec.discount AS coupon_discount,
1167 ec.deduction AS coupon_deduction,
1168 ec.limit AS coupon_limit,
1169 ec.customerLimit AS coupon_customerLimit,
1170 ec.status AS coupon_status,
1171 ';
1172
1173 $joins .= "
1174 LEFT JOIN {$couponsTable} ec ON ec.id = cb.couponId
1175 ";
1176 }
1177
1178 if (!empty($criteria['fetchEventsTickets'])) {
1179 $ticketsTable = EventsTicketsTable::getTableName();
1180
1181 $fields .= '
1182 eti.id AS ticket_id,
1183 eti.name AS ticket_name,
1184 eti.enabled AS ticket_enabled,
1185 eti.price AS ticket_price,
1186 eti.spots AS ticket_spots,
1187 eti.waitingListSpots AS ticket_waiting_list_spots,
1188 eti.dateRanges AS ticket_dateRanges,
1189 eti.translations AS ticket_translations,
1190 ';
1191
1192 $joins .= "
1193 LEFT JOIN {$ticketsTable} eti ON eti.eventId = e.id
1194 ";
1195 }
1196
1197 if (!empty($criteria['fetchEventsTags'])) {
1198 $tagsTable = EventsTagsTable::getTableName();
1199
1200 $fields .= '
1201 eta.id AS event_tagId,
1202 eta.name AS event_tagName,
1203 ';
1204
1205 $joins .= "
1206 LEFT JOIN {$tagsTable} eta ON eta.eventId = e.id
1207 ";
1208 }
1209
1210 if (!empty($criteria['fetchEventsImages'])) {
1211 $galleriesTable = GalleriesTable::getTableName();
1212
1213 $fields .= '
1214 eg.id AS gallery_id,
1215 eg.pictureFullPath AS gallery_picture_full,
1216 eg.pictureThumbPath AS gallery_picture_thumb,
1217 eg.position AS gallery_position,
1218 ';
1219
1220 $joins .= "
1221 LEFT JOIN {$galleriesTable} eg ON eg.entityId = e.id AND eg.entityType = 'event'
1222 ";
1223 }
1224
1225 if (!empty($criteria['fetchEventsProviders'])) {
1226 $eventsProvidersTable = EventsProvidersTable::getTableName();
1227
1228 $usersTable = UsersTable::getTableName();
1229
1230 $joins .= "
1231 LEFT JOIN {$eventsProvidersTable} epr ON epr.eventId = e.id
1232 LEFT JOIN {$usersTable} pu ON pu.id = epr.userId
1233 ";
1234
1235 $fields .= '
1236 pu.id AS provider_id,
1237 pu.firstName AS provider_firstName,
1238 pu.lastName AS provider_lastName,
1239 pu.email AS provider_email,
1240 pu.note AS provider_note,
1241 pu.description AS provider_description,
1242 pu.phone AS provider_phone,
1243 pu.gender AS provider_gender,
1244 pu.pictureFullPath AS provider_pictureFullPath,
1245 pu.pictureThumbPath AS provider_pictureThumbPath,
1246 pu.translations AS provider_translations,
1247 pu.timeZone AS provider_timeZone,
1248 ';
1249 }
1250
1251 $fields .= "
1252 e.id AS event_id,
1253 e.name AS event_name,
1254 e.status AS event_status,
1255 e.bookingOpens AS event_bookingOpens,
1256 e.bookingCloses AS event_bookingCloses,
1257 e.recurringCycle AS event_recurringCycle,
1258 e.recurringOrder AS event_recurringOrder,
1259 e.recurringInterval AS event_recurringInterval,
1260 e.recurringUntil AS event_recurringUntil,
1261 e.bringingAnyone AS event_bringingAnyone,
1262 e.bookMultipleTimes AS event_bookMultipleTimes,
1263 e.maxCapacity AS event_maxCapacity,
1264 e.maxCustomCapacity AS event_maxCustomCapacity,
1265 e.maxExtraPeople AS event_maxExtraPeople,
1266 e.price AS event_price,
1267 e.description AS event_description,
1268 e.color AS event_color,
1269 e.show AS event_show,
1270 e.notifyParticipants AS event_notifyParticipants,
1271 e.locationId AS event_locationId,
1272 e.customLocation AS event_customLocation,
1273 e.customPricing AS event_customPricing,
1274 e.parentId AS event_parentId,
1275 e.created AS event_created,
1276 e.settings AS event_settings,
1277 e.zoomUserId AS event_zoomUserId,
1278 e.translations AS event_translations,
1279 e.deposit AS event_deposit,
1280 e.depositPayment AS event_depositPayment,
1281 e.depositPerPerson AS event_depositPerPerson,
1282 e.fullPayment AS event_fullPayment,
1283 e.organizerId AS event_organizerId,
1284 e.aggregatedPrice AS event_aggregatedPrice,
1285
1286 ep.id AS event_periodId,
1287 ep.periodStart AS event_periodStart,
1288 ep.periodEnd AS event_periodEnd,
1289 ep.zoomMeeting AS event_periodZoomMeeting,
1290 ep.lessonSpace AS event_periodLessonSpace,
1291 ep.googleCalendarEventId AS event_googleCalendarEventId,
1292 ep.googleMeetUrl AS event_googleMeetUrl,
1293 ep.outlookCalendarEventId AS event_outlookCalendarEventId,
1294 ep.microsoftTeamsUrl AS event_microsoftTeamsUrl,
1295 ep.appleCalendarEventId AS event_appleCalendarEventId
1296 ";
1297
1298 $params = [
1299 ':customerBookingId' => $bookingId,
1300 ];
1301
1302 try {
1303 $statement = $this->connection->prepare(
1304 "SELECT
1305 {$fields}
1306 FROM {$customerBookingsEventsPeriods} cbe
1307 INNER JOIN {$eventsPeriodsTable} ep ON ep.id = cbe.eventPeriodId
1308 INNER JOIN {$this->table} e ON e.id = ep.eventId
1309 {$joins}
1310 WHERE cbe.customerBookingId = :customerBookingId"
1311 );
1312
1313 $statement->execute($params);
1314
1315 $rows = $statement->fetchAll();
1316 } catch (\Exception $e) {
1317 throw new QueryExecutionException('Unable to find event by booking id in ' . __CLASS__, $e->getCode(), $e);
1318 }
1319
1320 /** @var Collection $events */
1321 $events = call_user_func([static::FACTORY, 'createCollection'], $rows);
1322
1323 return $events->length() ? $events->getItem($events->keys()[0]) : null;
1324 }
1325
1326 /**
1327 * @param array $ids
1328 * @param array $criteria
1329 *
1330 * @return Collection
1331 * @throws QueryExecutionException
1332 * @throws InvalidArgumentException
1333 */
1334 public function getByIdsWithEntities($ids, $criteria = [])
1335 {
1336 $params = [];
1337
1338 $where = [];
1339
1340 $fields = '';
1341
1342 $joins = '';
1343
1344 $orderBy = '';
1345
1346 if (!empty($criteria['fetchEventsPeriods'])) {
1347 $eventsPeriodsTable = EventsPeriodsTable::getTableName();
1348
1349 $fields .= '
1350 ep.id AS event_periodId,
1351 ep.periodStart AS event_periodStart,
1352 ep.periodEnd AS event_periodEnd,
1353 ep.zoomMeeting AS event_periodZoomMeeting,
1354 ep.lessonSpace AS event_periodLessonSpace,
1355 ep.googleCalendarEventId AS event_googleCalendarEventId,
1356 ep.googleMeetUrl AS event_googleMeetUrl,
1357 ep.outlookCalendarEventId AS event_outlookCalendarEventId,
1358 ep.microsoftTeamsUrl AS event_microsoftTeamsUrl,
1359 ep.appleCalendarEventId AS event_appleCalendarEventId,
1360 ';
1361
1362 $joins .= "
1363 INNER JOIN {$eventsPeriodsTable} ep ON ep.eventId = e.id
1364 ";
1365
1366 $orderBy = !empty($criteria['ordered']) ? 'ORDER BY e.id, ep.periodStart' : 'ORDER BY ep.periodStart';
1367 }
1368
1369 if (!empty($criteria['fetchEventsCoupons'])) {
1370 $couponsTable = CouponsTable::getTableName();
1371
1372 $fields .= '
1373 ec.id AS coupon_id,
1374 ec.code AS coupon_code,
1375 ec.discount AS coupon_discount,
1376 ec.deduction AS coupon_deduction,
1377 ec.limit AS coupon_limit,
1378 ec.customerLimit AS coupon_customerLimit,
1379 ec.status AS coupon_status,
1380 ';
1381
1382 $joins .= "
1383 LEFT JOIN {$couponsTable} ec ON ec.id = cb.couponId
1384 ";
1385 }
1386
1387 if (!empty($criteria['fetchEventsTickets'])) {
1388 $ticketsTable = EventsTicketsTable::getTableName();
1389
1390 $fields .= '
1391 eti.id AS ticket_id,
1392 eti.name AS ticket_name,
1393 eti.enabled AS ticket_enabled,
1394 eti.price AS ticket_price,
1395 eti.spots AS ticket_spots,
1396 eti.waitingListSpots AS ticket_waiting_list_spots,
1397 eti.dateRanges AS ticket_dateRanges,
1398 eti.translations AS ticket_translations,
1399 ';
1400
1401 $joins .= "
1402 LEFT JOIN {$ticketsTable} eti ON eti.eventId = e.id
1403 ";
1404 }
1405
1406 if (!empty($criteria['fetchEventsTags'])) {
1407 $tagsTable = EventsTagsTable::getTableName();
1408
1409 $fields .= '
1410 eta.id AS event_tagId,
1411 eta.name AS event_tagName,
1412 ';
1413
1414 $joins .= "
1415 LEFT JOIN {$tagsTable} eta ON eta.eventId = e.id
1416 ";
1417 }
1418
1419 if (!empty($criteria['fetchEventsImages'])) {
1420 $galleriesTable = GalleriesTable::getTableName();
1421
1422 $fields .= '
1423 eg.id AS gallery_id,
1424 eg.pictureFullPath AS gallery_picture_full,
1425 eg.pictureThumbPath AS gallery_picture_thumb,
1426 eg.position AS gallery_position,
1427 ';
1428
1429 $joins .= "
1430 LEFT JOIN {$galleriesTable} eg ON eg.entityId = e.id AND eg.entityType = 'event'
1431 ";
1432 }
1433
1434 if (!empty($criteria['fetchEventsProviders'])) {
1435 $eventsProvidersTable = EventsProvidersTable::getTableName();
1436
1437 $usersTable = UsersTable::getTableName();
1438
1439 $joins .= "
1440 LEFT JOIN {$eventsProvidersTable} epr ON epr.eventId = e.id
1441 LEFT JOIN {$usersTable} pu ON pu.id = epr.userId
1442 ";
1443
1444 $fields .= '
1445 pu.id AS provider_id,
1446 pu.firstName AS provider_firstName,
1447 pu.lastName AS provider_lastName,
1448 pu.email AS provider_email,
1449 pu.note AS provider_note,
1450 pu.description AS provider_description,
1451 pu.phone AS provider_phone,
1452 pu.gender AS provider_gender,
1453 pu.pictureFullPath AS provider_pictureFullPath,
1454 pu.pictureThumbPath AS provider_pictureThumbPath,
1455 pu.translations AS provider_translations,
1456 pu.timeZone AS provider_timeZone,
1457 ';
1458 }
1459
1460 $fields .= "
1461 e.id AS event_id,
1462 e.name AS event_name,
1463 e.status AS event_status,
1464 e.bookingOpens AS event_bookingOpens,
1465 e.bookingCloses AS event_bookingCloses,
1466 e.bookingOpensRec AS event_bookingOpensRec,
1467 e.bookingClosesRec AS event_bookingClosesRec,
1468 e.ticketRangeRec AS event_ticketRangeRec,
1469 e.recurringCycle AS event_recurringCycle,
1470 e.recurringOrder AS event_recurringOrder,
1471 e.recurringInterval AS event_recurringInterval,
1472 e.recurringMonthly AS event_recurringMonthly,
1473 e.monthlyDate AS event_monthlyDate,
1474 e.monthlyOnRepeat AS event_monthlyOnRepeat,
1475 e.monthlyOnDay AS event_monthlyOnDay,
1476 e.recurringUntil AS event_recurringUntil,
1477 e.bringingAnyone AS event_bringingAnyone,
1478 e.bookMultipleTimes AS event_bookMultipleTimes,
1479 e.maxCapacity AS event_maxCapacity,
1480 e.maxCustomCapacity AS event_maxCustomCapacity,
1481 e.maxExtraPeople AS event_maxExtraPeople,
1482 e.price AS event_price,
1483 e.description AS event_description,
1484 e.color AS event_color,
1485 e.show AS event_show,
1486 e.notifyParticipants AS event_notifyParticipants,
1487 e.locationId AS event_locationId,
1488 e.customLocation AS event_customLocation,
1489 e.parentId AS event_parentId,
1490 e.created AS event_created,
1491 e.settings AS event_settings,
1492 e.zoomUserId AS event_zoomUserId,
1493 e.organizerId AS event_organizerId,
1494 e.translations AS event_translations,
1495 e.deposit AS event_deposit,
1496 e.depositPayment AS event_depositPayment,
1497 e.depositPerPerson AS event_depositPerPerson,
1498 e.fullPayment AS event_fullPayment,
1499 e.customPricing AS event_customPricing,
1500 e.closeAfterMin AS event_closeAfterMin,
1501 e.closeAfterMinBookings AS event_closeAfterMinBookings,
1502 e.aggregatedPrice AS event_aggregatedPrice
1503 ";
1504
1505 if (!empty($ids)) {
1506 $queryIds = [];
1507
1508 foreach ($ids as $index => $value) {
1509 $param = ':id' . $index;
1510
1511 $queryIds[] = $param;
1512
1513 $params[$param] = $value;
1514 }
1515
1516 $where[] = 'e.id IN (' . implode(', ', $queryIds) . ')';
1517 }
1518
1519 $where = $where ? 'WHERE ' . implode(' AND ', $where) : '';
1520
1521 try {
1522 $statement = $this->connection->prepare(
1523 "SELECT
1524 {$fields}
1525 FROM {$this->table} e
1526 {$joins}
1527 {$where}
1528 {$orderBy}"
1529 );
1530
1531 $statement->execute($params);
1532
1533 $rows = $statement->fetchAll();
1534 } catch (\Exception $e) {
1535 throw new QueryExecutionException('Unable to find event by id in ' . __CLASS__, $e->getCode(), $e);
1536 }
1537
1538 return call_user_func([static::FACTORY, 'createCollection'], $rows);
1539 }
1540
1541 /**
1542 * @param array $criteria
1543 *
1544 * @return Collection
1545 * @throws QueryExecutionException
1546 * @throws InvalidArgumentException
1547 */
1548 public function getBookingsByCriteria($criteria = [])
1549 {
1550 $params = [];
1551
1552 $where = [];
1553
1554 $fields = '';
1555
1556 $joins = '';
1557
1558 $eventsPeriodsTable = EventsPeriodsTable::getTableName();
1559
1560 $customerBookingsEventsPeriods = CustomerBookingsToEventsPeriodsTable::getTableName();
1561
1562 $customerBookingsTable = CustomerBookingsTable::getTableName();
1563
1564 if (!empty($criteria['fetchApprovedBookings'])) {
1565 $where[] = "cb.status = 'approved'";
1566 }
1567
1568 if (!empty($criteria['customerId'])) {
1569 $params[':customerId'] = $criteria['customerId'];
1570
1571 $where[] = 'cb.customerId = :customerId';
1572 }
1573
1574 if (!empty($criteria['customerBookingStatus'])) {
1575 $params[':customerBookingStatus'] = $criteria['customerBookingStatus'];
1576
1577 $where[] = 'cb.status = :customerBookingStatus';
1578 }
1579
1580 if (!empty($criteria['customerBookingId'])) {
1581 $params[':customerBookingId'] = $criteria['customerBookingId'];
1582
1583 $where[] = 'cb.id = :customerBookingId';
1584 }
1585
1586 if (!empty($criteria['fetchBookingsPayments'])) {
1587 $paymentsTable = PaymentsTable::getTableName();
1588
1589 $fields .= '
1590 p.id AS payment_id,
1591 p.amount AS payment_amount,
1592 p.dateTime AS payment_dateTime,
1593 p.created AS payment_created,
1594 p.status AS payment_status,
1595 p.gateway AS payment_gateway,
1596 p.gatewayTitle AS payment_gatewayTitle,
1597 p.transactionId AS payment_transactionId,
1598 p.data AS payment_data,
1599 p.wcOrderId AS payment_wcOrderId,
1600 p.wcOrderItemId AS payment_wcOrderItemId,
1601 p.invoiceNumber AS payment_invoiceNumber,
1602 ';
1603
1604 $joins .= "
1605 LEFT JOIN {$paymentsTable} p ON p.customerBookingId = cb.id
1606 ";
1607 }
1608
1609 if (!empty($criteria['fetchBookingsCoupons'])) {
1610 $couponsTable = CouponsTable::getTableName();
1611
1612 $fields .= '
1613 c.id AS coupon_id,
1614 c.code AS coupon_code,
1615 c.discount AS coupon_discount,
1616 c.deduction AS coupon_deduction,
1617 c.limit AS coupon_limit,
1618 c.customerLimit AS coupon_customerLimit,
1619 c.status AS coupon_status,
1620 ';
1621
1622 $joins .= "
1623 LEFT JOIN {$couponsTable} c ON c.id = cb.couponId
1624 ";
1625 }
1626
1627 if (!empty($criteria['fetchBookingsUsers'])) {
1628 $usersTable = UsersTable::getTableName();
1629
1630 $fields .= '
1631 cu.id AS customer_id,
1632 cu.type AS customer_type,
1633 cu.firstName AS customer_firstName,
1634 cu.lastName AS customer_lastName,
1635 cu.email AS customer_email,
1636 cu.note AS customer_note,
1637 cu.phone AS customer_phone,
1638 cu.gender AS customer_gender,
1639 cu.birthday AS customer_birthday,
1640 ';
1641
1642 $joins .= "
1643 INNER JOIN {$usersTable} cu ON cu.id = cb.customerId
1644 ";
1645 }
1646
1647 if (!empty($criteria['fetchBookingsTickets'])) {
1648 $bookingsTicketsTable = CustomerBookingToEventsTicketsTable::getTableName();
1649
1650 $fields .= '
1651 cbt.id AS booking_ticket_id,
1652 cbt.eventTicketId AS booking_ticket_eventTicketId,
1653 cbt.price AS booking_ticket_price,
1654 cbt.persons AS booking_ticket_persons,
1655 ';
1656
1657 $joins .= "
1658 LEFT JOIN {$bookingsTicketsTable} cbt ON cbt.customerBookingId = cb.id
1659 ";
1660 }
1661
1662 $fields .= '
1663 ep.eventId AS eventId,
1664 cb.id AS booking_id,
1665 cb.appointmentId AS booking_appointmentId,
1666 cb.customerId AS booking_customerId,
1667 cb.status AS booking_status,
1668 cb.price AS booking_price,
1669 cb.tax AS booking_tax,
1670 cb.persons AS booking_persons,
1671 cb.couponId AS booking_couponId,
1672 cb.customFields AS booking_customFields,
1673 cb.info AS booking_info,
1674 cb.utcOffset AS booking_utcOffset,
1675 cb.token AS booking_token,
1676 cb.aggregatedPrice AS booking_aggregatedPrice,
1677 cb.tax AS booking_tax
1678 ';
1679
1680 if (!empty($criteria['ids'])) {
1681 $queryIds = [];
1682
1683 foreach ($criteria['ids'] as $index => $value) {
1684 $param = ':id' . $index;
1685
1686 $queryIds[] = $param;
1687
1688 $params[$param] = $value;
1689 }
1690
1691 $where[] = 'ep.eventId IN (' . implode(', ', $queryIds) . ')';
1692 }
1693
1694 $where = $where ? 'WHERE ' . implode(' AND ', $where) : '';
1695
1696 try {
1697 $statement = $this->connection->prepare(
1698 "SELECT
1699 {$fields}
1700 FROM {$eventsPeriodsTable} ep
1701 INNER JOIN {$customerBookingsEventsPeriods} cbe ON cbe.eventPeriodId = ep.id
1702 INNER JOIN {$customerBookingsTable} cb ON cb.id = cbe.customerBookingId
1703 {$joins}
1704 {$where}
1705 ORDER BY cb.id"
1706 );
1707
1708 $statement->execute($params);
1709
1710 $rows = $statement->fetchAll();
1711 } catch (\Exception $e) {
1712 throw new QueryExecutionException('Unable to find event by id in ' . __CLASS__, $e->getCode(), $e);
1713 }
1714
1715 $reformattedData = [];
1716
1717 foreach ($rows as $row) {
1718 if (empty($reformattedData[$row['eventId']])) {
1719 $reformattedData[$row['eventId']] = [];
1720 }
1721
1722 $reformattedData[$row['eventId']][] = $row;
1723 }
1724
1725 $result = new Collection();
1726
1727 foreach ($reformattedData as $eventId => $bookingsData) {
1728 $reformattedBookingsData = CustomerBookingFactory::reformat($bookingsData);
1729
1730 $eventBookings = new Collection();
1731
1732 foreach ($reformattedBookingsData as $bookingId => $data) {
1733 $eventBookings->addItem(CustomerBookingFactory::create($data), $bookingId);
1734 }
1735
1736 $result->addItem($eventBookings, $eventId);
1737 }
1738
1739 return $result;
1740 }
1741
1742
1743 /**
1744 * @param Event $event
1745 * @param array $booking
1746 * @param array $limitPerCustomer
1747 * @return int
1748 * @throws QueryExecutionException
1749 * @throws InvalidArgumentException
1750 */
1751 public function getRelevantBookingsCount($event, $booking, $limitPerCustomer)
1752 {
1753 $eventsPeriodsTable = EventsPeriodsTable::getTableName();
1754
1755 $customerBookingsEventsPeriods = CustomerBookingsToEventsPeriodsTable::getTableName();
1756
1757 $customerBookingsTable = CustomerBookingsTable::getTableName();
1758
1759 $params = [
1760 ':customerId' => $booking['customerId']
1761 ];
1762
1763 $paymentTableJoin = '';
1764 $compareToDate = 'ep.periodStart';
1765
1766 if ($limitPerCustomer['from'] === 'bookingDate') {
1767 $eventStartDate =
1768 (clone $event->getPeriods()->getItems()[0]->getPeriodStart()->getValue())->setTimezone(new \DateTimeZone('UTC'))->format('Y-m-d H:i');
1769 } else {
1770 $paymentTableJoin = 'INNER JOIN ' . PaymentsTable::getTableName() . ' p ON p.customerBookingId = cb.id';
1771 $eventStartDate = DateTimeService::getNowDateTimeObject()->setTimezone(new \DateTimeZone('UTC'))->format('Y-m-d H:i');
1772 $compareToDate = 'p.created';
1773 }
1774
1775 $intervalString = "interval " . $limitPerCustomer['period'] . " " . $limitPerCustomer['timeFrame'];
1776
1777 $where = "(STR_TO_DATE('" . $eventStartDate . "', '%Y-%m-%d %H:%i:%s') BETWEEN " .
1778 "(" . $compareToDate . " - " . $intervalString . " + interval 1 second)" .
1779 " AND (" .
1780 $compareToDate . " + " . $intervalString . " - interval 1 second))";
1781
1782 try {
1783 $statement = $this->connection->prepare(
1784 "SELECT COUNT(DISTINCT cb.id) AS count FROM
1785 {$this->table} e
1786 INNER JOIN {$eventsPeriodsTable} ep ON ep.eventId = e.id
1787 INNER JOIN {$customerBookingsEventsPeriods} cbep ON cbep.eventPeriodId = ep.id
1788 INNER JOIN {$customerBookingsTable} cb ON cb.id = cbep.customerBookingId
1789 {$paymentTableJoin}
1790 WHERE cb.customerId = :customerId AND {$where} AND e.status = 'approved' AND cb.status = 'approved'
1791 "
1792 );
1793
1794 $statement->execute($params);
1795
1796 $rows = $statement->fetch()['count'];
1797 } catch (\Exception $e) {
1798 throw new QueryExecutionException('Unable to find by id in ' . __CLASS__, $e->getCode(), $e);
1799 }
1800
1801 return $rows;
1802 }
1803 }
1804