예제 #1
0
 public function moveShow($deltaDay, $deltaMin)
 {
     if ($this->getShow()->isRepeating()) {
         return "Can't drag and drop repeating shows";
     }
     $today_timestamp = time();
     $startsDateTime = new DateTime($this->getShowInstanceStart(), new DateTimeZone("UTC"));
     $endsDateTime = new DateTime($this->getShowInstanceEnd(), new DateTimeZone("UTC"));
     if ($today_timestamp > $startsDateTime->getTimestamp()) {
         return "Can't move a past show";
     }
     //the user is moving the show on the calendar from the perspective of local time.
     //incase a show is moved across a time change border offsets should be added to the localtime
     //stamp and then converted back to UTC to avoid show time changes!
     $startsDateTime->setTimezone(new DateTimeZone(date_default_timezone_get()));
     $endsDateTime->setTimezone(new DateTimeZone(date_default_timezone_get()));
     $newStartsDateTime = self::addDeltas($startsDateTime, $deltaDay, $deltaMin);
     $newEndsDateTime = self::addDeltas($endsDateTime, $deltaDay, $deltaMin);
     //convert our new starts/ends to UTC.
     $newStartsDateTime->setTimezone(new DateTimeZone("UTC"));
     $newEndsDateTime->setTimezone(new DateTimeZone("UTC"));
     if ($today_timestamp > $newStartsDateTime->getTimestamp()) {
         return "Can't move show into past";
     }
     //check if show is overlapping
     $overlapping = Application_Model_Schedule::checkOverlappingShows($newStartsDateTime, $newEndsDateTime, true, $this->getShowInstanceId());
     if ($overlapping) {
         return "Cannot schedule overlapping shows";
     }
     if ($this->isRecorded()) {
         //rebroadcasts should start at max 1 hour after a recorded show has ended.
         $minRebroadcastStart = self::addDeltas($newEndsDateTime, 0, 60);
         //check if we are moving a recorded show less than 1 hour before any of its own rebroadcasts.
         $rebroadcasts = CcShowInstancesQuery::create()->filterByDbOriginalShow($this->_instanceId)->filterByDbStarts($minRebroadcastStart->format('Y-m-d H:i:s'), Criteria::LESS_THAN)->find();
         if (count($rebroadcasts) > 0) {
             return "Can't move a recorded show less than 1 hour before its rebroadcasts.";
         }
     }
     if ($this->isRebroadcast()) {
         try {
             $recordedShow = new Application_Model_ShowInstance($this->_showInstance->getDbOriginalShow());
         } catch (Exception $e) {
             $this->_showInstance->delete();
             return "Show was deleted because recorded show does not exist!";
         }
         $recordEndDateTime = new DateTime($recordedShow->getShowInstanceEnd(), new DateTimeZone("UTC"));
         $newRecordEndDateTime = self::addDeltas($recordEndDateTime, 0, 60);
         if ($newStartsDateTime->getTimestamp() < $newRecordEndDateTime->getTimestamp()) {
             return "Must wait 1 hour to rebroadcast.";
         }
     }
     $this->setShowStart($newStartsDateTime);
     $this->setShowEnd($newEndsDateTime);
     $this->correctScheduleStartTimes();
     $show = new Application_Model_Show($this->getShowId());
     if (!$show->isRepeating() && is_null($this->isRebroadcast())) {
         $show->setShowFirstShow($newStartsDateTime);
         $show->setShowLastShow($newEndsDateTime);
     }
     Application_Model_RabbitMq::PushSchedule();
 }
예제 #2
0
 private function validateShowMove($deltaDay, $deltaMin)
 {
     if (!$this->currentUser->isAdminOrPM()) {
         throw new Exception(_("Permission denied"));
     }
     if ($this->ccShow->isRepeating()) {
         throw new Exception(_("Can't drag and drop repeating shows"));
     }
     $today_timestamp = time();
     $startsDateTime = $this->ccShowInstance->getDbStarts(null);
     $endsDateTime = $this->ccShowInstance->getDbEnds(null);
     if ($today_timestamp > $startsDateTime->getTimestamp()) {
         throw new Exception(_("Can't move a past show"));
     }
     //the user is moving the show on the calendar from the perspective of local time.
     //incase a show is moved across a time change border offsets should be added to the localtime
     //stamp and then converted back to UTC to avoid show time changes!
     $showTimezone = $this->ccShow->getFirstCcShowDay()->getDbTimezone();
     $startsDateTime->setTimezone(new DateTimeZone($showTimezone));
     $endsDateTime->setTimezone(new DateTimeZone($showTimezone));
     $duration = $startsDateTime->diff($endsDateTime);
     $newStartsDateTime = self::addDeltas($startsDateTime, $deltaDay, $deltaMin);
     /* WARNING: Do not separately add a time delta to the start and end times because
                    that does not preserve the duration across a DST time change.
                    For example, 5am - 3 hours = 3am when DST occurs at 2am.
                             BUT, 6am - 3 hours = 3am also!
                              So when a DST change occurs, adding the deltas like this
                              separately does not conserve the duration of a show.
                    Since that's what we want (otherwise we'll get a zero length show), 
                    we calculate the show duration FIRST, then we just add that on
                    to the start time to calculate the end time. 
                    This is a safer approach.
                    The key lesson here is that in general: duration != end - start
                    ... so be careful!
        */
     //$newEndsDateTime = self::addDeltas($endsDateTime, $deltaDay, $deltaMin); <--- Wrong, don't do it.
     $newEndsDateTime = clone $newStartsDateTime;
     $newEndsDateTime = $newEndsDateTime->add($duration);
     //convert our new starts/ends to UTC.
     $newStartsDateTime->setTimezone(new DateTimeZone("UTC"));
     $newEndsDateTime->setTimezone(new DateTimeZone("UTC"));
     if ($today_timestamp > $newStartsDateTime->getTimestamp()) {
         throw new Exception(_("Can't move show into past"));
     }
     //check if show is overlapping
     $overlapping = Application_Model_Schedule::checkOverlappingShows($newStartsDateTime, $newEndsDateTime, true, $this->ccShowInstance->getDbId());
     if ($overlapping) {
         throw new Exception(_("Cannot schedule overlapping shows"));
     }
     if ($this->ccShow->isRecorded()) {
         //rebroadcasts should start at max 1 hour after a recorded show has ended.
         $minRebroadcastStart = self::addDeltas($newEndsDateTime, 0, 60);
         //check if we are moving a recorded show less than 1 hour before any of its own rebroadcasts.
         $rebroadcasts = CcShowInstancesQuery::create()->filterByDbOriginalShow($this->ccShow->getDbId())->filterByDbStarts($minRebroadcastStart->format('Y-m-d H:i:s'), Criteria::LESS_THAN)->find();
         if (count($rebroadcasts) > 0) {
             throw new Exception(_("Can't move a recorded show less than 1 hour before its rebroadcasts."));
         }
     }
     if ($this->ccShow->isRebroadcast()) {
         $recordedShow = CcShowInstancesQuery::create()->filterByCcShow($this->ccShowInstance->getDbOriginalShow())->findOne();
         if (is_null($recordedShow)) {
             $this->ccShowInstance->delete();
             throw new Exception(_("Show was deleted because recorded show does not exist!"));
         }
         $recordEndDateTime = new DateTime($recordedShow->getDbEnds(), new DateTimeZone("UTC"));
         $newRecordEndDateTime = self::addDeltas($recordEndDateTime, 0, 60);
         if ($newStartsDateTime->getTimestamp() < $newRecordEndDateTime->getTimestamp()) {
             throw new Exception(_("Must wait 1 hour to rebroadcast."));
         }
     }
     return array($newStartsDateTime, $newEndsDateTime);
 }
예제 #3
0
 public function resizeShow($deltaDay, $deltaMin, $instanceId)
 {
     $con = Propel::getConnection();
     if ($deltaDay > 0) {
         return _("Shows can have a max length of 24 hours.");
     }
     $utcTimezone = new DateTimeZone("UTC");
     $nowDateTime = new DateTime("now", $utcTimezone);
     //keep track of cc_show_day entries we need to update
     $showDayIds = array();
     /*
      * If the resized show is an edited instance of a repeating show we
      * need to treat it as a separate show and not resize the other instances
      * 
      * Also, if the resized show has edited instances, we need to exclude
      * those from the resize
      */
     $ccShow = CcShowQuery::create()->findPk($this->_showId);
     if ($ccShow->isRepeating()) {
         //convert instance to local timezone
         $ccShowInstance = CcShowInstancesQuery::create()->findPk($instanceId);
         $startsDT = $ccShowInstance->getDbStarts(null);
         $timezone = $ccShow->getFirstCcShowDay()->getDbTimezone();
         $startsDT->setTimezone(new DateTimeZone($timezone));
         /* Get cc_show_day for the current instance. If we don't find one
          * we know it is a repeat interval of one of cc_show_days first
          * show and we can assume we aren't resizing a modified instance
          */
         $ccShowDay = CcShowDaysQuery::create()->filterByDbFirstShow($startsDT->format("Y-m-d"))->filterByDbStartTime($startsDT->format("H:i:s"))->filterByDbShowId($this->_showId)->findOne();
         /* Check if this cc_show_day rule is non-repeating. If it is, then
          * we know this instance was edited out of the repeating sequence
          */
         if (!$ccShowDay || $ccShowDay->getDbRepeatType() != -1) {
             $ccShowDays = $ccShow->getRepeatingCcShowDays();
             foreach ($ccShowDays as $day) {
                 array_push($showDayIds, $day->getDbId());
             }
             $excludeIds = $ccShow->getEditedRepeatingInstanceIds();
             //exlcude edited instances from resize
             $showInstances = CcShowInstancesQuery::create()->filterByDbShowId($this->_showId)->filterByDbModifiedInstance(false)->filterByDbId($excludeIds, criteria::NOT_IN)->find();
         } elseif ($ccShowDay->getDbRepeatType() == -1) {
             array_push($showDayIds, $ccShowDay->getDbId());
             //treat edited instance as separate show for resize
             $showInstances = CcShowInstancesQuery::create()->filterByDbId($instanceId)->find();
         }
     } else {
         $ccShowDays = $ccShow->getCcShowDayss();
         foreach ($ccShowDays as $day) {
             array_push($showDayIds, $day->getDbId());
         }
         $showInstances = CcShowInstancesQuery::create()->filterByDbShowId($this->_showId)->find($con);
     }
     /* Check two things:
        1. If the show being resized and any of its repeats end in the past
        2. If the show being resized and any of its repeats overlap
           with other scheduled shows */
     //keep track of instance ids for update show instances start/end times
     $instanceIds = array();
     $displayTimezone = new DateTimeZone(Application_Model_Preference::GetUserTimezone());
     //check if new show time overlaps with any other shows
     foreach ($showInstances as $si) {
         array_push($instanceIds, $si->getDbId());
         $startsDateTime = $si->getDbStarts(null);
         $endsDateTime = $si->getDbEnds(null);
         /* The user is moving the show on the calendar from the perspective
            of local time.  * incase a show is moved across a time change
            border offsets should be added to the local * timestamp and
            then converted back to UTC to avoid show time changes */
         $startsDateTime->setTimezone($displayTimezone);
         $endsDateTime->setTimezone($displayTimezone);
         //$newStartsDateTime = Application_Model_ShowInstance::addDeltas($startsDateTime, $deltaDay, $deltaMin);
         $newEndsDateTime = Application_Model_ShowInstance::addDeltas($endsDateTime, $deltaDay, $deltaMin);
         if ($newEndsDateTime->getTimestamp() < $nowDateTime->getTimestamp()) {
             return _("End date/time cannot be in the past");
         }
         //convert our new starts/ends to UTC.
         //$newStartsDateTime->setTimezone($utc);
         $newEndsDateTime->setTimezone($utcTimezone);
         $overlapping = Application_Model_Schedule::checkOverlappingShows($startsDateTime, $newEndsDateTime, true, $si->getDbId());
         if ($overlapping) {
             return _("Cannot schedule overlapping shows.\nNote: Resizing a repeating show " . "affects all of its repeats.");
         }
     }
     $hours = $deltaMin / 60;
     $hours = $hours > 0 ? floor($hours) : ceil($hours);
     $mins = abs($deltaMin % 60);
     $sql_gen = "UPDATE cc_show_instances " . "SET ends = (ends + :deltaDay1::INTERVAL + :interval1::INTERVAL) " . "WHERE (id IN (" . implode($instanceIds, ",") . ") " . "AND ends > :current_timestamp1) " . "AND ((ends + :deltaDay2::INTERVAL + :interval2::INTERVAL - starts) <= interval '24:00')";
     Application_Common_Database::prepareAndExecute($sql_gen, array(':deltaDay1' => "{$deltaDay} days", ':interval1' => "{$hours}:{$mins}", ':current_timestamp1' => $nowDateTime->format("Y-m-d H:i:s"), ':deltaDay2' => "{$deltaDay} days", ':interval2' => "{$hours}:{$mins}"), "execute");
     $sql_gen = "UPDATE cc_show_days " . "SET duration = (CAST(duration AS interval) + :deltaDay3::INTERVAL + :interval3::INTERVAL) " . "WHERE id IN (" . implode($showDayIds, ",") . ") " . "AND ((CAST(duration AS interval) + :deltaDay4::INTERVAL + :interval4::INTERVAL) <= interval '24:00')";
     Application_Common_Database::prepareAndExecute($sql_gen, array(':deltaDay3' => "{$deltaDay} days", ':interval3' => "{$hours}:{$mins}", ':deltaDay4' => "{$deltaDay} days", ':interval4' => "{$hours}:{$mins}"), "execute");
     $con = Propel::getConnection(CcSchedulePeer::DATABASE_NAME);
     $con->beginTransaction();
     try {
         //update the status flag in cc_schedule.
         /* Since we didn't use a propel object when updating
          * cc_show_instances table we need to clear the instances
          * so the correct information is retrieved from the db
          */
         CcShowInstancesPeer::clearInstancePool();
         $instances = CcShowInstancesQuery::create()->filterByDbEnds($nowDateTime->format("Y-m-d H:i:s"), Criteria::GREATER_THAN)->filterByDbId($instanceIds, Criteria::IN)->find($con);
         foreach ($instances as $instance) {
             $instance->updateScheduleStatus($con);
         }
         $con->commit();
     } catch (Exception $e) {
         $con->rollback();
         Logging::info("Couldn't update schedule status.");
         Logging::info($e->getMessage());
     }
     Application_Model_RabbitMq::PushSchedule();
 }
예제 #4
0
 public function checkRebroadcastDates($repeatShowStart, $formData, $hours, $minutes, $showEdit = false)
 {
     $overlapping = false;
     for ($i = 1; $i <= 10; $i++) {
         if (empty($formData["add_show_rebroadcast_date_" . $i])) {
             break;
         }
         $rebroadcastShowStart = clone $repeatShowStart;
         /* formData is in local time so we need to set the
          * show start back to local time
          */
         $rebroadcastShowStart->setTimezone(new DateTimeZone($formData["add_show_timezone"]));
         $rebroadcastWhenDays = explode(" ", $formData["add_show_rebroadcast_date_" . $i]);
         $rebroadcastWhenTime = explode(":", $formData["add_show_rebroadcast_time_" . $i]);
         $rebroadcastShowStart->add(new DateInterval("P" . $rebroadcastWhenDays[0] . "D"));
         $rebroadcastShowStart->setTime($rebroadcastWhenTime[0], $rebroadcastWhenTime[1]);
         $rebroadcastShowStart->setTimezone(new DateTimeZone('UTC'));
         $rebroadcastShowEnd = clone $rebroadcastShowStart;
         $rebroadcastShowEnd->add(new DateInterval("PT" . $hours . "H" . $minutes . "M"));
         if ($showEdit) {
             $overlapping = Application_Model_Schedule::checkOverlappingShows($rebroadcastShowStart, $rebroadcastShowEnd, true, null, $formData['add_show_id']);
         } else {
             $overlapping = Application_Model_Schedule::checkOverlappingShows($rebroadcastShowStart, $rebroadcastShowEnd);
         }
         if ($overlapping) {
             break;
         }
     }
     return $overlapping;
 }
예제 #5
0
파일: Show.php 프로젝트: nidzix/Airtime
    public function resizeShow($deltaDay, $deltaMin)
    {
        $con = Propel::getConnection();
        if ($deltaDay > 0) {
            return "Shows can have a max length of 24 hours.";
        }
        $utc = new DateTimeZone("UTC");
        $nowDateTime = new DateTime("now", $utc);
        $showInstances = CcShowInstancesQuery::create()->filterByDbShowId($this->_showId)->find($con);
        /* Check two things:
           1. If the show being resized and any of its repeats end in the past 
           2. If the show being resized and any of its repeats overlap
              with other scheduled shows */
        foreach ($showInstances as $si) {
            $startsDateTime = new DateTime($si->getDbStarts(), new DateTimeZone("UTC"));
            $endsDateTime = new DateTime($si->getDbEnds(), new DateTimeZone("UTC"));
            /* The user is moving the show on the calendar from the perspective
               of local time.  * incase a show is moved across a time change
               border offsets should be added to the local * timestamp and
               then converted back to UTC to avoid show time changes */
            $startsDateTime->setTimezone(new DateTimeZone(date_default_timezone_get()));
            $endsDateTime->setTimezone(new DateTimeZone(date_default_timezone_get()));
            $newStartsDateTime = Application_Model_ShowInstance::addDeltas($startsDateTime, $deltaDay, $deltaMin);
            $newEndsDateTime = Application_Model_ShowInstance::addDeltas($endsDateTime, $deltaDay, $deltaMin);
            if ($newEndsDateTime->getTimestamp() < $nowDateTime->getTimestamp()) {
                return "End date/time cannot be in the past";
            }
            //convert our new starts/ends to UTC.
            $newStartsDateTime->setTimezone($utc);
            $newEndsDateTime->setTimezone($utc);
            $overlapping = Application_Model_Schedule::checkOverlappingShows($newStartsDateTime, $newEndsDateTime, true, $si->getDbId());
            if ($overlapping) {
                return "Cannot schedule overlapping shows.\nNote: Resizing a repeating show " . "affects all of its repeats.";
            }
        }
        $hours = $deltaMin / 60;
        $hours = $hours > 0 ? floor($hours) : ceil($hours);
        $mins = abs($deltaMin % 60);
        //current timesamp in UTC.
        $current_timestamp = gmdate("Y-m-d H:i:s");
        $sql_gen = <<<SQL
UPDATE cc_show_instances
SET ends = (ends + :deltaDay1::INTERVAL + :interval1::INTERVAL)
WHERE (show_id = :show_id1
       AND ends > :current_timestamp1)
  AND ((ends + :deltaDay2::INTERVAL + :interval2::INTERVAL - starts) <= interval '24:00')
SQL;
        Application_Common_Database::prepareAndExecute($sql_gen, array(':deltaDay1' => "{$deltaDay} days", ':interval1' => "{$hours}:{$mins}", ':show_id1' => $this->_showId, ':current_timestamp1' => $current_timestamp, ':deltaDay2' => "{$deltaDay} days", ':interval2' => "{$hours}:{$mins}"), "execute");
        $sql_gen = <<<SQL
UPDATE cc_show_days
SET duration = (CAST(duration AS interval) + :deltaDay3::INTERVAL + :interval3::INTERVAL)
WHERE show_id = :show_id2
  AND ((CAST(duration AS interval) + :deltaDay4::INTERVAL + :interval4::INTERVAL) <= interval '24:00')
SQL;
        Application_Common_Database::prepareAndExecute($sql_gen, array(':deltaDay3' => "{$deltaDay} days", ':interval3' => "{$hours}:{$mins}", ':show_id2' => $this->_showId, ':deltaDay4' => "{$deltaDay} days", ':interval4' => "{$hours}:{$mins}"), "execute");
        $con = Propel::getConnection(CcSchedulePeer::DATABASE_NAME);
        $con->beginTransaction();
        try {
            //update the status flag in cc_schedule.
            $instances = CcShowInstancesQuery::create()->filterByDbEnds($current_timestamp, Criteria::GREATER_THAN)->filterByDbShowId($this->_showId)->find($con);
            foreach ($instances as $instance) {
                $instance->updateScheduleStatus($con);
            }
            $con->commit();
        } catch (Exception $e) {
            $con->rollback();
            Logging::info("Couldn't update schedule status.");
            Logging::info($e->getMessage());
        }
        Application_Model_RabbitMq::PushSchedule();
    }