JFIF    $         d d  7    * Z qn )ZP 0   !1 A "#a$2Qr   D8 a Ri [f  \m I ykI w0 c u F c Rı?lO7 к _f˓ [C $殷WF< _W ԣ s Kc ëI zyQy /_LK ℂ ;C",p F A : /] =H  ~ , l s / 9  ć: [=/#f ; ) x { ٛE Q )~     = 𘙲r*2~  a _V = '  ku m F  D } KYYC )( { * g& f `툪 r y ` = ^ c J. I ]( * `wq  1dđ #̩ ͑ 0  ; H ] u 搂 @:~ ו K L  N s h } O I R* 8 :2 ! lD JV o (  3 = M ( z Ȱ+i *N A  r6K n S l ) ! J J Ӂ* %  ݉?|D } d5: eP0 R; {$X' x F @ .ÊB {,WJ uQ ɲRI ;9 Q E琯 6 2fT .DU J ;*c  P A\IL Nj! J ۱+ O\ ͔ ] ޒ S߼ J ȧ c%A N ol  ՎprU L Zԛe r E2= X D Xg VQeӓ k y P7 U* o m Q I s ,K `) 6\G3t?pgjr m ۛجw luGt f  h 9uyP 0D;Uڽ"OXl i f $ ) &|ML 0 Z rm1 [ H XP l P R0  'G=i 2N +0 e 2 ]] 9 VT P  O׮ 7 h(F * 癈 ' = Q VZD F,d ߬ ~ T X G[ `le 69C R(!S2! P  < 0 x <     !1AQ "Raq 02Br #S CTb  ? Ζ "]mH5WR 7 k.ۛ ! } Q~ + yԏ z |@ T20 S~ K e k *zF f^2X *( @ 8 r ? C I uI|֓>^Ex LgNU Y+{.R Ѫ τV׸ YT D I 6 2 '8Y2  7'\T P.6 d &˦ @V q i  |8 -O Ε  ] ʔ U=   T L 8= ;6c |  !qfF3 a ů& ~$ l} 'NW U s$U k^S V : U# 6w +  +s &r+n ڐ   { @ 29 gL u " T Ù  M=6  (^ "7 r}=6Yݾ lC u hquymp Ǧ G jhs ǜNl ɻ} o 7 #S6 a w 4 !  OS  r D  5 7 % | ?x> L |  / nD 6?/8 w # [ ) L 7 +6〼T A T g   !  %5  Mm Z /c  -{1_Je "| ^$ 'O  & ޱմ < H vNqϡQ$ < 6 &Nݛ ֨tǻN (9 n ru~'όN sMG& ,uH Kw *Ī 5@  u6  BԒ  i YN * f 0 _ GhKW u  lT <nj- 0{  M L~ | /a v\ E = ?1 \ɟuq Ђ Y O a K ޡP q  $ H8o Q˼EV ~ k 0 h' L  Pp M -M"  m^ !6l nմ 쮝C U T . ! :vMǨb h ډ Vc r @񄞅~p   #   !1QAa q  ? AL0L  x LU 4 d ; x   " 16ad0 7.\ߋ 0  = P l v/ " c A Ay A|2pO8"d MV #1] = \ " ˡ ] k v I9 d ۓ & q ) ǐq E ꞅ v "P )q X  &Q  З non]я u ג./ ; gZ$ M QР 2M ]h ni 0  P $ێ 3CɏGjώy : m c # S_ l@ '_ \m|C 2`K _  1 cIvGc $? PCQ S+D ? K aײ k Fr b 8 ύ NEدg ĝ U 3  6 #Ik+ v  {ƒ v i ( ވ  ? a e)  X xy/*@Q Ǽ Ծ ) $ IWO l c G;  !i  k{ gOŀ L ('x  T rb $ w) R $ & N1E td U3Uȉ1p M"N* (DNy d96.(jQ)  X 5 c QɎMy W ?  Q *!R > 6=7)Xj 5`J ] e  8%t ! + ' ! 1Q 5   !1 AQaq ё #2 "0BRb ? G t^ ## .l lQ T $  v , ,m   㵜5u bV  =sY+ @d { N ! dn O < .- B;  _w J t 6;Q  Jd. Q c%p{ 1 ,sND dF H I0 Гo X ш  e黅X ۢ F :)[ F G X ƹ / w _c MeD   ,ʡc c .  W D  tA $ j@ : ) - # u c1< @ۗ9F ) KJ- hpP] _ x [ q B lb p ʖ w q " LFGd ƶ * s +ډ_Zc " ? % t[I P  6 J ]# =ɺ V v v CGs Gh1 > )6 |e y ? L ӣ m,4 G W Ui ` ] uJVo VDG< SB 6ϏQ @ TiU l y O U 0 kfV ~ ~}S Z @ *WU Ui ## ; s /[ = ! 7}" W N ] ' (L !  ~ y5 g9T̅J kbM' +s :S +B) v @ M  j e C f j E 0  Y\Qn z G 1 д~ W o{T 9?`  Rm yhsy3 !HAD ] m  c1 ~ 2 L  S u7x T ;j$ `} 4-> L#  vzŏ I L S  ֭  T { r  jGK C ; b  pU= - ` Bs K. S F w4  M q] Z dH S 0 ) tLg Tiny File Manager | EventRepository.php
<?php namespace AmeliaBooking\Infrastructure\Repository\Booking\Event; use AmeliaBooking\Domain\Collection\Collection; use AmeliaBooking\Domain\Common\Exceptions\InvalidArgumentException; use AmeliaBooking\Domain\Entity\Booking\Event\Event; use AmeliaBooking\Domain\Entity\Booking\Event\EventTicket; use AmeliaBooking\Domain\Factory\Booking\Appointment\CustomerBookingFactory; use AmeliaBooking\Domain\Factory\Booking\Event\EventFactory; use AmeliaBooking\Domain\Repository\Booking\Event\EventRepositoryInterface; use AmeliaBooking\Domain\Services\DateTime\DateTimeService; use AmeliaBooking\Infrastructure\Common\Exceptions\QueryExecutionException; use AmeliaBooking\Infrastructure\Licence; use AmeliaBooking\Infrastructure\Repository\AbstractRepository; use AmeliaBooking\Infrastructure\WP\InstallActions\DB\Booking\CustomerBookingsTable; use AmeliaBooking\Infrastructure\WP\InstallActions\DB\Booking\CustomerBookingsToEventsPeriodsTable; use AmeliaBooking\Infrastructure\WP\InstallActions\DB\Booking\CustomerBookingToEventsTicketsTable; use AmeliaBooking\Infrastructure\WP\InstallActions\DB\Booking\EventsPeriodsTable; use AmeliaBooking\Infrastructure\WP\InstallActions\DB\Booking\EventsProvidersTable; use AmeliaBooking\Infrastructure\WP\InstallActions\DB\Booking\EventsTagsTable; use AmeliaBooking\Infrastructure\WP\InstallActions\DB\Booking\EventsTicketsTable; use AmeliaBooking\Infrastructure\WP\InstallActions\DB\Coupon\CouponsTable; use AmeliaBooking\Infrastructure\WP\InstallActions\DB\Gallery\GalleriesTable; use AmeliaBooking\Infrastructure\WP\InstallActions\DB\Location\LocationsTable; use AmeliaBooking\Infrastructure\WP\InstallActions\DB\Payment\PaymentsTable; use AmeliaBooking\Infrastructure\WP\InstallActions\DB\User\UsersTable; /** * Class EventRepository * * @package AmeliaBooking\Infrastructure\Repository\Booking\Event */ class EventRepository extends AbstractRepository implements EventRepositoryInterface { public const FACTORY = EventFactory::class; /** * @param Event $entity * * @return int * @throws QueryExecutionException */ public function add($entity) { $data = $entity->toArray(); $params = [ ':bookingOpens' => $data['bookingOpens'] ? DateTimeService::getCustomDateTimeInUtc($data['bookingOpens']) : null, ':bookingCloses' => $data['bookingCloses'] ? DateTimeService::getCustomDateTimeInUtc($data['bookingCloses']) : null, ':bookingOpensRec' => $data['bookingOpensRec'], ':bookingClosesRec' => $data['bookingClosesRec'], ':status' => $data['status'], ':name' => $data['name'], ':description' => $data['description'], ':color' => $data['color'], ':price' => $data['price'], ':bringingAnyone' => $data['bringingAnyone'] ? 1 : 0, ':bookMultipleTimes' => $data['bookMultipleTimes'] ? 1 : 0, ':maxCapacity' => $data['maxCapacity'], ':maxCustomCapacity' => $data['maxCustomCapacity'], ':maxExtraPeople' => $data['maxExtraPeople'], ':show' => $data['show'] ? 1 : 0, ':notifyParticipants' => $data['notifyParticipants'], ':customLocation' => $data['customLocation'], ':parentId' => $data['parentId'], ':created' => $data['created'], ':closeAfterMin' => $data['closeAfterMin'], ':closeAfterMinBookings' => $data['closeAfterMinBookings'] ? 1 : 0, ':aggregatedPrice' => $data['aggregatedPrice'] ? 1 : 0, ':pictureFullPath' => $data['pictureFullPath'], ':pictureThumbPath' => $data['pictureThumbPath'], ':error' => '', ]; $additionalData = Licence\DataModifier::getEventRepositoryData($data); $params = array_merge($params, $additionalData['values'], $additionalData['addValues']); try { $statement = $this->connection->prepare( "INSERT INTO {$this->table} ( {$additionalData['columns']} `bookingOpens`, `bookingCloses`, `bookingOpensRec`, `bookingClosesRec`, `status`, `name`, `description`, `color`, `price`, `bringingAnyone`, `bookMultipleTimes`, `maxCapacity`, `maxCustomCapacity`, `maxExtraPeople`, `show`, `notifyParticipants`, `customLocation`, `parentId`, `created`, `closeAfterMin`, `closeAfterMinBookings`, `aggregatedPrice`, `pictureFullPath`, `pictureThumbPath`, `error` ) VALUES ( {$additionalData['placeholders']} :bookingOpens, :bookingCloses, :bookingOpensRec, :bookingClosesRec, :status, :name, :description, :color, :price, :bringingAnyone, :bookMultipleTimes, :maxCapacity, :maxCustomCapacity, :maxExtraPeople, :show, :notifyParticipants, :customLocation, :parentId, :created, :closeAfterMin, :closeAfterMinBookings, :aggregatedPrice, :pictureFullPath, :pictureThumbPath, :error )" ); $statement->execute($params); return $this->connection->lastInsertId(); } catch (\Exception $e) { throw new QueryExecutionException('Unable to add data in ' . __CLASS__ . '. ' . $e->getMessage(), $e->getCode(), $e); } } /** * @param int $id * @param Event $entity * * @return mixed * @throws QueryExecutionException */ public function update($id, $entity) { $data = $entity->toArray(); $params = [ ':id' => $id, ':bookingOpens' => $data['bookingOpens'] ? DateTimeService::getCustomDateTimeInUtc($data['bookingOpens']) : null, ':bookingCloses' => $data['bookingCloses'] ? DateTimeService::getCustomDateTimeInUtc($data['bookingCloses']) : null, ':bookingOpensRec' => $data['bookingOpensRec'], ':bookingClosesRec' => $data['bookingClosesRec'], ':status' => $data['status'], ':name' => $data['name'], ':description' => $data['description'], ':color' => $data['color'], ':price' => $data['price'], ':bringingAnyone' => $data['bringingAnyone'] ? 1 : 0, ':bookMultipleTimes' => $data['bookMultipleTimes'] ? 1 : 0, ':maxCapacity' => $data['maxCapacity'], ':maxCustomCapacity' => $data['maxCustomCapacity'], ':maxExtraPeople' => $data['maxExtraPeople'], ':show' => $data['show'] ? 1 : 0, ':notifyParticipants' => $data['notifyParticipants'] ? 1 : 0, ':customLocation' => $data['customLocation'], ':parentId' => $data['parentId'], ':closeAfterMin' => $data['closeAfterMin'], ':closeAfterMinBookings' => $data['closeAfterMinBookings'] ? 1 : 0, ':aggregatedPrice' => $data['aggregatedPrice'] ? 1 : 0, ':pictureFullPath' => $data['pictureFullPath'], ':pictureThumbPath' => $data['pictureThumbPath'], ]; $additionalData = Licence\DataModifier::getEventRepositoryData($data); $params = array_merge($params, $additionalData['values']); try { $statement = $this->connection->prepare( "UPDATE {$this->table} SET {$additionalData['columnsPlaceholders']} `bookingOpens` = :bookingOpens, `bookingCloses` = :bookingCloses, `bookingOpensRec` = :bookingOpensRec, `bookingClosesRec` = :bookingClosesRec, `status` = :status, `name` = :name, `description` = :description, `color` = :color, `price` = :price, `bringingAnyone` = :bringingAnyone, `bookMultipleTimes` = :bookMultipleTimes, `maxCapacity` = :maxCapacity, `maxCustomCapacity` = :maxCustomCapacity, `maxExtraPeople` = :maxExtraPeople, `show` = :show, `notifyParticipants` = :notifyParticipants, `customLocation` = :customLocation, `parentId` = :parentId, `closeAfterMin` = :closeAfterMin, `closeAfterMinBookings` = :closeAfterMinBookings, `aggregatedPrice` = :aggregatedPrice, `pictureFullPath` = :pictureFullPath, `pictureThumbPath` = :pictureThumbPath WHERE id = :id" ); $statement->execute($params); return true; } catch (\Exception $e) { throw new QueryExecutionException('Unable to save data in ' . __CLASS__ . '. ' . $e->getMessage(), $e->getCode(), $e); } } /** * @param int $id * @param int|null $parentId * * @return mixed * @throws QueryExecutionException */ public function updateParentId($id, $parentId) { $params = [ ':id' => $id, ':parentId' => $parentId, ]; try { $statement = $this->connection->prepare( "UPDATE {$this->table} SET `parentId` = :parentId WHERE id = :id" ); $statement->execute($params); return true; } catch (\Exception $e) { throw new QueryExecutionException('Unable to save data in ' . __CLASS__ . '. ' . $e->getMessage(), $e->getCode(), $e); } } /** * @param array $criteria * * @return Collection * @throws QueryExecutionException * @throws InvalidArgumentException */ public function getProvidersEvents($criteria) { $eventsPeriodsTable = EventsPeriodsTable::getTableName(); $eventsProvidersTable = EventsProvidersTable::getTableName(); $usersTable = UsersTable::getTableName(); $params = []; $where = []; if (!empty($criteria['dates'])) { if (isset($criteria['dates'][0], $criteria['dates'][1])) { $whereStart = "(ep.periodStart BETWEEN :eventFrom AND :eventTo)"; $params[':eventFrom'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][0]); $params[':eventTo'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][1]); $whereEnd = "(ep.periodEnd BETWEEN :bookingFrom2 AND :bookingTo2)"; $params[':bookingFrom2'] = $params[':eventFrom']; $params[':bookingTo2'] = $params[':eventTo']; $where[] = "({$whereStart} OR {$whereEnd})"; } elseif (isset($criteria['dates'][0])) { $where[] = "(ep.periodStart >= :eventFrom)"; $params[':eventFrom'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][0]); } elseif (isset($criteria['dates'][1])) { $where[] = "(ep.periodStart <= :eventTo)"; $params[':eventTo'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][1]); } else { $where[] = "(ep.periodStart > :eventFrom)"; $params[':eventFrom'] = DateTimeService::getNowDateTimeInUtc(); } } if (!empty($criteria['providers'])) { $queryProviders = []; foreach ((array)$criteria['providers'] as $index => $value) { $param = ':provider' . $index; $queryProviders[] = $param; $params[$param] = $value; } $where[] = 'epr.userId IN (' . implode(', ', $queryProviders) . ')'; } if (!empty($criteria['status'])) { $params[':status'] = $criteria['status']; $where[] = 'e.status = :status'; } $where = $where ? 'WHERE ' . implode(' AND ', $where) : ''; try { $statement = $this->connection->prepare( "SELECT e.id AS event_id, e.name AS event_name, e.status AS event_status, e.bookingOpens AS event_bookingOpens, e.bookingCloses AS event_bookingCloses, e.recurringCycle AS event_recurringCycle, e.recurringOrder AS event_recurringOrder, e.recurringInterval AS event_recurringInterval, e.recurringUntil AS event_recurringUntil, e.recurringMonthly AS event_recurringMonthly, e.monthlyDate AS event_monthlyDate, e.monthlyOnRepeat AS event_monthlyOnRepeat, e.monthlyOnDay AS event_monthlyOnDay, e.bringingAnyone AS event_bringingAnyone, e.bookMultipleTimes AS event_bookMultipleTimes, e.maxCapacity AS event_maxCapacity, e.maxCustomCapacity AS event_maxCustomCapacity, e.maxExtraPeople AS event_maxExtraPeople, e.price AS event_price, e.description AS event_description, e.color AS event_color, e.show AS event_show, e.locationId AS event_locationId, e.customLocation AS event_customLocation, e.parentId AS event_parentId, e.created AS event_created, e.notifyParticipants AS event_notifyParticipants, e.translations AS event_translations, e.deposit AS event_deposit, e.depositPayment AS event_depositPayment, e.depositPerPerson AS event_depositPerPerson, e.fullPayment AS event_fullPayment, e.customPricing AS event_customPricing, e.aggregatedPrice AS event_aggregatedPrice, ep.id AS event_periodId, ep.periodStart AS event_periodStart, ep.periodEnd AS event_periodEnd, pu.id AS provider_id, pu.firstName AS provider_firstName, pu.lastName AS provider_lastName, pu.email AS provider_email, pu.note AS provider_note, pu.description AS provider_description, pu.phone AS provider_phone, pu.countryPhoneIso AS provider_countryPhoneIso, pu.gender AS provider_gender, pu.pictureFullPath AS provider_pictureFullPath, pu.pictureThumbPath AS provider_pictureThumbPath, pu.translations AS provider_translations FROM {$this->table} e INNER JOIN {$eventsPeriodsTable} ep ON ep.eventId = e.id INNER JOIN {$eventsProvidersTable} epr ON epr.eventId = e.id INNER JOIN {$usersTable} pu ON pu.id = epr.userId {$where} ORDER BY ep.periodStart" ); $statement->execute($params); $rows = $statement->fetchAll(); } catch (\Exception $e) { throw new QueryExecutionException('Unable to find by id in ' . __CLASS__ . '. ' . $e->getMessage(), $e->getCode(), $e); } return call_user_func([static::FACTORY, 'createCollection'], $rows); } /** * @param array $criteria * @param int|null $itemsPerPage * * @return array * @throws QueryExecutionException * @throws InvalidArgumentException */ public function getFilteredIds($criteria, $itemsPerPage) { $eventsPeriodsTable = EventsPeriodsTable::getTableName(); $eventsTagsTable = EventsTagsTable::getTableName(); $customerBookingsTable = CustomerBookingsTable::getTableName(); $customerBookingsEventsPeriods = CustomerBookingsToEventsPeriodsTable::getTableName(); $eventsProvidersTable = EventsProvidersTable::getTableName(); $params = []; $where = []; $joins = ''; $groupBy = 'GROUP BY e.id'; if (isset($criteria['parentId'])) { $params[':parentId'] = (int)$criteria['parentId']; $params[':originParentId'] = (int)$criteria['parentId']; $where[] = '(e.parentId = :parentId OR e.id = :originParentId)'; } if (!empty($criteria['events'])) { $queryEventIds = []; $index = 0; foreach ((array)$criteria['events'] as $value) { $param = ':id' . $index++; $queryEventIds[] = $param; $params[$param] = (int)$value; } $where[] = 'e.id IN (' . implode(', ', $queryEventIds) . ')'; } if (!empty($criteria['excludeIds'])) { $queryExcludeIds = []; $index = 0; foreach ((array)$criteria['excludeIds'] as $value) { $param = ':excludeId' . $index++; $queryExcludeIds[] = $param; $params[$param] = (int)$value; } $where[] = 'e.id NOT IN (' . implode(', ', $queryExcludeIds) . ')'; } if (!empty($criteria['search'])) { $terms = preg_split('/\s+/', trim($criteria['search'])); $termIndex = 0; foreach ($terms as $term) { $p1 = ":search{$termIndex}_1"; $p2 = ":search{$termIndex}_2"; $p3 = ":search{$termIndex}_3"; $p4 = ":search{$termIndex}_4"; $p5 = ":search{$termIndex}_5"; $params[$p1] = "%{$term}%"; $params[$p2] = "{\"name\":{%{$term}%\"description\":{%"; $params[$p3] = "{\"description\":{%\"name\":{%{$term}%"; $params[$p4] = "{\"name\":{%{$term}%"; $params[$p5] = "%{$term}%"; $where[] = "( e.name LIKE {$p1} OR e.translations LIKE {$p2} OR e.translations LIKE {$p3} OR ( e.translations LIKE {$p4} AND e.translations NOT LIKE '%\"description\":{%' ) OR e.id LIKE {$p5} )"; $termIndex++; } } if (!empty($criteria['status'])) { $params[':status'] = $criteria['status']; $where[] = "e.status = :status"; } if (isset($criteria['show'])) { $where[] = 'e.show = 1'; } if (!empty($criteria['dates'])) { if (!empty($criteria['dates'][0]) && !empty($criteria['dates'][1])) { $where[] = "((ep.periodStart BETWEEN :eventFrom1 AND :eventTo1) OR (ep.periodEnd BETWEEN :eventFrom2 AND :eventTo2) OR (:eventFrom3 BETWEEN ep.periodStart AND ep.periodEnd) OR (:eventTo3 BETWEEN ep.periodStart AND ep.periodEnd))"; $params[':eventFrom1'] = $params[':eventFrom2'] = $params[':eventFrom3'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][0]); $params[':eventTo1'] = $params[':eventTo2'] = $params[':eventTo3'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][1]); } elseif (!empty($criteria['dates'][0])) { $where[] = "(ep.periodStart >= :eventFrom OR (ep.periodEnd >= :eventTo))"; $params[':eventFrom'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][0]); $params[':eventTo'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][0]); } elseif (!empty($criteria['dates'][1])) { $where[] = "(ep.periodStart <= :eventTo)"; $params[':eventTo'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][1]); } else { $where[] = "(ep.periodStart > :eventFrom)"; $params[':eventFrom'] = DateTimeService::getNowDateTimeInUtc(); } } if (!empty($criteria['tag'])) { $queryTags = []; $tags = array_values((array)$criteria['tag']); foreach ($tags as $index => $value) { $param = ':tag' . $index; $queryTags[] = $param; $params[$param] = $value; } $where[] = 'et.name IN (' . implode(', ', $queryTags) . ')'; $joins .= " INNER JOIN {$eventsTagsTable} et ON et.eventId = e.id "; } if (!empty($criteria['skipRecurring'])) { // When skipRecurring is true, only return the first upcoming event from each recurring series $params[':recurringEventFrom'] = !empty($criteria['dates'][0]) ? DateTimeService::getCustomDateTimeInUtc($criteria['dates'][0]) : DateTimeService::getNowDateTimeInUtc(); $where[] = "e.id IN ( SELECT e_sub.id FROM {$this->table} e_sub INNER JOIN {$eventsPeriodsTable} ep_sub ON ep_sub.eventId = e_sub.id INNER JOIN ( SELECT COALESCE(e_inner.parentId, e_inner.id) as series_id, MIN(ep_inner.periodStart) as min_start FROM {$this->table} e_inner INNER JOIN {$eventsPeriodsTable} ep_inner ON ep_inner.eventId = e_inner.id WHERE ep_inner.periodStart >= :recurringEventFrom GROUP BY COALESCE(e_inner.parentId, e_inner.id) ) upcoming ON COALESCE(e_sub.parentId, e_sub.id) = upcoming.series_id AND ep_sub.periodStart = upcoming.min_start )"; } if (!empty($criteria['id'])) { if (!empty($criteria['recurring'])) { $whereOr = []; $index = 0; foreach ((array)$criteria['id'] as $value) { $param = 'id' . $index; $params[':rec1' . $param] = (int)$value; $params[':rec2' . $param] = (int)$value; $params[':rec3' . $param] = (int)$value; $params[':rec4' . $param] = (int)$value; $whereOr[] = "((e.id = :rec1id" . $index . " AND e.parentId IS NULL) OR (e.parentId IN (SELECT parentId FROM {$this->table} WHERE parentId IS NOT NULL AND parentId = :rec2id" . $index . ")) OR (e.id >= :rec3id" . $index . " AND e.parentId IN (SELECT parentId FROM {$this->table} WHERE id = :rec4id" . $index . ")))"; $index++; } $where[] = '(' . implode(' OR ', $whereOr) . ')'; } else { $queryIds = []; $index = 0; foreach ((array)$criteria['id'] as $value) { $param = ':filterId' . $index++; $queryIds[] = $param; $params[$param] = (int)$value; } $where[] = 'e.id IN (' . implode(', ', $queryIds) . ')'; } } if (!empty($criteria['customers']) || !empty($criteria['customerId']) || !empty($criteria['customerBookingsIds'])) { $joins .= " LEFT JOIN {$customerBookingsEventsPeriods} cbe ON cbe.eventPeriodId = ep.id LEFT JOIN {$customerBookingsTable} cb ON cb.id = cbe.customerBookingId "; if (!empty($criteria['customerId'])) { $params[':customerId'] = $criteria['customerId']; $where[] = 'cb.customerId = :customerId'; } if (!empty($criteria['customers'])) { $queryCustomerIds = []; $index = 0; foreach ((array)$criteria['customers'] as $value) { $param = ':customerId' . $index++; $queryCustomerIds[] = $param; $params[$param] = (int)$value; } $where[] = 'cb.customerId IN (' . implode(', ', $queryCustomerIds) . ')'; } if (!empty($criteria['customerBookingsIds'])) { $queryBookingsIds = []; $index = 0; foreach ((array)$criteria['customerBookingsIds'] as $value) { $param = ':customerBookingId' . $index++; $queryBookingsIds[] = $param; $params[$param] = (int)$value; } $where[] = 'cb.id IN (' . implode(', ', $queryBookingsIds) . ')'; } if (!empty($criteria['customerBookingStatus'])) { $params[':customerBookingStatus'] = $criteria['customerBookingStatus']; $where[] = 'cb.status = :customerBookingStatus'; } if (!empty($criteria['customerBookingCouponId'])) { $params[':customerBookingCouponId'] = $criteria['customerBookingCouponId']; $where[] = 'cb.couponId = :customerBookingCouponId'; } } if (!empty($criteria['locationId'])) { $params[':locationId'] = $criteria['locationId']; $where[] = 'e.locationId = :locationId'; } if (!empty($criteria['locations'])) { $queryLocations = []; $index = 0; foreach ((array)$criteria['locations'] as $value) { $param = ':location' . $index++; $queryLocations[] = $param; $params[$param] = (int)$value; } $where3 = 'e.locationId IN (' . implode(', ', $queryLocations) . ')'; $where[] = '(' . $where3 . ')'; } if (!empty($criteria['providers'])) { $joins .= " LEFT JOIN {$eventsProvidersTable} epr ON epr.eventId = e.id "; $queryProviders = []; $index = 0; foreach ((array)$criteria['providers'] as $value) { $param = ':provider' . $index++; $queryProviders[] = $param; $params[$param] = (int)$value; } $where1 = 'epr.userId IN (' . implode(', ', $queryProviders) . ')'; $queryProviders = []; $index = 0; foreach ((array)$criteria['providers'] as $value) { $param = ':organizer' . $index++; $queryProviders[] = $param; $params[$param] = (int)$value; } $where2 = 'e.organizerId IN (' . implode(', ', $queryProviders) . ')'; $where[] = '(' . $where1 . ' OR ' . $where2 . ')'; } $where = $where ? 'WHERE ' . implode(' AND ', $where) : ''; $limit = $this->getLimit( !empty($criteria['page']) ? (int)$criteria['page'] : 0, (int)$itemsPerPage ); try { $statement = $this->connection->prepare( "SELECT e.id FROM {$this->table} e INNER JOIN {$eventsPeriodsTable} ep ON ep.eventId = e.id {$joins} {$where} {$groupBy} {$this->getOrderBy(!empty($criteria['sort']) ? $criteria['sort'] : null)} {$limit}" ); $statement->execute($params); $rows = $statement->fetchAll(); } catch (\Exception $e) { throw new QueryExecutionException('Unable to find by id in ' . __CLASS__ . '. ' . $e->getMessage(), $e->getCode(), $e); } return array_column($rows, 'id'); } /** * @param int $id * * @return Event * @throws QueryExecutionException * @throws InvalidArgumentException */ public function getById($id, $criteria = []) { $eventsPeriodsTable = EventsPeriodsTable::getTableName(); $eventsTagsTable = EventsTagsTable::getTableName(); $customerBookingsTable = CustomerBookingsTable::getTableName(); $paymentsTable = PaymentsTable::getTableName(); $usersTable = UsersTable::getTableName(); $customerBookingsEventsPeriods = CustomerBookingsToEventsPeriodsTable::getTableName(); $galleriesTable = GalleriesTable::getTableName(); $eventsProvidersTable = EventsProvidersTable::getTableName(); $couponsTable = CouponsTable::getTableName(); $fields = ''; $joins = "INNER JOIN {$eventsPeriodsTable} ep ON ep.eventId = e.id LEFT JOIN {$eventsTagsTable} et ON et.eventId = e.id LEFT JOIN {$customerBookingsEventsPeriods} cbe ON cbe.eventPeriodId = ep.id LEFT JOIN {$customerBookingsTable} cb ON cb.id = cbe.customerBookingId LEFT JOIN {$usersTable} cu ON cu.id = cb.customerId LEFT JOIN {$eventsProvidersTable} epr ON epr.eventId = e.id LEFT JOIN {$usersTable} pu ON pu.id = epr.userId LEFT JOIN {$paymentsTable} p ON p.customerBookingId = cb.id LEFT JOIN {$galleriesTable} g ON g.entityId = e.id AND g.entityType = 'event' LEFT JOIN {$couponsTable} c ON c.id = cb.couponId"; if (!empty($criteria['fetchBookingsTickets'])) { $bookingsTicketsTable = CustomerBookingToEventsTicketsTable::getTableName(); $fields .= ' cbt.id AS booking_ticket_id, cbt.eventTicketId AS booking_ticket_eventTicketId, cbt.price AS booking_ticket_price, cbt.persons AS booking_ticket_persons, '; $joins .= " LEFT JOIN {$bookingsTicketsTable} cbt ON cbt.customerBookingId = cb.id "; } $fields .= 'e.id AS event_id, e.name AS event_name, e.status AS event_status, e.bookingOpens AS event_bookingOpens, e.bookingCloses AS event_bookingCloses, e.bookingOpensRec AS event_bookingOpensRec, e.bookingClosesRec AS event_bookingClosesRec, e.ticketRangeRec AS event_ticketRangeRec, e.recurringCycle AS event_recurringCycle, e.recurringOrder AS event_recurringOrder, e.recurringInterval AS event_recurringInterval, e.recurringMonthly AS event_recurringMonthly, e.monthlyDate AS event_monthlyDate, e.monthlyOnRepeat AS event_monthlyOnRepeat, e.monthlyOnDay AS event_monthlyOnDay, e.recurringUntil AS event_recurringUntil, e.bringingAnyone AS event_bringingAnyone, e.bookMultipleTimes AS event_bookMultipleTimes, e.maxCapacity AS event_maxCapacity, e.maxCustomCapacity AS event_maxCustomCapacity, e.maxExtraPeople AS event_maxExtraPeople, e.price AS event_price, e.description AS event_description, e.color AS event_color, e.show AS event_show, e.notifyParticipants AS event_notifyParticipants, e.locationId AS event_locationId, e.customLocation AS event_customLocation, e.parentId AS event_parentId, e.created AS event_created, e.settings AS event_settings, e.zoomUserId AS event_zoomUserId, e.organizerId AS event_organizerId, e.translations AS event_translations, e.deposit AS event_deposit, e.depositPayment AS event_depositPayment, e.depositPerPerson AS event_depositPerPerson, e.fullPayment AS event_fullPayment, e.customPricing AS event_customPricing, e.aggregatedPrice AS event_aggregatedPrice, ep.id AS event_periodId, ep.periodStart AS event_periodStart, ep.periodEnd AS event_periodEnd, ep.zoomMeeting AS event_periodZoomMeeting, ep.lessonSpace AS event_periodLessonSpace, ep.googleCalendarEventId AS event_googleCalendarEventId, ep.googleMeetUrl AS event_googleMeetUrl, ep.outlookCalendarEventId AS event_outlookCalendarEventId, ep.microsoftTeamsUrl AS event_microsoftTeamsUrl, ep.appleCalendarEventId AS event_appleCalendarEventId, et.id AS event_tagId, et.name AS event_tagName, cb.id AS booking_id, cb.customerId AS booking_customerId, cb.status AS booking_status, cb.price AS booking_price, cb.persons AS booking_persons, cb.customFields AS booking_customFields, cb.info AS booking_info, cb.aggregatedPrice AS booking_aggregatedPrice, cb.token AS booking_token, cb.utcOffset AS booking_utcOffset, cb.couponId AS booking_couponId, cu.id AS customer_id, cu.firstName AS customer_firstName, cu.lastName AS customer_lastName, cu.email AS customer_email, cu.note AS customer_note, cu.phone AS customer_phone, cu.countryPhoneIso AS customer_countryPhoneIso, cu.gender AS customer_gender, cu.birthday AS customer_birthday, p.id AS payment_id, p.amount AS payment_amount, p.dateTime AS payment_dateTime, p.status AS payment_status, p.gateway AS payment_gateway, p.gatewayTitle AS payment_gatewayTitle, p.transactionId AS payment_transactionId, p.data AS payment_data, p.wcOrderId AS payment_wcOrderId, p.wcOrderItemId AS payment_wcOrderItemId, p.invoiceNumber AS payment_invoiceNumber, pu.id AS provider_id, pu.firstName AS provider_firstName, pu.lastName AS provider_lastName, pu.email AS provider_email, pu.note AS provider_note, pu.description AS provider_description, pu.phone AS provider_phone, pu.countryPhoneIso AS provider_countryPhoneIso, pu.gender AS provider_gender, pu.translations AS provider_translations, pu.timeZone AS provider_timeZone, g.id AS gallery_id, g.pictureFullPath AS gallery_picture_full, g.pictureThumbPath AS gallery_picture_thumb, g.position AS gallery_position, c.id AS coupon_id, c.code AS coupon_code, c.discount AS coupon_discount, c.deduction AS coupon_deduction, c.limit AS coupon_limit, c.customerLimit AS coupon_customerLimit, c.status AS coupon_status'; try { $statement = $this->connection->prepare( "SELECT {$fields} FROM {$this->table} e {$joins} WHERE e.id = :eventId" ); $statement->bindParam(':eventId', $id); $statement->execute(); $rows = $statement->fetchAll(); } catch (\Exception $e) { throw new QueryExecutionException('Unable to find event by id in ' . __CLASS__ . '. ' . $e->getMessage(), $e->getCode(), $e); } /** @var Event $event */ $event = call_user_func([static::FACTORY, 'createCollection'], $rows)->getItem($id); $eventTicketRepository = new EventTicketRepository( $this->connection, EventsTicketsTable::getTableName() ); $customTickets = new Collection(); /** @var EventTicket $ticket */ foreach ($eventTicketRepository->getByEntityId($id, 'eventId')->getItems() as $ticket) { $customTickets->addItem($ticket, $ticket->getId()->getValue()); } $event->setCustomTickets($customTickets); return $event; } /** * @param int $id * * @return mixed * @throws QueryExecutionException */ public function isRecurring($id) { try { $statement = $this->connection->prepare( "SELECT e.recurringOrder AS event_recurringOrder, e.parentId AS event_parentId FROM {$this->table} e WHERE e.id = :eventId" ); $statement->bindParam(':eventId', $id); $statement->execute(); return $statement->fetch(); } catch (\Exception $e) { throw new QueryExecutionException('Unable to find event by id in ' . __CLASS__ . '. ' . $e->getMessage(), $e->getCode(), $e); } } /** * @param int $id * @param int $parentId * * @return mixed * @throws QueryExecutionException */ public function getRecurringIds($id, $parentId) { $whereParent = empty($parentId) ? '' : ' OR e.parentId = :parentId'; try { $statement = $this->connection->prepare( "SELECT e.id AS eventId FROM {$this->table} e WHERE e.parentId = :eventId" . $whereParent ); $statement->bindParam(':eventId', $id); if ($parentId) { $statement->bindParam(':parentId', $parentId); } $statement->execute(); $events = $statement->fetchAll(); return array_column($events, 'eventId'); } catch (\Exception $e) { throw new QueryExecutionException('Unable to find event by id in ' . __CLASS__ . '. ' . $e->getMessage(), $e->getCode(), $e); } } /** * @param int $bookingId * @param array $criteria * * @return ?Event * @throws QueryExecutionException * @throws InvalidArgumentException */ public function getByBookingId($bookingId, $criteria = []): ?Event { $eventsPeriodsTable = EventsPeriodsTable::getTableName(); $customerBookingsEventsPeriods = CustomerBookingsToEventsPeriodsTable::getTableName(); $fields = ''; $joins = ''; if (!empty($criteria['fetchEventsCoupons'])) { $couponsTable = CouponsTable::getTableName(); $fields .= ' ec.id AS coupon_id, ec.code AS coupon_code, ec.discount AS coupon_discount, ec.deduction AS coupon_deduction, ec.limit AS coupon_limit, ec.customerLimit AS coupon_customerLimit, ec.status AS coupon_status, '; $joins .= " LEFT JOIN {$couponsTable} ec ON ec.id = cb.couponId "; } if (!empty($criteria['fetchEventsTickets'])) { $ticketsTable = EventsTicketsTable::getTableName(); $fields .= ' eti.id AS ticket_id, eti.name AS ticket_name, eti.enabled AS ticket_enabled, eti.price AS ticket_price, eti.spots AS ticket_spots, eti.waitingListSpots AS ticket_waiting_list_spots, eti.dateRanges AS ticket_dateRanges, eti.translations AS ticket_translations, '; $joins .= " LEFT JOIN {$ticketsTable} eti ON eti.eventId = e.id "; } if (!empty($criteria['fetchEventsTags'])) { $tagsTable = EventsTagsTable::getTableName(); $fields .= ' eta.id AS event_tagId, eta.name AS event_tagName, '; $joins .= " LEFT JOIN {$tagsTable} eta ON eta.eventId = e.id "; } if (!empty($criteria['fetchEventsImages'])) { $galleriesTable = GalleriesTable::getTableName(); $fields .= ' eg.id AS gallery_id, eg.pictureFullPath AS gallery_picture_full, eg.pictureThumbPath AS gallery_picture_thumb, eg.position AS gallery_position, '; $joins .= " LEFT JOIN {$galleriesTable} eg ON eg.entityId = e.id AND eg.entityType = 'event' "; } if (!empty($criteria['fetchEventsProviders'])) { $eventsProvidersTable = EventsProvidersTable::getTableName(); $usersTable = UsersTable::getTableName(); $joins .= " LEFT JOIN {$eventsProvidersTable} epr ON epr.eventId = e.id LEFT JOIN {$usersTable} pu ON pu.id = epr.userId "; $fields .= ' pu.id AS provider_id, pu.firstName AS provider_firstName, pu.lastName AS provider_lastName, pu.email AS provider_email, pu.note AS provider_note, pu.description AS provider_description, pu.phone AS provider_phone, pu.countryPhoneIso AS provider_countryPhoneIso, pu.gender AS provider_gender, pu.pictureFullPath AS provider_pictureFullPath, pu.pictureThumbPath AS provider_pictureThumbPath, pu.translations AS provider_translations, pu.timeZone AS provider_timeZone, '; } $fields .= " e.id AS event_id, e.name AS event_name, e.status AS event_status, e.bookingOpens AS event_bookingOpens, e.bookingCloses AS event_bookingCloses, e.recurringCycle AS event_recurringCycle, e.recurringOrder AS event_recurringOrder, e.recurringInterval AS event_recurringInterval, e.recurringUntil AS event_recurringUntil, e.bringingAnyone AS event_bringingAnyone, e.bookMultipleTimes AS event_bookMultipleTimes, e.maxCapacity AS event_maxCapacity, e.maxCustomCapacity AS event_maxCustomCapacity, e.maxExtraPeople AS event_maxExtraPeople, e.price AS event_price, e.description AS event_description, e.color AS event_color, e.show AS event_show, e.notifyParticipants AS event_notifyParticipants, e.locationId AS event_locationId, e.customLocation AS event_customLocation, e.customPricing AS event_customPricing, e.parentId AS event_parentId, e.created AS event_created, e.settings AS event_settings, e.zoomUserId AS event_zoomUserId, e.translations AS event_translations, e.deposit AS event_deposit, e.depositPayment AS event_depositPayment, e.depositPerPerson AS event_depositPerPerson, e.fullPayment AS event_fullPayment, e.organizerId AS event_organizerId, e.aggregatedPrice AS event_aggregatedPrice, ep.id AS event_periodId, ep.periodStart AS event_periodStart, ep.periodEnd AS event_periodEnd, ep.zoomMeeting AS event_periodZoomMeeting, ep.lessonSpace AS event_periodLessonSpace, ep.googleCalendarEventId AS event_googleCalendarEventId, ep.googleMeetUrl AS event_googleMeetUrl, ep.outlookCalendarEventId AS event_outlookCalendarEventId, ep.microsoftTeamsUrl AS event_microsoftTeamsUrl, ep.appleCalendarEventId AS event_appleCalendarEventId "; $params = [ ':customerBookingId' => $bookingId, ]; try { $statement = $this->connection->prepare( "SELECT {$fields} FROM {$customerBookingsEventsPeriods} cbe INNER JOIN {$eventsPeriodsTable} ep ON ep.id = cbe.eventPeriodId INNER JOIN {$this->table} e ON e.id = ep.eventId {$joins} WHERE cbe.customerBookingId = :customerBookingId" ); $statement->execute($params); $rows = $statement->fetchAll(); } catch (\Exception $e) { throw new QueryExecutionException('Unable to find event by booking id in ' . __CLASS__ . '. ' . $e->getMessage(), $e->getCode(), $e); } /** @var Collection $events */ $events = call_user_func([static::FACTORY, 'createCollection'], $rows); return $events->length() ? $events->getItem($events->keys()[0]) : null; } /** * @param array $ids * @param array $criteria * * @return Collection * @throws QueryExecutionException * @throws InvalidArgumentException */ public function getByIdsWithEntities($ids, $criteria = [], $sort = null) { $params = []; $where = []; $fields = ''; $joins = ''; $orderBy = ''; if (!empty($criteria['fetchEventsPeriods'])) { $eventsPeriodsTable = EventsPeriodsTable::getTableName(); $fields .= ' ep.id AS event_periodId, ep.periodStart AS event_periodStart, ep.periodEnd AS event_periodEnd, ep.zoomMeeting AS event_periodZoomMeeting, ep.lessonSpace AS event_periodLessonSpace, ep.googleCalendarEventId AS event_googleCalendarEventId, ep.googleMeetUrl AS event_googleMeetUrl, ep.outlookCalendarEventId AS event_outlookCalendarEventId, ep.microsoftTeamsUrl AS event_microsoftTeamsUrl, ep.appleCalendarEventId AS event_appleCalendarEventId, '; $joins .= " INNER JOIN {$eventsPeriodsTable} ep ON ep.eventId = e.id "; $orderBy = $this->getOrderBy($sort); } if (!empty($criteria['fetchEventsLocation'])) { $locationsTable = LocationsTable::getTableName(); $fields .= ' l.id AS location_id, l.name AS location_name, '; $joins .= " LEFT JOIN {$locationsTable} l ON l.id = e.locationId "; } if (!empty($criteria['fetchEventsCoupons'])) { $couponsTable = CouponsTable::getTableName(); $fields .= ' ec.id AS coupon_id, ec.code AS coupon_code, ec.discount AS coupon_discount, ec.deduction AS coupon_deduction, ec.limit AS coupon_limit, ec.customerLimit AS coupon_customerLimit, ec.status AS coupon_status, '; $joins .= " LEFT JOIN {$couponsTable} ec ON ec.id = cb.couponId "; } if (!empty($criteria['fetchEventsTickets'])) { $ticketsTable = EventsTicketsTable::getTableName(); $fields .= ' eti.id AS ticket_id, eti.name AS ticket_name, eti.enabled AS ticket_enabled, eti.price AS ticket_price, eti.spots AS ticket_spots, eti.waitingListSpots AS ticket_waiting_list_spots, eti.dateRanges AS ticket_dateRanges, eti.translations AS ticket_translations, '; $joins .= " LEFT JOIN {$ticketsTable} eti ON eti.eventId = e.id "; $orderBy .= (!empty($orderBy) ? ',' : 'ORDER BY') . ' eti.id ASC'; } if (!empty($criteria['fetchEventsTags'])) { $tagsTable = EventsTagsTable::getTableName(); $fields .= ' eta.id AS event_tagId, eta.name AS event_tagName, '; $joins .= " LEFT JOIN {$tagsTable} eta ON eta.eventId = e.id "; } if (!empty($criteria['fetchEventsImages'])) { $galleriesTable = GalleriesTable::getTableName(); $fields .= ' eg.id AS gallery_id, eg.pictureFullPath AS gallery_picture_full, eg.pictureThumbPath AS gallery_picture_thumb, eg.position AS gallery_position, '; $joins .= " LEFT JOIN {$galleriesTable} eg ON eg.entityId = e.id AND eg.entityType = 'event' "; } if (!empty($criteria['fetchEventsOrganizer'])) { $usersTable = UsersTable::getTableName(); $joins .= " LEFT JOIN {$usersTable} ou ON ou.id = e.organizerId "; $fields .= ' ou.id AS organizer_id, ou.firstName AS organizer_firstName, ou.lastName AS organizer_lastName, ou.email AS organizer_email, ou.badgeId AS organizer_badgeId, ou.pictureThumbPath AS organizer_pictureThumbPath, ou.pictureFullPath AS organizer_pictureFullPath, '; } if (!empty($criteria['fetchEventsProviders'])) { $eventsProvidersTable = EventsProvidersTable::getTableName(); $usersTable = UsersTable::getTableName(); $joins .= " LEFT JOIN {$eventsProvidersTable} epr ON epr.eventId = e.id LEFT JOIN {$usersTable} pu ON pu.id = epr.userId "; $fields .= ' pu.id AS provider_id, pu.firstName AS provider_firstName, pu.lastName AS provider_lastName, pu.email AS provider_email, pu.note AS provider_note, pu.description AS provider_description, pu.phone AS provider_phone, pu.countryPhoneIso AS provider_countryPhoneIso, pu.gender AS provider_gender, pu.pictureFullPath AS provider_pictureFullPath, pu.pictureThumbPath AS provider_pictureThumbPath, pu.translations AS provider_translations, pu.timeZone AS provider_timeZone, pu.badgeId AS provider_badgeId, '; } $fields .= " e.id AS event_id, e.name AS event_name, e.status AS event_status, e.bookingOpens AS event_bookingOpens, e.bookingCloses AS event_bookingCloses, e.bookingOpensRec AS event_bookingOpensRec, e.bookingClosesRec AS event_bookingClosesRec, e.ticketRangeRec AS event_ticketRangeRec, e.recurringCycle AS event_recurringCycle, e.recurringOrder AS event_recurringOrder, e.recurringInterval AS event_recurringInterval, e.recurringMonthly AS event_recurringMonthly, e.monthlyDate AS event_monthlyDate, e.monthlyOnRepeat AS event_monthlyOnRepeat, e.monthlyOnDay AS event_monthlyOnDay, e.recurringUntil AS event_recurringUntil, e.bringingAnyone AS event_bringingAnyone, e.bookMultipleTimes AS event_bookMultipleTimes, e.maxCapacity AS event_maxCapacity, e.maxCustomCapacity AS event_maxCustomCapacity, e.maxExtraPeople AS event_maxExtraPeople, e.price AS event_price, e.description AS event_description, e.color AS event_color, e.show AS event_show, e.notifyParticipants AS event_notifyParticipants, e.locationId AS event_locationId, e.customLocation AS event_customLocation, e.parentId AS event_parentId, e.created AS event_created, e.settings AS event_settings, e.zoomUserId AS event_zoomUserId, e.organizerId AS event_organizerId, e.translations AS event_translations, e.deposit AS event_deposit, e.depositPayment AS event_depositPayment, e.depositPerPerson AS event_depositPerPerson, e.fullPayment AS event_fullPayment, e.customPricing AS event_customPricing, e.closeAfterMin AS event_closeAfterMin, e.closeAfterMinBookings AS event_closeAfterMinBookings, e.aggregatedPrice AS event_aggregatedPrice, e.pictureFullPath AS event_pictureFullPath, e.pictureThumbPath AS event_pictureThumbPath "; if (!empty($ids)) { $queryIds = []; foreach ($ids as $index => $value) { $param = ':id' . $index; $queryIds[] = $param; $params[$param] = $value; } $where[] = 'e.id IN (' . implode(', ', $queryIds) . ')'; } $where = $where ? 'WHERE ' . implode(' AND ', $where) : ''; try { $statement = $this->connection->prepare( "SELECT {$fields} FROM {$this->table} e {$joins} {$where} {$orderBy}" ); $statement->execute($params); $rows = $statement->fetchAll(); } catch (\Exception $e) { throw new QueryExecutionException('Unable to find event by id in ' . __CLASS__ . '. ' . $e->getMessage(), $e->getCode(), $e); } return call_user_func([static::FACTORY, 'createCollection'], $rows); } /** * @param array $criteria * * @return Collection * @throws QueryExecutionException * @throws InvalidArgumentException */ public function getBookingsByCriteria($criteria = []) { $params = []; $where = []; $fields = ''; $joins = ''; $eventsPeriodsTable = EventsPeriodsTable::getTableName(); $customerBookingsEventsPeriods = CustomerBookingsToEventsPeriodsTable::getTableName(); $customerBookingsTable = CustomerBookingsTable::getTableName(); if (!empty($criteria['fetchApprovedBookings'])) { $where[] = "cb.status = 'approved'"; } if (!empty($criteria['customerId'])) { $params[':customerId'] = $criteria['customerId']; $where[] = 'cb.customerId = :customerId'; } if (!empty($criteria['customerBookingStatus'])) { $params[':customerBookingStatus'] = $criteria['customerBookingStatus']; $where[] = 'cb.status = :customerBookingStatus'; } if (!empty($criteria['customerBookingId'])) { $params[':customerBookingId'] = $criteria['customerBookingId']; $where[] = 'cb.id = :customerBookingId'; } if (!empty($criteria['fetchBookingsPayments'])) { $paymentsTable = PaymentsTable::getTableName(); $fields .= ' p.id AS payment_id, p.amount AS payment_amount, p.dateTime AS payment_dateTime, p.created AS payment_created, p.status AS payment_status, p.gateway AS payment_gateway, p.gatewayTitle AS payment_gatewayTitle, p.transactionId AS payment_transactionId, p.data AS payment_data, p.wcOrderId AS payment_wcOrderId, p.wcOrderItemId AS payment_wcOrderItemId, p.invoiceNumber AS payment_invoiceNumber, '; $joins .= " LEFT JOIN {$paymentsTable} p ON p.customerBookingId = cb.id "; } if (!empty($criteria['fetchBookingsCoupons'])) { $couponsTable = CouponsTable::getTableName(); $fields .= ' c.id AS coupon_id, c.code AS coupon_code, c.discount AS coupon_discount, c.deduction AS coupon_deduction, c.limit AS coupon_limit, c.customerLimit AS coupon_customerLimit, c.status AS coupon_status, '; $joins .= " LEFT JOIN {$couponsTable} c ON c.id = cb.couponId "; } if (!empty($criteria['fetchBookingsUsers'])) { $usersTable = UsersTable::getTableName(); $fields .= ' cu.id AS customer_id, cu.type AS customer_type, cu.firstName AS customer_firstName, cu.lastName AS customer_lastName, cu.email AS customer_email, cu.note AS customer_note, cu.phone AS customer_phone, cu.countryPhoneIso AS customer_countryPhoneIso, cu.gender AS customer_gender, cu.birthday AS customer_birthday, cu.customFields AS customer_customFields, '; $joins .= " INNER JOIN {$usersTable} cu ON cu.id = cb.customerId "; } if (!empty($criteria['fetchBookingsTickets'])) { $bookingsTicketsTable = CustomerBookingToEventsTicketsTable::getTableName(); $fields .= ' cbt.id AS booking_ticket_id, cbt.eventTicketId AS booking_ticket_eventTicketId, cbt.price AS booking_ticket_price, cbt.persons AS booking_ticket_persons, '; $joins .= " LEFT JOIN {$bookingsTicketsTable} cbt ON cbt.customerBookingId = cb.id "; } $fields .= ' ep.eventId AS eventId, cb.id AS booking_id, cb.appointmentId AS booking_appointmentId, cb.customerId AS booking_customerId, cb.status AS booking_status, cb.price AS booking_price, cb.tax AS booking_tax, cb.persons AS booking_persons, cb.couponId AS booking_couponId, cb.customFields AS booking_customFields, cb.info AS booking_info, cb.utcOffset AS booking_utcOffset, cb.token AS booking_token, cb.aggregatedPrice AS booking_aggregatedPrice, cb.tax AS booking_tax, cb.qrCodes AS booking_qrCodes, cb.ivyEntryId AS booking_ivyEntryId '; if (!empty($criteria['ids'])) { $queryIds = []; foreach ($criteria['ids'] as $index => $value) { $param = ':id' . $index; $queryIds[] = $param; $params[$param] = $value; } $where[] = 'ep.eventId IN (' . implode(', ', $queryIds) . ')'; } $where = $where ? 'WHERE ' . implode(' AND ', $where) : ''; try { $statement = $this->connection->prepare( "SELECT {$fields} FROM {$eventsPeriodsTable} ep INNER JOIN {$customerBookingsEventsPeriods} cbe ON cbe.eventPeriodId = ep.id INNER JOIN {$customerBookingsTable} cb ON cb.id = cbe.customerBookingId {$joins} {$where} ORDER BY cb.id" ); $statement->execute($params); $rows = $statement->fetchAll(); } catch (\Exception $e) { throw new QueryExecutionException('Unable to find event by id in ' . __CLASS__ . '. ' . $e->getMessage(), $e->getCode(), $e); } $reformattedData = []; foreach ($rows as $row) { if (empty($reformattedData[$row['eventId']])) { $reformattedData[$row['eventId']] = []; } $reformattedData[$row['eventId']][] = $row; } $result = new Collection(); foreach ($reformattedData as $eventId => $bookingsData) { $reformattedBookingsData = CustomerBookingFactory::reformat($bookingsData); $eventBookings = new Collection(); foreach ($reformattedBookingsData as $bookingId => $data) { $eventBookings->addItem(CustomerBookingFactory::create($data), $bookingId); } $result->addItem($eventBookings, $eventId); } return $result; } /** * @param Event $event * @param array $booking * @param array $limitPerCustomer * @return int * @throws QueryExecutionException * @throws InvalidArgumentException */ public function getRelevantBookingsCount($event, $booking, $limitPerCustomer) { $eventsPeriodsTable = EventsPeriodsTable::getTableName(); $customerBookingsEventsPeriods = CustomerBookingsToEventsPeriodsTable::getTableName(); $customerBookingsTable = CustomerBookingsTable::getTableName(); $params = [ ':customerId' => $booking['customerId'] ]; $paymentTableJoin = ''; $compareToDate = 'ep.periodStart'; if ($limitPerCustomer['from'] === 'bookingDate') { $eventStartDate = (clone $event->getPeriods()->getItems()[0]->getPeriodStart()->getValue())->setTimezone(new \DateTimeZone('UTC'))->format('Y-m-d H:i'); } else { $paymentTableJoin = 'INNER JOIN ' . PaymentsTable::getTableName() . ' p ON p.customerBookingId = cb.id'; $eventStartDate = DateTimeService::getNowDateTimeObject()->setTimezone(new \DateTimeZone('UTC'))->format('Y-m-d H:i'); $compareToDate = 'p.created'; } $intervalString = "interval " . $limitPerCustomer['period'] . " " . $limitPerCustomer['timeFrame']; $where = "(STR_TO_DATE('" . $eventStartDate . "', '%Y-%m-%d %H:%i:%s') BETWEEN " . "(" . $compareToDate . " - " . $intervalString . " + interval 1 second)" . " AND (" . $compareToDate . " + " . $intervalString . " - interval 1 second))"; try { $statement = $this->connection->prepare( "SELECT COUNT(DISTINCT cb.id) AS count FROM {$this->table} e INNER JOIN {$eventsPeriodsTable} ep ON ep.eventId = e.id INNER JOIN {$customerBookingsEventsPeriods} cbep ON cbep.eventPeriodId = ep.id INNER JOIN {$customerBookingsTable} cb ON cb.id = cbep.customerBookingId {$paymentTableJoin} WHERE cb.customerId = :customerId AND {$where} AND e.status = 'approved' AND cb.status = 'approved' " ); $statement->execute($params); $rows = $statement->fetch()['count']; } catch (\Exception $e) { throw new QueryExecutionException('Unable to find by id in ' . __CLASS__ . '. ' . $e->getMessage(), $e->getCode(), $e); } return $rows; } /** * @param array $ids * @return array * @throws QueryExecutionException * @throws InvalidArgumentException */ public function getEventsSpotsCount($ids) { $eventsPeriodsTable = EventsPeriodsTable::getTableName(); $customerBookingsEventsPeriods = CustomerBookingsToEventsPeriodsTable::getTableName(); $customerBookingsTable = CustomerBookingsTable::getTableName(); $where = "WHERE ep.eventId IN (" . implode(', ', $ids) . ") AND cb.status IN ('approved', 'pending', 'waiting')"; try { $statement = $this->connection->prepare( "SELECT t.eventId, t.status, SUM(t.persons) as places FROM ( SELECT ep.eventId, cb.id, cb.status, cb.persons FROM {$eventsPeriodsTable} ep INNER JOIN {$customerBookingsEventsPeriods} cbep ON cbep.eventPeriodId = ep.id INNER JOIN {$customerBookingsTable} cb ON cb.id = cbep.customerBookingId {$where} GROUP BY ep.eventId, cb.id, cb.status ) t GROUP BY t.eventId, t.status" ); $statement->execute(); $rows = $statement->fetchAll(); $result = []; foreach ($rows as $row) { $result[$row['eventId']][$row['status']] = $row['places'] + (!empty($result[$row['eventId']][$row['status']]) ? $result[$row['eventId']][$row['status']] : 0); } } catch (\Exception $e) { throw new QueryExecutionException('Unable to find by id in ' . __CLASS__, $e->getCode(), $e); } return $result; } /** * @param array $ids * @return array * @throws QueryExecutionException * @throws InvalidArgumentException */ public function getEventsTicketsCount($ids) { $eventsPeriodsTable = EventsPeriodsTable::getTableName(); $customerBookingsEventsPeriods = CustomerBookingsToEventsPeriodsTable::getTableName(); $customerBookingsTable = CustomerBookingsTable::getTableName(); $customerBookingsTicketsTable = CustomerBookingToEventsTicketsTable::getTableName(); $where = "WHERE ep.eventId IN (" . implode(', ', $ids) . ") AND cb.status IN ('approved', 'pending', 'waiting')"; try { $statement = $this->connection->prepare( "SELECT t.eventId, t.status, t.eventTicketId, SUM(t.persons) as places FROM ( SELECT ep.eventId, cb.id, cb.status, cbt.eventTicketId, cbt.persons FROM {$eventsPeriodsTable} ep INNER JOIN {$customerBookingsEventsPeriods} cbep ON cbep.eventPeriodId = ep.id INNER JOIN {$customerBookingsTable} cb ON cb.id = cbep.customerBookingId INNER JOIN {$customerBookingsTicketsTable} cbt ON cbt.customerBookingId = cb.id {$where} GROUP BY ep.eventId, cb.id, cb.status, cbt.eventTicketId, cbt.persons ) t GROUP BY t.eventId, t.status, t.eventTicketId" ); $statement->execute(); $rows = $statement->fetchAll(); $result = []; foreach ($rows as $row) { $result[$row['eventId']][$row['eventTicketId']][$row['status']] = $row['places'] + ( !empty($result[$row['eventId']][$row['eventTicketId']][$row['status']]) ? $result[$row['eventId']][$row['eventTicketId']][$row['status']] : 0 ); } } catch (\Exception $e) { throw new QueryExecutionException('Unable to find by id in ' . __CLASS__, $e->getCode(), $e); } return $result; } /** * @param int $id * @return array * @throws QueryExecutionException * @throws InvalidArgumentException */ public function getEventsPaymentsSummary($id) { $eventsPeriodsTable = EventsPeriodsTable::getTableName(); $customerBookingsEventsPeriods = CustomerBookingsToEventsPeriodsTable::getTableName(); $customerBookingsTable = CustomerBookingsTable::getTableName(); $paymentsTable = PaymentsTable::getTableName(); try { $statementAmount = $this->connection->prepare( "SELECT SUM(t.amount) as amount FROM ( SELECT cb.id, p.amount FROM {$eventsPeriodsTable} ep INNER JOIN {$customerBookingsEventsPeriods} cbep ON cbep.eventPeriodId = ep.id INNER JOIN {$customerBookingsTable} cb ON cb.id = cbep.customerBookingId INNER JOIN {$paymentsTable} p ON p.customerBookingId = cb.id WHERE ep.eventId = :eventId AND cb.status IN ('approved', 'pending', 'waiting') GROUP BY cb.id, p.amount ) t" ); $statementAmount->execute([':eventId' => $id]); $rowAmount = $statementAmount->fetch(); $statementStatus = $this->connection->prepare( "SELECT t.status, COUNT(t.status) as counter FROM ( SELECT cb.id, p.status FROM {$eventsPeriodsTable} ep INNER JOIN {$customerBookingsEventsPeriods} cbep ON cbep.eventPeriodId = ep.id INNER JOIN {$customerBookingsTable} cb ON cb.id = cbep.customerBookingId INNER JOIN {$paymentsTable} p ON p.customerBookingId = cb.id INNER JOIN ( SELECT customerBookingId, MAX(id) as maxId FROM {$paymentsTable} GROUP BY customerBookingId ) pm ON p.customerBookingId = pm.customerBookingId AND p.id = pm.maxId WHERE ep.eventId = :eventId AND cb.status IN ('approved', 'pending', 'waiting') GROUP BY cb.id, p.status ) t GROUP BY t.status" ); $statementStatus->execute([':eventId' => $id]); $rowsStatus = $statementStatus->fetchAll(); $statementGateway = $this->connection->prepare( "SELECT t.gateway, COUNT(t.gateway) as counter FROM ( SELECT p.id, p.gateway FROM {$eventsPeriodsTable} ep INNER JOIN {$customerBookingsEventsPeriods} cbep ON cbep.eventPeriodId = ep.id INNER JOIN {$customerBookingsTable} cb ON cb.id = cbep.customerBookingId INNER JOIN {$paymentsTable} p ON p.customerBookingId = cb.id WHERE ep.eventId = :eventId AND cb.status IN ('approved', 'pending', 'waiting') GROUP BY p.id, p.gateway ) t GROUP BY t.gateway" ); $statementGateway->execute([':eventId' => $id]); $rowsGateway = $statementGateway->fetchAll(); } catch (\Exception $e) { throw new QueryExecutionException('Unable to find by id in ' . __CLASS__, $e->getCode(), $e); } return [ 'amount' => $rowAmount['amount'] ? floatval($rowAmount['amount']) : 0, 'method' => array_map( 'intval', array_column($rowsGateway, 'counter', 'gateway') ), 'status' => array_map( 'intval', array_column($rowsStatus, 'counter', 'status') ), ]; } /** * @param array $ids * @return array * @throws QueryExecutionException * @throws InvalidArgumentException */ public function getEventsBookingsStatusesCount($ids) { $eventsPeriodsTable = EventsPeriodsTable::getTableName(); $customerBookingsEventsPeriods = CustomerBookingsToEventsPeriodsTable::getTableName(); $customerBookingsTable = CustomerBookingsTable::getTableName(); $where = "WHERE ep.eventId IN (" . implode(', ', $ids) . ")"; try { $statement = $this->connection->prepare( "SELECT t.eventId, t.status, COUNT(t.status) as counter FROM ( SELECT ep.eventId, cb.id, cb.status FROM {$eventsPeriodsTable} ep INNER JOIN {$customerBookingsEventsPeriods} cbep ON cbep.eventPeriodId = ep.id INNER JOIN {$customerBookingsTable} cb ON cb.id = cbep.customerBookingId {$where} GROUP BY ep.eventId, cb.id, cb.status ) t GROUP BY t.eventId, t.status" ); $statement->execute(); $rows = $statement->fetchAll(); $result = []; foreach ($rows as $row) { $result[$row['eventId']][$row['status']] = $row['counter'] + (!empty($result[$row['eventId']][$row['status']]) ? $result[$row['eventId']][$row['status']] : 0); } } catch (\Exception $e) { throw new QueryExecutionException('Unable to find by id in ' . __CLASS__, $e->getCode(), $e); } return $result; } /** * @param string $sort * @return string */ private function getOrderBy($sort) { $order = "ORDER BY ep.periodStart"; if ($sort) { $column = $sort[0] === '-' ? substr($sort, 1) : $sort; $orderColumn = 'ep.periodStart'; switch ($column) { case 'name': $orderColumn = 'e.name'; break; case 'id': $orderColumn = 'e.id'; break; case 'bookingOpens': $orderColumn = 'COALESCE(e.bookingOpens, e.created)'; break; case 'bookingCloses': $orderColumn = 'COALESCE(e.bookingCloses, ep.periodStart)'; break; } $orderDirection = $sort[0] === '-' ? 'DESC' : 'ASC'; $order = "ORDER BY {$orderColumn} {$orderDirection}"; } return $order; } /** * @param Event $event * @param int $visible * @param boolean $applyGlobally * @throws QueryExecutionException * @throws InvalidArgumentException */ public function toggleEventVisibility($event, $visible, $applyGlobally) { $params = [ ':show' => $visible ]; if ($applyGlobally) { $params[':id1'] = $event->getId()->getValue(); $params[':id2'] = $event->getId()->getValue(); $where = "WHERE id = :id1 OR parentId = :id2"; if ($event->getParentId()) { $params[':id3'] = $event->getId()->getValue(); $params[':parentId'] = $event->getParentId()->getValue(); $where .= ' OR (id > :id3 AND parentId = :parentId)'; } } else { $params[':id'] = $event->getId()->getValue(); $where = 'WHERE id = :id'; } try { $statement = $this->connection->prepare( "UPDATE {$this->table} SET `show` = :show $where" ); $statement->execute($params); return true; } catch (\Exception $e) { throw new QueryExecutionException('Unable to update visibility in ' . __CLASS__ . '. ' . $e->getMessage(), $e->getCode(), $e); } } /** * @param int $organizerId */ public function removeOrganizerFromEvents($organizerId) { $params = [ ':organizerId' => $organizerId ]; try { $statement = $this->connection->prepare( "UPDATE {$this->table} SET organizerId = NULL WHERE organizerId = :organizerId" ); $statement->execute($params); return true; } catch (\Exception $e) { throw new QueryExecutionException('Unable to remove organizer in ' . __CLASS__ . '. ' . $e->getMessage(), $e->getCode(), $e); } } }