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