/** * @param ISummit $summit * @param string $promo_code_type * @param int $batch_size * @return ISpeakerSummitRegistrationPromoCode */ public function getNextAvailableByType(ISummit $summit, $promo_code_type, $batch_size = 10) { switch ($promo_code_type) { case ISpeakerSummitRegistrationPromoCode::TypeAccepted: if (count($this->promo_code_speaker_session_pool) === 0) { $query = new QueryObject(new SpeakerSummitRegistrationPromoCode()); $query->addAndCondition(QueryCriteria::equal('Type', $promo_code_type)); $query->addAndCondition(QueryCriteria::equal('SpeakerID', 0)); $query->addAndCondition(QueryCriteria::equal('SummitID', $summit->getIdentifier())); $query->addOrder(QueryOrder::asc('ID')); list($this->promo_code_speaker_session_pool, $count) = $this->getAll($query, 0, $batch_size); } return array_shift($this->promo_code_speaker_session_pool); break; case ISpeakerSummitRegistrationPromoCode::TypeAlternate: if (count($this->promo_code_alternate_speaker_session_pool) === 0) { $query = new QueryObject(new SpeakerSummitRegistrationPromoCode()); $query->addAndCondition(QueryCriteria::equal('Type', $promo_code_type)); $query->addAndCondition(QueryCriteria::equal('SpeakerID', 0)); $query->addAndCondition(QueryCriteria::equal('SummitID', $summit->getIdentifier())); $query->addOrder(QueryOrder::asc('ID')); list($this->promo_code_alternate_speaker_session_pool, $count) = $this->getAll($query, 0, $batch_size); } return array_shift($this->promo_code_alternate_speaker_session_pool); break; } return null; }
/** * @param ISummit $summit * @param IPresentationSpeaker $speaker * @param string $role * @return PresentationSpeakerAcceptedAnnouncementEmailSender * @throws Exception */ public function build(ISummit $summit, IPresentationSpeaker $speaker, $role = IPresentationSpeaker::RoleSpeaker) { $has_published = $speaker->hasPublishedPresentations($summit->getIdentifier(), $role); $has_rejected = $speaker->hasRejectedPresentations($summit->getIdentifier(), $role); $has_alternate = $speaker->hasAlternatePresentations($summit->getIdentifier(), $role); if ($has_published && !$has_rejected && !$has_alternate) { return new PresentationSpeakerAcceptedAnnouncementEmailSender(); } if (!$has_published && !$has_rejected && $has_alternate) { return new PresentationSpeakerAlternateAnnouncementEmailSender(); } if (!$has_published && $has_rejected && !$has_alternate) { return new PresentationSpeakerRejectedAnnouncementEmailSender(); } if ($has_published && !$has_rejected && $has_alternate) { return new PresentationSpeakerAcceptedAlternateAnnouncementEmailSender(); } if ($has_published && $has_rejected && !$has_alternate) { return new PresentationSpeakerAcceptedRejectedAnnouncementEmailSender(); } if (!$has_published && $has_rejected && $has_alternate) { return new PresentationSpeakerAlternateRejectedAnnouncementEmailSender(); } if ($has_published && $has_rejected && $has_alternate) { return new PresentationSpeakerAcceptedAlternateAnnouncementEmailSender(); } return null; }
/** * @param ISummit $summit * @return SummitAppSchedPage */ public static function getBy(ISummit $summit) { $page = Versioned::get_by_stage('SummitAppSchedPage', 'Live')->filter('SummitID', $summit->getIdentifier())->first(); if (is_null($page)) { $page = Versioned::get_by_stage('SummitAppSchedPage', 'Stage')->filter('SummitID', $summit->getIdentifier())->first(); } return $page; }
/** * @param ISummit $summit * @param IPresentationSpeaker $speaker * @return IMessageSenderService */ public function build(ISummit $summit, IPresentationSpeaker $speaker) { /** * Rules are: * All speakers that are in a Track, besides BoF and Working Groups * Send the code they already received, unless they are new and don’t have a code. Then they get a new one. * Send the custom registration link to say they’re coming to the summit and leave their onsite phone * ( if they are registered, that is memberid <> 0) * If the user is already registered, we shouldn't send their code again: ( confirmed assistance for summit) * they still need the email, just not the part with the code. Probably a slightly altered verbiage as well */ if ($speaker->breakoutEmailAlreadySent($summit->getIdentifier())) { return null; } if ($speaker->hasConfirmedAssistanceFor($summit->getIdentifier())) { // send reminder without code return new PresentationSpeakerSummitReminderEmailSender(); } // send reminder with code return new PresentationSpeakerConfirmSummitAssistanceEmailReminderSender(); }
/** * @param ISummit $summit * @param string $term * @return IPresentationSpeaker[] */ public function searchBySummitAndTerm(ISummit $summit, $term) { $speakers = array(); $summit_id = $summit->getIdentifier(); $sql_speakers = <<<SQL SELECT DISTINCT S.*, CONCAT(S.FirstName,' ',S.LastName) AS FullName FROM PresentationSpeaker S WHERE EXISTS ( SELECT P.ID From Presentation P INNER JOIN SummitEvent E ON E.ID = P.ID AND E.Published = 1 AND E.SummitID = {$summit_id} INNER JOIN Presentation_Speakers PS ON PS.PresentationID = P.ID WHERE PS.PresentationSpeakerID = S.ID ) HAVING FullName LIKE '%{$term}%' UNION SELECT DISTINCT S.*, CONCAT(S.FirstName,' ',S.LastName) AS FullName FROM PresentationSpeaker S WHERE EXISTS ( SELECT P.ID From Presentation P INNER JOIN SummitEvent E ON E.ID = P.ID AND E.Published = 1 AND E.SummitID = {$summit_id} INNER JOIN Presentation_Speakers PS ON PS.PresentationID = P.ID WHERE PS.PresentationSpeakerID = S.ID ) HAVING SOUNDEX(FullName) = SOUNDEX('{$term}') UNION SELECT DISTINCT S.*, CONCAT(S.FirstName,' ',S.LastName) AS FullName FROM PresentationSpeaker S WHERE EXISTS ( SELECT P.ID From Presentation P INNER JOIN SummitEvent E ON E.ID = P.ID AND E.Published = 1 AND E.SummitID = {$summit_id} INNER JOIN Presentation_Speakers PS ON PS.PresentationID = P.ID WHERE PS.PresentationSpeakerID = S.ID AND E.Title LIKE '%{$term}%' ) SQL; foreach (DB::query($sql_speakers) as $row) { $class = $row['ClassName']; array_push($speakers, new $class($row)); } return $speakers; }
/** * @param ISummit $summit * @param array $event_data * @return mixed */ public function updateEvent(ISummit $summit, array $event_data) { $event_repository = $this->event_repository; return $this->tx_service->transaction(function () use($summit, $event_data, $event_repository) { if (!isset($event_data['id'])) { throw new EntityValidationException(array('missing required param: id')); } $event_id = intval($event_data['id']); $event = $event_repository->getById($event_id); if (is_null($event)) { throw new NotFoundEntityException('Summit Event', sprintf('id %s', $event_id)); } if (intval($event->SummitID) !== intval($summit->getIdentifier())) { throw new EntityValidationException(array('event doest not belongs to summit')); } $event->Title = $event_data['title']; $event->Description = $event_data['description']; $event->setStartDate($event_data['start_date']); $event->setEndDate($event_data['end_date']); $event->AllowFeedBack = $event_data['allow_feedback']; $event->LocationID = intval($event_data['location_id']); $event->TypeID = intval($event_data['event_type']); $event->AllowedSummitTypes()->setByIDList($event_data['summit_type']); $event->Tags()->setByIDList(explode(',', $event_data['tags'])); $event->Sponsors()->setByIDList(explode(',', $event_data['sponsors'])); // Speakers, if one of the added members is not a speaker, we need to make him one if ($event->isPresentation()) { $presentation = $event_repository->getPresentationById($event_id); $speaker_ids = array(); $member_ids = explode(',', $event_data['speakers']); foreach ($member_ids as $member_id) { $speaker = PresentationSpeaker::get()->filter('MemberID', $member_id)->first(); if (!$speaker) { $member = Member::get()->byID($member_id); $speaker = new PresentationSpeaker(); $speaker->FirstName = $member->FirstName; $speaker->LastName = $member->Surname; $speaker->MemberID = $member->ID; $speaker->write(); } $speaker_ids[] = $speaker->ID; } $event->Speakers()->setByIDList($speaker_ids); } return $event; }); }
/** * @param ISummit $summit * @param string $term * @return ISummitEvent[] */ public function searchBySummitTermAndHasRSVP(ISummit $summit, $term) { $events = array(); $summit_id = $summit->getIdentifier(); $sql_events = <<<SQL SELECT * FROM ( SELECT DISTINCT E.* FROM SummitEvent E WHERE E.SummitID = {$summit_id} AND E.Published = 1 AND E.RSVPTemplateID > 0 AND (Title LIKE '%{$term}%' OR E.ID = '{$term}') UNION SELECT DISTINCT E.* FROM SummitEvent E WHERE E.SummitID = {$summit_id} AND E.Published = 1 AND E.RSVPTemplateID > 0 AND EXISTS ( SELECT T.ID FROM Tag T INNER JOIN SummitEvent_Tags ET ON ET.TagID = T.ID WHERE ET.SummitEventID = E.ID AND T.Tag LIKE '%{$term}%' ) UNION SELECT DISTINCT E.* FROM SummitEvent E WHERE E.SummitID = {$summit_id} AND E.Published = 1 AND E.RSVPTemplateID > 0 AND EXISTS ( SELECT P.ID FROM Presentation P LEFT JOIN PresentationCategory PC ON PC.ID = P.CategoryID WHERE P.ID = E.ID AND PC.Title LIKE '%{$term}%' ) UNION SELECT DISTINCT E.* FROM SummitEvent E LEFT JOIN SummitEventType ET ON ET.ID = E.TypeID WHERE E.SummitID = {$summit_id} AND E.Published = 1 AND E.RSVPTemplateID > 0 AND ET.Type LIKE '%{$term}%' UNION SELECT DISTINCT E.* FROM SummitEvent E WHERE E.SummitID = {$summit_id} AND E.Published = 1 AND E.RSVPTemplateID > 0 AND EXISTS ( SELECT P.ID FROM Presentation P WHERE P.ID = E.ID AND P.Level LIKE '%{$term}%' ) UNION SELECT DISTINCT E.* FROM SummitEvent E WHERE E.SummitID = {$summit_id} AND E.Published = 1 AND E.RSVPTemplateID > 0 AND EXISTS ( SELECT P.ID, CONCAT(S.FirstName,' ',S.LastName) AS SpeakerFullName From Presentation P INNER JOIN Presentation_Speakers PS ON PS.PresentationID = P.ID INNER JOIN PresentationSpeaker S ON S.ID = PS.PresentationSpeakerID WHERE P.ID = E.ID HAVING SpeakerFullName LIKE '%{$term}%' OR SOUNDEX(SpeakerFullName) = SOUNDEX('{$term}') ) UNION SELECT DISTINCT E.* FROM SummitEvent E WHERE E.SummitID = {$summit_id} AND E.Published = 1 AND E.RSVPTemplateID > 0 AND EXISTS ( SELECT P.ID, CONCAT(S.FirstName,' ',S.LastName) AS SpeakerFullName From Presentation P INNER JOIN Presentation_Speakers PS ON PS.PresentationID = P.ID INNER JOIN PresentationSpeaker S ON S.ID = PS.PresentationSpeakerID WHERE P.ID = E.ID AND S.ID = '{$term}' ) SQL; foreach (DB::query($sql_events . ") AS Q1 ORDER BY StartDate ASC, EndDate ASC ;") as $row) { $class = $row['ClassName']; array_push($events, new $class($row)); } return $events; }
/** * @param ISummit $summit_id * @param array $days * @param string $start_time * @param string $end_time * @param array $locations * @return array */ public function getPublishedByTimeAndVenue(ISummit $summit, $days, $start_time, $end_time, $locations) { $where_clause = ''; if (!empty($days)) { $where_clause .= "("; foreach ($days as $day) { $start_date = $summit->convertDateFromTimeZone2UTC($day . ' ' . $start_time); $end_date = $summit->convertDateFromTimeZone2UTC($day . ' ' . $end_time); $where_clause .= "(StartDate < '{$end_date}' AND EndDate > '{$start_date}') OR "; } $where_clause = substr($where_clause, 0, -4) . ")"; } if (!empty($locations)) { $locations_string = implode(',', $locations); $where_clause .= " AND LocationID IN ({$locations_string})"; } $events = SummitEvent::get()->filter(array('SummitID' => $summit->getIdentifier(), 'Published' => 1))->where($where_clause)->sort('LocationID,StartDate')->toArray(); return $events; }
/** * @param ISummit $summit * @param array $data */ public function updateBulkPresentations(ISummit $summit, array $data) { $event_repository = $this->event_repository; $this->tx_service->transaction(function () use($summit, $data, $event_repository) { foreach ($data as $presentation) { $event = $event_repository->getById($presentation['id']); if (is_null($event)) { throw new NotFoundEntityException('SummitEvent'); } if (intval($event->SummitID) !== $summit->getIdentifier()) { throw new EntityValidationException('SummitEvent does not belong to Summit!'); } $event->Title = $presentation['title']; $event->write(); } }); }
/** * @param $promo_code_value * @param ISummit $summit * @return ISpeakerSummitRegistrationPromoCode * @throws EntityValidationException * @throws ValidationException */ public function registerSummitPromoCodeByValue($promo_code_value, ISummit $summit) { // check if we have an assigned one already $old_code = SpeakerSummitRegistrationPromoCode::get()->filter(['SummitID' => $summit->getIdentifier(), 'SpeakerID' => $this->ID])->first(); // we are trying to update the promo code with another one .... if ($old_code && $promo_code_value !== $old_code->Code) { throw new EntityValidationException(sprintf('speaker has already assigned to another registration code (%s)', $old_code->Code)); } //we already have the same code ... if ($old_code) { return $old_code; } // check if the promo code already exists and assigned to another user $existent_code = SpeakerSummitRegistrationPromoCode::get()->filter(['Code' => $promo_code_value, 'SummitID' => $summit->getIdentifier(), 'SpeakerID:ExactMatch:not' => 0])->first(); if ($existent_code) { throw new EntityValidationException(sprintf('there is another speaker with that code for this summit (%s)', $promo_code_value)); } // check if promo code exists and its not assigned ... $code = SpeakerSummitRegistrationPromoCode::get()->filter(['Code' => $promo_code_value, 'SummitID' => $summit->getIdentifier(), 'SpeakerID' => 0])->first(); if (!$code) { //create it $code = SpeakerSummitRegistrationPromoCode::create(); $code->SummitID = $summit->getIdentifier(); $code->Code = $promo_code_value; $code->write(); } $this->registerSummitPromoCode($code); $code->write(); return $code; }
/** * @param ISummit $summit * @param int $eb_attendee_id * @param int $member_id * @return ISummitAttendee */ public function matchEventbriteAttendee(ISummit $summit, $eb_attendee_id, $member_id) { $attendee_repository = $this->attendee_repository; $eventbrite_attendee_repository = new SapphireEventbriteAttendeeRepository(); $member_repository = $this->member_repository; return $this->tx_service->transaction(function () use($summit, $eb_attendee_id, $member_id, $attendee_repository, $eventbrite_attendee_repository, $member_repository) { $eb_attendee = $eventbrite_attendee_repository->getByAttendeeId($eb_attendee_id); if (is_null($eb_attendee)) { throw new NotFoundEntityException('Attendee', sprintf(' id %s', $eb_attendee_id)); } $member = $member_repository->getById($member_id); if (is_null($member)) { throw new NotFoundEntityException('Member', sprintf(' id %s', $member_id)); } $attendee = $attendee_repository->getByMemberAndSummit($member_id, $summit->getIdentifier()); if (!$attendee) { $attendee = new SummitAttendee(); $attendee->MemberID = $member_id; $attendee->SummitID = $summit->getIdentifier(); $attendee->write(); } list($eb_attendees, $count) = $eventbrite_attendee_repository->getByEmail($eb_attendee->Email); foreach ($eb_attendees as $eb_ticket) { $attendee_ticket = SummitAttendeeTicket::get()->where("ExternalAttendeeId = " . $eb_ticket->ExternalAttendeeId)->first(); if (!$attendee_ticket) { $attendee_ticket = new SummitAttendeeTicket(); $ticket_type = SummitTicketType::get()->where("ExternalId = " . $eb_ticket->ExternalTicketClassId)->first(); $external_event = EventbriteEvent::get()->where("ID = " . $eb_ticket->EventbriteOrderId)->first(); $attendee_ticket->ExternalOrderId = $external_event->ExternalOrderId; $attendee_ticket->ExternalAttendeeId = $eb_ticket->ExternalAttendeeId; $attendee_ticket->TicketTypeID = $ticket_type ? $ticket_type->ID : 0; } $attendee_ticket->OwnerID = $attendee->ID; $attendee_ticket->write(); } return $attendee; }); }
/** * @param ISummit $current_summit * @param int $batch_size * @return void */ public function send(ISummit $current_summit, $batch_size) { $speaker_repository = $this->speaker_repository; $sender_factory = $this->sender_breakout_factory; $promo_code_repository = $this->promo_code_repository; $batch_repository = $this->batch_repository; $batch_task_factory = $this->batch_task_factory; $not_allowed_categories = array('Working Groups', 'Birds of a Feather'); return $this->tx_manager->transaction(function () use($current_summit, $batch_size, $speaker_repository, $sender_factory, $promo_code_repository, $batch_repository, $batch_task_factory, $not_allowed_categories) { $summit_id = $current_summit->getIdentifier(); try { $page = 1; $page_size = $batch_size; $task = $batch_repository->findByName(self::TaskName . $summit_id); if (is_null($task)) { //create task $task = $batch_task_factory->buildBatchTask(self::TaskName . $summit_id, 0, $page); $batch_repository->add($task); } $page = $task->getCurrentPage(); echo "Processing Page " . $page . PHP_EOL; list($page, $page_size, $count, $speakers) = $speaker_repository->searchBySummitSchedulePaginated($current_summit, $page, $page_size); $speakers_notified = 0; foreach ($speakers as $speaker) { if (!$speaker instanceof IPresentationSpeaker) { continue; } // we need an email for this speaker ... $email = $speaker->getEmail(); if (empty($email)) { continue; } if ($speaker->breakoutEmailAlreadySent($current_summit->ID)) { continue; } /** * Rules are: * All speakers that are in a Track, besides BoF and Working Groups * Send the code they already received, unless they are new and don’t have a code. Then they get a new one. * Send the custom registration link to say they’re coming to the summit and leave their onsite phone * If the user is already registered, we shouldn't send their code again: * they still need the email, just not the part with the code. Probably a slightly altered verbiage as well */ $code = null; $presentations = $speaker->AllPublishedPresentations($current_summit->getIdentifier()); if (intval($presentations->Count()) === 1) { if (in_array($presentations->first()->Category()->Title, $not_allowed_categories)) { continue; } } $sender_service = $sender_factory->build($current_summit, $speaker); if (is_null($sender_service)) { continue; } $params = array('Speaker' => $speaker, 'Summit' => $current_summit); if (!$speaker->hasConfirmedAssistanceFor($current_summit->getIdentifier())) { if (!$speaker->hasSummitPromoCode($current_summit->getIdentifier())) { $code = $promo_code_repository->getNextAvailableByType($current_summit, ISpeakerSummitRegistrationPromoCode::TypeAccepted, $batch_size); if (is_null($code)) { throw new Exception('not available promo code!!!'); } $speaker->registerSummitPromoCode($code); $code->write(); } $params['PromoCode'] = $speaker->getSummitPromoCode($current_summit->getIdentifier()); } echo sprintf("sending email to %s", $speaker->getEmail()) . PHP_EOL; $sender_service->send($params); ++$speakers_notified; } $task->updatePage($count, $page_size); $task->write(); return $speakers_notified; } catch (Exception $ex) { SS_Log::log($ex->getMessage(), SS_Log::ERR); echo $ex->getMessage() . PHP_EOL; throw $ex; } }); }
/** * @param ISummit $current_summit * @param int $batch_size * @return void */ public function sendModerators(ISummit $current_summit, $batch_size) { $speaker_repository = $this->speaker_repository; $sender_factory = $this->sender_factory; $promo_code_repository = $this->promo_code_repository; $batch_repository = $this->batch_repository; $batch_task_factory = $this->batch_task_factory; return $this->tx_manager->transaction(function () use($current_summit, $batch_size, $speaker_repository, $sender_factory, $promo_code_repository, $batch_repository, $batch_task_factory) { try { $page = 1; $page_size = $batch_size; $task = $batch_repository->findByName(self::TaskName . '_MODERATORS_' . $current_summit->getIdentifier()); if (is_null($task)) { //create task $task = $batch_task_factory->buildBatchTask(self::TaskName . '_MODERATORS_' . $current_summit->getIdentifier(), 0, $page); $batch_repository->add($task); } $page = $task->getCurrentPage(); echo "Processing Page " . $page . PHP_EOL; // get speakers with not email sent for this current summit list($page, $page_size, $count, $moderators) = $speaker_repository->searchModeratorsBySummitPaginated($current_summit, $page, $page_size); $speakers_notified = 0; foreach ($moderators as $moderator) { if (!$moderator instanceof IPresentationSpeaker) { continue; } // we need an email for this speaker ... $email = $moderator->getEmail(); if (empty($email)) { continue; } if ($moderator->announcementEmailAlreadySent($current_summit->ID)) { continue; } $sender_service = $sender_factory->build($current_summit, $moderator, IPresentationSpeaker::RoleModerator); // get registration code if (is_null($sender_service)) { continue; } $code = null; if ($moderator->hasPublishedPresentations($current_summit->getIdentifier(), IPresentationSpeaker::RoleModerator)) { $code = $promo_code_repository->getNextAvailableByType($current_summit, ISpeakerSummitRegistrationPromoCode::TypeAccepted, $batch_size); if (is_null($code)) { throw new Exception('not available promo code!!!'); } } else { if ($moderator->hasAlternatePresentations($current_summit->getIdentifier(), IPresentationSpeaker::RoleModerator)) { $code = $promo_code_repository->getNextAvailableByType($current_summit, ISpeakerSummitRegistrationPromoCode::TypeAlternate, $batch_size); if (is_null($code)) { throw new Exception('not available alternate promo code!!!'); } } } $params = array('Speaker' => $moderator, 'Summit' => $current_summit, "Role" => IPresentationSpeaker::RoleModerator); if (!is_null($code)) { $moderator->registerSummitPromoCode($code); $code->setEmailSent(true); $code->write(); $params['PromoCode'] = $code; } $sender_service->send($params); ++$speakers_notified; } $task->updatePage($count, $page_size); $task->write(); return $speakers_notified; } catch (Exception $ex) { SS_Log::log($ex->getMessage(), SS_Log::ERR); throw $ex; } }); }