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