ccShow = CcShowQuery::create()->findPk($showId); } if (isset($showData["add_show_repeats"]) && $showData["add_show_repeats"]) { $this->repeatType = $showData["add_show_repeat_type"]; if ($showData["add_show_repeat_type"] == 2) { $this->repeatType = $showData["add_show_monthly_repeat_type"]; } } else { $this->repeatType = -1; } $this->isRecorded = (isset($showData['add_show_record']) && $showData['add_show_record']) ? 1 : 0; $this->isRebroadcast = (isset($showData['add_show_rebroadcast']) && $showData['add_show_rebroadcast']) ? 1 : 0; $this->isUpdate = $isUpdate; } public function editRepeatingShowInstance($showData) { $service_user = new Application_Service_UserService(); $currentUser = $service_user->getCurrentUser(); $showData["add_show_duration"] = $this->formatShowDuration( $showData["add_show_duration"]); $con = Propel::getConnection(); $con->beginTransaction(); try { if (!$currentUser->isAdminOrPM()) { throw new Exception("Permission denied"); } $showId = $showData["add_show_id"]; /****** UPDATE SCHEDULE START TIME ******/ //get the ccShow object to which this instance belongs //so we can get the original start date and time $this->ccShow = CcShowQuery::create() ->findPk($showId); //DateTime in shows's local time $newStartDateTime = new DateTime($showData["add_show_start_date"]." ". $showData["add_show_start_time"], new DateTimeZone($showData["add_show_timezone"])); $ccShowInstanceOrig = CcShowInstancesQuery::create() ->findPk($showData["add_show_instance_id"]); //convert original start time into the show's local timezone $origLocalStartDateTime = $ccShowInstanceOrig->getLocalStartDateTime(); $diff = $this->calculateShowStartDiff($newStartDateTime, $origLocalStartDateTime); if ($diff != 0) { Application_Service_SchedulerService::updateScheduleStartTime( array($showData["add_show_instance_id"]), $diff); } /****** UPDATE SCHEDULE START TIME ENDS******/ /* * In the case where an instance is being edited for a second * (or third, fourth, etc.) time we need to delete the old * cc_show_day record * * Since we don't store the cc_show_day ids we need to use the * original start time from cc_show_instances, convert it to the show's * local timezone, and find the record in cc_show_days * * *** There is a flaw here: We have to assume the show timezone has * *** not changed (make timezone readonly??) */ $origCcShowDay = CcShowDaysQuery::create() ->filterByDbShowId($showId) ->filterByDbRepeatType(-1) ->filterByDbFirstShow($origLocalStartDateTime->format("Y-m-d")) ->filterByDbStartTime($origLocalStartDateTime->format("H:i:s")) ->delete(); /* * Set the new cc_show_day record * Associates it with the current show_id and sets it to non-repeating */ $this->setCcShowDays($showData); /* * We need to find the new show day rule we just created by passing * in the first show and start time in case multiple single * instances have been edited out of the repeating sequence. */ $showDay = CcShowDaysQuery::create() ->filterByDbShowId($showId) ->filterByDbRepeatType(-1) ->filterByDbFirstShow($showData["add_show_start_date"]) ->filterByDbStartTime($showData["add_show_start_time"].":00") ->findOne(); $ccShowInstance = $this->createNonRepeatingInstance($showDay, $this->getPopulateShowUntilDateTIme()); //update cc_schedule with the new instance id $con = Propel::getConnection(CcShowInstancesPeer::DATABASE_NAME); $selectCriteria = new Criteria(); $selectCriteria->add(CcSchedulePeer::INSTANCE_ID, $showData["add_show_instance_id"]); $updateCriteria = new Criteria(); $updateCriteria->add(CcSchedulePeer::INSTANCE_ID, $ccShowInstance->getDbId()); BasePeer::doUpdate($selectCriteria, $updateCriteria, $con); $ccShowInstance->updateDbTimeFilled($con); $ccShowInstance->updateScheduleStatus($con); //delete the edited instance from the repeating sequence $ccShowInstanceOrig->setDbModifiedInstance(true)->save(); $con->commit(); Application_Model_RabbitMq::PushSchedule(); } catch (Exception $e) { $con->rollback(); Logging::info("EXCEPTION: Show update failed."); Logging::info($e->getMessage()); } } /** * * If a user is editing a show we need to store the original timezone and * start time in case the show's timezone is changed and we are crossing * over DST */ private function storeOrigLocalShowInfo() { if ($this->ccShow->isRepeating()) { $this->origCcShowDay = $this->ccShow->getFirstRepeatingCcShowDay(); } else { $this->origCcShowDay = $this->ccShow->getFirstCcShowDay(); } $this->oldShowTimezone = $this->origCcShowDay->getDbTimezone(); $origStartTime = explode(":", $this->origCcShowDay->getDbStartTime()); $this->localShowStartHour = $origStartTime[0]; $this->localShowStartMin = $origStartTime[1]; } public function addUpdateShow($showData) { $service_user = new Application_Service_UserService(); $currentUser = $service_user->getCurrentUser(); $showData["add_show_duration"] = $this->formatShowDuration( $showData["add_show_duration"]); $con = Propel::getConnection(); $con->beginTransaction(); try { if (!$currentUser->isAdminOrPM()) { throw new Exception("Permission denied"); } //update ccShow $this->setCcShow($showData); $daysAdded = array(); if ($this->isUpdate) { $daysAdded = $this->delegateInstanceCleanup($showData); $this->storeOrigLocalShowInfo(); $this->deleteRebroadcastInstances(); $this->deleteCcShowHosts(); if ($this->isRebroadcast) { //delete entry in cc_show_rebroadcast $this->deleteCcShowRebroadcasts(); } } //update ccShowDays $this->setCcShowDays($showData); //update ccShowRebroadcasts $this->setCcShowRebroadcasts($showData); //update ccShowHosts $this->setCcShowHosts($showData); //create new ccShowInstances $this->delegateInstanceCreation($daysAdded); if ($this->isUpdate) { $this->adjustSchedule($showData); } $con->commit(); Application_Model_RabbitMq::PushSchedule(); } catch (Exception $e) { $con->rollback(); $this->isUpdate ? $action = "update" : $action = "creation"; Logging::info("EXCEPTION: Show ".$action." failed."); Logging::info($e->getMessage()); } } private function adjustSchedule($showData) { $con = Propel::getConnection(CcSchedulePeer::DATABASE_NAME); $ccShowInstances = CcShowInstancesQuery::create() ->filterByDbShowId($this->ccShow->getDbId()) ->find(); $this->updateScheduleStartEndTimes($showData); foreach ($ccShowInstances as $instance) { $instance->updateScheduleStatus($con); } } /** * * Receives a cc_show id and determines whether to create a * single show instance or repeating show instances */ public function delegateInstanceCreation($daysAdded=null, $end=null, $fillInstances=false) { $populateUntil = $this->getPopulateShowUntilDateTIme(); if (is_null($this->ccShow)) { $ccShowDays = $this->getShowDaysInRange($populateUntil, $end); } else { if ($this->ccShow->isRepeating()) { $ccShowDays = $this->ccShow->getRepeatingCcShowDays(); } else { $ccShowDays = $this->ccShow->getCcShowDayss(); } } if (!is_null($end)) { $populateUntil = $end; } /* In case the user is moving forward in the calendar and there are * linked shows in the schedule we need to keep track of each cc_show * so we know which shows need to be filled with content */ $ccShows = array(); foreach ($ccShowDays as $day) { $this->ccShow = $day->getCcShow(); $this->isRecorded = $this->ccShow->isRecorded(); $this->isRebroadcast = $this->ccShow->isRebroadcast(); if (!isset($ccShows[$day->getDbShowId()])) { $ccShows[$day->getDbShowId()] = $day->getccShow(); } switch ($day->getDbRepeatType()) { case NO_REPEAT: $this->createNonRepeatingInstance($day, $populateUntil); break; case REPEAT_WEEKLY: $this->createWeeklyRepeatInstances($day, $populateUntil, REPEAT_WEEKLY, new DateInterval("P7D"), $daysAdded); break; case REPEAT_BI_WEEKLY: $this->createWeeklyRepeatInstances($day, $populateUntil, REPEAT_BI_WEEKLY, new DateInterval("P14D"), $daysAdded); break; case REPEAT_TRI_WEEKLY: $this->createWeeklyRepeatInstances($day, $populateUntil, REPEAT_TRI_WEEKLY, new DateInterval("P21D"), $daysAdded); break; case REPEAT_QUAD_WEEKLY: $this->createWeeklyRepeatInstances($day, $populateUntil, REPEAT_QUAD_WEEKLY, new DateInterval("P28D"), $daysAdded); break; case REPEAT_MONTHLY_MONTHLY: $this->createMonthlyRepeatInstances($day, $populateUntil); break; case REPEAT_MONTHLY_WEEKLY: $this->createMonthlyRepeatInstances($day, $populateUntil); break; } } foreach ($ccShows as $ccShow) { if (($this->isUpdate || $fillInstances) && $ccShow->isLinked()) { Application_Service_SchedulerService::fillNewLinkedInstances($ccShow); } } if (isset($this->linkedShowContent)) { Application_Service_SchedulerService::fillPreservedLinkedShowContent( $this->ccShow, $this->linkedShowContent); } return $this->ccShow; } private function getShowDaysInRange($start, $end) { $endTimeString = $end->format("Y-m-d H:i:s"); if (!is_null($start)) { $startTimeString = $start->format("Y-m-d H:i:s"); } else { $today_timestamp = new DateTime("now", new DateTimeZone("UTC")); $startTimeString = $today_timestamp->format("Y-m-d H:i:s"); } $c = new Criteria(); $c->add(CcShowDaysPeer::FIRST_SHOW, $endTimeString, Criteria::LESS_THAN); $c->addAnd(CcShowDaysPeer::LAST_SHOW, $startTimeString, Criteria::GREATER_THAN); $c->addAnd(CcShowDaysPeer::REPEAT_TYPE, -1, Criteria::NOT_EQUAL); $c->addOr(CcShowDaysPeer::LAST_SHOW, null, Criteria::ISNULL); return CcShowDaysPeer::doSelect($c); } public static function formatShowDuration($duration) { $hPos = strpos($duration, 'h'); $mPos = strpos($duration, 'm'); $hValue = 0; $mValue = 0; if ($hPos !== false) { $hValue = trim(substr($duration, 0, $hPos)); } if ($mPos !== false) { $hPos = $hPos === false ? 0 : $hPos+1; $mValue = trim(substr($duration, $hPos, -1 )); } return $hValue.":".$mValue; } /** * * Deletes all the cc_show_days entries for a specific show * that is currently being edited. They will get recreated with * the new show day specs */ private function deleteCcShowDays() { CcShowDaysQuery::create()->filterByDbShowId($this->ccShow->getDbId())->delete(); } private function deleteRebroadcastInstances() { $sql = << :timestamp::TIMESTAMP AND show_id = :showId AND rebroadcast = 1; SQL; Application_Common_Database::prepareAndExecute( $sql, array( ':showId' => $this->ccShow->getDbId(), ':timestamp' => gmdate("Y-m-d H:i:s")), 'execute'); } /** * TODO: This function is messy. Needs refactoring * * When editing a show we may need to perform some actions to reflect the new specs: * - Delete some show instances * - Update duration * - Update start and end time * * @param $showData edit show form values in raw form * @param $isRecorded value computed from the edit show form * @param $repeatType value computed from the edit show form */ private function delegateInstanceCleanup($showData) { $showId = $this->ccShow->getDbId(); $daysAdded = array(); //CcShowDay object if ($this->ccShow->isRepeating()) { $currentShowDay = $this->ccShow->getFirstRepeatingCcShowDay(); } else { $currentShowDay = $this->ccShow->getFirstCcShowDay(); } //new end date in the show's timezone (from the select box) $endDateTime = $this->calculateEndDate($showData); //repeat option was toggled if ($showData['add_show_repeats'] != $currentShowDay->isRepeating()) { $this->deleteAllRepeatInstances($currentShowDay, $showId); //if repeat option was checked we need to treat the current show day //as a new show day so the repeat instances get created properly //in createWeeklyRepeatInstances() if ($showData['add_show_repeats']) { array_push($daysAdded, $currentShowDay->getDbDay()); } } if ($showData['add_show_repeats']) { $localShowStart = $currentShowDay->getLocalStartDateAndTime(); //if the start date changes, these are the repeat types //that require show instance deletion $deleteRepeatTypes = array(REPEAT_BI_WEEKLY, REPEAT_TRI_WEEKLY, REPEAT_QUAD_WEEKLY, REPEAT_MONTHLY_MONTHLY, REPEAT_MONTHLY_WEEKLY); if (in_array($this->repeatType, $deleteRepeatTypes) && $showData["add_show_start_date"] != $localShowStart->format("Y-m-d")) { //Start date has changed when repeat type is bi-weekly or monthly. //This screws up the repeating positions of show instances, so //we need to delete them (CC-2351) $this->deleteAllInstances($showId); } $currentRepeatType = $currentShowDay->getDbRepeatType(); //only delete instances if the show being edited was already repeating //and the repeat type changed if ($currentRepeatType != -1 && $this->repeatType != $currentRepeatType) { $this->deleteAllInstances($showId); // when repeating by day of the month (1st, 2nd, etc.) we do not store the repeat week days } elseif ($currentRepeatType != 2) { //repeat type is the same, check if the days of the week are the same $repeatingDaysChanged = false; if ($this->ccShow->isRepeating()) { $ccShowDays = $this->ccShow->getRepeatingCcShowDays(); } else { $ccShowDays = $this->ccShow->getCcShowDayss(); } $showDays = array(); foreach ($ccShowDays as $day) { $showDays[] = $day->getDbDay(); } if (count($showData['add_show_day_check']) == count($showDays)) { //same number of days checked, lets see if they are the same numbers $intersect = array_intersect($showData['add_show_day_check'], $showDays); if (count($intersect) != count($showData['add_show_day_check'])) { $repeatingDaysChanged = true; } } else { $repeatingDaysChanged = true; } if ($repeatingDaysChanged) { $daysRemoved = array_diff($showDays, $showData['add_show_day_check']); $newDays = array_diff($showData["add_show_day_check"], $showDays); foreach ($newDays as $newDay) { array_push($daysAdded, $newDay); } if (count($daysRemoved) > 0) { //delete repeating show instances for the repeating //days that were removed if ($this->ccShow->isLinked()) { $this->preserveLinkedShowContent(); } $this->deleteRemovedShowDayInstances($daysRemoved, $ccShowDays, $showId); } } if ($showData['add_show_start_date'] != $localShowStart->format("Y-m-d") || $showData['add_show_start_time'] != $localShowStart->format("H:i")) { //start date has been pushed forward so we need to delete //any instances of this show scheduled before the new start date if ($showData['add_show_start_date'] > $localShowStart->format("Y-m-d")) { $this->deleteInstancesBeforeDate($showData['add_show_start_date'], $showId); } } } //get the endate from the past for this show. //check if this is null if "no end" $currentShowEndDateTime = $this->getRepeatingEndDate(); if ($currentShowEndDateTime != $endDateTime) { $endDate = clone $endDateTime; $endDate->setTimezone(new DateTimeZone("UTC")); //show "No End" option was toggled //or the end date comes earlier if (is_null($currentShowEndDateTime) || ($endDateTime < $currentShowEndDateTime)) { //"No End" option was unchecked so we need to delete the //repeat instances that are scheduled after the new end date //OR //end date was pushed back so we have to delete any //instances of this show scheduled after the new end date $this->deleteInstancesFromDate($endDate->format("Y-m-d"), $showId); } } } return $daysAdded; } private function preserveLinkedShowContent() { /* Get show content from any linekd instance. It doesn't * matter which instance since content is the same in all. */ $ccShowInstance = $this->ccShow->getCcShowInstancess()->getFirst(); $ccSchedules = CcScheduleQuery::create() ->filterByDbInstanceId($ccShowInstance->getDbId()) ->find(); if (!$ccSchedules->isEmpty()) { $this->linkedShowContent = $ccSchedules; } } /* * returns a DateTime of the current show end date set to the timezone of the show. */ public function getRepeatingEndDate() { $sql = << $this->ccShow->getDbId() ), 'single'); $date = null; if ($query !== false && isset($query["last_show"])) { $date = new DateTime( $query["last_show"], new DateTimeZone($query["timezone"]) ); } return $date; } private function deleteInstancesFromDate($endDate, $showId) { $sql = <<= :endDate::DATE AND starts > :timestamp::TIMESTAMP AND show_id = :showId SQL; Application_Common_Database::prepareAndExecute($sql, array( ':endDate' => $endDate, ':timestamp' => gmdate("Y-m-d H:i:s"), ':showId' => $showId), 'execute'); } private function deleteInstancesBeforeDate($newStartDate, $showId) { $sql = << :timestamp::TIMESTAMP AND show_id = :showId SQL; Application_Common_Database::prepareAndExecute($sql, array( ":newStartDate" => $newStartDate, ":timestamp" => gmdate("Y-m-d H:i:s"), ":showId" => $showId), "execute"); } /** * * Enter description here ... * @param $daysRemoved array of days (days of the week) removed * (days of the week are represented numerically * 0=>sunday, 1=>monday, 2=>tuesday, etc.) * @param $showDays array of ccShowDays objects * @param $showId */ private function deleteRemovedShowDayInstances($daysRemoved, $showDays, $showId) { $daysRemovedUTC = array(); //convert the start day of the week to UTC foreach ($showDays as $showDay) { if (in_array($showDay->getDbDay(), $daysRemoved)) { $showDay->reload(); $startDay = $showDay->getUTCStartDateAndTime(); $daysRemovedUTC[] = $startDay->format('w'); } } foreach ($daysRemoved as $day) { //delete the cc_show_day entries as well CcShowDaysQuery::create() ->filterByDbShowId($showId) ->filterByDbDay($day) ->delete(); } $uncheckedDays = pg_escape_string(implode(",", $daysRemovedUTC)); $sql = << :timestamp::TIMESTAMP AND show_id = :showId SQL; Application_Common_Database::prepareAndExecute( $sql, array( ":timestamp" => gmdate("Y-m-d H:i:s"), ":showId" => $showId), "execute"); } public function deleteShow($instanceId, $singleInstance=false) { $service_user = new Application_Service_UserService(); $currentUser = $service_user->getCurrentUser(); $con = Propel::getConnection(); $con->beginTransaction(); try { if (!$currentUser->isAdminOrPM()) { throw new Exception("Permission denied"); } $ccShowInstance = CcShowInstancesQuery::create() ->findPk($instanceId); if (!$ccShowInstance) { throw new Exception("Could not find show instance"); } $showId = $ccShowInstance->getDbShowId(); if ($singleInstance) { $ccShowInstances = array($ccShowInstance); } else { $ccShowInstances = CcShowInstancesQuery::create() ->filterByDbShowId($showId) ->filterByDbStarts($ccShowInstance->getDbStarts(), Criteria::GREATER_EQUAL) ->find(); } if (gmdate("Y-m-d H:i:s") <= $ccShowInstance->getDbEnds()) { $this->deleteShowInstances($ccShowInstances, $showId); } else { throw new Exception("Cannot delete a show instance in the past"); } Application_Model_StoredFile::updatePastFilesIsScheduled(); Application_Model_RabbitMq::PushSchedule(); $con->commit(); return $showId; } catch (Exception $e) { $con->rollback(); Logging::info("Delete show instance failed"); Logging::info($e->getMessage()); return false; } } public function deleteShowInstances($ccShowInstances, $showId) { foreach ($ccShowInstances as $ccShowInstance) { $instanceId = $ccShowInstance->getDbId(); $ccShowInstance ->setDbModifiedInstance(true) ->save(); //delete the rebroadcasts of the removed recorded show if ($ccShowInstance->isRecorded()) { CcShowInstancesQuery::create() ->filterByDbOriginalShow($instanceId) ->delete(); } //delete all files scheduled in cc_schedules table CcScheduleQuery::create() ->filterByDbInstanceId($instanceId) ->delete(); } if ($this->checkToDeleteCcShow($showId)) { CcShowQuery::create() ->filterByDbId($showId) ->delete(); /* There is only one cc_show_instance if the user selects 'Delete This Instance' * There is more than one cc_show_instance if the user selects 'Delete This * Instance and All Following'. We only need to set the last_show value * when 'Delete This Instance and All Following' has been selected */ } elseif (count($ccShowInstances) > 1) { $this->setLastRepeatingShowDate($showId); } } private function setLastRepeatingShowDate($showId) { $ccShowInstances = CcShowInstancesQuery::create() ->filterByDbShowId($showId) ->filterByDbModifiedInstance(false) ->filterByDbRebroadcast(0) ->orderByDbStarts() ->find(); /* We need to update the last_show in cc_show_days so the instances * don't get recreated as the user moves forward in the calendar */ $lastShowDays = array(); //get the show's timezone $ccShow = CcShowQuery::create()->findPk($showId); if ($ccShow->isRepeating()) { $showTimezone = $ccShow->getFirstRepeatingCcShowDay()->getDbTimezone(); } else { $showTimezone = $ccShow->getFirstCcShowDay()->getDbTimezone(); } /* Creates an array where the key is the day of the week (monday, * tuesday, etc.) and the value is the last show date for each * day of the week. We will use this array to update the last_show * for each cc_show_days entry of a cc_show */ foreach ($ccShowInstances as $instance) { $instanceStartDT = $instance->getDbStarts(null); $instanceStartDT->setTimezone(new DateTimeZone($showTimezone)); $lastShowDays[$instanceStartDT->format("w")] = $instanceStartDT; } foreach ($lastShowDays as $dayOfWeek => $lastShowStartDT) { $ccShowDay = CcShowDaysQuery::create() ->filterByDbShowId($showId) ->filterByDbDay($dayOfWeek) ->filterByDbRepeatType(-1, Criteria::NOT_EQUAL) ->findOne(); if (isset($ccShowDay)) { $lastShowStartDT->setTimeZone(new DateTimeZone( $ccShowDay->getDbTimezone())); $lastShowEndDT = Application_Service_CalendarService::addDeltas( $lastShowStartDT, 1, 0); $ccShowDay ->setDbLastShow($lastShowEndDT->format("Y-m-d")) ->save(); } } // NOTE: Some cc_show_day records may not get updated because there may not be an instance // left on one of the repeating days so we have to find the entries where the last_show is // still null $showDays = CcShowDaysQuery::create() ->filterByDbShowId($showId) ->filterByDbRepeatType(0, Criteria::GREATER_EQUAL) ->filterByDbLastShow(null) ->find(); foreach ($showDays as $showDay) { $showDay->setDbLastShow($showDay->getDbFirstShow())->save(); } } private function checkToDeleteCcShow($showId) { // check if there are any non deleted show instances remaining. $ccShowInstances = CcShowInstancesQuery::create() ->filterByDbShowId($showId) ->filterByDbModifiedInstance(false) ->filterByDbRebroadcast(0) ->orderByDbStarts() ->find(); if ($ccShowInstances->isEmpty()) { return true; } return false; } private function deleteAllInstances($showId) { $sql = << :timestamp::TIMESTAMP AND show_id = :showId SQL; Application_Common_Database::prepareAndExecute( $sql, array( ':timestamp' => gmdate("Y-m-d H:i:s"), ':showId' => $showId), 'execute'); } private function deleteAllRepeatInstances($currentShowDay, $showId) { $firstShow = $currentShowDay->getUTCStartDateAndTime(); $sql = << :timestamp::TIMESTAMP AND show_id = :showId AND starts != :firstShow SQL; Application_Common_Database::prepareAndExecute( $sql, array( ':timestamp' => gmdate("Y-m-d H:i:s"), ':showId' => $showId, ':firstShow' => $firstShow->format("Y-m-d H:i:s")), 'execute'); } /** * * Determines what the show end date should be based on * the form data * * @param $showData add/edit show form data * @return DateTime object in user's local timezone */ private function calculateEndDate($showData) { //if no end return null if ($showData['add_show_no_end']) { $endDate = null; } //if the show is repeating & ends, then return the end date elseif ($showData['add_show_repeats']) { $endDate = new DateTime( $showData['add_show_end_date'], new DateTimeZone($showData["add_show_timezone"]) ); $endDate->add(new DateInterval("P1D")); } //the show doesn't repeat, so add one day to the start date. else { $endDate = new DateTime( $showData['add_show_start_date'], new DateTimeZone($showData["add_show_timezone"]) ); $endDate->add(new DateInterval("P1D")); } return $endDate; } private function updateScheduleStartEndTimes($showData) { $showId = $this->ccShow->getDbId(); //DateTime in show's local time $newStartDateTime = new DateTime($showData["add_show_start_date"]." ". $showData["add_show_start_time"], new DateTimeZone($showData["add_show_timezone"])); $diff = $this->calculateShowStartDiff($newStartDateTime, $this->origCcShowDay->getLocalStartDateAndTime()); $ccShowInstances = $this->ccShow->getFutureCcShowInstancess(); $instanceIds = array(); foreach ($ccShowInstances as $ccShowInstance) { array_push($instanceIds, $ccShowInstance->getDbId()); } Application_Service_SchedulerService::updateScheduleStartTime($instanceIds, $diff); } /** * * Returns the difference in seconds between a show's new and * old start time * * @param $newStartDateTime DateTime object * @param $oldStartDateTime DateTime object */ private function calculateShowStartDiff($newStartDateTime, $oldStartDateTime) { return $newStartDateTime->getTimestamp() - $oldStartDateTime->getTimestamp(); } /** * * Updates the start and end time for cc_show_instances * * @param $showData edit show form data */ private function updateInstanceStartEndTime($diff) { $sql = << :timestamp::TIMESTAMP SQL; Application_Common_Database::prepareAndExecute($sql, array(':diff1' => $diff, ':diff2' => $diff, ':showId' => $this->ccShow->getDbId(), ':timestamp' => gmdate("Y-m-d H:i:s")), 'execute'); } /** * * Enter description here ... * @param ccShowDays $showDay * @param DateTime $showStartDate user's local time * @param $instanceId */ private function createRebroadcastInstances($showDay, $showStartDate, $instanceId) { $currentUtcTimestamp = gmdate("Y-m-d H:i:s"); $showId = $this->ccShow->getDbId(); $sql = "SELECT * FROM cc_show_rebroadcast WHERE show_id=:show_id"; $rebroadcasts = Application_Common_Database::prepareAndExecute($sql, array( ':show_id' => $showId ), 'all'); foreach ($rebroadcasts as $rebroadcast) { $days = explode(" ", $rebroadcast["day_offset"]); $time = explode(":", $rebroadcast["start_time"]); $offset = array("days"=>$days[0], "hours"=>$time[0], "mins"=>$time[1]); list($utcStartDateTime, $utcEndDateTime) = $this->createUTCStartEndDateTime( $showStartDate, $showDay->getDbDuration(), $offset); if ($utcStartDateTime->format("Y-m-d H:i:s") > $currentUtcTimestamp) { $ccShowInstance = new CcShowInstances(); $ccShowInstance->setDbShowId($showId); $ccShowInstance->setDbStarts($utcStartDateTime); $ccShowInstance->setDbEnds($utcEndDateTime); $ccShowInstance->setDbRecord(0); $ccShowInstance->setDbRebroadcast(1); $ccShowInstance->setDbOriginalShow($instanceId); $ccShowInstance->save(); } } } /** * * Sets a single cc_show_instance table row * @param $showDay * @param $populateUntil */ private function createNonRepeatingInstance($showDay, $populateUntil) { //DateTime object $start = $showDay->getLocalStartDateAndTime(); list($utcStartDateTime, $utcEndDateTime) = $this->createUTCStartEndDateTime( $start, $showDay->getDbDuration()); if ($utcStartDateTime->getTimestamp() < $populateUntil->getTimestamp()) { $ccShowInstance = new CcShowInstances(); if ($this->isUpdate) { //use original cc_show_day object to get the current cc_show_instance $origStartDateTime = new DateTime( $this->origCcShowDay->getDbFirstShow()." ".$this->origCcShowDay->getDbStartTime(), new DateTimeZone($this->origCcShowDay->getDbTimezone()) ); $origStartDateTime->setTimezone(new DateTimeZone("UTC")); $ccShowInstance = $this->getInstance($origStartDateTime); } $ccShowInstance->setDbShowId($this->ccShow->getDbId()); $ccShowInstance->setDbStarts($utcStartDateTime); $ccShowInstance->setDbEnds($utcEndDateTime); $ccShowInstance->setDbRecord($showDay->getDbRecord()); $ccShowInstance->save(); if ($this->isRebroadcast) { $this->createRebroadcastInstances($showDay, $start, $ccShowInstance->getDbId()); } } return $ccShowInstance; } /** * * Sets multiple cc_show_instances table rows * @param unknown_type $showDay * @param unknown_type $populateUntil * @param unknown_type $repeatInterval * @param unknown_type $isRebroadcast */ private function createWeeklyRepeatInstances($showDay, $populateUntil, $repeatType, $repeatInterval, $daysAdded=null) { $show_id = $showDay->getDbShowId(); $first_show = $showDay->getDbFirstShow(); //non-UTC $last_show = $showDay->getDbLastShow(); //non-UTC $duration = $showDay->getDbDuration(); $day = $showDay->getDbDay(); $record = $showDay->getDbRecord(); $timezone = $showDay->getDbTimezone(); //DateTime local $start = $this->getNextRepeatingPopulateStartDateTime($showDay); if (is_null($repeatInterval)&& $repeatType == REPEAT_MONTHLY_WEEKLY) { $repeatInterval = $this->getMonthlyWeeklyRepeatInterval($start, $timezone); } //DatePeriod in user's local time $datePeriod = $this->getDatePeriod($start, $timezone, $last_show, $repeatInterval, $populateUntil); if ($last_show) { $utcLastShowDateTime = new DateTime($last_show, new DateTimeZone($timezone)); $utcLastShowDateTime->setTimezone(new DateTimeZone("UTC")); } else { $utcLastShowDateTime = null; } $previousDate = clone $start; foreach ($datePeriod as $date) { list($utcStartDateTime, $utcEndDateTime) = $this->createUTCStartEndDateTime( $date, $duration); /* * Make sure start date is less than populate until date AND * last show date is null OR start date is less than last show date */ if ($utcStartDateTime <= $populateUntil && ( is_null($utcLastShowDateTime) || $utcStartDateTime < $utcLastShowDateTime) ) { $lastCreatedShow = clone $utcStartDateTime; /* There may not always be an instance when editing a show * This will be the case when we are adding a new show day to * a repeating show */ if ($this->isUpdate) { if ($this->hasInstance($utcStartDateTime)) { $ccShowInstance = $this->getInstance($utcStartDateTime); $newInstance = false; $updateScheduleStatus = true; } else { $newInstance = true; $ccShowInstance = new CcShowInstances(); $updateScheduleStatus = false; } } else { $newInstance = true; $ccShowInstance = new CcShowInstances(); $updateScheduleStatus = false; } /* When editing the start/end time of a repeating show, we don't want to * change shows that are in the past so we check the end time. */ if ($newInstance || $ccShowInstance->getDbEnds() > gmdate("Y-m-d H:i:s")) { $ccShowInstance->setDbShowId($show_id); $ccShowInstance->setDbStarts($utcStartDateTime); $ccShowInstance->setDbEnds($utcEndDateTime); $ccShowInstance->setDbRecord($record); $ccShowInstance->save(); } if ($this->isRebroadcast) { $this->createRebroadcastInstances($showDay, $date, $ccShowInstance->getDbId()); } } $previousDate = clone $date; } /* We need to set the next populate date for repeat shows so when a user * moves forward in the calendar we know when to start generating new * show instances. * If $utcStartDateTime is not set then we know zero new shows were * created and we shouldn't update the next populate date. */ if (isset($lastCreatedShow)) { /* Set UTC to local time before setting the next repeat date. If we don't * the next repeat date might be scheduled for the following day * THIS MUST BE IN THE TIMEZONE THE SHOW WAS CREATED IN */ $lastCreatedShow->setTimezone(new DateTimeZone($timezone)); $nextDate = $lastCreatedShow->add($repeatInterval); $this->setNextRepeatingShowDate($nextDate->format("Y-m-d"), $day, $show_id); } } private function createMonthlyRepeatInstances($showDay, $populateUntil) { $show_id = $showDay->getDbShowId(); $first_show = $showDay->getDbFirstShow(); //non-UTC $last_show = $showDay->getDbLastShow(); //non-UTC $duration = $showDay->getDbDuration(); $day = $showDay->getDbDay(); $record = $showDay->getDbRecord(); $timezone = $showDay->getDbTimezone(); //DateTime local $start = $this->getNextRepeatingPopulateStartDateTime($showDay); if (isset($last_show)) { $end = new DateTime($last_show, new DateTimeZone($timezone)); } else { $end = $populateUntil; } // We will only need this if the repeat type is MONTHLY_WEEKLY list($weekNumberOfMonth, $dayOfWeek) = $this->getMonthlyWeeklyRepeatInterval( new DateTime($first_show, new DateTimeZone($timezone))); $this->repeatType = $showDay->getDbRepeatType(); if ($last_show) { $utcLastShowDateTime = new DateTime($last_show, new DateTimeZone($timezone)); $utcLastShowDateTime->setTimezone(new DateTimeZone("UTC")); } else { $utcLastShowDateTime = null; } while ($start->getTimestamp() < $end->getTimestamp()) { list($utcStartDateTime, $utcEndDateTime) = $this->createUTCStartEndDateTime( $start, $duration); /* * Make sure start date is less than populate until date AND * last show date is null OR start date is less than last show date */ if ($utcStartDateTime->getTimestamp() <= $populateUntil->getTimestamp() && ( is_null($utcLastShowDateTime) || $utcStartDateTime->getTimestamp() < $utcLastShowDateTime->getTimestamp()) ) { $lastCreatedShow = clone $utcStartDateTime; /* There may not always be an instance when editing a show * This will be the case when we are adding a new show day to * a repeating show */ if ($this->isUpdate && $this->hasInstance($utcStartDateTime)) { $ccShowInstance = $this->getInstance($utcStartDateTime); $newInstance = false; $updateScheduleStatus = true; } else { $newInstance = true; $ccShowInstance = new CcShowInstances(); $updateScheduleStatus = false; } /* When editing the start/end time of a repeating show, we don't want to * change shows that started in the past. So check the start time. */ if ($newInstance || $ccShowInstance->getDbStarts() > gmdate("Y-m-d H:i:s")) { $ccShowInstance->setDbShowId($show_id); $ccShowInstance->setDbStarts($utcStartDateTime); $ccShowInstance->setDbEnds($utcEndDateTime); $ccShowInstance->setDbRecord($record); $ccShowInstance->save(); } if ($this->isRebroadcast) { $this->createRebroadcastInstances($showDay, $start, $ccShowInstance->getDbId()); } } if ($this->repeatType == REPEAT_MONTHLY_WEEKLY) { $monthlyWeeklyStart = new DateTime($utcStartDateTime->format("Y-m"), new DateTimeZone("UTC")); $monthlyWeeklyStart->add(new DateInterval("P1M")); $start = $this->getNextMonthlyWeeklyRepeatDate( $monthlyWeeklyStart, $timezone, $showDay->getDbStartTime(), $weekNumberOfMonth, $dayOfWeek); } else { $start = $this->getNextMonthlyMonthlyRepeatDate( $start, $timezone, $showDay->getDbStartTime()); } } $this->setNextRepeatingShowDate($start->format("Y-m-d"), $day, $show_id); } /** * * i.e. last thursday of each month * i.e. second monday of each month * * @param string $showStart * @param string $timezone user's local timezone */ private function getMonthlyWeeklyRepeatInterval($showStart) { $start = clone $showStart; $dayOfMonth = $start->format("j"); $dayOfWeek = $start->format("l"); $yearAndMonth = $start->format("Y-m"); $firstDayOfWeek = strtotime($dayOfWeek." ".$yearAndMonth); // if $dayOfWeek is Friday, what number of the month does // the first Friday fall on $numberOfFirstDayOfWeek = date("j", $firstDayOfWeek); $weekCount = 0; while ($dayOfMonth >= $numberOfFirstDayOfWeek) { $weekCount++; $dayOfMonth -= 7; } switch ($weekCount) { case 1: $weekNumberOfMonth = "first"; break; case 2: $weekNumberOfMonth = "second"; break; case 3: $weekNumberOfMonth = "third"; break; case 4: $weekNumberOfMonth = "fourth"; break; case 5: $weekNumberOfMonth = "fifth"; break; } /* return DateInterval::createFromDateString( $weekNumberOfMonth." ".$dayOfWeek." of next month"); */ return array($weekNumberOfMonth, $dayOfWeek); } /** * * Enter description here ... * @param $start user's local time */ private function getNextMonthlyMonthlyRepeatDate($start, $timezone, $startTime) { $dt = new DateTime($start->format("Y-m"), new DateTimeZone($timezone)); do { $dt->add(new DateInterval("P1M")); } while (!checkdate($dt->format("m"), $start->format("d"), $dt->format("Y"))); $dt->setDate($dt->format("Y"), $dt->format("m"), $start->format("d")); $startTime = explode(":", $startTime); $hours = isset($startTime[0]) ? $startTime[0] : "00"; $minutes = isset($startTime[1]) ? $startTime[1] : "00"; $seconds = isset($startTime[2]) ? $startTime[2] : "00"; $dt->setTime($hours, $minutes, $seconds); return $dt; } private function getNextMonthlyWeeklyRepeatDate( $start, $timezone, $startTime, $weekNumberOfMonth, $dayOfWeek) { $dt = new DateTime($start->format("Y-m"), new DateTimeZone($timezone)); $tempDT = clone $dt; $fifthWeekExists = false; do { $nextDT = date_create($weekNumberOfMonth." ".$dayOfWeek. " of ".$tempDT->format("F")." ".$tempDT->format("Y")); $nextDT->setTimezone(new DateTimeZone($timezone)); /* We have to check if the next date is in the same month in case * the repeat day is in the fifth week of the month. * If it's not in the same month we know that a fifth week of * the next month does not exist. So let's skip it. */ if ($tempDT->format("F") == $nextDT->format("F")) { $fifthWeekExists = true; } $tempDT->add(new DateInterval("P1M")); } while (!$fifthWeekExists); $dt = $nextDT; $startTime = explode(":", $startTime); $hours = isset($startTime[0]) ? $startTime[0] : "00"; $minutes = isset($startTime[1]) ? $startTime[1] : "00"; $seconds = isset($startTime[2]) ? $startTime[2] : "00"; $dt->setTime($hours, $minutes, $seconds); return $dt; } private function getNextRepeatingPopulateStartDateTime($showDay) { $nextPopDate = $showDay->getDbNextPopDate(); $startTime = $showDay->getDbStartTime(); if (isset($nextPopDate)) { return new DateTime($nextPopDate." ".$startTime, new DateTimeZone($showDay->getDbTimezone())); } else { return new DateTime($showDay->getDbFirstShow()." ".$startTime, new DateTimeZone($showDay->getDbTimezone())); } } /** * * Create a DatePeriod object in the user's local time * It will get converted to UTC before the show instance gets created */ private function getDatePeriod($start, $timezone, $lastShow, $repeatInterval, $populateUntil) { if (isset($lastShow)) { $endDatePeriod = new DateTime($lastShow, new DateTimeZone($timezone)); } else { $endDatePeriod = $populateUntil; } return new DatePeriod($start, $repeatInterval, $endDatePeriod); } private function hasInstance($starts) { return $this->getInstance($starts) ? true : false; } /** * * Attempts to retrieve the cc_show_instance belonging to a cc_show * that starts at $starts. We have to pass in the start * time in case the show is repeating * * Returns the instance if one was found (one that is not a recording * and modified instance is false (has not been deleted)) */ private function getInstance($starts) { $temp = clone($starts); $temp->setTimezone(new DateTimeZone($this->oldShowTimezone)); $temp->setTime($this->localShowStartHour, $this->localShowStartMin); $temp->setTimezone(new DateTimeZone("UTC")); $ccShowInstance = CcShowInstancesQuery::create() ->filterByDbStarts($temp->format("Y-m-d H:i:s"), Criteria::EQUAL) ->filterByDbShowId($this->ccShow->getDbId(), Criteria::EQUAL) //->filterByDbModifiedInstance(false, Criteria::EQUAL) ->filterByDbRebroadcast(0, Criteria::EQUAL) ->limit(1) ->find(); if ($ccShowInstance->isEmpty()) { return false; } else { return $ccShowInstance[0]; } } private function hasCcShowDay($repeatType, $day) { return $this->getCcShowDay($repeatType, $day) ? true : false; } private function getCcShowDay($repeatType, $day) { $ccShowDay = CcShowDaysQuery::create() ->filterByDbShowId($this->ccShow->getDbId()) ->filterByDbDay($day) ->filterByDbRepeatType($repeatType) ->limit(1) ->find(); if ($ccShowDay->isEmpty()) { return false; } else { return $ccShowDay[0]; } } /** * * Sets the fields for a cc_show table row * @param $ccShow * @param $showData */ private function setCcShow($showData) { if (!$this->isUpdate) { $ccShow = new CcShow(); } else { $ccShow = CcShowQuery::create()->findPk($showData["add_show_id"]); } $ccShow->setDbName($showData['add_show_name']); $ccShow->setDbDescription($showData['add_show_description']); $ccShow->setDbUrl($showData['add_show_url']); $ccShow->setDbGenre($showData['add_show_genre']); $ccShow->setDbColor($showData['add_show_color']); $ccShow->setDbBackgroundColor($showData['add_show_background_color']); $ccShow->setDbLiveStreamUsingAirtimeAuth($showData['cb_airtime_auth'] == 1); $ccShow->setDbLiveStreamUsingCustomAuth($showData['cb_custom_auth'] == 1); $ccShow->setDbLiveStreamUser($showData['custom_username']); $ccShow->setDbLiveStreamPass($showData['custom_password']); // Once a show is unlinked it cannot be linked again if ($ccShow->getDbLinked() && !$showData["add_show_linked"]) { $ccShow->setDbIsLinkable(false); } $ccShow->setDbLinked($showData["add_show_linked"]); $ccShow->save(); $this->ccShow = $ccShow; } /** * * Sets the fields for a cc_show_days table row * @param $showData * @param $showId * @param $userId * @param $repeatType * @param $isRecorded * @param $showDay ccShowDay object we are setting values on */ private function setCcShowDays($showData) { $showId = $this->ccShow->getDbId(); $startDateTime = new DateTime( $showData['add_show_start_date']." ".$showData['add_show_start_time'], new DateTimeZone($showData['add_show_timezone']) ); $endDateTime = $this->calculateEndDate($showData); if (!is_null($endDateTime)) { $endDate = $endDateTime->format("Y-m-d"); } else { $endDate = null; } //Our calculated start DOW must be used for non repeating since a day has not been selected. //For all repeating shows, only the selected days of the week will be repeated on. $startDow = $startDateTime->format("w"); if (!$showData['add_show_repeats']) { $showData['add_show_day_check'] = array($startDow); } // Don't set day for monthly repeat type, it's invalid if ($showData['add_show_repeats'] && $showData['add_show_repeat_type'] == 2) { if ($this->isUpdate) { $showDay = CcShowDaysQuery::create() ->filterByDbShowId($showId) ->filterByDbRepeatType($showData['add_show_repeat_type']) ->findOne(); } else { $showDay = new CcShowDays(); } $showDay->setDbFirstShow($startDateTime->format("Y-m-d")); $showDay->setDbLastShow($endDate); $showDay->setDbStartTime($startDateTime->format("H:i:s")); $showDay->setDbTimezone($showData['add_show_timezone']); $showDay->setDbDuration($showData['add_show_duration']); $showDay->setDbRepeatType($this->repeatType); $showDay->setDbShowId($showId); $showDay->setDbRecord($this->isRecorded); //in case we are editing a show we need to set this to the first show //so when editing, the date period iterator will start from the beginning $showDay->setDbNextPopDate($startDateTime->format("Y-m-d")); $showDay->save(); } else { foreach ($showData['add_show_day_check'] as $day) { $daysAdd=0; $startDateTimeClone = clone $startDateTime; if ($startDow !== $day) { if ($startDow > $day) $daysAdd = 6 - $startDow + 1 + $day; else $daysAdd = $day - $startDow; $startDateTimeClone->add(new DateInterval("P".$daysAdd."D")); } if (is_null($endDate) || $startDateTimeClone->getTimestamp() <= $endDateTime->getTimestamp()) { if ($this->isUpdate) { $showDay = CcShowDaysQuery::create() ->filterByDbShowId($showId) ->filterByDbRepeatType($this->repeatType) ->filterByDbDay($day) ->findOne(); if (!$showDay) { //if no show day object was found it is because a new //repeating day of the week was added $showDay = new CcShowDays(); } } else { $showDay = new CcShowDays(); } $showDay->setDbFirstShow($startDateTimeClone->format("Y-m-d")); $showDay->setDbLastShow($endDate); $showDay->setDbStartTime($startDateTimeClone->format("H:i")); $showDay->setDbTimezone($showData['add_show_timezone']); $showDay->setDbDuration($showData['add_show_duration']); $showDay->setDbDay($day); $showDay->setDbRepeatType($this->repeatType); $showDay->setDbShowId($showId); $showDay->setDbRecord($this->isRecorded); //in case we are editing a show we need to set this to the first show //so when editing, the date period iterator will start from the beginning $showDay->setDbNextPopDate($startDateTimeClone->format("Y-m-d")); $showDay->save(); } } } } /** * * Deletes all the cc_show_rebroadcast entries for a specific show * that is currently being edited. They will get recreated with * the new show specs */ private function deleteCcShowRebroadcasts() { CcShowRebroadcastQuery::create()->filterByDbShowId($this->ccShow->getDbId())->delete(); } /** * * Sets the fields for a cc_show_rebroadcast table row * @param $showData * @param $showId * @param $repeatType * @param $isRecorded */ private function setCcShowRebroadcasts($showData) { $showId = $this->ccShow->getDbId(); if (($this->isRecorded && $showData['add_show_rebroadcast']) && ($this->repeatType != -1)) { for ($i = 1; $i <= MAX_REBROADCAST_DATES; $i++) { if ($showData['add_show_rebroadcast_date_'.$i]) { $showRebroad = new CcShowRebroadcast(); $showRebroad->setDbDayOffset($showData['add_show_rebroadcast_date_'.$i]); $showRebroad->setDbStartTime($showData['add_show_rebroadcast_time_'.$i]); $showRebroad->setDbShowId($showId); $showRebroad->save(); } } } elseif ($this->isRecorded && $showData['add_show_rebroadcast'] && ($this->repeatType == -1)) { for ($i = 1; $i <= MAX_REBROADCAST_DATES; $i++) { if ($showData['add_show_rebroadcast_date_absolute_'.$i]) { $rebroadcastDate = new DateTime($showData["add_show_rebroadcast_date_absolute_$i"]); $startDate = new DateTime($showData['add_show_start_date']); $offsetDays = $startDate->diff($rebroadcastDate); $showRebroad = new CcShowRebroadcast(); $showRebroad->setDbDayOffset($offsetDays->format("%a days")); $showRebroad->setDbStartTime($showData['add_show_rebroadcast_time_absolute_'.$i]); $showRebroad->setDbShowId($showId); $showRebroad->save(); } } } } /** * * Deletes all the cc_show_hosts entries for a specific show * that is currently being edited. They will get recreated with * the new show specs */ private function deleteCcShowHosts() { CcShowHostsQuery::create()->filterByDbShow($this->ccShow->getDbId())->delete(); } /** * * Sets the fields for a cc_show_hosts table row * @param $showData * @param $showId */ private function setCcShowHosts($showData) { if (is_array($showData['add_show_hosts'])) { foreach ($showData['add_show_hosts'] as $host) { $showHost = new CcShowHosts(); $showHost->setDbShow($this->ccShow->getDbId()); $showHost->setDbHost($host); $showHost->save(); } } } /** * * Gets the date and time shows (particularly repeating shows) * can be populated until. * * @return DateTime object */ private static function getPopulateShowUntilDateTIme() { $populateUntil = Application_Model_Preference::GetShowsPopulatedUntil(); if (is_null($populateUntil)) { $populateUntil = new DateTime("now", new DateTimeZone('UTC')); Application_Model_Preference::SetShowsPopulatedUntil($populateUntil); } return $populateUntil; } /** * * Enter description here ... * @param DateTime $showStart user's local time * @param string $duration time interval (h)h:(m)m(:ss) * @param string $timezone "Europe/Prague" * @param array $offset (days, hours, mins) used for rebroadcast shows * * @return array of 2 DateTime objects, start/end time of the show in UTC */ private function createUTCStartEndDateTime($showStart, $duration, $offset=null) { $startDateTime = clone $showStart; $timezone = $startDateTime->getTimezone(); if (isset($offset)) { //$offset["hours"] and $offset["mins"] represents the start time //of a rebroadcast show $startDateTime = new DateTime($startDateTime->format("Y-m-d")." ". $offset["hours"].":".$offset["mins"], $timezone); $startDateTime->add(new DateInterval("P{$offset["days"]}D")); } $endDateTime = clone $startDateTime; $duration = explode(":", $duration); list($hours, $mins) = array_slice($duration, 0, 2); $endDateTime->add(new DateInterval("PT{$hours}H{$mins}M")); $startDateTime->setTimezone(new DateTimeZone('UTC')); $endDateTime->setTimezone(new DateTimeZone('UTC')); return array($startDateTime, $endDateTime); } /** * * Show instances for repeating shows only get created up * until what is visible on the calendar. We need to set the * date for when the next repeating show instance should be created * as the user browses the calendar further. * * @param $nextDate * @param $showId * @param $day */ private function setNextRepeatingShowDate($nextDate, $day, $showId) { $nextInfo = explode(" ", $nextDate); $repeatInfo = CcShowDaysQuery::create() ->filterByDbShowId($showId) ->filterByDbDay($day) ->filterByDbRepeatType(-1, Criteria::NOT_EQUAL) ->findOne(); $repeatInfo->setDbNextPopDate($nextInfo[0]) ->save(); } }