ccShow = CcShowQuery::create()->findPk($showId); } $this->instanceId = $instanceId; } /** * * @return array of show forms */ public function createShowForms() { $formWhat = new Application_Form_AddShowWhat(); $formAutoPlaylist = new Application_Form_AddShowAutoPlaylist(); $formWho = new Application_Form_AddShowWho(); $formWhen = new Application_Form_AddShowWhen(); $formRepeats = new Application_Form_AddShowRepeats(); $formStyle = new Application_Form_AddShowStyle(); $formLive = new Application_Form_AddShowLiveStream(); $formRecord = new Application_Form_AddShowRR(); $formAbsoluteRebroadcast = new Application_Form_AddShowAbsoluteRebroadcastDates(); $formRebroadcast = new Application_Form_AddShowRebroadcastDates(); $formWhat->removeDecorator('DtDdWrapper'); $formAutoPlaylist->removeDecorator('DtDdWrapper'); $formWho->removeDecorator('DtDdWrapper'); $formWhen->removeDecorator('DtDdWrapper'); $formRepeats->removeDecorator('DtDdWrapper'); $formStyle->removeDecorator('DtDdWrapper'); $formLive->removeDecorator('DtDdWrapper'); $formRecord->removeDecorator('DtDdWrapper'); $formAbsoluteRebroadcast->removeDecorator('DtDdWrapper'); $formRebroadcast->removeDecorator('DtDdWrapper'); $forms = array(); $forms["what"] = $formWhat; $forms["autoplaylist"] = $formAutoPlaylist; $forms["who"] = $formWho; $forms["when"] = $formWhen; $forms["repeats"] = $formRepeats; $forms["style"] = $formStyle; $forms["live"] = $formLive; $forms["record"] = $formRecord; $forms["abs_rebroadcast"] = $formAbsoluteRebroadcast; $forms["rebroadcast"] = $formRebroadcast; return $forms; } /** * * Popluates the what, autoplaylist, when, and repeat forms * with default values */ public function populateNewShowForms($formWhat, $formWhen, $formRepeats) { $formWhat->populate( array('add_show_id' => '-1', 'add_show_instance_id' => '-1')); $formWhen->populate( array('add_show_start_date' => date("Y-m-d"), 'add_show_start_time' => '00:00', 'add_show_end_date_no_repeate' => date("Y-m-d"), 'add_show_end_time' => '01:00', 'add_show_duration' => '01h 00m')); $formRepeats->populate(array('add_show_end_date' => date("Y-m-d"))); } public function delegateShowInstanceFormPopulation($forms) { $this->populateFormWhat($forms["what"]); $this->populateInstanceFormWhen($forms["when"]); $this->populateFormWho($forms["who"]); $this->populateFormLive($forms["live"]); $this->populateFormStyle($forms["style"]); /* Only the field on the 'when' form will get updated so we should * make all other forms disabled or readonly * * 'what' needs to be readonly because zendform will not validate * if they are disabled * * All other forms can be disabled because we do not update those values * when the user edits a repeating instance */ $forms["what"]->makeReadonly(); $forms["what"]->enableInstanceDesc(); $forms["autoplaylist"]->disable(); $forms["repeats"]->disable(); $forms["who"]->disable(); $forms["style"]->disable(); // Hide the show logo fields when users are editing a single instance $forms["style"]->hideShowLogo(); $forms["live"]->disable(); $forms["record"]->disable(); $forms["rebroadcast"]->disable(); $forms["abs_rebroadcast"]->disable(); } /** * * Delegates populating each show form with the appropriate * data of the current show being edited * * @param $forms */ public function delegateShowFormPopulation($forms) { $this->populateFormWhat($forms["what"]); //local show start DT $this->populateFormAutoPlaylist($forms["autoplaylist"]); $showStart = $this->populateFormWhen($forms["when"]); $this->populateFormRepeats($forms["repeats"], $showStart); $this->populateFormWho($forms["who"]); $this->populateFormStyle($forms["style"]); $this->populateFormLive($forms["live"]); $this->populateFormRecord($forms["record"]); $this->populateFormRebroadcastRelative($forms["rebroadcast"]); $this->populateFormRebroadcastAbsolute($forms["abs_rebroadcast"]); } private function populateFormWhat($form) { $ccShowInstance = CcShowInstancesQuery::create()->findPk($this->instanceId); $form->populate( array( 'add_show_instance_id' => $this->instanceId, 'add_show_id' => $this->ccShow->getDbId(), 'add_show_name' => $this->ccShow->getDbName(), 'add_show_url' => $this->ccShow->getDbUrl(), 'add_show_genre' => $this->ccShow->getDbGenre(), 'add_show_description' => $this->ccShow->getDbDescription(), 'add_show_instance_description' => $ccShowInstance->getDbDescription(), )); } private function populateFormAutoPlaylist($form) { $ccShowInstance = CcShowInstancesQuery::create()->findPk($this->instanceId); $form->populate( array( 'add_show_has_autoplaylist' => $this->ccShow->getDbHasAutoPlaylist() ? 1 : 0, 'add_show_autoplaylist_id' => $this->ccShow->getDbAutoPlaylistId() )); } private function populateFormWhen($form) { if ($this->ccShow->isRepeating()) { $ccShowDay = $this->ccShow->getFirstRepeatingCcShowDay(); } else { $ccShowDay = $this->ccShow->getFirstCcShowDay(); } $showStart = $ccShowDay->getLocalStartDateAndTime(); $showEnd = $ccShowDay->getLocalEndDateAndTime(); //check if the first show is in the past if ($ccShowDay->isShowStartInPast()) { //for a non-repeating show, we should never allow user to change the start time. //for a repeating show, we should allow because the form works as repeating template form if (!$ccShowDay->isRepeating()) { $form->disableStartDateAndTime(); } else { $showStartAndEnd = $this->getNextFutureRepeatShowTime(); if (!is_null($showStartAndEnd)) { $showStart = $showStartAndEnd["starts"]; $showEnd = $showStartAndEnd["ends"]; } if ($this->hasShowStarted($showStart)) { $form->disableStartDateAndTime(); } } } //Disable starting a show 'now' when editing an existing show. $form->getElement('add_show_start_now')->setAttrib('disable', array('now')); $form->populate( array( 'add_show_start_date' => $showStart->format("Y-m-d"), 'add_show_start_time' => $showStart->format("H:i"), 'add_show_end_date_no_repeat' => $showEnd->format("Y-m-d"), 'add_show_end_time' => $showEnd->format("H:i"), 'add_show_duration' => $ccShowDay->formatDuration(true), 'add_show_timezone' => $ccShowDay->getDbTimezone(), 'add_show_repeats' => $ccShowDay->isRepeating() ? 1 : 0)); return $showStart; } public function getNextFutureRepeatShowTime() { $ccShowInstance = CcShowInstancesQuery::create() ->filterByDbShowId($this->ccShow->getDbId()) ->filterByDbModifiedInstance(false) ->filterByDbStarts(gmdate("Y-m-d H:i:s"), Criteria::GREATER_THAN) ->orderByDbStarts() ->findOne(); if (!$ccShowInstance) { return null; } $starts = new DateTime($ccShowInstance->getDbStarts(), new DateTimeZone("UTC")); $ends = new DateTime($ccShowInstance->getDbEnds(), new DateTimeZone("UTC")); $showTimezone = $this->ccShow->getFirstCcShowDay()->getDbTimezone(); $starts->setTimezone(new DateTimeZone($showTimezone)); $ends->setTimezone(new DateTimeZone($showTimezone)); return array("starts" => $starts, "ends" => $ends); } private function populateInstanceFormWhen($form) { $ccShowInstance = CcShowInstancesQuery::create()->findPk($this->instanceId); //get timezone the show is created in $timezone = $ccShowInstance->getCcShow()->getFirstCcShowDay()->getDbTimezone(); //$timezone = new DateTimeZone(Application_Model_Preference::GetDefaultTimezone()); //DateTime object in UTC $showStart = $ccShowInstance->getDbStarts(null); $showStart->setTimezone(new DateTimeZone($timezone)); $showEnd = $ccShowInstance->getDbEnds(null); $showEnd->setTimezone(new DateTimeZone($timezone)); //if the show has started, do not allow editing on the start time if ($showStart->getTimestamp() <= time()) { $form->disableStartDateAndTime(); } //Disable starting a show 'now' when editing an existing show. $form->getElement('add_show_start_now')->setAttrib('disable', array('now')); $form->populate( array( 'add_show_start_now' => 'future', 'add_show_start_date' => $showStart->format("Y-m-d"), 'add_show_start_time' => $showStart->format("H:i"), 'add_show_end_date_no_repeat' => $showEnd->format("Y-m-d"), 'add_show_end_time' => $showEnd->format("H:i"), 'add_show_duration' => $this->calculateDuration( $showStart->format(DEFAULT_TIMESTAMP_FORMAT), $showEnd->format(DEFAULT_TIMESTAMP_FORMAT), $timezone), 'add_show_timezone' => $timezone, 'add_show_repeats' => 0)); $form->getElement('add_show_repeats')->setOptions(array("disabled" => true)); } /** * * Enter description here ... * @param $form * @param DateTime $nextFutureShowStart user's local timezone */ private function populateFormRepeats($form, $nextFutureShowStart) { if ($this->ccShow->isRepeating()) { $ccShowDays = $this->ccShow->getRepeatingCcShowDays(); } else { $ccShowDays = $this->ccShow->getCcShowDayss(); } $days = array(); foreach ($ccShowDays as $ccShowDay) { $showStart = $ccShowDay->getLocalStartDateAndTime(); array_push($days, $showStart->format("w")); } $service_show = new Application_Service_ShowService($this->ccShow->getDbId()); $repeatEndDate = $service_show->getRepeatingEndDate(); //end dates are stored non-inclusively so we need to //subtract one day if (!is_null($repeatEndDate)) { $repeatEndDate->sub(new DateInterval("P1D")); } //default monthly repeat type $monthlyRepeatType = 2; $repeatType = $ccShowDays[0]->getDbRepeatType(); if ($repeatType == REPEAT_MONTHLY_WEEKLY) { $monthlyRepeatType = $repeatType; //a repeat type of 2 means the show is repeating monthly $repeatType = 2; } elseif ($repeatType == REPEAT_MONTHLY_MONTHLY) { $monthlyRepeatType = $repeatType; } $form->populate( array( 'add_show_linked' => $this->ccShow->getDbLinked(), 'add_show_repeat_type' => $repeatType, 'add_show_day_check' => $days, 'add_show_end_date' => (!is_null($repeatEndDate)) ? $repeatEndDate->format("Y-m-d"):null, 'add_show_no_end' => (is_null($repeatEndDate)), 'add_show_monthly_repeat_type' => $monthlyRepeatType)); if (!$this->ccShow->isLinkable() || $this->ccShow->isRecorded()) { $form->getElement('add_show_linked')->setOptions(array('disabled' => true)); } /* Because live editing of a linked show is disabled, we will make * the linking option readonly if the current show is being edited. We * dont' want the user to suddenly not be able to edit the current show * * Readonly does not work with checkboxes but we can't disable it * because the value won't get posted. In add-show.js we stop the * onclick event from firing by returning false */ if ($this->hasShowStarted($nextFutureShowStart)) { $form->getElement('add_show_linked')->setAttrib('readonly', 'readonly'); } } private function populateFormWho($form) { $ccShowHosts = $this->ccShow->getCcShowHostss(); $hosts = array(); foreach ($ccShowHosts as $ccShowHost) { array_push($hosts, $ccShowHost->getDbHost()); } $form->populate(array('add_show_hosts' => $hosts)); } private function populateFormStyle($form) { $src = $this->ccShow->getDbImagePath() ? $this->imagePathToDataUri($this->ccShow->getDbImagePath()) : ''; $form->populate( array( 'add_show_background_color' => $this->ccShow->getDbBackgroundColor(), 'add_show_color' => $this->ccShow->getDbColor(), 'add_show_logo_current' => $src)); } /** * Convert a static image from disk to a base64 data URI * * @param unknown $path * - the path to the image on the disk * @return string * - the data URI representation of the image */ private function imagePathToDataUri($path) { $imageData = null; $bytesRead = 0; try { ob_start(); header("Content-type: image/*"); $bytesRead = @readfile($path); $imageData = base64_encode(ob_get_contents()); ob_end_clean(); if ($bytesRead === FALSE) { $imageData = null; } } catch (Exception $e) { Logging::error("Failed to read image: " . $path); $imageData = null; } // return the data URI - data:{mime};base64,{data} return ($imageData === null || $imageData === '') ? '' : 'data: '.mime_content_type($path).';base64,'.$imageData; } private function populateFormLive($form) { $form->populate( array( "cb_airtime_auth" => $this->ccShow->getDbLiveStreamUsingAirtimeAuth(), "cb_custom_auth" => $this->ccShow->getDbLiveStreamUsingCustomAuth(), "custom_username" => $this->ccShow->getDbLiveStreamUser(), "custom_password" => $this->ccShow->getDbLiveStreamPass())); } private function populateFormRecord($form) { $form->populate( array( 'add_show_record' => $this->ccShow->isRecorded(), 'add_show_rebroadcast' => $this->ccShow->isRebroadcast())); $form->getElement('add_show_record')->setOptions(array('disabled' => true)); } private function populateFormRebroadcastRelative($form) { $relativeRebroadcasts = $this->ccShow->getRebroadcastsRelative(); $formValues = array(); $i = 1; foreach ($relativeRebroadcasts as $rr) { $formValues["add_show_rebroadcast_date_$i"] = $rr->getDbDayOffset(); $formValues["add_show_rebroadcast_time_$i"] = Application_Common_DateHelper::removeSecondsFromTime( $rr->getDbStartTime()); $i++; } $form->populate($formValues); } private function populateFormRebroadcastAbsolute($form) { $absolutRebroadcasts = $this->ccShow->getRebroadcastsAbsolute(); $timezone = $this->ccShow->getFirstCcShowDay()->getDbTimezone(); $formValues = array(); $i = 1; foreach ($absolutRebroadcasts as $ar) { //convert dates to user's local time $start = new DateTime($ar->getDbStarts(), new DateTimeZone("UTC")); $start->setTimezone(new DateTimeZone($timezone)); $formValues["add_show_rebroadcast_date_absolute_$i"] = $start->format("Y-m-d"); $formValues["add_show_rebroadcast_time_absolute_$i"] = $start->format("H:i"); $i++; } $form->populate($formValues); } /** * * Enter description here ... * @param DateTime $showStart user's local time */ private function hasShowStarted($p_showStart) { $showStart = clone $p_showStart; $showStart->setTimeZone(new DateTimeZone("UTC")); if ($showStart->format("Y-m-d H:i:s") < gmdate("Y-m-d H:i:s")) { return true; } else { return false; } } /** * Before we send the form data in for validation, there * are a few fields we may need to adjust first * * @param $formData */ public function preEditShowValidationCheck($formData) { // If the start date or time were disabled, don't validate them $validateStartDate = $formData['start_date_disabled'] === "false"; $validateStartTime = $formData['start_time_disabled'] === "false"; //CcShowDays object of the show currently being edited $currentShowDay = $this->ccShow->getFirstCcShowDay(); //DateTime object $dt = $currentShowDay->getLocalStartDateAndTime(); $formData['add_show_record'] = $currentShowDay->getDbRecord(); //if the show is repeating, set the start date to the next //repeating instance in the future $originalShowStartDateTime = $this->getCurrentOrNextInstanceStartTime(); if (!$originalShowStartDateTime) { $originalShowStartDateTime = $dt; } return array($formData, $validateStartDate, $validateStartTime, $originalShowStartDateTime); } /** * * Returns a DateTime object, in the user's local time, * of the current or next show instance start time * * Returns null if there is no next future repeating show instance */ public function getCurrentOrNextInstanceStartTime() { $ccShowInstance = CcShowInstancesQuery::create() ->filterByDbShowId($this->ccShow->getDbId()) ->filterByDbModifiedInstance(false) ->filterByDbStarts(gmdate("Y-m-d H:i:s"), Criteria::GREATER_EQUAL) ->orderByDbStarts() ->findOne(); if (!$ccShowInstance) { return null; } $starts = new DateTime($ccShowInstance->getDbStarts(), new DateTimeZone("UTC")); $showTimezone = $this->ccShow->getFirstCcShowDay()->getDbTimezone(); $starts->setTimezone(new DateTimeZone($showTimezone)); return $starts; } /** * * Validates show forms * * @return boolean */ public function validateShowForms($forms, $formData, $validateStartDate = true, $originalStartDate=null, $editShow=false, $instanceId=null) { $what = $forms["what"]->isValid($formData); $autoplaylist = $forms["autoplaylist"]->isValid($formData); $live = $forms["live"]->isValid($formData); $record = $forms["record"]->isValid($formData); $who = $forms["who"]->isValid($formData); /* * hack to prevent validating the file upload field since it * isn't passed into $data */ $upload = $forms["style"]->getElement("add_show_logo"); $forms["style"]->removeElement("add_show_logo"); $style = $forms["style"]->isValid($formData); // re-add the upload element $forms["style"]->addElement($upload); $when = $forms["when"]->isWhenFormValid($formData, $validateStartDate, $originalStartDate, $editShow, $instanceId); $repeats = true; if ($formData["add_show_repeats"]) { $repeats = $forms["repeats"]->isValid($formData); /* * Make the absolute rebroadcast form valid since * it does not get used if the show is repeating */ $forms["abs_rebroadcast"]->reset(); $absRebroadcast = true; $rebroadcast = true; if (isset($formData["add_show_rebroadcast"]) && $formData["add_show_rebroadcast"]) { $formData["add_show_duration"] = Application_Service_ShowService::formatShowDuration( $formData["add_show_duration"]); $rebroadcast = $forms["rebroadcast"]->isValid($formData); } } else { /* * Make the rebroadcast form valid since it does * not get used if the show is not repeating. * Instead, we use the absolute rebroadcast form */ $forms["rebroadcast"]->reset(); $rebroadcast = true; $absRebroadcast = true; if (isset($formData["add_show_rebroadcast"]) && $formData["add_show_rebroadcast"]) { $formData["add_show_duration"] = Application_Service_ShowService::formatShowDuration( $formData["add_show_duration"]); $absRebroadcast = $forms["abs_rebroadcast"]->isValid($formData); } } return ($what && $autoplaylist && $live && $record && $who && $style && $when && $repeats && $absRebroadcast && $rebroadcast); } public function calculateDuration($start, $end, $timezone) { try { $tz = new DateTimeZone($timezone); $startDateTime = new DateTime($start, $tz); $endDateTime = new DateTime($end, $tz); $duration = $startDateTime->diff($endDateTime); $day = intval($duration->format('%d')); if ($day > 0) { $hour = intval($duration->format('%h')); $min = intval($duration->format('%i')); $hour += $day * 24; $hour = min($hour, 99); $sign = $duration->format('%r'); return sprintf('%s%02dh %02dm', $sign, $hour, $min); } else { return $duration->format('%r%Hh %Im'); } } catch (Exception $e) { Logging::info($e->getMessage()); return "Invalid Date"; } } /** * When the timezone is changed in add-show form this function * applies the new timezone to the start and end time * * @param $date String * @param $time String * @param $timezone String */ public static function localizeDateTime($date, $time, $newTimezone, $oldTimezone) { $dt = new DateTime($date." ".$time, new DateTimeZone($oldTimezone)); $dt->setTimeZone(new DateTimeZone($newTimezone)); return array( "date" => $dt->format("Y-m-d"), "time" => $dt->format("H:i") ); } }