diff --git a/CREDITS b/CREDITS index 42e3215a7..52b8b9b18 100644 --- a/CREDITS +++ b/CREDITS @@ -1,11 +1,32 @@ ======= CREDITS ======= +Version 2.0.1 +------------- +Naomi Aro (naomi.aro@sourcefabric.org) + Role: Software Developer + +Martin Konecny (martin.konecny@sourcefabric.org) + Role: Software Developer + +James Moon (james.moon@sourcefabric.org) + Role: Software Developer + +Daniel Franklin (daniel.franklin@sourcefabric.org) + Role: Software Developer + +Ofir Gal (ofir.gal@sourcefabric.org) + Role: QA + +Daniel James (daniel.james@sourcefabric.org) + Role: Documentor & QA + +Paul Baranowski (paul.baranowski@sourcefabric.org) + Role: Project Manager + Version 2.0.0 ------------- -Welcome to Yuchen Wang! - Naomi Aro (naomi.aro@sourcefabric.org) Role: Software Developer diff --git a/airtime_mvc/application/Bootstrap.php b/airtime_mvc/application/Bootstrap.php index 6e17898b6..d4ca032f5 100644 --- a/airtime_mvc/application/Bootstrap.php +++ b/airtime_mvc/application/Bootstrap.php @@ -56,6 +56,7 @@ class Bootstrap extends Zend_Application_Bootstrap_Bootstrap $view = $this->getResource('view'); $baseUrl = Zend_Controller_Front::getInstance()->getBaseUrl(); + $baseDir = dirname($_SERVER['SCRIPT_FILENAME']); $view->headLink()->appendStylesheet($baseUrl.'/css/redmond/jquery-ui-1.8.8.custom.css?'.$CC_CONFIG['airtime_version']); $view->headLink()->appendStylesheet($baseUrl.'/css/pro_dropdown_3.css?'.$CC_CONFIG['airtime_version']); @@ -69,6 +70,7 @@ class Bootstrap extends Zend_Application_Bootstrap_Bootstrap $view = $this->getResource('view'); $baseUrl = Zend_Controller_Front::getInstance()->getBaseUrl(); + $baseDir = dirname($_SERVER['SCRIPT_FILENAME']); $view->headScript()->appendFile('https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js'); $view->headScript()->appendFile('https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js'); diff --git a/airtime_mvc/application/configs/application.ini b/airtime_mvc/application/configs/application.ini index 836d659da..c342ebda7 100644 --- a/airtime_mvc/application/configs/application.ini +++ b/airtime_mvc/application/configs/application.ini @@ -1,7 +1,6 @@ [production] phpSettings.display_startup_errors = 0 phpSettings.display_errors = 0 -includePaths.library = APPLICATION_PATH "/../library" bootstrap.path = APPLICATION_PATH "/Bootstrap.php" bootstrap.class = "Bootstrap" appnamespace = "Application" diff --git a/airtime_mvc/application/configs/conf.php b/airtime_mvc/application/configs/conf.php index 3eb436520..dc3e03a2b 100644 --- a/airtime_mvc/application/configs/conf.php +++ b/airtime_mvc/application/configs/conf.php @@ -17,9 +17,7 @@ $CC_CONFIG = array( 'soundcloud-client-id' => '2CLCxcSXYzx7QhhPVHN4A', 'soundcloud-client-secret' => 'pZ7beWmF06epXLHVUP1ufOg2oEnIt9XhE8l8xt0bBs', - "rootDir" => __DIR__."/../..", - 'pearPath' => dirname(__FILE__).'/../../library/pear', - 'zendPath' => dirname(__FILE__).'/../../library/Zend' + "rootDir" => __DIR__."/../.." ); @@ -50,12 +48,6 @@ $CC_CONFIG['permSequence'] = $CC_CONFIG['permTable'].'_id'; $CC_CONFIG['subjSequence'] = $CC_CONFIG['subjTable'].'_id'; $CC_CONFIG['smembSequence'] = $CC_CONFIG['smembTable'].'_id'; -// Add libs to the PHP path -$old_include_path = get_include_path(); -set_include_path('.'.PATH_SEPARATOR.$CC_CONFIG['pearPath'] - .PATH_SEPARATOR.$CC_CONFIG['zendPath'] - .PATH_SEPARATOR.$old_include_path); - class Config { public static function loadConfig($p_path) { global $CC_CONFIG; diff --git a/airtime_mvc/application/configs/constants.php b/airtime_mvc/application/configs/constants.php index 50008e3f8..cfe93182e 100644 --- a/airtime_mvc/application/configs/constants.php +++ b/airtime_mvc/application/configs/constants.php @@ -2,6 +2,7 @@ define('AIRTIME_COPYRIGHT_DATE', '2010-2011'); define('AIRTIME_REST_VERSION', '1.1'); +define('AIRTIME_API_VERSION', '1.0'); // Metadata Keys for files define('MDATA_KEY_FILEPATH', 'filepath'); diff --git a/airtime_mvc/application/controllers/ApiController.php b/airtime_mvc/application/controllers/ApiController.php index 8ddbeac8d..4026d7460 100644 --- a/airtime_mvc/application/controllers/ApiController.php +++ b/airtime_mvc/application/controllers/ApiController.php @@ -217,7 +217,8 @@ class ApiController extends Zend_Controller_Action "currentShow"=>Application_Model_Show::GetCurrentShow($utcTimeNow), "nextShow"=>Application_Model_Show::GetNextShows($utcTimeNow, $limit, $utcTimeEnd), "timezone"=> date("T"), - "timezoneOffset"=> date("Z")); + "timezoneOffset"=> date("Z"), + "AIRTIME_API_VERSION"=>AIRTIME_API_VERSION); //used by caller to determine if the airtime they are running or widgets in use is out of date. //Convert from UTC to localtime for user. Application_Model_Show::ConvertToLocalTimeZone($result["currentShow"], array("starts", "ends", "start_timestamp", "end_timestamp")); @@ -256,7 +257,7 @@ class ApiController extends Zend_Controller_Action $result[$dow[$i]] = $shows; } - + $result['AIRTIME_API_VERSION'] = AIRTIME_API_VERSION; //used by caller to determine if the airtime they are running or widgets in use is out of date. header("Content-type: text/javascript"); echo $_GET['callback'].'('.json_encode($result).')'; } else { @@ -406,7 +407,10 @@ class ApiController extends Zend_Controller_Action $tempFileName = basename($tempFilePath); $fileName = isset($_REQUEST["name"]) ? $_REQUEST["name"] : ''; - Application_Model_StoredFile::copyFileToStor($upload_dir, $fileName, $tempFileName); + $result = Application_Model_StoredFile::copyFileToStor($upload_dir, $fileName, $tempFileName); + if (isset($result)){ + die('{"jsonrpc" : "2.0", "error" : {"code": '.$result[code].', "message" : "'.$result[message].'"}}'); + } } public function uploadRecordedAction() diff --git a/airtime_mvc/application/controllers/LibraryController.php b/airtime_mvc/application/controllers/LibraryController.php index ff7ba6c90..1b2f9dfe4 100644 --- a/airtime_mvc/application/controllers/LibraryController.php +++ b/airtime_mvc/application/controllers/LibraryController.php @@ -37,6 +37,8 @@ class LibraryController extends Zend_Controller_Action { global $CC_CONFIG; + $this->_helper->viewRenderer->setResponseSegment('library'); + $request = $this->getRequest(); $baseUrl = $request->getBaseUrl(); @@ -56,16 +58,6 @@ class LibraryController extends Zend_Controller_Action $this->view->headLink()->appendStylesheet($baseUrl.'/css/datatables/css/ColVis.css?'.$CC_CONFIG['airtime_version']); $this->view->headLink()->appendStylesheet($baseUrl.'/css/datatables/css/ColReorder.css?'.$CC_CONFIG['airtime_version']); $this->view->headLink()->appendStylesheet($baseUrl.'/css/TableTools.css?'.$CC_CONFIG['airtime_version']); - - $this->_helper->viewRenderer->setResponseSegment('library'); - - $form = new Application_Form_AdvancedSearch(); - $form->addGroup(1, 1); - - $this->search_sess->next_group = 2; - $this->search_sess->next_row[1] = 2; - $this->view->form = $form; - $this->view->md = $this->search_sess->md; } public function contextMenuAction() diff --git a/airtime_mvc/application/controllers/PluploadController.php b/airtime_mvc/application/controllers/PluploadController.php index cfdb39629..0f94ca2ed 100644 --- a/airtime_mvc/application/controllers/PluploadController.php +++ b/airtime_mvc/application/controllers/PluploadController.php @@ -38,8 +38,10 @@ class PluploadController extends Zend_Controller_Action $upload_dir = ini_get("upload_tmp_dir") . DIRECTORY_SEPARATOR . "plupload"; $filename = $this->_getParam('name'); $tempname = $this->_getParam('tempname'); - Application_Model_StoredFile::copyFileToStor($upload_dir, $filename, $tempname); - + $result = Application_Model_StoredFile::copyFileToStor($upload_dir, $filename, $tempname); + if (isset($result)){ + die('{"jsonrpc" : "2.0", "error" : {"code": '.$result[code].', "message" : "'.$result[message].'"}}'); + } die('{"jsonrpc" : "2.0"}'); } } diff --git a/airtime_mvc/application/controllers/ScheduleController.php b/airtime_mvc/application/controllers/ScheduleController.php index ab807c083..e0b326e55 100644 --- a/airtime_mvc/application/controllers/ScheduleController.php +++ b/airtime_mvc/application/controllers/ScheduleController.php @@ -198,20 +198,20 @@ class ScheduleController extends Zend_Controller_Action $showStartLocalDT = Application_Model_DateHelper::ConvertToLocalDateTime($instance->getShowInstanceStart()); $showEndLocalDT = Application_Model_DateHelper::ConvertToLocalDateTime($instance->getShowInstanceEnd()); - /* - if ($epochNow < $showStartDateHelper->getTimestamp()) { + if ($epochNow < $showStartLocalDT->getTimestamp()) { - if ($user->isUserType(array(UTYPE_ADMIN, UTYPE_PROGRAM_MANAGER, UTYPE_HOST),$show->getShowId()) && !$show->isRecorded() && !$show->isRebroadcast()) { + if ($user->isUserType(array(UTYPE_ADMIN, UTYPE_PROGRAM_MANAGER, UTYPE_HOST), $instance->getShowId()) + && !$instance->isRecorded() + && !$instance->isRebroadcast()) { - $menu[] = array('action' => array('type' => 'ajax', 'url' => '/Schedule/schedule-show-dialog'.$params, - 'callback' => 'window["buildScheduleDialog"]'), 'title' => 'Add / Remove Content'); + $menu["schedule"] = array("name"=> "Add / Remove Content", + "url" => "/showbuilder/index/"); - $menu[] = array('action' => array('type' => 'ajax', 'url' => '/Schedule/clear-show'.$params, - 'callback' => 'window["scheduleRefetchEvents"]'), 'title' => 'Remove All Content'); + $menu["clear"] = array("name"=> "Remove All Content", "icon" => "delete", + "url" => "/schedule/clear-show"); } } - */ if (!$instance->isRecorded()) { diff --git a/airtime_mvc/application/controllers/ShowbuilderController.php b/airtime_mvc/application/controllers/ShowbuilderController.php index dd6134f68..ba1d683f8 100644 --- a/airtime_mvc/application/controllers/ShowbuilderController.php +++ b/airtime_mvc/application/controllers/ShowbuilderController.php @@ -25,17 +25,36 @@ class ShowbuilderController extends Zend_Controller_Action public function builderAction() { + $this->_helper->viewRenderer->setResponseSegment('builder'); + $request = $this->getRequest(); $baseUrl = $request->getBaseUrl(); + $now = time(); + $from = $request->getParam("from", $now); + $to = $request->getParam("to", $now+(24*60*60)); + + $start = DateTime::createFromFormat("U", $from, new DateTimeZone("UTC")); + $start->setTimezone(new DateTimeZone(date_default_timezone_get())); + $end = DateTime::createFromFormat("U", $to, new DateTimeZone("UTC")); + $end->setTimezone(new DateTimeZone(date_default_timezone_get())); + + $form = new Application_Form_ShowBuilder(); + $form->populate(array( + 'sb_date_start' => $start->format("Y-m-d"), + 'sb_time_start' => $start->format("H:i"), + 'sb_date_end' => $end->format("Y-m-d"), + 'sb_time_end' => $end->format("H:i") + )); + + $this->view->sb_form = $form; + $this->view->headScript()->appendScript("var serverTimezoneOffset = ".date("Z")."; //in seconds"); $this->view->headScript()->appendFile($baseUrl.'/js/timepicker/jquery.ui.timepicker.js','text/javascript'); $this->view->headScript()->appendFile($baseUrl.'/js/airtime/showbuilder/builder.js','text/javascript'); $this->view->headLink()->appendStylesheet($baseUrl.'/css/jquery.ui.timepicker.css'); $this->view->headLink()->appendStylesheet($baseUrl.'/css/showbuilder.css'); - - $this->_helper->viewRenderer->setResponseSegment('builder'); } public function builderFeedAction() { @@ -46,6 +65,8 @@ class ShowbuilderController extends Zend_Controller_Action $starts_epoch = $request->getParam("start", $current_time); //default ends is 24 hours after starts. $ends_epoch = $request->getParam("end", $current_time + (60*60*24)); + $show_filter = intval($request->getParam("showFilter", 0)); + $my_shows = intval($request->getParam("myShows", 0)); $startsDT = DateTime::createFromFormat("U", $starts_epoch, new DateTimeZone("UTC")); $endsDT = DateTime::createFromFormat("U", $ends_epoch, new DateTimeZone("UTC")); @@ -53,7 +74,8 @@ class ShowbuilderController extends Zend_Controller_Action Logging::log("showbuilder starts {$startsDT->format("Y-m-d H:i:s")}"); Logging::log("showbuilder ends {$endsDT->format("Y-m-d H:i:s")}"); - $showBuilder = new Application_Model_ShowBuilder($startsDT, $endsDT); + $opts = array("myShows" => $my_shows, "showFilter" => $show_filter); + $showBuilder = new Application_Model_ShowBuilder($startsDT, $endsDT, $opts); $this->view->schedule = $showBuilder->GetItems(); } @@ -61,21 +83,24 @@ class ShowbuilderController extends Zend_Controller_Action public function scheduleAddAction() { $request = $this->getRequest(); - $mediaItems = $request->getParam("mediaIds", null); $scheduledIds = $request->getParam("schedIds", null); - $json = array(); - try { $scheduler = new Application_Model_Scheduler(); $scheduler->scheduleAfter($scheduledIds, $mediaItems); - - $json["message"]="success... maybe"; + } + catch (OutDatedScheduleException $e) { + $this->view->error = $e->getMessage(); + Logging::log($e->getMessage()); + Logging::log("{$e->getFile()}"); + Logging::log("{$e->getLine()}"); } catch (Exception $e) { - $json["message"]=$e->getMessage(); + $this->view->error = $e->getMessage(); Logging::log($e->getMessage()); + Logging::log("{$e->getFile()}"); + Logging::log("{$e->getLine()}"); } $this->view->data = $json; @@ -84,45 +109,98 @@ class ShowbuilderController extends Zend_Controller_Action public function scheduleRemoveAction() { $request = $this->getRequest(); - - $ids = $request->getParam("ids", null); - - $json = array(); + $items = $request->getParam("items", null); try { $scheduler = new Application_Model_Scheduler(); - $scheduler->removeItems($ids); - - $json["message"]="success... maybe"; + $scheduler->removeItems($items); + } + catch (OutDatedScheduleException $e) { + $this->view->error = $e->getMessage(); + Logging::log($e->getMessage()); + Logging::log("{$e->getFile()}"); + Logging::log("{$e->getLine()}"); } catch (Exception $e) { - $json["message"]=$e->getMessage(); + $this->view->error = $e->getMessage(); Logging::log($e->getMessage()); + Logging::log("{$e->getFile()}"); + Logging::log("{$e->getLine()}"); } - - $this->view->data = $json; } public function scheduleMoveAction() { $request = $this->getRequest(); - $selectedItem = $request->getParam("selectedItem"); $afterItem = $request->getParam("afterItem"); - $json = array(); - try { $scheduler = new Application_Model_Scheduler(); $scheduler->moveItem($selectedItem, $afterItem); - - $json["message"]="success... maybe"; + } + catch (OutDatedScheduleException $e) { + $this->view->error = $e->getMessage(); + Logging::log($e->getMessage()); + Logging::log("{$e->getFile()}"); + Logging::log("{$e->getLine()}"); } catch (Exception $e) { - $json["message"]=$e->getMessage(); + $this->view->error = $e->getMessage(); Logging::log($e->getMessage()); + Logging::log("{$e->getFile()}"); + Logging::log("{$e->getLine()}"); } $this->view->data = $json; } + + public function scheduleReorderAction() { + + $request = $this->getRequest(); + + $showInstance = $request->getParam("instanceId"); + } + + /* + * make sure any incoming requests for scheduling are ligit. + * + * @param array $items, an array containing pks of cc_schedule items. + */ + private function filterSelected($items) { + + $allowed = array(); + $user = Application_Model_User::GetCurrentUser(); + $type = $user->getType(); + + //item must be within the host's show. + if ($type === UTYPE_HOST) { + + $hosted = CcShowHostsQuery::create() + ->filterByDbHost($user->getId()) + ->find(); + + $allowed_shows = array(); + foreach ($hosted as $host) { + $allowed_shows[] = $host->getDbShow(); + } + + for ($i = 0; $i < count($items); $i++) { + + $instance = $items[$i]["instance"]; + + if (in_array($instance, $allowed_shows)) { + $allowed[] = $items[$i]; + } + } + + $this->view->shows = $res; + } + //they can schedule anything. + else if ($type === UTYPE_ADMIN || $type === UTYPE_PROGRAM_MANAGER) { + $allowed = $items; + } + + return $allowed; + } } \ No newline at end of file diff --git a/airtime_mvc/application/controllers/SystemstatusController.php b/airtime_mvc/application/controllers/SystemstatusController.php index 5561fd659..8a04f2f9b 100644 --- a/airtime_mvc/application/controllers/SystemstatusController.php +++ b/airtime_mvc/application/controllers/SystemstatusController.php @@ -4,6 +4,8 @@ class SystemstatusController extends Zend_Controller_Action { public function init() { + global $CC_CONFIG; + $request = $this->getRequest(); $baseUrl = $request->getBaseUrl(); diff --git a/airtime_mvc/application/forms/AdvancedSearch.php b/airtime_mvc/application/forms/AdvancedSearch.php deleted file mode 100644 index 4c15795b7..000000000 --- a/airtime_mvc/application/forms/AdvancedSearch.php +++ /dev/null @@ -1,65 +0,0 @@ -addElement('button', 'search_add_group', array( - 'ignore' => true, - 'label' => 'Add', - 'order' => '-2' - )); - $this->getElement('search_add_group')->removeDecorator('DtDdWrapper'); - - // Add the submit button - $this->addElement('button', 'search_submit', array( - 'ignore' => true, - 'label' => 'Save', - 'order' => '-1' - )); - $this->getElement('search_submit')->removeDecorator('DtDdWrapper'); - } - - public function addGroup($group_id, $row_id=null) { - - $this->addSubForm(new Application_Form_AdvancedSearchGroup(), 'group_'.$group_id, $group_id); - $this->getSubForm('group_'.$group_id)->removeDecorator('DtDdWrapper'); - - if(!is_null($row_id)) { - $subGroup = $this->getSubForm('group_'.$group_id); - $subGroup->addRow($row_id); - } - } - - public function preValidation(array $data) { - - function findId($name) { - $t = explode("_", $name); - return $t[1]; - } - - function findFields($field) { - return strpos($field, 'group') !== false; - } - - $groups = array_filter(array_keys($data), 'findFields'); - - foreach ($groups as $group) { - - $group_id = findId($group); - $this->addGroup($group_id); - - $subGroup = $this->getSubForm($group); - - foreach (array_keys($data[$group]) as $row) { - - $row_id = findId($row); - $subGroup->addRow($row_id, $data[$group][$row]); - } - } - - } -} - diff --git a/airtime_mvc/application/forms/AdvancedSearchGroup.php b/airtime_mvc/application/forms/AdvancedSearchGroup.php deleted file mode 100644 index e2571885f..000000000 --- a/airtime_mvc/application/forms/AdvancedSearchGroup.php +++ /dev/null @@ -1,37 +0,0 @@ -addElement('button', 'search_add_row', array( - 'ignore' => true, - 'label' => 'Add', - 'order' => '-2' - )); - $this->getElement('search_add_row')->removeDecorator('DtDdWrapper'); - - // Add the add button - $this->addElement('button', 'search_remove_group', array( - 'ignore' => true, - 'label' => 'Remove', - 'order' => '-1' - )); - $this->getElement('search_remove_group')->removeDecorator('DtDdWrapper'); - } - - public function addRow($row_id, $data=null) { - - $this->addSubForm(new Application_Form_AdvancedSearchRow(), 'row_'.$row_id, $row_id); - $row = $this->getSubForm('row_'.$row_id); - $row->removeDecorator('DtDdWrapper'); - - if(!is_null($data)) { - $row->setDefaults($data); - } - } - - -} - diff --git a/airtime_mvc/application/forms/AdvancedSearchRow.php b/airtime_mvc/application/forms/AdvancedSearchRow.php deleted file mode 100644 index b50cfb176..000000000 --- a/airtime_mvc/application/forms/AdvancedSearchRow.php +++ /dev/null @@ -1,70 +0,0 @@ -addElement( - 'select', - 'metadata', - array( - 'required' => true, - 'multiOptions' => array( - "dc:title" => "Title", - "dc:format" => "Format", - "dc:creator" => "Artist/Creator", - "dc:source" => "Album", - "ls:bitrate" => "Bitrate", - "ls:samplerate" => "Samplerate", - "dcterms:extent" => "Length", - "dc:description" => "Comments", - "dc:type" => "Genre", - "ls:channels" => "channels", - "ls:year" => "Year", - "ls:track_num" => "track_number", - "ls:mood" => "mood", - "ls:bpm" => "BPM", - "ls:rating" => "rating", - "ls:encoded_by" => "encoded_by", - "dc:publisher" => "label", - "ls:composer" => "Composer", - "ls:encoder" => "Encoder", - "ls:lyrics" => "lyrics", - "ls:orchestra" => "orchestra", - "ls:conductor" => "conductor", - "ls:lyricist" => "lyricist", - "ls:originallyricist" => "original_lyricist", - "ls:isrcnumber" => "isrc_number", - "dc:language" => "Language", - ), - ) - ); - $this->getElement('metadata')->removeDecorator('Label')->removeDecorator('HtmlTag'); - - $this->addElement( - 'select', - 'match', - array( - 'required' => true, - 'multiOptions' => array( - "0" => "partial", - "1" => "=", - "2" => "<", - "3" => "<=", - "4" => ">", - "5" => ">=", - "6" => "!=", - ), - ) - ); - $this->getElement('match')->removeDecorator('Label')->removeDecorator('HtmlTag'); - - $this->addElement('text', 'search', array( - 'required' => true, - )); - $this->getElement('search')->removeDecorator('Label')->removeDecorator('HtmlTag'); - } - - -} - diff --git a/airtime_mvc/application/forms/EditAudioMD.php b/airtime_mvc/application/forms/EditAudioMD.php index a4968644f..6a9a8e2e0 100644 --- a/airtime_mvc/application/forms/EditAudioMD.php +++ b/airtime_mvc/application/forms/EditAudioMD.php @@ -35,7 +35,7 @@ class Application_Form_EditAudioMD extends Zend_Form // Add artist field $this->addElement('text', 'artist_name', array( - 'label' => 'Artist:', + 'label' => 'Creator:', 'class' => 'input_text', 'filters' => array('StringTrim'), )); diff --git a/airtime_mvc/application/forms/GeneralPreferences.php b/airtime_mvc/application/forms/GeneralPreferences.php index ace81ab44..66be09ce1 100644 --- a/airtime_mvc/application/forms/GeneralPreferences.php +++ b/airtime_mvc/application/forms/GeneralPreferences.php @@ -71,8 +71,10 @@ class Application_Form_GeneralPreferences extends Zend_Form_SubForm 'Africa' => DateTimeZone::AFRICA, 'America' => DateTimeZone::AMERICA, 'Antarctica' => DateTimeZone::ANTARCTICA, + 'Arctic' => DateTimeZone::ARCTIC, 'Asia' => DateTimeZone::ASIA, 'Atlantic' => DateTimeZone::ATLANTIC, + 'Australia' => DateTimeZone::AUSTRALIA, 'Europe' => DateTimeZone::EUROPE, 'Indian' => DateTimeZone::INDIAN, 'Pacific' => DateTimeZone::PACIFIC diff --git a/airtime_mvc/application/forms/ShowBuilder.php b/airtime_mvc/application/forms/ShowBuilder.php new file mode 100644 index 000000000..dddc91ffa --- /dev/null +++ b/airtime_mvc/application/forms/ShowBuilder.php @@ -0,0 +1,104 @@ +setDecorators(array( + array('ViewScript', array('viewScript' => 'form/showbuilder.phtml')) + )); + + // Add start date element + $startDate = new Zend_Form_Element_Text('sb_date_start'); + $startDate->class = 'input_text'; + $startDate->setRequired(true) + ->setLabel('Date Start:') + ->setValue(date("Y-m-d")) + ->setFilters(array('StringTrim')) + ->setValidators(array( + 'NotEmpty', + array('date', false, array('YYYY-MM-DD')))) + ->setDecorators(array('ViewHelper')); + $startDate->setAttrib('alt', 'date'); + $this->addElement($startDate); + + // Add start time element + $startTime = new Zend_Form_Element_Text('sb_time_start'); + $startTime->class = 'input_text'; + $startTime->setRequired(true) + ->setValue('00:00') + ->setFilters(array('StringTrim')) + ->setValidators(array( + 'NotEmpty', + array('date', false, array('HH:mm')), + array('regex', false, array('/^[0-9:]+$/', 'messages' => 'Invalid character entered')))) + ->setDecorators(array('ViewHelper')); + $startTime->setAttrib('alt', 'time'); + $this->addElement($startTime); + + // Add end date element + $endDate = new Zend_Form_Element_Text('sb_date_end'); + $endDate->class = 'input_text'; + $endDate->setRequired(true) + ->setLabel('Date End:') + ->setValue(date("Y-m-d")) + ->setFilters(array('StringTrim')) + ->setValidators(array( + 'NotEmpty', + array('date', false, array('YYYY-MM-DD')))) + ->setDecorators(array('ViewHelper')); + $endDate->setAttrib('alt', 'date'); + $this->addElement($endDate); + + // Add end time element + $endTime = new Zend_Form_Element_Text('sb_time_end'); + $endTime->class = 'input_text'; + $endTime->setRequired(true) + ->setValue('01:00') + ->setFilters(array('StringTrim')) + ->setValidators(array( + 'NotEmpty', + array('date', false, array('HH:mm')), + array('regex', false, array('/^[0-9:]+$/', 'messages' => 'Invalid character entered')))) + ->setDecorators(array('ViewHelper')); + $endTime->setAttrib('alt', 'time'); + $this->addElement($endTime); + + + // add a select to choose a show. + $showSelect = new Zend_Form_Element_Select("sb_show_filter"); + $showSelect->setLabel("Filter By Show:"); + $showSelect->setMultiOptions($this->getShowNames()); + $showSelect->setValue(null); + $showSelect->setDecorators(array('ViewHelper')); + $this->addElement($showSelect); + + if ($user->getType() === 'H') { + $myShows = new Zend_Form_Element_Checkbox('sb_my_shows'); + $myShows->setLabel('All My Shows') + ->setDecorators(array('ViewHelper')); + $this->addElement($myShows); + } + } + + private function getShowNames() { + + $showNames = array("0" => "-------------------------"); + + $shows = CcShowQuery::create() + ->setFormatter(ModelCriteria::FORMAT_ON_DEMAND) + ->orderByDbName() + ->find(); + + foreach ($shows as $show) { + + $showNames[$show->getDbId()] = $show->getDbName(); + } + + return $showNames; + } + +} \ No newline at end of file diff --git a/airtime_mvc/application/forms/StreamSetting.php b/airtime_mvc/application/forms/StreamSetting.php index eda28845b..127706d48 100644 --- a/airtime_mvc/application/forms/StreamSetting.php +++ b/airtime_mvc/application/forms/StreamSetting.php @@ -39,12 +39,14 @@ class Application_Form_StreamSetting extends Zend_Form } # tooltip - $description = 'VLC and mplayer have a serious bug when playing an OGG/VORBIS - stream that has metadata information enabled (stream metadata is the - track title, show name, etc displayed in the audio player): they will - disconnect from the stream after every song if this option is enabled. - If your listeners do not require support for these audio players, - then you should enable this option.'; + $description = 'This option enables metadata for OGG streams (stream + metadata is the track title, artist, and show name that is + displayed in an audio player). VLC and mplayer have a + serious bug when playing an OGG/VORBIS stream that has + metadata information enabled: they will disconnect from the + stream after every song. If you are using an OGG stream and + your listeners do not require support for these audio + players, then feel free to enable this option.'; $icecast_vorbis_metadata = new Zend_Form_Element_Checkbox('icecast_vorbis_metadata'); $icecast_vorbis_metadata->setLabel('Icecast Vorbis Metadata') diff --git a/airtime_mvc/application/models/Nowplaying.php b/airtime_mvc/application/models/Nowplaying.php index 223d48578..b834dd765 100644 --- a/airtime_mvc/application/models/Nowplaying.php +++ b/airtime_mvc/application/models/Nowplaying.php @@ -9,16 +9,16 @@ class Application_Model_Nowplaying private static function CreateDatatableRows($p_dbRows){ $dataTablesRows = array(); - + $epochNow = time(); - + foreach ($p_dbRows as $dbRow){ - + $showStartDateTime = Application_Model_DateHelper::ConvertToLocalDateTime($dbRow['show_starts']); $showEndDateTime = Application_Model_DateHelper::ConvertToLocalDateTime($dbRow['show_ends']); $itemStartDateTime = Application_Model_DateHelper::ConvertToLocalDateTime($dbRow['item_starts']); $itemEndDateTime = Application_Model_DateHelper::ConvertToLocalDateTime($dbRow['item_ends']); - + $showStarts = $showStartDateTime->format("Y-m-d H:i:s"); $showEnds = $showEndDateTime->format("Y-m-d H:i:s"); $itemStarts = $itemStartDateTime->format("Y-m-d H:i:s"); @@ -28,29 +28,29 @@ class Application_Model_Nowplaying $status = ($showEnds < $itemEnds) ? "x" : ""; $type = "a"; - $type .= ($itemStartDateTime->getTimestamp() <= $epochNow + $type .= ($itemStartDateTime->getTimestamp() <= $epochNow && $epochNow < $itemEndDateTime->getTimestamp() && $epochNow < $showEndDateTime->getTimestamp()) ? "c" : ""; - + // remove millisecond from the time format $itemStart = explode('.', $dbRow['item_starts']); $itemEnd = explode('.', $dbRow['item_ends']); - + //format duration $duration = explode('.', $dbRow['clip_length']); $formatted = self::FormatDuration($duration[0]); - $dataTablesRows[] = array($type, $showStarts, $itemStarts, $itemEnds, + $dataTablesRows[] = array($type, $itemStarts, $itemStarts, $itemEnds, $formatted, $dbRow['track_title'], $dbRow['artist_name'], $dbRow['album_title'], $dbRow['playlist_name'], $dbRow['show_name'], $status); } return $dataTablesRows; } - + private static function CreateGapRow($p_gapTime){ return array("g", "", "", "", $p_gapTime, "", "", "", "", "", ""); } - + private static function CreateRecordingRow($p_showInstance){ return array("r", "", "", "", $p_showInstance->getName(), "", "", "", "", "", ""); } @@ -60,7 +60,7 @@ class Application_Model_Nowplaying if ($viewType == "now"){ $dateTime = new DateTime("now", new DateTimeZone("UTC")); $timeNow = $dateTime->format("Y-m-d H:i:s"); - + $startCutoff = 60; $endCutoff = 86400; //60*60*24 - seconds in a day } else { @@ -72,30 +72,30 @@ class Application_Model_Nowplaying $startCutoff = $date->getNowDayStartDiff(); $endCutoff = $date->getNowDayEndDiff(); } - + $data = array(); $showIds = Application_Model_ShowInstance::GetShowsInstancesIdsInRange($timeNow, $startCutoff, $endCutoff); foreach ($showIds as $showId){ $instanceId = $showId['id']; - + $si = new Application_Model_ShowInstance($instanceId); - + $showId = $si->getShowId(); $show = new Application_Model_Show($showId); - + $showStartDateTime = Application_Model_DateHelper::ConvertToLocalDateTime($si->getShowInstanceStart()); $showEndDateTime = Application_Model_DateHelper::ConvertToLocalDateTime($si->getShowInstanceEnd()); - + //append show header row $data[] = self::CreateHeaderRow($show->getName(), $showStartDateTime->format("Y-m-d H:i:s"), $showEndDateTime->format("Y-m-d H:i:s")); - + $scheduledItems = $si->getScheduleItemsInRange($timeNow, $startCutoff, $endCutoff); $dataTablesRows = self::CreateDatatableRows($scheduledItems); - + //append show audio item rows $data = array_merge($data, $dataTablesRows); - + //append show gap time row $gapTime = self::FormatDuration($si->getShowEndGapTime(), true); if ($si->isRecorded()) @@ -118,7 +118,7 @@ class Application_Model_Nowplaying } /* * default $time format should be in format of 00:00:00 - * if $inSecond = true, then $time should be in seconds + * if $inSecond = true, then $time should be in seconds */ private static function FormatDuration($time, $inSecond=false){ if($inSecond == false){ @@ -129,13 +129,13 @@ class Application_Model_Nowplaying $duration[1] = intval(($time/60)%60); $duration[2] = $time%60; } - + if($duration[2] == 0){ $duration[2] = ''; }else{ $duration[2] = intval($duration[2],10).'s'; } - + if($duration[1] == 0){ if($duration[2] == ''){ $duration[1] = ''; @@ -145,13 +145,13 @@ class Application_Model_Nowplaying }else{ $duration[1] = intval($duration[1],10).'m '; } - + if($duration[0] == 0){ $duration[0] = ''; }else{ $duration[0] = intval($duration[0],10).'h '; } - + $out = $duration[0].$duration[1].$duration[2]; return $out; } diff --git a/airtime_mvc/application/models/Playlist.php b/airtime_mvc/application/models/Playlist.php index 9feca24ab..441ed9a43 100644 --- a/airtime_mvc/application/models/Playlist.php +++ b/airtime_mvc/application/models/Playlist.php @@ -768,4 +768,4 @@ class Application_Model_Playlist { } // class Playlist class PlaylistNotFoundException extends Exception {} -class OutDatedException extends Exception {} +class PlaylistOutDatedException extends Exception {} diff --git a/airtime_mvc/application/models/Preference.php b/airtime_mvc/application/models/Preference.php index 287d776b3..061c694c8 100644 --- a/airtime_mvc/application/models/Preference.php +++ b/airtime_mvc/application/models/Preference.php @@ -102,7 +102,6 @@ class Application_Model_Preference public static function SetHeadTitle($title, $view=null){ self::SetValue("station_name", $title); - Application_Model_RabbitMq::PushSchedule(); // in case this is called from airtime-saas script if($view !== null){ @@ -111,6 +110,11 @@ class Application_Model_Preference $view->headTitle()->exchangeArray(array()); //clear headTitle ArrayObject $view->headTitle(self::GetHeadTitle()); } + + $eventType = "update_station_name"; + $md = array("station_name"=>$title); + + Application_Model_RabbitMq::SendMessageToPypo($eventType, $md); } /** @@ -153,7 +157,11 @@ class Application_Model_Preference public static function SetStreamLabelFormat($type){ self::SetValue("stream_label_format", $type); - Application_Model_RabbitMq::PushSchedule(); + + $eventType = "update_stream_format"; + $md = array("stream_format"=>$type); + + Application_Model_RabbitMq::SendMessageToPypo($eventType, $md); } public static function GetStreamLabelFormat(){ diff --git a/airtime_mvc/application/models/RabbitMq.php b/airtime_mvc/application/models/RabbitMq.php index b0b2d7426..f3b823eb5 100644 --- a/airtime_mvc/application/models/RabbitMq.php +++ b/airtime_mvc/application/models/RabbitMq.php @@ -46,7 +46,8 @@ class Application_Model_RabbitMq $conn = new AMQPConnection($CC_CONFIG["rabbitmq"]["host"], $CC_CONFIG["rabbitmq"]["port"], $CC_CONFIG["rabbitmq"]["user"], - $CC_CONFIG["rabbitmq"]["password"]); + $CC_CONFIG["rabbitmq"]["password"], + $CC_CONFIG["rabbitmq"]["vhost"]); $channel = $conn->channel(); $channel->access_request($CC_CONFIG["rabbitmq"]["vhost"], false, false, true, true); @@ -68,7 +69,8 @@ class Application_Model_RabbitMq $conn = new AMQPConnection($CC_CONFIG["rabbitmq"]["host"], $CC_CONFIG["rabbitmq"]["port"], $CC_CONFIG["rabbitmq"]["user"], - $CC_CONFIG["rabbitmq"]["password"]); + $CC_CONFIG["rabbitmq"]["password"], + $CC_CONFIG["rabbitmq"]["vhost"]); $channel = $conn->channel(); $channel->access_request($CC_CONFIG["rabbitmq"]["vhost"], false, false, true, true); diff --git a/airtime_mvc/application/models/Schedule.php b/airtime_mvc/application/models/Schedule.php index 499cf68b1..1c2100d35 100644 --- a/airtime_mvc/application/models/Schedule.php +++ b/airtime_mvc/application/models/Schedule.php @@ -303,7 +303,7 @@ class Application_Model_Schedule { * @return array $scheduledItems * */ - public static function GetScheduleDetailItems($p_startDateTime, $p_endDateTime) + public static function GetScheduleDetailItems($p_startDateTime, $p_endDateTime, $p_shows) { global $CC_CONFIG, $CC_DBC; @@ -313,7 +313,7 @@ class Application_Model_Schedule { showt.background_color AS show_background_colour, showt.id AS show_id, si.starts AS si_starts, si.ends AS si_ends, si.time_filled AS si_time_filled, - si.record AS si_record, si.rebroadcast AS si_rebroadcast, si.id AS si_id, + si.record AS si_record, si.rebroadcast AS si_rebroadcast, si.id AS si_id, si.last_scheduled AS si_last_scheduled, sched.starts AS sched_starts, sched.ends AS sched_ends, sched.id AS sched_id, @@ -328,11 +328,15 @@ class Application_Model_Schedule { WHERE si.modified_instance = false AND - si.starts >= '{$p_startDateTime}' AND si.starts <= '{$p_endDateTime}' + si.starts >= '{$p_startDateTime}' AND si.starts < '{$p_endDateTime}'"; - ORDER BY si.starts, sched.starts;"; + if (count($p_shows) > 0) { + $sql .= " AND show_id IN (".implode(",", $p_shows).")"; + } - //Logging::log($sql); + $sql .= " ORDER BY si.starts, sched.starts;"; + + Logging::log($sql); $rows = $CC_DBC->GetAll($sql); return $rows; diff --git a/airtime_mvc/application/models/Scheduler.php b/airtime_mvc/application/models/Scheduler.php index b34897ae9..9f0dc8e19 100644 --- a/airtime_mvc/application/models/Scheduler.php +++ b/airtime_mvc/application/models/Scheduler.php @@ -31,11 +31,16 @@ class Application_Model_Scheduler { if ($type === "audioclip") { $file = CcFilesQuery::create()->findPK($id, $this->con); - $data = $this->fileInfo; - $data["id"] = $id; - $data["cliplength"] = $file->getDbLength(); + if (is_null($file) || !$file->getDbFileExists()) { + throw new Exception("A selected File does not exist!"); + } + else { + $data = $this->fileInfo; + $data["id"] = $id; + $data["cliplength"] = $file->getDbLength(); - $files[] = $data; + $files[] = $data; + } } else if ($type === "playlist") { @@ -44,17 +49,25 @@ class Application_Model_Scheduler { ->filterByDbPlaylistId($id) ->find($this->con); + if (is_null($contents)) { + throw new Exception("A selected Playlist does not exist!"); + } + foreach ($contents as $plItem) { - $data = $this->fileInfo; - $data["id"] = $plItem->getDbFileId(); - $data["cliplength"] = $plItem->getDbCliplength(); - $data["cuein"] = $plItem->getDbCuein(); - $data["cueout"] = $plItem->getDbCueout(); - $data["fadein"] = $plItem->getDbFadein(); - $data["fadeout"] = $plItem->getDbFadeout(); + $file = $plItem->getCcFiles($this->con); + if (isset($file) && $file->getDbFileExists()) { - $files[] = $data; + $data = $this->fileInfo; + $data["id"] = $plItem->getDbFileId(); + $data["cliplength"] = $plItem->getDbCliplength(); + $data["cuein"] = $plItem->getDbCuein(); + $data["cueout"] = $plItem->getDbCueout(); + $data["fadein"] = $plItem->getDbFadein(); + $data["fadeout"] = $plItem->getDbFadeout(); + + $files[] = $data; + } } } @@ -68,7 +81,7 @@ class Application_Model_Scheduler { * * @return DateTime endDT in UTC */ - private function findEndTime($p_startDT, $p_duration) { + public static function findEndTime($p_startDT, $p_duration) { $startEpoch = $p_startDT->format("U.u"); $durationSeconds = Application_Model_Playlist::playlistTimeToSeconds($p_duration); @@ -98,6 +111,8 @@ class Application_Model_Scheduler { try { + $affectedShowInstances = array(); + //dont want to recalculate times for moved items. $excludeIds = array(); foreach ($schedFiles as $file) { @@ -108,34 +123,42 @@ class Application_Model_Scheduler { foreach ($scheduleItems as $schedule) { $id = intval($schedule["id"]); + $ts = intval($schedule["timestamp"]); Logging::log("scheduling after scheduled item: ".$id); Logging::log("in show: ".intval($schedule["instance"])); if ($id !== 0) { $schedItem = CcScheduleQuery::create()->findPK($id, $this->con); - $instance = $schedItem->getDbInstanceId(); - - //user has an old copy of the time line opened. - if ($instance !== intval($schedule["instance"])) { - Logging::log("items have been since updated"); - return; + $instance = $schedItem->getCcShowInstances($this->con); + if (intval($schedule["instance"]) !== $instance->getDbId()) { + throw new OutDatedScheduleException("The schedule you're viewing is out of date!"); } - $nextStartDT = $schedItem->getDbEnds(null); } //selected empty row to add after else { - $showInstance = CcShowInstancesQuery::create()->findPK($schedule["instance"], $this->con); - $nextStartDT = $showInstance->getDbStarts(null); - $instance = intval($schedule["instance"]); + $instance = CcShowInstancesQuery::create()->findPK($schedule["instance"], $this->con); + $nextStartDT = $instance->getDbStarts(null); + } + + $currTs = intval($instance->getDbLastScheduled("U")) ? : 0; + //user has an old copy of the time line opened. + if ($ts !== $currTs) { + Logging::log("currTs {$currTs}, ts {$ts}"); + $show = $instance->getCcShow($this->con); + throw new OutDatedScheduleException("The show {$show->getDbName()} has been previously updated!"); + } + + if (!in_array($instance->getDbId(), $affectedShowInstances)) { + $affectedShowInstances[] = $instance->getDbId(); } Logging::log("finding items >= {$nextStartDT->format("Y-m-d H:i:s.u")}"); if ($adjustSched === true) { $followingSchedItems = CcScheduleQuery::create() ->filterByDBStarts($nextStartDT->format("Y-m-d H:i:s.u"), Criteria::GREATER_EQUAL) - ->filterByDbInstanceId($instance) + ->filterByDbInstanceId($instance->getDbId()) ->filterByDbId($excludeIds, Criteria::NOT_IN) ->orderByDbStarts() ->find($this->con); @@ -149,7 +172,7 @@ class Application_Model_Scheduler { Logging::log("adding file with id: ".$file["id"]); - $endTimeDT = $this->findEndTime($nextStartDT, $file['cliplength']); + $endTimeDT = self::findEndTime($nextStartDT, $file['cliplength']); //item existed previously and is being moved. //need to keep same id for resources if we want REST. @@ -171,7 +194,7 @@ class Application_Model_Scheduler { $sched->setDbFadeIn($file['fadein']); $sched->setDbFadeOut($file['fadeout']); $sched->setDbClipLength($file['cliplength']); - $sched->setDbInstanceId($instance); + $sched->setDbInstanceId($instance->getDbId()); $sched->save($this->con); $nextStartDT = $endTimeDT; @@ -184,7 +207,7 @@ class Application_Model_Scheduler { Logging::log("adjusting iterm {$item->getDbId()}"); - $endTimeDT = $this->findEndTime($nextStartDT, $item->getDbClipLength()); + $endTimeDT = self::findEndTime($nextStartDT, $item->getDbClipLength()); $item->setDbStarts($nextStartDT); $item->setDbEnds($endTimeDT); @@ -195,6 +218,10 @@ class Application_Model_Scheduler { } } + //update the last scheduled timestamp. + CcShowInstancesQuery::create() + ->filterByPrimaryKeys($affectedShowInstances) + ->update(array('DbLastScheduled' => new DateTime("now", new DateTimeZone("UTC"))), $this->con); } catch (Exception $e) { throw $e; @@ -236,36 +263,53 @@ class Application_Model_Scheduler { * @param array $selectedItem * @param array $afterItem */ - public function moveItem($selectedItem, $afterItem, $adjustSched = true) { + public function moveItem($selectedItems, $afterItems, $adjustSched = true) { $this->con->beginTransaction(); try { - $origSelIns = intval($selectedItem[0]["instance"]); - $origAfterIns = intval($afterItem[0]["instance"]); + $origSelTs = intval($selectedItems[0]["timestamp"]); + $origAfterTs = intval($afterItems[0]["timestamp"]); - Logging::log("Moving item {$selectedItem[0]["id"]}"); - Logging::log("After {$afterItem[0]["id"]}"); + Logging::log("Moving item {$selectedItems[0]["id"]}"); + Logging::log("After {$afterItems[0]["id"]}"); - $selected = CcScheduleQuery::create()->findPk($selectedItem[0]["id"]); - $after = CcScheduleQuery::create()->findPk($afterItem[0]["id"]); - - /* - if (isset($after) && $origSelIns !== $selected->getDBInstanceId() - || $origAfterIns !== $after->getDBInstanceId()) { - - Logging::log("items have been since updated"); - return; + $selected = CcScheduleQuery::create()->findPk($selectedItems[0]["id"], $this->con); + if (is_null($selected)) { + throw new OutDatedScheduleException("The schedule you're viewing is out of date!"); } - */ + $selectedInstance = $selected->getCcShowInstances($this->con); - $this->removeGaps($origSelIns, $selected->getDbId()); - - //moved to another show, remove gaps from original show. - if ($adjustSched === true && $origSelIns !== $origAfterIns) { + if (intval($afterItems[0]["id"]) === 0) { + $afterInstance = CcShowInstancesQuery::create()->findPK($afterItems[0]["instance"], $this->con); } + else { + $after = CcScheduleQuery::create()->findPk($afterItems[0]["id"], $this->con); + if (is_null($after)) { + throw new OutDatedScheduleException("The schedule you're viewing is out of date!"); + } + $afterInstance = $after->getCcShowInstances($this->con); + } + + if (is_null($selectedInstance) || is_null($afterInstance)) { + throw new OutDatedScheduleException("The schedule you're viewing is out of date!"); + } + + $currTs = intval($selectedInstance->getDbLastScheduled("U")) ? : 0; + if ($origSelTs !== $currTs) { + $show = $selectedInstance->getCcShow($this->con); + throw new OutDatedScheduleException("The show {$show->getDbName()} has been previously updated!"); + } + + $currTs = intval($afterInstance->getDbLastScheduled("U")) ? : 0; + if ($origAfterTs !== $currTs) { + $show = $afterInstance->getCcShow($this->con); + throw new OutDatedScheduleException("The show {$show->getDbName()} has been previously updated!"); + } + + $this->removeGaps($selectedInstance->getDbId(), $selected->getDbId()); $data = $this->fileInfo; $data["id"] = $selected->getDbFileId(); @@ -276,7 +320,7 @@ class Application_Model_Scheduler { $data["fadeout"] = $selected->getDbFadeOut(); $data["sched_id"] = $selected->getDbId(); - $this->insertAfter($afterItem, array($data), $adjustSched); + $this->insertAfter($afterItems, array($data), $adjustSched); $this->con->commit(); @@ -288,14 +332,35 @@ class Application_Model_Scheduler { } } - public function removeItems($scheduledIds, $adjustSched = true) { + public function removeItems($scheduledItems, $adjustSched = true) { $showInstances = array(); $this->con->beginTransaction(); try { - $removedItems = CcScheduleQuery::create()->findPks($scheduledIds); + $scheduledIds = array(); + foreach ($scheduledItems as $item) { + $scheduledIds[$item["id"]] = intval($item["timestamp"]); + } + + $removedItems = CcScheduleQuery::create()->findPks(array_keys($scheduledIds)); + + //check to make sure all items selected are up to date + foreach ($removedItems as $removedItem) { + $ts = $scheduledIds[$removedItem->getDbId()]; + $instance = $removedItem->getCcShowInstances($this->con); + if (is_null($instance)) { + throw new OutDatedScheduleException("The schedule you're viewing is out of date!"); + } + $currTs = intval($instance->getDbLastScheduled("U")) ? : 0; + + if ($ts !== $currTs) { + $show = $instance->getCcShow($this->con); + throw new OutDatedScheduleException("The show {$show->getDbName()} has been previously updated!"); + } + } + $removedItems->delete($this->con); if ($adjustSched === true) { @@ -313,6 +378,11 @@ class Application_Model_Scheduler { } } + //update the last scheduled timestamp. + CcShowInstancesQuery::create() + ->filterByPrimaryKeys($showInstances) + ->update(array('DbLastScheduled' => new DateTime("now", new DateTimeZone("UTC"))), $this->con); + $this->con->commit(); Application_Model_RabbitMq::PushSchedule(); @@ -328,11 +398,15 @@ class Application_Model_Scheduler { * @param array $exclude * ids of sched items to remove from the calulation. */ - public function removeGaps($showInstance, $exclude=null) { + private function removeGaps($showInstance, $exclude=null) { Logging::log("removing gaps from show instance #".$showInstance); $instance = CcShowInstancesQuery::create()->findPK($showInstance, $this->con); + if (is_null($instance)) { + throw new OutDatedScheduleException("The schedule you're viewing is out of date!"); + } + $itemStartDT = $instance->getDbStarts(null); $schedule = CcScheduleQuery::create() @@ -346,7 +420,7 @@ class Application_Model_Scheduler { Logging::log("adjusting item #".$item->getDbId()); - $itemEndDT = $this->findEndTime($itemStartDT, $item->getDbClipLength()); + $itemEndDT = self::findEndTime($itemStartDT, $item->getDbClipLength()); $item->setDbStarts($itemStartDT); $item->setDbEnds($itemEndDT); @@ -355,4 +429,6 @@ class Application_Model_Scheduler { $itemStartDT = $itemEndDT; } } -} \ No newline at end of file +} + +class OutDatedScheduleException extends Exception {} \ No newline at end of file diff --git a/airtime_mvc/application/models/Show.php b/airtime_mvc/application/models/Show.php index 31bd75d44..c46729e3e 100644 --- a/airtime_mvc/application/models/Show.php +++ b/airtime_mvc/application/models/Show.php @@ -351,13 +351,15 @@ class Application_Model_Show { public function isRepeating() { $showDaysRow = CcShowDaysQuery::create() - ->filterByDbShowId($this->_showId) - ->findOne(); + ->filterByDbShowId($this->_showId) + ->findOne(); if (!is_null($showDaysRow)){ return ($showDaysRow->getDbRepeatType() != -1); - } else + } + else { return false; + } } /** @@ -1164,7 +1166,9 @@ class Application_Model_Show { Logging::log('$start time of non repeating record '.$start); - self::createRebroadcastInstances($rebroadcasts, $currentUtcTimestamp, $show_id, $show_instance_id, $start, $duration, $timezone); + if ($newInstance){ + self::createRebroadcastInstances($rebroadcasts, $currentUtcTimestamp, $show_id, $show_instance_id, $start, $duration, $timezone); + } } } @@ -1392,7 +1396,7 @@ class Application_Model_Show { Application_Model_Preference::SetShowsPopulatedUntil($end_timestamp); } - $sql = "SELECT starts, ends, record, rebroadcast, instance_id, show_id, name, description, + $sql = "SELECT starts, ends, record, rebroadcast, instance_id, show_id, name, color, background_color, file_id, cc_show_instances.id AS instance_id FROM cc_show_instances LEFT JOIN cc_show ON cc_show.id = cc_show_instances.show_id @@ -1455,18 +1459,18 @@ class Application_Model_Show { $endTimeString = $p_endTimestamp->format("Y-m-d H:i:s"); if (!is_null($p_startTimestamp)) { $startTimeString = $p_startTimestamp->format("Y-m-d H:i:s"); - $sql = "SELECT * FROM cc_show_days - WHERE last_show IS NULL - OR first_show < '{$endTimeString}' AND last_show > '{$startTimeString}'"; } else { $today_timestamp = new DateTime("now", new DateTimeZone("UTC")); - $today_timestamp_string = $today_timestamp->format("Y-m-d H:i:s"); - $sql = "SELECT * FROM cc_show_days - WHERE last_show IS NULL - OR first_show < '{$endTimeString}' AND last_show > '{$today_timestamp_string}'"; + $startTimeString = $today_timestamp->format("Y-m-d H:i:s"); } + $sql = "SELECT * FROM cc_show_days + WHERE last_show IS NULL + OR first_show < '{$endTimeString}' AND last_show > '{$startTimeString}'"; + + Logging::log($sql); + $res = $CC_DBC->GetAll($sql); foreach ($res as $row) { @@ -1527,13 +1531,15 @@ class Application_Model_Show { $endDateTime = new DateTime($show["ends"], new DateTimeZone("UTC")); $endDateTime->setTimezone(new DateTimeZone(date_default_timezone_get())); - $event["id"] = $show["instance_id"]; + $event["id"] = intval($show["instance_id"]); $event["title"] = $show["name"]; $event["start"] = $startDateTime->format("Y-m-d H:i:s"); + $event["startUnix"] = $startDateTime->format("U"); $event["end"] = $endDateTime->format("Y-m-d H:i:s"); + $event["endUnix"] = $endDateTime->format("U"); $event["allDay"] = false; $event["description"] = $show["description"]; - $event["showId"] = $show["show_id"]; + $event["showId"] = intval($show["show_id"]); $event["record"] = intval($show["record"]); $event["rebroadcast"] = intval($show["rebroadcast"]); diff --git a/airtime_mvc/application/models/ShowBuilder.php b/airtime_mvc/application/models/ShowBuilder.php index 136ceea5c..01dc84636 100644 --- a/airtime_mvc/application/models/ShowBuilder.php +++ b/airtime_mvc/application/models/ShowBuilder.php @@ -6,6 +6,9 @@ class Application_Model_ShowBuilder { private $startDT; private $endDT; private $user; + private $opts; + + private $contentDT; private $defaultRowArray = array( "header" => false, @@ -15,25 +18,25 @@ class Application_Model_ShowBuilder { "id" => 0, "instance" => "", "starts" => "", - "startsUnix" => null, "ends" => "", - "endsUnix" => null, "runtime" => "", "title" => "", "creator" => "", - "album" => "" + "album" => "", + "timestamp" => null ); /* * @param DateTime $p_startsDT * @param DateTime $p_endsDT */ - public function __construct($p_startDT, $p_endDT) { + public function __construct($p_startDT, $p_endDT, $p_opts) { $this->startDT = $p_startDT; $this->endDT = $p_endDT; $this->timezone = date_default_timezone_get(); $this->user = Application_Model_User::GetCurrentUser(); + $this->opts = $p_opts; } /* @@ -56,17 +59,64 @@ class Application_Model_ShowBuilder { return $runtime; } - private function makeFooterRow() { + private function formatTimeFilled($p_sec) { + + $formatted = ""; + $sign = ($p_sec < 0) ? "-" : "+"; + + $time = Application_Model_Playlist::secondsToPlaylistTime(abs($p_sec)); + Logging::log("time is: ".$time); + $info = explode(":", $time); + + $formatted .= $sign; + + if ($info[0] > 0) { + $formatted .= " {$info[0]}h"; + } + + if ($info[1] > 0) { + $formatted .= " {$info[1]}m"; + } + + if ($info[2] > 0) { + $sec = round($info[2], 0); + $formatted .= " {$sec}s"; + } + + return $formatted; + } + + private function makeFooterRow($p_item) { $row = $this->defaultRowArray; $row["footer"] = true; + $showEndDT = new DateTime($p_item["si_ends"], new DateTimeZone("UTC")); + $contentDT = $this->contentDT; + + $runtime = bcsub($contentDT->format("U.u"), $showEndDT->format("U.u"), 6); + $row["runtime"] = $runtime; + $row["fRuntime"] = $this->formatTimeFilled($runtime); + return $row; } + private function getRowTimestamp($p_item, &$row) { + + if (is_null($p_item["si_last_scheduled"])) { + $ts = 0; + } + else { + $dt = new DateTime($p_item["si_last_scheduled"], new DateTimeZone("UTC")); + $ts = intval($dt->format("U")); + } + $row["timestamp"] = $ts; + } + private function makeHeaderRow($p_item) { $row = $this->defaultRowArray; + $this->getRowTimestamp($p_item, &$row); $showStartDT = new DateTime($p_item["si_starts"], new DateTimeZone("UTC")); $showStartDT->setTimezone(new DateTimeZone($this->timezone)); @@ -80,13 +130,20 @@ class Application_Model_ShowBuilder { $row["title"] = $p_item["show_name"]; $row["instance"] = intval($p_item["si_id"]); + $this->contentDT = $showStartDT; + return $row; } private function makeScheduledItemRow($p_item) { $row = $this->defaultRowArray; + $epoch_now = time(); - if ($this->user->canSchedule($item["show_id"]) == true) { + $showStartDT = new DateTime($p_item["si_starts"], new DateTimeZone("UTC")); + $this->getRowTimestamp($p_item, &$row); + + //can only schedule the show if it hasn't started and you are allowed. + if ($epoch_now < $showStartDT->format('U') && $this->user->canSchedule($p_item["show_id"]) == true) { $row["checkbox"] = true; } @@ -107,6 +164,8 @@ class Application_Model_ShowBuilder { $row["title"] = $p_item["file_track_title"]; $row["creator"] = $p_item["file_artist_name"]; $row["album"] = $p_item["file_album_title"]; + + $this->contentDT = $schedEndDT; } //show is empty else { @@ -123,16 +182,35 @@ class Application_Model_ShowBuilder { $current_id = -1; $display_items = array(); - $scheduled_items = Application_Model_Schedule::GetScheduleDetailItems($this->startDT->format("Y-m-d H:i:s"), $this->endDT->format("Y-m-d H:i:s")); + $shows = array(); + if ($this->opts["myShows"] === 1) { - foreach ($scheduled_items as $item) { + $host_shows = CcShowHostsQuery::create() + ->setFormatter(ModelCriteria::FORMAT_ON_DEMAND) + ->filterByDbHost($this->user->getId()) + ->find(); + + foreach ($host_shows as $host_show) { + $shows[] = $host_show->getDbShow(); + } + } + else if ($this->opts["showFilter"] !== 0) { + $shows[] = $this->opts["showFilter"]; + } + + $scheduled_items = Application_Model_Schedule::GetScheduleDetailItems($this->startDT->format("Y-m-d H:i:s"), $this->endDT->format("Y-m-d H:i:s"), $shows); + + for ($i = 0, $rows = count($scheduled_items); $i < $rows; $i++) { + + $item = $scheduled_items[$i]; //make a header row. if ($current_id !== $item["si_id"]) { //make a footer row. if ($current_id !== -1) { - $display_items[] = $this->makeFooterRow(); + //pass in the previous row as it's the last row for the previous show. + $display_items[] = $this->makeFooterRow($scheduled_items[$i-1]); } $display_items[] = $this->makeHeaderRow($item); @@ -146,7 +224,7 @@ class Application_Model_ShowBuilder { //make the last footer if there were any scheduled items. if (count($scheduled_items) > 0) { - $display_items[] = $this->makeFooterRow(); + $display_items[] = $this->makeFooterRow($scheduled_items[count($scheduled_items)-1]); } return $display_items; diff --git a/airtime_mvc/application/models/ShowInstance.php b/airtime_mvc/application/models/ShowInstance.php index de62f7c83..984304c7b 100644 --- a/airtime_mvc/application/models/ShowInstance.php +++ b/airtime_mvc/application/models/ShowInstance.php @@ -58,21 +58,19 @@ class Application_Model_ShowInstance { /** * Return the start time of the Show (UTC time) * @return string in format "Y-m-d H:i:s" (PHP time notation) - * TODO: make this function return a DateTime object instead. */ - public function getShowInstanceStart() + public function getShowInstanceStart($format="Y-m-d H:i:s") { - return $this->_showInstance->getDbStarts(); + return $this->_showInstance->getDbStarts($format); } /** * Return the end time of the Show (UTC time) * @return string in format "Y-m-d H:i:s" (PHP time notation) - * TODO: make this function return a DateTime object instead. */ - public function getShowInstanceEnd() + public function getShowInstanceEnd($format="Y-m-d H:i:s") { - return $this->_showInstance->getDbEnds(); + return $this->_showInstance->getDbEnds($format); } public function getStartDate() @@ -444,6 +442,81 @@ class Application_Model_ShowInstance { $this->updateScheduledTime(); } + private function checkToDeleteShow($showId) + { + //UTC DateTime object + $showsPopUntil = Application_Model_Preference::GetShowsPopulatedUntil(); + + $showDays = CcShowDaysQuery::create() + ->filterByDbShowId($showId) + ->findOne(); + + $showEnd = $showDays->getDbLastShow(); + + //there will always be more shows populated. + if (is_null($showEnd)) { + return false; + } + + $lastShowStartDateTime = new DateTime("{$showEnd} {$showDays->getDbStartTime()}", new DateTimeZone($showDays->getDbTimezone())); + //end dates were non inclusive. + $lastShowStartDateTime = self::addDeltas($lastShowStartDateTime, -1, 0); + + //there's still some shows left to be populated. + if ($lastShowStartDateTime->getTimestamp() > $showsPopUntil->getTimestamp()) { + return false; + } + + // check if there are any non deleted show instances remaining. + $showInstances = CcShowInstancesQuery::create() + ->filterByDbShowId($showId) + ->filterByDbModifiedInstance(false) + ->filterByDbRebroadcast(0) + ->find(); + + if (is_null($showInstances)){ + return true; + } + //only 1 show instance left of the show, make it non repeating. + else if (count($showInstances) === 1) { + $showInstance = $showInstances[0]; + + $showDaysOld = CcShowDaysQuery::create() + ->filterByDbShowId($showId) + ->find(); + + $tz = $showDaysOld[0]->getDbTimezone(); + + $startDate = new DateTime($showInstance->getDbStarts(), new DateTimeZone("UTC")); + $startDate->setTimeZone(new DateTimeZone($tz)); + $endDate = self::addDeltas($startDate, 1, 0); + + //make a new rule for a non repeating show. + $showDayNew = new CcShowDays(); + $showDayNew->setDbFirstShow($startDate->format("Y-m-d")); + $showDayNew->setDbLastShow($endDate->format("Y-m-d")); + $showDayNew->setDbStartTime($startDate->format("H:i:s")); + $showDayNew->setDbTimezone($tz); + $showDayNew->setDbDay($startDate->format('w')); + $showDayNew->setDbDuration($showDaysOld[0]->getDbDuration()); + $showDayNew->setDbRepeatType(-1); + $showDayNew->setDbShowId($showDaysOld[0]->getDbShowId()); + $showDayNew->setDbRecord($showDaysOld[0]->getDbRecord()); + $showDayNew->save(); + + //delete the old rules for repeating shows + $showDaysOld->delete(); + + //remove the old repeating deleted instances. + $showInstances = CcShowInstancesQuery::create() + ->filterByDbShowId($showId) + ->filterByDbModifiedInstance(true) + ->delete(); + } + + return false; + } + public function delete() { global $CC_DBC; @@ -465,6 +538,10 @@ class Application_Model_ShowInstance { ->setDbModifiedInstance(true) ->save(); + if ($this->isRebroadcast()) { + return; + } + //delete the rebroadcasts of the removed recorded show. if ($recording) { CcShowInstancesQuery::create() @@ -477,17 +554,8 @@ class Application_Model_ShowInstance { ->filterByDbInstanceId($this->_instanceId) ->delete(); - // check if we can safely delete the show - $showInstancesRow = CcShowInstancesQuery::create() - ->filterByDbShowId($showId) - ->filterByDbModifiedInstance(false) - ->findOne(); - /* If we didn't find any instances of the show that haven't - * been deleted, then just erase everything related to that show. - * We can just delete, the show and the foreign key-constraint should - * take care of deleting all of its instances. */ - if(is_null($showInstancesRow)){ + if ($this->checkToDeleteShow($showId)){ CcShowQuery::create() ->filterByDbId($showId) ->delete(); @@ -537,20 +605,26 @@ class Application_Model_ShowInstance { return $time; } + + public function getTimeScheduledSecs() + { + $time_filled = $this->getTimeScheduled(); + return Application_Model_Schedule::WallTimeToMillisecs($time_filled) / 1000; + } + + public function getDurationSecs() + { + $ends = $this->getShowInstanceEnd(null); + $starts = $this->getShowInstanceStart(null); + return $ends->format('U') - $starts->format('U'); + } + public function getPercentScheduled() { - $start_timestamp = $this->getShowInstanceStart(); - $end_timestamp = $this->getShowInstanceEnd(); - $time_filled = $this->getTimeScheduled(); + $durationSeconds = $this->getDurationSecs(); + $timeSeconds = $this->getTimeScheduledSecs(); - $s_epoch = strtotime($start_timestamp); - $e_epoch = strtotime($end_timestamp); - $i_epoch = Application_Model_Schedule::WallTimeToMillisecs($time_filled) / 1000; - - $percent = ceil(($i_epoch / ($e_epoch - $s_epoch)) * 100); - - if ($percent > 100) - $percent = 100; + $percent = ceil(($timeSeconds / $durationSeconds) * 100); return $percent; } @@ -714,6 +788,7 @@ class Application_Model_ShowInstance { $sql = "SELECT si.id" ." FROM $CC_CONFIG[showInstances] si" ." WHERE si.ends < TIMESTAMP '$p_timeNow'" + ." AND si.modified_instance = 'f'" ." ORDER BY si.ends DESC" ." LIMIT 1"; @@ -728,10 +803,18 @@ class Application_Model_ShowInstance { public static function GetCurrentShowInstance($p_timeNow){ global $CC_CONFIG, $CC_DBC; + /* Orderby si.starts descending, because in some cases + * we can have multiple shows overlapping each other. In + * this case, the show that started later is the one that + * is actually playing, and so this is the one we want. + */ + $sql = "SELECT si.id" ." FROM $CC_CONFIG[showInstances] si" ." WHERE si.starts <= TIMESTAMP '$p_timeNow'" ." AND si.ends > TIMESTAMP '$p_timeNow'" + ." AND si.modified_instance = 'f'" + ." ORDER BY si.starts DESC" ." LIMIT 1"; $id = $CC_DBC->GetOne($sql); @@ -748,6 +831,7 @@ class Application_Model_ShowInstance { $sql = "SELECT si.id" ." FROM $CC_CONFIG[showInstances] si" ." WHERE si.starts > TIMESTAMP '$p_timeNow'" + ." AND si.modified_instance = 'f'" ." ORDER BY si.starts" ." LIMIT 1"; diff --git a/airtime_mvc/application/models/StoredFile.php b/airtime_mvc/application/models/StoredFile.php index 05a25abef..175c2b918 100644 --- a/airtime_mvc/application/models/StoredFile.php +++ b/airtime_mvc/application/models/StoredFile.php @@ -583,7 +583,7 @@ class Application_Model_StoredFile { { global $CC_CONFIG; - $displayData = array("track_title", "artist_name", "album_title", "genre", "length", "year", "utime", "mtime", "ftype"); + $displayData = array("track_title", "artist_name", "album_title", "genre", "length", "year", "utime", "mtime", "ftype", "track_number"); $plSelect = "SELECT "; $fileSelect = "SELECT "; @@ -610,6 +610,9 @@ class Application_Model_StoredFile { } else if ($key === "mtime") { $plSelect .= $key.", "; $fileSelect .= $key.", "; + } else if ($key === "track_number") { + $plSelect .= "NULL AS ".$key.", "; + $fileSelect .= $key.", "; } else { $plSelect .= "NULL AS ".$key.", "; $fileSelect .= $key.", "; @@ -621,7 +624,8 @@ class Application_Model_StoredFile { UNION (".$fileSelect."id FROM ".$CC_CONFIG["filesTable"]." AS FILES WHERE file_exists = 'TRUE')) AS RESULTS"; - $results = Application_Model_StoredFile::searchFiles($fromTable, $datatables); + $results = Application_Model_StoredFile::searchFiles($fromTable, $datatables); + foreach($results['aaData'] as &$row){ @@ -733,6 +737,7 @@ class Application_Model_StoredFile { $sql = $selectorRows." FROM ".$fromTable." ORDER BY ".$orderby." OFFSET ".$data["iDisplayStart"]." LIMIT ".$data["iDisplayLength"]; } + //display sql executed in airtime log for testing //Logging::log($sql); $results = $CC_DBC->getAll($sql); @@ -847,57 +852,61 @@ class Application_Model_StoredFile { * enough space to move the $audio_file into and report back to the user if not. **/ public static function checkForEnoughDiskSpaceToCopy($destination_folder, $audio_file){ - //check to see if we have enough space in the /organize directory to copy the file - $freeSpace = disk_free_space($destination_folder); - $fileSize = filesize($audio_file); - - if ( $freeSpace < $fileSize ){ - $freeSpace = floor($freeSpace/1024/1024); - $fileSize = floor($fileSize/1024/1024); - die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "The file was not uploaded, there was '.$freeSpace.'MB disk space left the file you are uploadings size is '.$fileSize.'MB."}}'); - } + //check to see if we have enough space in the /organize directory to copy the file + $freeSpace = disk_free_space($destination_folder); + $fileSize = filesize($audio_file); + + if ( $freeSpace < $fileSize){ + $freeSpace = ceil($freeSpace/1024/1024); + $fileSize = ceil($fileSize/1024/1024); + $result = array("code" => 107, "message" => "The file was not uploaded, there is ".$freeSpace."MB of disk space left and the file you are uploading has a size of ".$fileSize."MB."); + + } + return $result; } - + public static function copyFileToStor($p_targetDir, $fileName, $tempname){ $audio_file = $p_targetDir . DIRECTORY_SEPARATOR . $tempname; Logging::log('copyFileToStor: moving file '.$audio_file); $md5 = md5_file($audio_file); $duplicate = Application_Model_StoredFile::RecallByMd5($md5); if ($duplicate) { - if (PEAR::isError($duplicate)) { - die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": ' . $duplicate->getMessage() .'}}'); + if (PEAR::isError($duplicate)) { + $result = array("code" => 105, "message" => $duplicate->getMessage()); } if (file_exists($duplicate->getFilePath())) { $duplicateName = $duplicate->getMetadataValue('MDATA_KEY_TITLE'); - die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "An identical audioclip named \"' . $duplicateName . '\" already exists on the server."}}'); + $result = array( "code" => 106, "message" => "An identical audioclip named '$duplicateName' already exists on the server."); } } - $storDir = Application_Model_MusicDir::getStorDir(); - $stor = $storDir->getDirectory(); - - //check to see if there is enough space in $stor to continue. - Application_Model_StoredFile::checkForEnoughDiskSpaceToCopy($stor, $audio_file); - - $stor .= "/organize"; - $audio_stor = $stor . DIRECTORY_SEPARATOR . $fileName; - - Logging::log("copyFileToStor: moving file $audio_file to $audio_stor"); - //Martin K.: changed to rename: Much less load + quicker since this is an atomic operation - $r = @rename($audio_file, $audio_stor); + if (!isset($result)){//The file has no duplicate, so procceed to copy. + $storDir = Application_Model_MusicDir::getStorDir(); + $stor = $storDir->getDirectory(); - if ($r === false) { - #something went wrong likely there wasn't enough space in the audio_stor to move the file too. - #warn the user that the file wasn't uploaded and they should check if there is enough disk space. - unlink($audio_file);//remove the file from the organize after failed rename - die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "The file was not uploaded, this error will occur if the computer hard drive does not have enough disk space."}}'); - } + //check to see if there is enough space in $stor to continue. + $result = Application_Model_StoredFile::checkForEnoughDiskSpaceToCopy($stor, $audio_file); + if (!isset($result)){//if result not set then there's enough disk space to copy the file over + $stor .= "/organize"; + $audio_stor = $stor . DIRECTORY_SEPARATOR . $fileName; - //$r = @copy($audio_file, $audio_stor); - //$r = @unlink($audio_file); + Logging::log("copyFileToStor: moving file $audio_file to $audio_stor"); + //Martin K.: changed to rename: Much less load + quicker since this is an atomic operation + $r = @rename($audio_file, $audio_stor); + + if ($r === false) { + #something went wrong likely there wasn't enough space in the audio_stor to move the file too. + #warn the user that the file wasn't uploaded and they should check if there is enough disk space. + unlink($audio_file);//remove the file from the organize after failed rename + $result = array("code" => 108, "message" => "The file was not uploaded, this error will occur if the computer hard drive does not have enough disk space."); + + } + } + } + return $result; } - + public static function getFileCount() { global $CC_CONFIG, $CC_DBC; @@ -1028,3 +1037,4 @@ class Application_Model_StoredFile { } class DeleteScheduledFileException extends Exception {} +class FileDoesNotExistException extends Exception {} diff --git a/airtime_mvc/application/models/StreamSetting.php b/airtime_mvc/application/models/StreamSetting.php index 1e4d77956..0ae84a009 100644 --- a/airtime_mvc/application/models/StreamSetting.php +++ b/airtime_mvc/application/models/StreamSetting.php @@ -83,8 +83,12 @@ class Application_Model_StreamSetting { $CC_DBC->query($sql); } else if ($key == "output_sound_device_type") { $sql = "UPDATE cc_stream_setting SET value='$d' WHERE keyname='$key'"; - $CC_DBC->query($sql); - } else { + $CC_DBC->query($sql); + } else if ($key == "streamFormat"){ + // this goes into cc_pref table + Logging::log("Insert stream label format $d"); + Application_Model_Preference::SetStreamLabelFormat($d); + } else if (is_array($d)) { $temp = explode('_', $key); $prefix = $temp[0]; foreach ($d as $k=>$v) { @@ -96,6 +100,8 @@ class Application_Model_StreamSetting { $sql = "UPDATE cc_stream_setting SET value='$v' WHERE keyname='$keyname'"; $CC_DBC->query($sql); } + } else { + Logging::log("Warning unexpected value: ".$key); } } } diff --git a/airtime_mvc/application/models/Systemstatus.php b/airtime_mvc/application/models/Systemstatus.php index 5231ba350..601cbaa1f 100644 --- a/airtime_mvc/application/models/Systemstatus.php +++ b/airtime_mvc/application/models/Systemstatus.php @@ -120,23 +120,31 @@ class Application_Model_Systemstatus public static function GetPypoStatus(){ $component = CcServiceRegisterQuery::create()->findOneByDbName("pypo"); - $ip = $component->getDbIp(); - - $docRoot = self::GetMonitStatus($ip); - $data = self::ExtractServiceInformation($docRoot, "airtime-playout"); + if (is_null($component)){ + return null; + } else { + $ip = $component->getDbIp(); + + $docRoot = self::GetMonitStatus($ip); + $data = self::ExtractServiceInformation($docRoot, "airtime-playout"); - return $data; + return $data; + } } public static function GetLiquidsoapStatus(){ $component = CcServiceRegisterQuery::create()->findOneByDbName("pypo"); - $ip = $component->getDbIp(); - - $docRoot = self::GetMonitStatus($ip); - $data = self::ExtractServiceInformation($docRoot, "airtime-liquidsoap"); + if (is_null($component)){ + return null; + } else { + $ip = $component->getDbIp(); + + $docRoot = self::GetMonitStatus($ip); + $data = self::ExtractServiceInformation($docRoot, "airtime-liquidsoap"); - return $data; + return $data; + } } public static function GetShowRecorderStatus(){ diff --git a/airtime_mvc/application/models/airtime/CcShowInstances.php b/airtime_mvc/application/models/airtime/CcShowInstances.php index 26d568f09..d1c97f437 100644 --- a/airtime_mvc/application/models/airtime/CcShowInstances.php +++ b/airtime_mvc/application/models/airtime/CcShowInstances.php @@ -76,4 +76,35 @@ class CcShowInstances extends BaseCcShowInstances { return $dt->format($format); } } + + /** + * Get the [optionally formatted] temporal [last_scheduled] column value. + * + * + * @param string $format The date/time format string (either date()-style or strftime()-style). + * If format is NULL, then the raw DateTime object will be returned. + * @return mixed Formatted date/time value as string or DateTime object (if format is NULL), NULL if column is NULL + * @throws PropelException - if unable to parse/validate the date/time value. + */ + public function getDbLastScheduled($format = 'Y-m-d H:i:s') + { + if ($this->last_scheduled === null) { + return null; + } + + try { + $dt = new DateTime($this->last_scheduled, new DateTimeZone("UTC")); + } catch (Exception $x) { + throw new PropelException("Internally stored date/time/timestamp value could not be converted to DateTime: " . var_export($this->last_scheduled, true), $x); + } + + if ($format === null) { + // Because propel.useDateTimeClass is TRUE, we return a DateTime object. + return $dt; + } elseif (strpos($format, '%') !== false) { + return strftime($format, $dt->format('U')); + } else { + return $dt->format($format); + } + } } // CcShowInstances diff --git a/airtime_mvc/application/models/airtime/map/CcShowInstancesTableMap.php b/airtime_mvc/application/models/airtime/map/CcShowInstancesTableMap.php index 75e7da2c7..b605da53d 100644 --- a/airtime_mvc/application/models/airtime/map/CcShowInstancesTableMap.php +++ b/airtime_mvc/application/models/airtime/map/CcShowInstancesTableMap.php @@ -46,7 +46,8 @@ class CcShowInstancesTableMap extends TableMap { $this->addColumn('REBROADCAST', 'DbRebroadcast', 'TINYINT', false, null, 0); $this->addForeignKey('INSTANCE_ID', 'DbOriginalShow', 'INTEGER', 'cc_show_instances', 'ID', false, null, null); $this->addForeignKey('FILE_ID', 'DbRecordedFile', 'INTEGER', 'cc_files', 'ID', false, null, null); - $this->addColumn('TIME_FILLED', 'DbTimeFilled', 'TIME', false, null, null); + $this->addColumn('TIME_FILLED', 'DbTimeFilled', 'VARCHAR', false, null, '00:00:00'); + $this->addColumn('LAST_SCHEDULED', 'DbLastScheduled', 'TIMESTAMP', false, null, null); $this->addColumn('MODIFIED_INSTANCE', 'DbModifiedInstance', 'BOOLEAN', true, null, false); // validators } // initialize() diff --git a/airtime_mvc/application/models/airtime/om/BaseCcPlaylistcontents.php b/airtime_mvc/application/models/airtime/om/BaseCcPlaylistcontents.php index 44b6c7a6e..457a9b958 100644 --- a/airtime_mvc/application/models/airtime/om/BaseCcPlaylistcontents.php +++ b/airtime_mvc/application/models/airtime/om/BaseCcPlaylistcontents.php @@ -4,7 +4,7 @@ /** * Base class that represents a row from the 'cc_playlistcontents' table. * - * + * * * @package propel.generator.airtime.om */ @@ -137,7 +137,7 @@ abstract class BaseCcPlaylistcontents extends BaseObject implements Persistent /** * Get the [id] column value. - * + * * @return int */ public function getDbId() @@ -147,7 +147,7 @@ abstract class BaseCcPlaylistcontents extends BaseObject implements Persistent /** * Get the [playlist_id] column value. - * + * * @return int */ public function getDbPlaylistId() @@ -157,7 +157,7 @@ abstract class BaseCcPlaylistcontents extends BaseObject implements Persistent /** * Get the [file_id] column value. - * + * * @return int */ public function getDbFileId() @@ -167,7 +167,7 @@ abstract class BaseCcPlaylistcontents extends BaseObject implements Persistent /** * Get the [position] column value. - * + * * @return int */ public function getDbPosition() @@ -177,7 +177,7 @@ abstract class BaseCcPlaylistcontents extends BaseObject implements Persistent /** * Get the [optionally formatted] temporal [cliplength] column value. - * + * * * @param string $format The date/time format string (either date()-style or strftime()-style). * If format is NULL, then the raw DateTime object will be returned. @@ -210,7 +210,7 @@ abstract class BaseCcPlaylistcontents extends BaseObject implements Persistent /** * Get the [optionally formatted] temporal [cuein] column value. - * + * * * @param string $format The date/time format string (either date()-style or strftime()-style). * If format is NULL, then the raw DateTime object will be returned. @@ -243,7 +243,7 @@ abstract class BaseCcPlaylistcontents extends BaseObject implements Persistent /** * Get the [optionally formatted] temporal [cueout] column value. - * + * * * @param string $format The date/time format string (either date()-style or strftime()-style). * If format is NULL, then the raw DateTime object will be returned. @@ -276,7 +276,7 @@ abstract class BaseCcPlaylistcontents extends BaseObject implements Persistent /** * Get the [optionally formatted] temporal [fadein] column value. - * + * * * @param string $format The date/time format string (either date()-style or strftime()-style). * If format is NULL, then the raw DateTime object will be returned. @@ -289,6 +289,8 @@ abstract class BaseCcPlaylistcontents extends BaseObject implements Persistent return null; } + + try { $dt = new DateTime($this->fadein); } catch (Exception $x) { @@ -307,7 +309,7 @@ abstract class BaseCcPlaylistcontents extends BaseObject implements Persistent /** * Get the [optionally formatted] temporal [fadeout] column value. - * + * * * @param string $format The date/time format string (either date()-style or strftime()-style). * If format is NULL, then the raw DateTime object will be returned. @@ -340,7 +342,7 @@ abstract class BaseCcPlaylistcontents extends BaseObject implements Persistent /** * Set the value of [id] column. - * + * * @param int $v new value * @return CcPlaylistcontents The current object (for fluent API support) */ @@ -360,7 +362,7 @@ abstract class BaseCcPlaylistcontents extends BaseObject implements Persistent /** * Set the value of [playlist_id] column. - * + * * @param int $v new value * @return CcPlaylistcontents The current object (for fluent API support) */ @@ -384,7 +386,7 @@ abstract class BaseCcPlaylistcontents extends BaseObject implements Persistent /** * Set the value of [file_id] column. - * + * * @param int $v new value * @return CcPlaylistcontents The current object (for fluent API support) */ @@ -408,7 +410,7 @@ abstract class BaseCcPlaylistcontents extends BaseObject implements Persistent /** * Set the value of [position] column. - * + * * @param int $v new value * @return CcPlaylistcontents The current object (for fluent API support) */ @@ -428,7 +430,7 @@ abstract class BaseCcPlaylistcontents extends BaseObject implements Persistent /** * Sets the value of [cliplength] column to a normalized version of the date/time value specified. - * + * * @param mixed $v string, integer (timestamp), or DateTime value. Empty string will * be treated as NULL for temporal objects. * @return CcPlaylistcontents The current object (for fluent API support) @@ -464,7 +466,7 @@ abstract class BaseCcPlaylistcontents extends BaseObject implements Persistent $currNorm = ($this->cliplength !== null && $tmpDt = new DateTime($this->cliplength)) ? $tmpDt->format('H:i:s') : null; $newNorm = ($dt !== null) ? $dt->format('H:i:s') : null; - if ( ($currNorm !== $newNorm) // normalized values don't match + if ( ($currNorm !== $newNorm) // normalized values don't match || ($dt->format('H:i:s') === '00:00:00') // or the entered value matches the default ) { @@ -478,7 +480,7 @@ abstract class BaseCcPlaylistcontents extends BaseObject implements Persistent /** * Sets the value of [cuein] column to a normalized version of the date/time value specified. - * + * * @param mixed $v string, integer (timestamp), or DateTime value. Empty string will * be treated as NULL for temporal objects. * @return CcPlaylistcontents The current object (for fluent API support) @@ -514,7 +516,7 @@ abstract class BaseCcPlaylistcontents extends BaseObject implements Persistent $currNorm = ($this->cuein !== null && $tmpDt = new DateTime($this->cuein)) ? $tmpDt->format('H:i:s') : null; $newNorm = ($dt !== null) ? $dt->format('H:i:s') : null; - if ( ($currNorm !== $newNorm) // normalized values don't match + if ( ($currNorm !== $newNorm) // normalized values don't match || ($dt->format('H:i:s') === '00:00:00') // or the entered value matches the default ) { @@ -528,7 +530,7 @@ abstract class BaseCcPlaylistcontents extends BaseObject implements Persistent /** * Sets the value of [cueout] column to a normalized version of the date/time value specified. - * + * * @param mixed $v string, integer (timestamp), or DateTime value. Empty string will * be treated as NULL for temporal objects. * @return CcPlaylistcontents The current object (for fluent API support) @@ -564,7 +566,7 @@ abstract class BaseCcPlaylistcontents extends BaseObject implements Persistent $currNorm = ($this->cueout !== null && $tmpDt = new DateTime($this->cueout)) ? $tmpDt->format('H:i:s') : null; $newNorm = ($dt !== null) ? $dt->format('H:i:s') : null; - if ( ($currNorm !== $newNorm) // normalized values don't match + if ( ($currNorm !== $newNorm) // normalized values don't match || ($dt->format('H:i:s') === '00:00:00') // or the entered value matches the default ) { @@ -578,7 +580,7 @@ abstract class BaseCcPlaylistcontents extends BaseObject implements Persistent /** * Sets the value of [fadein] column to a normalized version of the date/time value specified. - * + * * @param mixed $v string, integer (timestamp), or DateTime value. Empty string will * be treated as NULL for temporal objects. * @return CcPlaylistcontents The current object (for fluent API support) @@ -614,7 +616,7 @@ abstract class BaseCcPlaylistcontents extends BaseObject implements Persistent $currNorm = ($this->fadein !== null && $tmpDt = new DateTime($this->fadein)) ? $tmpDt->format('H:i:s') : null; $newNorm = ($dt !== null) ? $dt->format('H:i:s') : null; - if ( ($currNorm !== $newNorm) // normalized values don't match + if ( ($currNorm !== $newNorm) // normalized values don't match || ($dt->format('H:i:s') === '00:00:00') // or the entered value matches the default ) { @@ -628,7 +630,7 @@ abstract class BaseCcPlaylistcontents extends BaseObject implements Persistent /** * Sets the value of [fadeout] column to a normalized version of the date/time value specified. - * + * * @param mixed $v string, integer (timestamp), or DateTime value. Empty string will * be treated as NULL for temporal objects. * @return CcPlaylistcontents The current object (for fluent API support) @@ -664,7 +666,7 @@ abstract class BaseCcPlaylistcontents extends BaseObject implements Persistent $currNorm = ($this->fadeout !== null && $tmpDt = new DateTime($this->fadeout)) ? $tmpDt->format('H:i:s') : null; $newNorm = ($dt !== null) ? $dt->format('H:i:s') : null; - if ( ($currNorm !== $newNorm) // normalized values don't match + if ( ($currNorm !== $newNorm) // normalized values don't match || ($dt->format('H:i:s') === '00:00:00') // or the entered value matches the default ) { @@ -836,7 +838,7 @@ abstract class BaseCcPlaylistcontents extends BaseObject implements Persistent if ($con === null) { $con = Propel::getConnection(CcPlaylistcontentsPeer::DATABASE_NAME, Propel::CONNECTION_WRITE); } - + $con->beginTransaction(); try { $ret = $this->preDelete($con); @@ -878,7 +880,7 @@ abstract class BaseCcPlaylistcontents extends BaseObject implements Persistent if ($con === null) { $con = Propel::getConnection(CcPlaylistcontentsPeer::DATABASE_NAME, Propel::CONNECTION_WRITE); } - + $con->beginTransaction(); $isInsert = $this->isNew(); try { @@ -1131,7 +1133,7 @@ abstract class BaseCcPlaylistcontents extends BaseObject implements Persistent * type constants. * * @param string $keyType (optional) One of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME, - * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM. + * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM. * Defaults to BasePeer::TYPE_PHPNAME. * @param boolean $includeLazyLoadColumns (optional) Whether to include lazy loaded columns. Defaults to TRUE. * @param boolean $includeForeignObjects (optional) Whether to include hydrated related objects. Default to FALSE. @@ -1526,7 +1528,7 @@ abstract class BaseCcPlaylistcontents extends BaseObject implements Persistent } // aggregate_column_relation behavior - + /** * Update the aggregate column in the related CcPlaylist object * diff --git a/airtime_mvc/application/models/airtime/om/BaseCcShowInstances.php b/airtime_mvc/application/models/airtime/om/BaseCcShowInstances.php index c78c34142..d5701f2be 100644 --- a/airtime_mvc/application/models/airtime/om/BaseCcShowInstances.php +++ b/airtime_mvc/application/models/airtime/om/BaseCcShowInstances.php @@ -76,10 +76,17 @@ abstract class BaseCcShowInstances extends BaseObject implements Persistent /** * The value for the time_filled field. + * Note: this column has a database default value of: '00:00:00' * @var string */ protected $time_filled; + /** + * The value for the last_scheduled field. + * @var string + */ + protected $last_scheduled; + /** * The value for the modified_instance field. * Note: this column has a database default value of: false @@ -136,6 +143,7 @@ abstract class BaseCcShowInstances extends BaseObject implements Persistent { $this->record = 0; $this->rebroadcast = 0; + $this->time_filled = '00:00:00'; $this->modified_instance = false; } @@ -276,7 +284,17 @@ abstract class BaseCcShowInstances extends BaseObject implements Persistent } /** - * Get the [optionally formatted] temporal [time_filled] column value. + * Get the [time_filled] column value. + * + * @return string + */ + public function getDbTimeFilled() + { + return $this->time_filled; + } + + /** + * Get the [optionally formatted] temporal [last_scheduled] column value. * * * @param string $format The date/time format string (either date()-style or strftime()-style). @@ -284,18 +302,18 @@ abstract class BaseCcShowInstances extends BaseObject implements Persistent * @return mixed Formatted date/time value as string or DateTime object (if format is NULL), NULL if column is NULL * @throws PropelException - if unable to parse/validate the date/time value. */ - public function getDbTimeFilled($format = '%X') + public function getDbLastScheduled($format = 'Y-m-d H:i:s') { - if ($this->time_filled === null) { + if ($this->last_scheduled === null) { return null; } try { - $dt = new DateTime($this->time_filled); + $dt = new DateTime($this->last_scheduled); } catch (Exception $x) { - throw new PropelException("Internally stored date/time/timestamp value could not be converted to DateTime: " . var_export($this->time_filled, true), $x); + throw new PropelException("Internally stored date/time/timestamp value could not be converted to DateTime: " . var_export($this->last_scheduled, true), $x); } if ($format === null) { @@ -549,13 +567,33 @@ abstract class BaseCcShowInstances extends BaseObject implements Persistent } // setDbRecordedFile() /** - * Sets the value of [time_filled] column to a normalized version of the date/time value specified. + * Set the value of [time_filled] column. + * + * @param string $v new value + * @return CcShowInstances The current object (for fluent API support) + */ + public function setDbTimeFilled($v) + { + if ($v !== null) { + $v = (string) $v; + } + + if ($this->time_filled !== $v || $this->isNew()) { + $this->time_filled = $v; + $this->modifiedColumns[] = CcShowInstancesPeer::TIME_FILLED; + } + + return $this; + } // setDbTimeFilled() + + /** + * Sets the value of [last_scheduled] column to a normalized version of the date/time value specified. * * @param mixed $v string, integer (timestamp), or DateTime value. Empty string will * be treated as NULL for temporal objects. * @return CcShowInstances The current object (for fluent API support) */ - public function setDbTimeFilled($v) + public function setDbLastScheduled($v) { // we treat '' as NULL for temporal objects because DateTime('') == DateTime('now') // -- which is unexpected, to say the least. @@ -580,22 +618,22 @@ abstract class BaseCcShowInstances extends BaseObject implements Persistent } } - if ( $this->time_filled !== null || $dt !== null ) { + if ( $this->last_scheduled !== null || $dt !== null ) { // (nested ifs are a little easier to read in this case) - $currNorm = ($this->time_filled !== null && $tmpDt = new DateTime($this->time_filled)) ? $tmpDt->format('H:i:s') : null; - $newNorm = ($dt !== null) ? $dt->format('H:i:s') : null; + $currNorm = ($this->last_scheduled !== null && $tmpDt = new DateTime($this->last_scheduled)) ? $tmpDt->format('Y-m-d\\TH:i:sO') : null; + $newNorm = ($dt !== null) ? $dt->format('Y-m-d\\TH:i:sO') : null; if ( ($currNorm !== $newNorm) // normalized values don't match ) { - $this->time_filled = ($dt ? $dt->format('H:i:s') : null); - $this->modifiedColumns[] = CcShowInstancesPeer::TIME_FILLED; + $this->last_scheduled = ($dt ? $dt->format('Y-m-d\\TH:i:sO') : null); + $this->modifiedColumns[] = CcShowInstancesPeer::LAST_SCHEDULED; } } // if either are not null return $this; - } // setDbTimeFilled() + } // setDbLastScheduled() /** * Set the value of [modified_instance] column. @@ -635,6 +673,10 @@ abstract class BaseCcShowInstances extends BaseObject implements Persistent return false; } + if ($this->time_filled !== '00:00:00') { + return false; + } + if ($this->modified_instance !== false) { return false; } @@ -670,7 +712,8 @@ abstract class BaseCcShowInstances extends BaseObject implements Persistent $this->instance_id = ($row[$startcol + 6] !== null) ? (int) $row[$startcol + 6] : null; $this->file_id = ($row[$startcol + 7] !== null) ? (int) $row[$startcol + 7] : null; $this->time_filled = ($row[$startcol + 8] !== null) ? (string) $row[$startcol + 8] : null; - $this->modified_instance = ($row[$startcol + 9] !== null) ? (boolean) $row[$startcol + 9] : null; + $this->last_scheduled = ($row[$startcol + 9] !== null) ? (string) $row[$startcol + 9] : null; + $this->modified_instance = ($row[$startcol + 10] !== null) ? (boolean) $row[$startcol + 10] : null; $this->resetModified(); $this->setNew(false); @@ -679,7 +722,7 @@ abstract class BaseCcShowInstances extends BaseObject implements Persistent $this->ensureConsistency(); } - return $startcol + 10; // 10 = CcShowInstancesPeer::NUM_COLUMNS - CcShowInstancesPeer::NUM_LAZY_LOAD_COLUMNS). + return $startcol + 11; // 11 = CcShowInstancesPeer::NUM_COLUMNS - CcShowInstancesPeer::NUM_LAZY_LOAD_COLUMNS). } catch (Exception $e) { throw new PropelException("Error populating CcShowInstances object", $e); @@ -1104,6 +1147,9 @@ abstract class BaseCcShowInstances extends BaseObject implements Persistent return $this->getDbTimeFilled(); break; case 9: + return $this->getDbLastScheduled(); + break; + case 10: return $this->getDbModifiedInstance(); break; default: @@ -1139,7 +1185,8 @@ abstract class BaseCcShowInstances extends BaseObject implements Persistent $keys[6] => $this->getDbOriginalShow(), $keys[7] => $this->getDbRecordedFile(), $keys[8] => $this->getDbTimeFilled(), - $keys[9] => $this->getDbModifiedInstance(), + $keys[9] => $this->getDbLastScheduled(), + $keys[10] => $this->getDbModifiedInstance(), ); if ($includeForeignObjects) { if (null !== $this->aCcShow) { @@ -1210,6 +1257,9 @@ abstract class BaseCcShowInstances extends BaseObject implements Persistent $this->setDbTimeFilled($value); break; case 9: + $this->setDbLastScheduled($value); + break; + case 10: $this->setDbModifiedInstance($value); break; } // switch() @@ -1245,7 +1295,8 @@ abstract class BaseCcShowInstances extends BaseObject implements Persistent if (array_key_exists($keys[6], $arr)) $this->setDbOriginalShow($arr[$keys[6]]); if (array_key_exists($keys[7], $arr)) $this->setDbRecordedFile($arr[$keys[7]]); if (array_key_exists($keys[8], $arr)) $this->setDbTimeFilled($arr[$keys[8]]); - if (array_key_exists($keys[9], $arr)) $this->setDbModifiedInstance($arr[$keys[9]]); + if (array_key_exists($keys[9], $arr)) $this->setDbLastScheduled($arr[$keys[9]]); + if (array_key_exists($keys[10], $arr)) $this->setDbModifiedInstance($arr[$keys[10]]); } /** @@ -1266,6 +1317,7 @@ abstract class BaseCcShowInstances extends BaseObject implements Persistent if ($this->isColumnModified(CcShowInstancesPeer::INSTANCE_ID)) $criteria->add(CcShowInstancesPeer::INSTANCE_ID, $this->instance_id); if ($this->isColumnModified(CcShowInstancesPeer::FILE_ID)) $criteria->add(CcShowInstancesPeer::FILE_ID, $this->file_id); if ($this->isColumnModified(CcShowInstancesPeer::TIME_FILLED)) $criteria->add(CcShowInstancesPeer::TIME_FILLED, $this->time_filled); + if ($this->isColumnModified(CcShowInstancesPeer::LAST_SCHEDULED)) $criteria->add(CcShowInstancesPeer::LAST_SCHEDULED, $this->last_scheduled); if ($this->isColumnModified(CcShowInstancesPeer::MODIFIED_INSTANCE)) $criteria->add(CcShowInstancesPeer::MODIFIED_INSTANCE, $this->modified_instance); return $criteria; @@ -1336,6 +1388,7 @@ abstract class BaseCcShowInstances extends BaseObject implements Persistent $copyObj->setDbOriginalShow($this->instance_id); $copyObj->setDbRecordedFile($this->file_id); $copyObj->setDbTimeFilled($this->time_filled); + $copyObj->setDbLastScheduled($this->last_scheduled); $copyObj->setDbModifiedInstance($this->modified_instance); if ($deepCopy) { @@ -1854,6 +1907,7 @@ abstract class BaseCcShowInstances extends BaseObject implements Persistent $this->instance_id = null; $this->file_id = null; $this->time_filled = null; + $this->last_scheduled = null; $this->modified_instance = null; $this->alreadyInSave = false; $this->alreadyInValidation = false; diff --git a/airtime_mvc/application/models/airtime/om/BaseCcShowInstancesPeer.php b/airtime_mvc/application/models/airtime/om/BaseCcShowInstancesPeer.php index d30a1a8ab..6780ec14f 100644 --- a/airtime_mvc/application/models/airtime/om/BaseCcShowInstancesPeer.php +++ b/airtime_mvc/application/models/airtime/om/BaseCcShowInstancesPeer.php @@ -26,7 +26,7 @@ abstract class BaseCcShowInstancesPeer { const TM_CLASS = 'CcShowInstancesTableMap'; /** The total number of columns. */ - const NUM_COLUMNS = 10; + const NUM_COLUMNS = 11; /** The number of lazy-loaded columns. */ const NUM_LAZY_LOAD_COLUMNS = 0; @@ -58,6 +58,9 @@ abstract class BaseCcShowInstancesPeer { /** the column name for the TIME_FILLED field */ const TIME_FILLED = 'cc_show_instances.TIME_FILLED'; + /** the column name for the LAST_SCHEDULED field */ + const LAST_SCHEDULED = 'cc_show_instances.LAST_SCHEDULED'; + /** the column name for the MODIFIED_INSTANCE field */ const MODIFIED_INSTANCE = 'cc_show_instances.MODIFIED_INSTANCE'; @@ -77,12 +80,12 @@ abstract class BaseCcShowInstancesPeer { * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' */ private static $fieldNames = array ( - BasePeer::TYPE_PHPNAME => array ('DbId', 'DbStarts', 'DbEnds', 'DbShowId', 'DbRecord', 'DbRebroadcast', 'DbOriginalShow', 'DbRecordedFile', 'DbTimeFilled', 'DbModifiedInstance', ), - BasePeer::TYPE_STUDLYPHPNAME => array ('dbId', 'dbStarts', 'dbEnds', 'dbShowId', 'dbRecord', 'dbRebroadcast', 'dbOriginalShow', 'dbRecordedFile', 'dbTimeFilled', 'dbModifiedInstance', ), - BasePeer::TYPE_COLNAME => array (self::ID, self::STARTS, self::ENDS, self::SHOW_ID, self::RECORD, self::REBROADCAST, self::INSTANCE_ID, self::FILE_ID, self::TIME_FILLED, self::MODIFIED_INSTANCE, ), - BasePeer::TYPE_RAW_COLNAME => array ('ID', 'STARTS', 'ENDS', 'SHOW_ID', 'RECORD', 'REBROADCAST', 'INSTANCE_ID', 'FILE_ID', 'TIME_FILLED', 'MODIFIED_INSTANCE', ), - BasePeer::TYPE_FIELDNAME => array ('id', 'starts', 'ends', 'show_id', 'record', 'rebroadcast', 'instance_id', 'file_id', 'time_filled', 'modified_instance', ), - BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ) + BasePeer::TYPE_PHPNAME => array ('DbId', 'DbStarts', 'DbEnds', 'DbShowId', 'DbRecord', 'DbRebroadcast', 'DbOriginalShow', 'DbRecordedFile', 'DbTimeFilled', 'DbLastScheduled', 'DbModifiedInstance', ), + BasePeer::TYPE_STUDLYPHPNAME => array ('dbId', 'dbStarts', 'dbEnds', 'dbShowId', 'dbRecord', 'dbRebroadcast', 'dbOriginalShow', 'dbRecordedFile', 'dbTimeFilled', 'dbLastScheduled', 'dbModifiedInstance', ), + BasePeer::TYPE_COLNAME => array (self::ID, self::STARTS, self::ENDS, self::SHOW_ID, self::RECORD, self::REBROADCAST, self::INSTANCE_ID, self::FILE_ID, self::TIME_FILLED, self::LAST_SCHEDULED, self::MODIFIED_INSTANCE, ), + BasePeer::TYPE_RAW_COLNAME => array ('ID', 'STARTS', 'ENDS', 'SHOW_ID', 'RECORD', 'REBROADCAST', 'INSTANCE_ID', 'FILE_ID', 'TIME_FILLED', 'LAST_SCHEDULED', 'MODIFIED_INSTANCE', ), + BasePeer::TYPE_FIELDNAME => array ('id', 'starts', 'ends', 'show_id', 'record', 'rebroadcast', 'instance_id', 'file_id', 'time_filled', 'last_scheduled', 'modified_instance', ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ) ); /** @@ -92,12 +95,12 @@ abstract class BaseCcShowInstancesPeer { * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 */ private static $fieldKeys = array ( - BasePeer::TYPE_PHPNAME => array ('DbId' => 0, 'DbStarts' => 1, 'DbEnds' => 2, 'DbShowId' => 3, 'DbRecord' => 4, 'DbRebroadcast' => 5, 'DbOriginalShow' => 6, 'DbRecordedFile' => 7, 'DbTimeFilled' => 8, 'DbModifiedInstance' => 9, ), - BasePeer::TYPE_STUDLYPHPNAME => array ('dbId' => 0, 'dbStarts' => 1, 'dbEnds' => 2, 'dbShowId' => 3, 'dbRecord' => 4, 'dbRebroadcast' => 5, 'dbOriginalShow' => 6, 'dbRecordedFile' => 7, 'dbTimeFilled' => 8, 'dbModifiedInstance' => 9, ), - BasePeer::TYPE_COLNAME => array (self::ID => 0, self::STARTS => 1, self::ENDS => 2, self::SHOW_ID => 3, self::RECORD => 4, self::REBROADCAST => 5, self::INSTANCE_ID => 6, self::FILE_ID => 7, self::TIME_FILLED => 8, self::MODIFIED_INSTANCE => 9, ), - BasePeer::TYPE_RAW_COLNAME => array ('ID' => 0, 'STARTS' => 1, 'ENDS' => 2, 'SHOW_ID' => 3, 'RECORD' => 4, 'REBROADCAST' => 5, 'INSTANCE_ID' => 6, 'FILE_ID' => 7, 'TIME_FILLED' => 8, 'MODIFIED_INSTANCE' => 9, ), - BasePeer::TYPE_FIELDNAME => array ('id' => 0, 'starts' => 1, 'ends' => 2, 'show_id' => 3, 'record' => 4, 'rebroadcast' => 5, 'instance_id' => 6, 'file_id' => 7, 'time_filled' => 8, 'modified_instance' => 9, ), - BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ) + BasePeer::TYPE_PHPNAME => array ('DbId' => 0, 'DbStarts' => 1, 'DbEnds' => 2, 'DbShowId' => 3, 'DbRecord' => 4, 'DbRebroadcast' => 5, 'DbOriginalShow' => 6, 'DbRecordedFile' => 7, 'DbTimeFilled' => 8, 'DbLastScheduled' => 9, 'DbModifiedInstance' => 10, ), + BasePeer::TYPE_STUDLYPHPNAME => array ('dbId' => 0, 'dbStarts' => 1, 'dbEnds' => 2, 'dbShowId' => 3, 'dbRecord' => 4, 'dbRebroadcast' => 5, 'dbOriginalShow' => 6, 'dbRecordedFile' => 7, 'dbTimeFilled' => 8, 'dbLastScheduled' => 9, 'dbModifiedInstance' => 10, ), + BasePeer::TYPE_COLNAME => array (self::ID => 0, self::STARTS => 1, self::ENDS => 2, self::SHOW_ID => 3, self::RECORD => 4, self::REBROADCAST => 5, self::INSTANCE_ID => 6, self::FILE_ID => 7, self::TIME_FILLED => 8, self::LAST_SCHEDULED => 9, self::MODIFIED_INSTANCE => 10, ), + BasePeer::TYPE_RAW_COLNAME => array ('ID' => 0, 'STARTS' => 1, 'ENDS' => 2, 'SHOW_ID' => 3, 'RECORD' => 4, 'REBROADCAST' => 5, 'INSTANCE_ID' => 6, 'FILE_ID' => 7, 'TIME_FILLED' => 8, 'LAST_SCHEDULED' => 9, 'MODIFIED_INSTANCE' => 10, ), + BasePeer::TYPE_FIELDNAME => array ('id' => 0, 'starts' => 1, 'ends' => 2, 'show_id' => 3, 'record' => 4, 'rebroadcast' => 5, 'instance_id' => 6, 'file_id' => 7, 'time_filled' => 8, 'last_scheduled' => 9, 'modified_instance' => 10, ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ) ); /** @@ -178,6 +181,7 @@ abstract class BaseCcShowInstancesPeer { $criteria->addSelectColumn(CcShowInstancesPeer::INSTANCE_ID); $criteria->addSelectColumn(CcShowInstancesPeer::FILE_ID); $criteria->addSelectColumn(CcShowInstancesPeer::TIME_FILLED); + $criteria->addSelectColumn(CcShowInstancesPeer::LAST_SCHEDULED); $criteria->addSelectColumn(CcShowInstancesPeer::MODIFIED_INSTANCE); } else { $criteria->addSelectColumn($alias . '.ID'); @@ -189,6 +193,7 @@ abstract class BaseCcShowInstancesPeer { $criteria->addSelectColumn($alias . '.INSTANCE_ID'); $criteria->addSelectColumn($alias . '.FILE_ID'); $criteria->addSelectColumn($alias . '.TIME_FILLED'); + $criteria->addSelectColumn($alias . '.LAST_SCHEDULED'); $criteria->addSelectColumn($alias . '.MODIFIED_INSTANCE'); } } diff --git a/airtime_mvc/application/models/airtime/om/BaseCcShowInstancesQuery.php b/airtime_mvc/application/models/airtime/om/BaseCcShowInstancesQuery.php index d127d88ad..ea429edab 100644 --- a/airtime_mvc/application/models/airtime/om/BaseCcShowInstancesQuery.php +++ b/airtime_mvc/application/models/airtime/om/BaseCcShowInstancesQuery.php @@ -15,6 +15,7 @@ * @method CcShowInstancesQuery orderByDbOriginalShow($order = Criteria::ASC) Order by the instance_id column * @method CcShowInstancesQuery orderByDbRecordedFile($order = Criteria::ASC) Order by the file_id column * @method CcShowInstancesQuery orderByDbTimeFilled($order = Criteria::ASC) Order by the time_filled column + * @method CcShowInstancesQuery orderByDbLastScheduled($order = Criteria::ASC) Order by the last_scheduled column * @method CcShowInstancesQuery orderByDbModifiedInstance($order = Criteria::ASC) Order by the modified_instance column * * @method CcShowInstancesQuery groupByDbId() Group by the id column @@ -26,6 +27,7 @@ * @method CcShowInstancesQuery groupByDbOriginalShow() Group by the instance_id column * @method CcShowInstancesQuery groupByDbRecordedFile() Group by the file_id column * @method CcShowInstancesQuery groupByDbTimeFilled() Group by the time_filled column + * @method CcShowInstancesQuery groupByDbLastScheduled() Group by the last_scheduled column * @method CcShowInstancesQuery groupByDbModifiedInstance() Group by the modified_instance column * * @method CcShowInstancesQuery leftJoin($relation) Adds a LEFT JOIN clause to the query @@ -64,6 +66,7 @@ * @method CcShowInstances findOneByDbOriginalShow(int $instance_id) Return the first CcShowInstances filtered by the instance_id column * @method CcShowInstances findOneByDbRecordedFile(int $file_id) Return the first CcShowInstances filtered by the file_id column * @method CcShowInstances findOneByDbTimeFilled(string $time_filled) Return the first CcShowInstances filtered by the time_filled column + * @method CcShowInstances findOneByDbLastScheduled(string $last_scheduled) Return the first CcShowInstances filtered by the last_scheduled column * @method CcShowInstances findOneByDbModifiedInstance(boolean $modified_instance) Return the first CcShowInstances filtered by the modified_instance column * * @method array findByDbId(int $id) Return CcShowInstances objects filtered by the id column @@ -75,6 +78,7 @@ * @method array findByDbOriginalShow(int $instance_id) Return CcShowInstances objects filtered by the instance_id column * @method array findByDbRecordedFile(int $file_id) Return CcShowInstances objects filtered by the file_id column * @method array findByDbTimeFilled(string $time_filled) Return CcShowInstances objects filtered by the time_filled column + * @method array findByDbLastScheduled(string $last_scheduled) Return CcShowInstances objects filtered by the last_scheduled column * @method array findByDbModifiedInstance(boolean $modified_instance) Return CcShowInstances objects filtered by the modified_instance column * * @package propel.generator.airtime.om @@ -422,22 +426,44 @@ abstract class BaseCcShowInstancesQuery extends ModelCriteria /** * Filter the query on the time_filled column * - * @param string|array $dbTimeFilled The value to use as filter. - * Accepts an associative array('min' => $minValue, 'max' => $maxValue) + * @param string $dbTimeFilled The value to use as filter. + * Accepts wildcards (* and % trigger a LIKE) * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL * * @return CcShowInstancesQuery The current query, for fluid interface */ public function filterByDbTimeFilled($dbTimeFilled = null, $comparison = null) { - if (is_array($dbTimeFilled)) { + if (null === $comparison) { + if (is_array($dbTimeFilled)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $dbTimeFilled)) { + $dbTimeFilled = str_replace('*', '%', $dbTimeFilled); + $comparison = Criteria::LIKE; + } + } + return $this->addUsingAlias(CcShowInstancesPeer::TIME_FILLED, $dbTimeFilled, $comparison); + } + + /** + * Filter the query on the last_scheduled column + * + * @param string|array $dbLastScheduled The value to use as filter. + * Accepts an associative array('min' => $minValue, 'max' => $maxValue) + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return CcShowInstancesQuery The current query, for fluid interface + */ + public function filterByDbLastScheduled($dbLastScheduled = null, $comparison = null) + { + if (is_array($dbLastScheduled)) { $useMinMax = false; - if (isset($dbTimeFilled['min'])) { - $this->addUsingAlias(CcShowInstancesPeer::TIME_FILLED, $dbTimeFilled['min'], Criteria::GREATER_EQUAL); + if (isset($dbLastScheduled['min'])) { + $this->addUsingAlias(CcShowInstancesPeer::LAST_SCHEDULED, $dbLastScheduled['min'], Criteria::GREATER_EQUAL); $useMinMax = true; } - if (isset($dbTimeFilled['max'])) { - $this->addUsingAlias(CcShowInstancesPeer::TIME_FILLED, $dbTimeFilled['max'], Criteria::LESS_EQUAL); + if (isset($dbLastScheduled['max'])) { + $this->addUsingAlias(CcShowInstancesPeer::LAST_SCHEDULED, $dbLastScheduled['max'], Criteria::LESS_EQUAL); $useMinMax = true; } if ($useMinMax) { @@ -447,7 +473,7 @@ abstract class BaseCcShowInstancesQuery extends ModelCriteria $comparison = Criteria::IN; } } - return $this->addUsingAlias(CcShowInstancesPeer::TIME_FILLED, $dbTimeFilled, $comparison); + return $this->addUsingAlias(CcShowInstancesPeer::LAST_SCHEDULED, $dbLastScheduled, $comparison); } /** diff --git a/airtime_mvc/application/models/tests/AllTests.php b/airtime_mvc/application/models/tests/AllTests.php index 7ff5a8d9f..2d5620935 100644 --- a/airtime_mvc/application/models/tests/AllTests.php +++ b/airtime_mvc/application/models/tests/AllTests.php @@ -1,5 +1,4 @@ + element->getElement('sb_date_start') ?> + element->getElement('sb_time_start') ?> + element->getElement('sb_date_end') ?> + element->getElement('sb_time_end') ?> + + +
+ + element->getElement('sb_show_filter') ?> + + element->getElement('sb_my_shows')):?> + + element->getElement('sb_my_shows'); ?> + +
\ No newline at end of file diff --git a/airtime_mvc/application/views/scripts/library/library.phtml b/airtime_mvc/application/views/scripts/library/library.phtml index d1f8d7cb8..fda9aec34 100644 --- a/airtime_mvc/application/views/scripts/library/library.phtml +++ b/airtime_mvc/application/views/scripts/library/library.phtml @@ -3,7 +3,5 @@
- - -
+
diff --git a/airtime_mvc/application/views/scripts/showbuilder/builder.phtml b/airtime_mvc/application/views/scripts/showbuilder/builder.phtml index d33f605ca..f9374325a 100644 --- a/airtime_mvc/application/views/scripts/showbuilder/builder.phtml +++ b/airtime_mvc/application/views/scripts/showbuilder/builder.phtml @@ -1,6 +1,2 @@ - - - - - +sb_form; ?>
diff --git a/airtime_mvc/build/schema.xml b/airtime_mvc/build/schema.xml index 89c86b891..edc6b2b86 100644 --- a/airtime_mvc/build/schema.xml +++ b/airtime_mvc/build/schema.xml @@ -156,7 +156,8 @@ - + + ' : '-->') . PHP_EOL - . ''; - - return $style; - } - - /** - * Render DjConfig values - * - * @return string - */ - protected function _renderDjConfig() - { - $djConfigValues = $this->getDjConfig(); - if (empty($djConfigValues)) { - return ''; - } - - require_once 'Zend/Json.php'; - $scriptTag = ''; - - return $scriptTag; - } - - /** - * Render dojo script tag - * - * Renders Dojo script tag by utilizing either local path provided or the - * CDN. If any djConfig values were set, they will be serialized and passed - * with that attribute. - * - * @return string - */ - protected function _renderDojoScriptTag() - { - if ($this->useCdn()) { - $source = $this->getCdnBase() - . $this->getCdnVersion() - . $this->getCdnDojoPath(); - } else { - $source = $this->getLocalPath(); - } - - $scriptTag = ''; - return $scriptTag; - } - - /** - * Render layers (custom builds) as script tags - * - * @return string - */ - protected function _renderLayers() - { - $layers = $this->getLayers(); - if (empty($layers)) { - return ''; - } - - $enc = 'UTF-8'; - if ($this->view instanceof Zend_View_Interface - && method_exists($this->view, 'getEncoding') - ) { - $enc = $this->view->getEncoding(); - } - - $html = array(); - foreach ($layers as $path) { - $html[] = sprintf( - '', - htmlspecialchars($path, ENT_QUOTES, $enc) - ); - } - - return implode("\n", $html); - } - - /** - * Render dojo module paths and requires - * - * @return string - */ - protected function _renderExtras() - { - $js = array(); - $modulePaths = $this->getModulePaths(); - if (!empty($modulePaths)) { - foreach ($modulePaths as $module => $path) { - $js[] = 'dojo.registerModulePath("' . $this->view->escape($module) . '", "' . $this->view->escape($path) . '");'; - } - } - - $modules = $this->getModules(); - if (!empty($modules)) { - foreach ($modules as $module) { - $js[] = 'dojo.require("' . $this->view->escape($module) . '");'; - } - } - - $onLoadActions = array(); - // Get Zend specific onLoad actions; these will always be first to - // ensure that dijits are created in the correct order - foreach ($this->_getZendLoadActions() as $callback) { - $onLoadActions[] = 'dojo.addOnLoad(' . $callback . ');'; - } - - // Get all other onLoad actions - foreach ($this->getOnLoadActions() as $callback) { - $onLoadActions[] = 'dojo.addOnLoad(' . $callback . ');'; - } - - $javascript = implode("\n ", $this->getJavascript()); - - $content = ''; - if (!empty($js)) { - $content .= implode("\n ", $js) . "\n"; - } - - if (!empty($onLoadActions)) { - $content .= implode("\n ", $onLoadActions) . "\n"; - } - - if (!empty($javascript)) { - $content .= $javascript . "\n"; - } - - if (preg_match('/^\s*$/s', $content)) { - return ''; - } - - $html = ''; - return $html; - } - - /** - * Add an onLoad action related to ZF dijit creation - * - * This method is public, but prefixed with an underscore to indicate that - * it should not normally be called by userland code. It is pertinent to - * ensuring that the correct order of operations occurs during dijit - * creation. - * - * @param string $callback - * @return Zend_Dojo_View_Helper_Dojo_Container - */ - public function _addZendLoad($callback) - { - if (!in_array($callback, $this->_zendLoadActions, true)) { - $this->_zendLoadActions[] = $callback; - } - return $this; - } - - /** - * Retrieve all ZF dijit callbacks - * - * @return array - */ - public function _getZendLoadActions() - { - return $this->_zendLoadActions; - } -} diff --git a/airtime_mvc/library/Zend/Dojo/View/Helper/Editor.php b/airtime_mvc/library/Zend/Dojo/View/Helper/Editor.php deleted file mode 100644 index dfe591609..000000000 --- a/airtime_mvc/library/Zend/Dojo/View/Helper/Editor.php +++ /dev/null @@ -1,187 +0,0 @@ - 'LinkDialog', - 'insertImage' => 'LinkDialog', - 'fontName' => 'FontChoice', - 'fontSize' => 'FontChoice', - 'formatBlock' => 'FontChoice', - 'foreColor' => 'TextColor', - 'hiliteColor' => 'TextColor' - ); - - /** - * JSON-encoded parameters - * @var array - */ - protected $_jsonParams = array('captureEvents', 'events', 'plugins'); - - /** - * dijit.Editor - * - * @param string $id - * @param string $value - * @param array $params - * @param array $attribs - * @return string - */ - public function editor($id, $value = null, $params = array(), $attribs = array()) - { - if (isset($params['plugins'])) { - foreach ($this->_getRequiredModules($params['plugins']) as $module) { - $this->dojo->requireModule($module); - } - } - - // Previous versions allowed specifying "degrade" to allow using a - // textarea instead of a div -- but this is insecure. Removing the - // parameter if set to prevent its injection in the dijit. - if (isset($params['degrade'])) { - unset($params['degrade']); - } - - $hiddenName = $id; - if (array_key_exists('id', $attribs)) { - $hiddenId = $attribs['id']; - } else { - $hiddenId = $hiddenName; - } - $hiddenId = $this->_normalizeId($hiddenId); - - $textareaName = $this->_normalizeEditorName($hiddenName); - $textareaId = $hiddenId . '-Editor'; - - $hiddenAttribs = array( - 'id' => $hiddenId, - 'name' => $hiddenName, - 'value' => $value, - 'type' => 'hidden', - ); - $attribs['id'] = $textareaId; - - $this->_createGetParentFormFunction(); - $this->_createEditorOnSubmit($hiddenId, $textareaId); - - $attribs = $this->_prepareDijit($attribs, $params, 'textarea'); - - $html = '_htmlAttribs($hiddenAttribs) . $this->getClosingBracket(); - $html .= '_htmlAttribs($attribs) . '>' - . $value - . "\n"; - - // Embed a textarea in a