diff --git a/CREDITS b/CREDITS index 644b4ab59..a9053b04c 100644 --- a/CREDITS +++ b/CREDITS @@ -2,7 +2,7 @@ CREDITS ======= -Version 2.3.0 +Version 2.3.0/2.3.1 ------------- Martin Konecny (martin.konecny@sourcefabric.org) Role: Developer Team Lead diff --git a/VERSION b/VERSION index 7c1777d22..bdc7d50a4 100644 --- a/VERSION +++ b/VERSION @@ -1,2 +1,2 @@ PRODUCT_ID=Airtime -PRODUCT_RELEASE=2.3.0 +PRODUCT_RELEASE=2.3.1 diff --git a/airtime_mvc/application/Bootstrap.php b/airtime_mvc/application/Bootstrap.php index 38d4d9c7a..e289e9c54 100644 --- a/airtime_mvc/application/Bootstrap.php +++ b/airtime_mvc/application/Bootstrap.php @@ -17,15 +17,12 @@ require_once "Timezone.php"; require_once __DIR__.'/forms/helpers/ValidationTypes.php'; require_once __DIR__.'/controllers/plugins/RabbitMqPlugin.php'; - - date_default_timezone_set('UTC'); require_once (APPLICATION_PATH."/logging/Logging.php"); Logging::setLogPath('/var/log/airtime/zendphp.log'); date_default_timezone_set(Application_Model_Preference::GetTimezone()); Config::setAirtimeVersion(); -$CC_CONFIG = Config::getConfig(); require_once __DIR__."/configs/navigation.php"; Zend_Validate::setDefaultNamespaces("Zend"); diff --git a/airtime_mvc/application/common/DateHelper.php b/airtime_mvc/application/common/DateHelper.php index cc02544cd..5d40e9b5f 100644 --- a/airtime_mvc/application/common/DateHelper.php +++ b/airtime_mvc/application/common/DateHelper.php @@ -229,7 +229,7 @@ class Application_Common_DateHelper public static function calculateLengthInSeconds($p_time){ if (2 !== substr_count($p_time, ":")){ - return FALSE; + return false; } if (1 === substr_count($p_time, ".")){ @@ -241,12 +241,8 @@ class Application_Common_DateHelper list($hours, $minutes, $seconds) = explode(":", $hhmmss); - // keep ms in 3 digits - $ms = substr($ms, 0, 3); - - $totalSeconds = $hours*3600 + $minutes*60 + $seconds + $ms/1000; - - return $totalSeconds; + $totalSeconds = ($hours*3600 + $minutes*60 + $seconds).".$ms"; + return round($totalSeconds, 3); } public static function ConvertToUtcDateTime($p_dateString, $timezone=null){ diff --git a/airtime_mvc/application/configs/airtime-conf.php b/airtime_mvc/application/configs/airtime-conf.php index c717a858e..aa69b6156 100644 --- a/airtime_mvc/application/configs/airtime-conf.php +++ b/airtime_mvc/application/configs/airtime-conf.php @@ -1,6 +1,6 @@ array ( diff --git a/airtime_mvc/application/controllers/ApiController.php b/airtime_mvc/application/controllers/ApiController.php index 6bbe480da..2833cffb1 100644 --- a/airtime_mvc/application/controllers/ApiController.php +++ b/airtime_mvc/application/controllers/ApiController.php @@ -42,8 +42,10 @@ class ApiController extends Zend_Controller_Action ->addActionContext('reload-metadata-group' , 'json') ->addActionContext('notify-webstream-data' , 'json') ->addActionContext('get-stream-parameters' , 'json') - ->addActionContext('push-stream-stats' , 'json') - ->addActionContext('update-stream-setting-table' , 'json') + ->addActionContext('push-stream-stats' , 'json') + ->addActionContext('update-stream-setting-table' , 'json') + ->addActionContext('update-replay-gain-value' , 'json') + ->addActionContext('update-cue-values-by-silan' , 'json') ->initContext(); } @@ -261,7 +263,14 @@ class ApiController extends Zend_Controller_Action "currentShow"=>Application_Model_Show::getCurrentShow($utcTimeNow), "nextShow"=>Application_Model_Show::getNextShows($utcTimeNow, $limit, $utcTimeEnd) ); - + // XSS exploit prevention + foreach ($result["currentShow"] as &$current) { + $current["name"] = htmlspecialchars($current["name"]); + } + foreach ($result["nextShow"] as &$next) { + $next["name"] = htmlspecialchars($next["name"]); + } + Application_Model_Show::convertToLocalTimeZone($result["currentShow"], array("starts", "ends", "start_timestamp", "end_timestamp")); Application_Model_Show::convertToLocalTimeZone($result["nextShow"], @@ -269,6 +278,17 @@ class ApiController extends Zend_Controller_Action } else { $result = Application_Model_Schedule::GetPlayOrderRange(); + // XSS exploit prevention + $result["previous"]["name"] = htmlspecialchars($result["previous"]["name"]); + $result["current"]["name"] = htmlspecialchars($result["current"]["name"]); + $result["next"]["name"] = htmlspecialchars($result["next"]["name"]); + foreach ($result["currentShow"] as &$current) { + $current["name"] = htmlspecialchars($current["name"]); + } + foreach ($result["nextShow"] as &$next) { + $next["name"] = htmlspecialchars($next["name"]); + } + //Convert from UTC to localtime for Web Browser. Application_Model_Show::ConvertToLocalTimeZone($result["currentShow"], array("starts", "ends", "start_timestamp", "end_timestamp")); @@ -315,7 +335,15 @@ class ApiController extends Zend_Controller_Action $result[$dow[$i]] = $shows; } - + + // XSS exploit prevention + foreach ($dow as $d) { + foreach ($result[$d] as &$show) { + $show["name"] = htmlspecialchars($show["name"]); + $show["url"] = htmlspecialchars($show["url"]); + } + } + //used by caller to determine if the airtime they are running or widgets in use is out of date. $result['AIRTIME_API_VERSION'] = AIRTIME_API_VERSION; header("Content-type: text/javascript"); @@ -411,7 +439,9 @@ class ApiController extends Zend_Controller_Action $result = Application_Model_StoredFile::copyFileToStor($upload_dir, $fileName, $tempFileName); if (!is_null($result)) { - die('{"jsonrpc" : "2.0", "error" : {"code": '.$result['code'].', "message" : "'.$result['message'].'"}}'); + $this->_helper->json->sendJson( + array("jsonrpc" => "2.0", "error" => array("code" => $result['code'], "message" => $result['message'])) + ); } } @@ -600,7 +630,7 @@ class ApiController extends Zend_Controller_Action $response['key'] = $k; array_push($responses, $response); } - die( json_encode($responses) ); + $this->_helper->json->sendJson($responses); } public function listAllFilesAction() @@ -668,7 +698,6 @@ class ApiController extends Zend_Controller_Action "platform"=>Application_Model_Systemstatus::GetPlatformInfo(), "airtime_version"=>Application_Model_Preference::GetAirtimeVersion(), "services"=>array( - "rabbitmq"=>Application_Model_Systemstatus::GetRabbitMqStatus(), "pypo"=>Application_Model_Systemstatus::GetPypoStatus(), "liquidsoap"=>Application_Model_Systemstatus::GetLiquidsoapStatus(), "media_monitor"=>Application_Model_Systemstatus::GetMediaMonitorStatus() @@ -919,7 +948,7 @@ class ApiController extends Zend_Controller_Action public function updateReplayGainValueAction() { - // disable layout + // disable the view and the layout $this->view->layout()->disableLayout(); $this->_helper->viewRenderer->setNoRender(true); @@ -933,17 +962,19 @@ class ApiController extends Zend_Controller_Action $file->setDbReplayGain($gain); $file->save(); } + + $this->view->msg = "OK"; } public function updateCueValuesBySilanAction() { - // disable layout + // disable the view and the layout $this->view->layout()->disableLayout(); $this->_helper->viewRenderer->setNoRender(true); - + $request = $this->getRequest(); $data = json_decode($request->getParam('data')); - Logging::info($data); + foreach ($data as $pair) { list($id, $info) = $pair; // TODO : move this code into model -- RG @@ -955,6 +986,8 @@ class ApiController extends Zend_Controller_Action $file->setDbSilanCheck(true); $file->save(); } + + echo json_encode(array()); } public function notifyWebstreamDataAction() @@ -962,7 +995,6 @@ class ApiController extends Zend_Controller_Action $request = $this->getRequest(); $data = $request->getParam("data"); $media_id = $request->getParam("media_id"); - $data_arr = json_decode($data); if (!is_null($media_id)) { diff --git a/airtime_mvc/application/controllers/AudiopreviewController.php b/airtime_mvc/application/controllers/AudiopreviewController.php index e094a7450..6955fccd9 100644 --- a/airtime_mvc/application/controllers/AudiopreviewController.php +++ b/airtime_mvc/application/controllers/AudiopreviewController.php @@ -60,8 +60,10 @@ class AudiopreviewController extends Zend_Controller_Action $this->view->uri = $uri; $this->view->mime = $mime; $this->view->audioFileID = $audioFileID; - $this->view->audioFileArtist = $audioFileArtist; - $this->view->audioFileTitle = $audioFileTitle; + // We need to decode artist and title because it gets + // encoded twice in js + $this->view->audioFileArtist = htmlspecialchars(urldecode($audioFileArtist)); + $this->view->audioFileTitle = htmlspecialchars(urldecode($audioFileTitle)); $this->view->type = $type; $this->_helper->viewRenderer->setRender('audio-preview'); diff --git a/airtime_mvc/application/controllers/LibraryController.php b/airtime_mvc/application/controllers/LibraryController.php index 2b38349dd..79dd4b2be 100644 --- a/airtime_mvc/application/controllers/LibraryController.php +++ b/airtime_mvc/application/controllers/LibraryController.php @@ -81,6 +81,17 @@ class LibraryController extends Zend_Controller_Action $this->view->length = $formatter->format(); $this->view->type = $obj_sess->type; } + + //get user settings and determine if we need to hide + // or show the playlist editor + $showPlaylist = false; + $data = Application_Model_Preference::getLibraryScreenSettings(); + if (!is_null($data)) { + if ($data["playlist"] == "true") { + $showPlaylist = true; + } + } + $this->view->showPlaylist = $showPlaylist; } catch (PlaylistNotFoundException $e) { $this->playlistNotFound($obj_sess->type); } catch (Exception $e) { @@ -382,23 +393,6 @@ class LibraryController extends Zend_Controller_Action # terrible name for the method below. it does not only search files. $r = Application_Model_StoredFile::searchLibraryFiles($params); - //TODO move this to the datatables row callback. - foreach ($r["aaData"] as &$data) { - - if ($data['ftype'] == 'audioclip') { - $file = Application_Model_StoredFile::Recall($data['id']); - $scid = $file->getSoundCloudId(); - - if ($scid == "-2") { - $data['track_title'] .= ''; - } elseif ($scid == "-3") { - $data['track_title'] .= ''; - } elseif (!is_null($scid)) { - $data['track_title'] .= ''; - } - } - } - $this->view->sEcho = $r["sEcho"]; $this->view->iTotalDisplayRecords = $r["iTotalDisplayRecords"]; $this->view->iTotalRecords = $r["iTotalRecords"]; @@ -524,7 +518,7 @@ class LibraryController extends Zend_Controller_Action $id = $this->_getParam('id'); Application_Model_Soundcloud::uploadSoundcloud($id); // we should die with ui info - die(); + $this->_helper->json->sendJson(null); } public function getUploadToSoundcloudStatusAction() diff --git a/airtime_mvc/application/controllers/ListenerstatController.php b/airtime_mvc/application/controllers/ListenerstatController.php index 817f6ca11..bb280378d 100644 --- a/airtime_mvc/application/controllers/ListenerstatController.php +++ b/airtime_mvc/application/controllers/ListenerstatController.php @@ -76,6 +76,6 @@ class ListenerstatController extends Zend_Controller_Action $endsDT = DateTime::createFromFormat("U", $ends_epoch, new DateTimeZone("UTC")); $data = Application_Model_ListenerStat::getDataPointsWithinRange($startsDT->format("Y-m-d H:i:s"), $endsDT->format("Y-m-d H:i:s"), $mountName); - die(json_encode($data)); + $this->_helper->json->sendJson($data); } } diff --git a/airtime_mvc/application/controllers/LocaleController.php b/airtime_mvc/application/controllers/LocaleController.php index d689417be..efdecff80 100644 --- a/airtime_mvc/application/controllers/LocaleController.php +++ b/airtime_mvc/application/controllers/LocaleController.php @@ -4,10 +4,6 @@ class LocaleController extends Zend_Controller_Action { public function init() { - $ajaxContext = $this->_helper->getHelper("AjaxContext"); - $ajaxContext->addActionContext("general-translation-table", "json") - ->addActionContext("datatables-translation-table", "json") - ->initContext(); } public function datatablesTranslationTableAction() @@ -26,7 +22,7 @@ class LocaleController extends Zend_Controller_Action $locale.".txt") ); } - + public function generalTranslationTableAction() { $translations = array ( diff --git a/airtime_mvc/application/controllers/PlaylistController.php b/airtime_mvc/application/controllers/PlaylistController.php index 19c2756e7..3f0dd66b7 100644 --- a/airtime_mvc/application/controllers/PlaylistController.php +++ b/airtime_mvc/application/controllers/PlaylistController.php @@ -14,6 +14,7 @@ class PlaylistController extends Zend_Controller_Action ->addActionContext('new', 'json') ->addActionContext('edit', 'json') ->addActionContext('delete', 'json') + ->addActionContext('close-playlist', 'json') ->addActionContext('play', 'json') ->addActionContext('set-playlist-fades', 'json') ->addActionContext('get-playlist-fades', 'json') @@ -26,6 +27,7 @@ class PlaylistController extends Zend_Controller_Action ->addActionContext('smart-block-shuffle', 'json') ->addActionContext('get-block-info', 'json') ->addActionContext('shuffle', 'json') + ->addActionContext('empty-content', 'json') ->initContext(); } @@ -132,7 +134,7 @@ class PlaylistController extends Zend_Controller_Action if (!$p_isJson) { $this->createFullResponse(null); } else { - die(json_encode(array("error"=>$this->view->error, "result"=>1, "html"=>$this->createFullResponse(null, $p_isJson)))); + $this->_helper->json->sendJson(array("error"=>$this->view->error, "result"=>1, "html"=>$this->createFullResponse(null, $p_isJson))); } } @@ -245,6 +247,13 @@ class PlaylistController extends Zend_Controller_Action } } + public function closePlaylistAction() { + $type = $this->_getParam('type'); + $obj = null; + Application_Model_Library::changePlaylist($obj, $type); + $this->createFullResponse($obj); + } + public function addItemsAction() { $ids = $this->_getParam('aItems', array()); @@ -336,6 +345,26 @@ class PlaylistController extends Zend_Controller_Action $this->playlistUnknownError($e); } } + + public function emptyContentAction() + { + $type = $this->_getParam('obj_type'); + try { + $obj = $this->getPlaylist($type); + if ($type == 'playlist') { + $obj->deleteAllFilesFromPlaylist(); + } else { + $obj->deleteAllFilesFromBlock(); + } + $this->createUpdateResponse($obj); + } catch (PlaylistOutDatedException $e) { + $this->playlistOutdated($e); + } catch (PlaylistNotFoundException $e) { + $this->playlistNotFound($type); + } catch (Exception $e) { + $this->playlistUnknownError($e); + } + } public function setCueAction() { @@ -488,7 +517,7 @@ class PlaylistController extends Zend_Controller_Action } $result["modified"] = $this->view->modified; - die(json_encode($result)); + $this->_helper->json->sendJson($result); } public function smartBlockGenerateAction() @@ -504,7 +533,7 @@ class PlaylistController extends Zend_Controller_Action $form->startForm($params['obj_id']); if ($form->isValid($params)) { $result = $bl->generateSmartBlock($params['data']); - die(json_encode(array("result"=>0, "html"=>$this->createFullResponse($bl, true, true)))); + $this->_helper->json->sendJson(array("result"=>0, "html"=>$this->createFullResponse($bl, true, true))); } else { $this->view->obj = $bl; $this->view->id = $bl->getId(); @@ -512,7 +541,7 @@ class PlaylistController extends Zend_Controller_Action $viewPath = 'playlist/smart-block.phtml'; $result['html'] = $this->view->render($viewPath); $result['result'] = 1; - die(json_encode($result)); + $this->_helper->json->sendJson($result); } } catch (BlockNotFoundException $e) { $this->playlistNotFound('block', true); @@ -531,9 +560,9 @@ class PlaylistController extends Zend_Controller_Action $result = $bl->shuffleSmartBlock(); if ($result['result'] == 0) { - die(json_encode(array("result"=>0, "html"=>$this->createFullResponse($bl, true)))); + $this->_helper->json->sendJson(array("result"=>0, "html"=>$this->createFullResponse($bl, true))); } else { - die(json_encode($result)); + $this->_helper->json->sendJson($result); } } catch (BlockNotFoundException $e) { $this->playlistNotFound('block', true); @@ -551,9 +580,9 @@ class PlaylistController extends Zend_Controller_Action $result = $pl->shuffle(); if ($result['result'] == 0) { - die(json_encode(array("result"=>0, "html"=>$this->createFullResponse($pl, true)))); + $this->_helper->json->sendJson(array("result"=>0, "html"=>$this->createFullResponse($pl, true))); } else { - die(json_encode($result)); + $this->_helper->json->sendJson($result); } } catch (PlaylistNotFoundException $e) { $this->playlistNotFound('block', true); @@ -574,7 +603,7 @@ class PlaylistController extends Zend_Controller_Action $out = $bl->getCriteria(); $out['isStatic'] = false; } - die(json_encode($out)); + $this->_helper->json->sendJson($out); } } class WrongTypeToBlockException extends Exception {} diff --git a/airtime_mvc/application/controllers/PluploadController.php b/airtime_mvc/application/controllers/PluploadController.php index ed7403693..9698b163a 100644 --- a/airtime_mvc/application/controllers/PluploadController.php +++ b/airtime_mvc/application/controllers/PluploadController.php @@ -32,7 +32,7 @@ class PluploadController extends Zend_Controller_Action $tempFilePath = Application_Model_StoredFile::uploadFile($upload_dir); $tempFileName = basename($tempFilePath); - die('{"jsonrpc" : "2.0", "tempfilepath" : "'.$tempFileName.'" }'); + $this->_helper->json->sendJson(array("jsonrpc" => "2.0", "tempfilepath" => $tempFileName)); } public function copyfileAction() @@ -43,8 +43,8 @@ class PluploadController extends Zend_Controller_Action $result = Application_Model_StoredFile::copyFileToStor($upload_dir, $filename, $tempname); if (!is_null($result)) - die('{"jsonrpc" : "2.0", "error" : '.json_encode($result).'}'); + $this->_helper->json->sendJson(array("jsonrpc" => "2.0", "error" => $result)); - die('{"jsonrpc" : "2.0"}'); + $this->_helper->json->sendJson(array("jsonrpc" => "2.0")); } } diff --git a/airtime_mvc/application/controllers/PreferenceController.php b/airtime_mvc/application/controllers/PreferenceController.php index 269215783..77f615528 100644 --- a/airtime_mvc/application/controllers/PreferenceController.php +++ b/airtime_mvc/application/controllers/PreferenceController.php @@ -70,10 +70,10 @@ class PreferenceController extends Zend_Controller_Action $this->view->statusMsg = "
". _("Preferences updated.")."
"; $this->view->form = $form; - die(json_encode(array("valid"=>"true", "html"=>$this->view->render('preference/index.phtml')))); + $this->_helper->json->sendJson(array("valid"=>"true", "html"=>$this->view->render('preference/index.phtml'))); } else { $this->view->form = $form; - die(json_encode(array("valid"=>"false", "html"=>$this->view->render('preference/index.phtml')))); + $this->_helper->json->sendJson(array("valid"=>"false", "html"=>$this->view->render('preference/index.phtml'))); } } $this->view->form = $form; @@ -139,17 +139,13 @@ class PreferenceController extends Zend_Controller_Action { $CC_CONFIG = Config::getConfig(); - if(Application_Model_Preference::GetPlanLevel() == 'disabled'){ - - $baseUrl = Application_Common_OsPath::getBaseDir(); + $baseUrl = Application_Common_OsPath::getBaseDir(); - $this->view->headScript()->appendFile($baseUrl.'js/serverbrowse/serverbrowser.js?'.$CC_CONFIG['airtime_version'],'text/javascript'); - $this->view->headScript()->appendFile($baseUrl.'js/airtime/preferences/musicdirs.js?'.$CC_CONFIG['airtime_version'],'text/javascript'); + $this->view->headScript()->appendFile($baseUrl.'js/serverbrowse/serverbrowser.js?'.$CC_CONFIG['airtime_version'],'text/javascript'); + $this->view->headScript()->appendFile($baseUrl.'js/airtime/preferences/musicdirs.js?'.$CC_CONFIG['airtime_version'],'text/javascript'); - $watched_dirs_pref = new Application_Form_WatchedDirPreferences(); - - $this->view->form = $watched_dirs_pref; - } + $watched_dirs_pref = new Application_Form_WatchedDirPreferences(); + $this->view->form = $watched_dirs_pref; } public function streamSettingAction() @@ -251,12 +247,9 @@ class PreferenceController extends Zend_Controller_Action /* If the admin password values are empty then we should not * set the pseudo password ('xxxxxx') on the front-end */ - $s1_set_admin_pass = true; - $s2_set_admin_pass = true; - $s3_set_admin_pass = true; - if (empty($values["s1_data"]["admin_pass"])) $s1_set_admin_pass = false; - if (empty($values["s2_data"]["admin_pass"])) $s2_set_admin_pass = false; - if (empty($values["s3_data"]["admin_pass"])) $s3_set_admin_pass = false; + $s1_set_admin_pass = !empty($values["s1_data"]["admin_pass"]); + $s2_set_admin_pass = !empty($values["s2_data"]["admin_pass"]); + $s3_set_admin_pass = !empty($values["s3_data"]["admin_pass"]); // this goes into cc_pref table Application_Model_Preference::SetStreamLabelFormat($values['streamFormat']); @@ -274,6 +267,7 @@ class PreferenceController extends Zend_Controller_Action Application_Model_Preference::setReplayGainModifier($values["replayGainModifier"]); $md = array('schedule' => Application_Model_Schedule::getSchedule()); Application_Model_RabbitMq::SendMessageToPypo("update_schedule", $md); + //Application_Model_RabbitMq::PushSchedule(); } if (!Application_Model_Preference::GetMasterDjConnectionUrlOverride()) { @@ -322,19 +316,19 @@ class PreferenceController extends Zend_Controller_Action $this->view->form = $form; $this->view->num_stream = $num_of_stream; $this->view->statusMsg = "
"._("Stream Setting Updated.")."
"; - die(json_encode(array( + $this->_helper->json->sendJson(array( "valid"=>"true", "html"=>$this->view->render('preference/stream-setting.phtml'), "s1_set_admin_pass"=>$s1_set_admin_pass, "s2_set_admin_pass"=>$s2_set_admin_pass, "s3_set_admin_pass"=>$s3_set_admin_pass, - ))); + )); } else { $live_stream_subform->updateVariables(); $this->view->enable_stream_conf = Application_Model_Preference::GetEnableStreamConf(); $this->view->form = $form; $this->view->num_stream = $num_of_stream; - die(json_encode(array("valid"=>"false", "html"=>$this->view->render('preference/stream-setting.phtml')))); + $this->_helper->json->sendJson(array("valid"=>"false", "html"=>$this->view->render('preference/stream-setting.phtml'))); } } @@ -378,7 +372,7 @@ class PreferenceController extends Zend_Controller_Action } ksort($result); //returns format serverBrowse is looking for. - die(json_encode($result)); + $this->_helper->json->sendJson($result); } public function changeStorDirectoryAction() @@ -420,7 +414,7 @@ class PreferenceController extends Zend_Controller_Action Application_Model_RabbitMq::SendMessageToMediaMonitor('rescan_watch', $data); Logging::info("Unhiding all files belonging to:: $dir_path"); $dir->unhideFiles(); - die(); # Get rid of this ugliness later + $this->_helper->json->sendJson(null); } public function removeWatchDirectoryAction() @@ -440,7 +434,7 @@ class PreferenceController extends Zend_Controller_Action if (Application_Model_Preference::GetImportTimestamp()+10 > $now) { $res = true; } - die(json_encode($res)); + $this->_helper->json->sendJson($res); } public function getLiquidsoapStatusAction() @@ -455,7 +449,7 @@ class PreferenceController extends Zend_Controller_Action } $out[] = array("id"=>$i, "status"=>$status); } - die(json_encode($out)); + $this->_helper->json->sendJson($out); } public function setSourceConnectionUrlAction() @@ -473,7 +467,7 @@ class PreferenceController extends Zend_Controller_Action Application_Model_Preference::SetLiveDjConnectionUrlOverride($override); } - die(); + $this->_helper->json->sendJson(null); } public function getAdminPasswordStatusAction() @@ -486,6 +480,6 @@ class PreferenceController extends Zend_Controller_Action $out["s".$i] = true; } } - die(json_encode($out)); + $this->_helper->json->sendJson($out); } } diff --git a/airtime_mvc/application/controllers/ScheduleController.php b/airtime_mvc/application/controllers/ScheduleController.php index 15dca0621..08fde37dc 100644 --- a/airtime_mvc/application/controllers/ScheduleController.php +++ b/airtime_mvc/application/controllers/ScheduleController.php @@ -9,6 +9,7 @@ class ScheduleController extends Zend_Controller_Action { $ajaxContext = $this->_helper->getHelper('AjaxContext'); $ajaxContext->addActionContext('event-feed', 'json') + ->addActionContext('event-feed-preload', 'json') ->addActionContext('make-context-menu', 'json') ->addActionContext('add-show-dialog', 'json') ->addActionContext('add-show', 'json') @@ -33,6 +34,7 @@ class ScheduleController extends Zend_Controller_Action ->addActionContext('dj-edit-show', 'json') ->addActionContext('calculate-duration', 'json') ->addActionContext('get-current-show', 'json') + ->addActionContext('update-future-is-scheduled', 'json') ->initContext(); $this->sched_sess = new Zend_Session_Namespace("schedule"); @@ -88,15 +90,23 @@ class ScheduleController extends Zend_Controller_Action $this->view->headLink()->appendStylesheet($baseUrl.'css/showbuilder.css?'.$CC_CONFIG['airtime_version']); //End Show builder JS/CSS requirements + Application_Model_Schedule::createNewFormSections($this->view); - $user = Application_Model_User::getCurrentUser(); - if ($user->isUserType(array(UTYPE_ADMIN, UTYPE_PROGRAM_MANAGER))) { $this->view->preloadShowForm = true; } - $this->view->headScript()->appendScript("var weekStart = ".Application_Model_Preference::GetWeekStartDay().";"); + $this->view->headScript()->appendScript( + "var calendarPref = {};\n". + "calendarPref.weekStart = ".Application_Model_Preference::GetWeekStartDay().";\n". + "calendarPref.timestamp = ".time().";\n". + "calendarPref.timezoneOffset = ".date("Z").";\n". + "calendarPref.timeScale = '".Application_Model_Preference::GetCalendarTimeScale()."';\n". + "calendarPref.timeInterval = ".Application_Model_Preference::GetCalendarTimeInterval().";\n". + "calendarPref.weekStartDay = ".Application_Model_Preference::GetWeekStartDay().";\n". + "var calendarEvents = null;" + ); } public function eventFeedAction() @@ -108,10 +118,28 @@ class ScheduleController extends Zend_Controller_Action $userInfo = Zend_Auth::getInstance()->getStorage()->read(); $user = new Application_Model_User($userInfo->id); - if ($user->isUserType(array(UTYPE_ADMIN, UTYPE_PROGRAM_MANAGER))) { - $editable = true; + $editable = $user->isUserType(array(UTYPE_ADMIN, UTYPE_PROGRAM_MANAGER)); + + $events = &Application_Model_Show::getFullCalendarEvents($start, $end, $editable); + $this->view->events = $events; + } + + public function eventFeedPreloadAction() + { + $userInfo = Zend_Auth::getInstance()->getStorage()->read(); + $user = new Application_Model_User($userInfo->id); + $editable = $user->isUserType(array(UTYPE_ADMIN, UTYPE_PROGRAM_MANAGER)); + + $calendar_interval = Application_Model_Preference::GetCalendarTimeScale(); + Logging::info($calendar_interval); + if ($calendar_interval == "agendaDay") { + list($start, $end) = Application_Model_Show::getStartEndCurrentDayView(); + } else if ($calendar_interval == "agendaWeek") { + list($start, $end) = Application_Model_Show::getStartEndCurrentWeekView(); + } else if ($calendar_interval == "month") { + list($start, $end) = Application_Model_Show::getStartEndCurrentMonthView(); } else { - $editable = false; + Logging::error("Invalid Calendar Interval '$calendar_interval'"); } $events = &Application_Model_Show::getFullCalendarEvents($start, $end, $editable); @@ -218,7 +246,7 @@ class ScheduleController extends Zend_Controller_Action $id = $file->getId(); Application_Model_Soundcloud::uploadSoundcloud($id); // we should die with ui info - die(); + $this->_helper->json->sendJson(null); } public function makeContextMenuAction() @@ -452,7 +480,7 @@ class ScheduleController extends Zend_Controller_Action $this->view->percentFilled = $show->getPercentScheduled(); $this->view->showContent = $show->getShowListContent(); $this->view->dialog = $this->view->render('schedule/show-content-dialog.phtml'); - $this->view->showTitle = $show->getName(); + $this->view->showTitle = htmlspecialchars($show->getName()); unset($this->view->showContent); } @@ -546,7 +574,10 @@ class ScheduleController extends Zend_Controller_Action return; } - if ($isDJ) { + // in case a user was once a dj and had been assigned to a show + // but was then changed to an admin user we need to allow + // the user to edit the show as an admin (CC-4925) + if ($isDJ && !$isAdminOrPM) { $this->view->action = "dj-edit-show"; } @@ -599,7 +630,11 @@ class ScheduleController extends Zend_Controller_Action if (!$showInstance->getShow()->isRepeating()) { $formWhen->disableStartDateAndTime(); } else { - $formWhen->getElement('add_show_start_date')->setOptions(array('disabled' => true)); + $nextFutureRepeatShow = $show->getNextFutureRepeatShowTime(); + $formWhen->getElement('add_show_start_date')->setValue($nextFutureRepeatShow["starts"]->format("Y-m-d")); + $formWhen->getElement('add_show_start_time')->setValue($nextFutureRepeatShow["starts"]->format("H:i")); + $formWhen->getElement('add_show_end_date_no_repeat')->setValue($nextFutureRepeatShow["ends"]->format("Y-m-d")); + $formWhen->getElement('add_show_end_time')->setValue($nextFutureRepeatShow["ends"]->format("H:i")); } } @@ -774,10 +809,16 @@ class ScheduleController extends Zend_Controller_Action } $data['add_show_record'] = $show->isRecorded(); - $origianlShowStartDateTime = Application_Common_DateHelper::ConvertToLocalDateTime($show->getStartDateAndTime()); + if ($show->isRepeating()) { + $nextFutureRepeatShow = $show->getNextFutureRepeatShowTime(); + $originalShowStartDateTime = $nextFutureRepeatShow["starts"]; + } else { + $originalShowStartDateTime = Application_Common_DateHelper::ConvertToLocalDateTime( + $show->getStartDateAndTime()); + } $success = Application_Model_Schedule::addUpdateShow($data, $this, - $validateStartDate, $origianlShowStartDateTime, true, + $validateStartDate, $originalShowStartDateTime, true, $data['add_show_instance_id']); if ($success) { @@ -867,6 +908,7 @@ class ScheduleController extends Zend_Controller_Action try { $scheduler = new Application_Model_Scheduler(); $scheduler->cancelShow($id); + Application_Model_StoredFile::updatePastFilesIsScheduled(); // send kick out source stream signal to pypo $data = array("sourcename"=>"live_dj"); Application_Model_RabbitMq::SendMessageToPypo("disconnect_source", $data); @@ -897,7 +939,7 @@ class ScheduleController extends Zend_Controller_Action 'title' => _('Download')); //returns format jjmenu is looking for. - die(json_encode($menu)); + $this->_helper->json->sendJson($menu); } /** @@ -950,4 +992,11 @@ class ScheduleController extends Zend_Controller_Action echo Zend_Json::encode($result); exit(); } + + public function updateFutureIsScheduledAction() + { + $schedId = $this->_getParam('schedId'); + $redrawLibTable = Application_Model_StoredFile::setIsScheduled($schedId, false); + $this->_helper->json->sendJson(array("redrawLibTable" => $redrawLibTable)); + } } diff --git a/airtime_mvc/application/controllers/SystemstatusController.php b/airtime_mvc/application/controllers/SystemstatusController.php index c84a23f9e..496dae625 100644 --- a/airtime_mvc/application/controllers/SystemstatusController.php +++ b/airtime_mvc/application/controllers/SystemstatusController.php @@ -17,7 +17,6 @@ class SystemstatusController extends Zend_Controller_Action "pypo"=>Application_Model_Systemstatus::GetPypoStatus(), "liquidsoap"=>Application_Model_Systemstatus::GetLiquidsoapStatus(), "media-monitor"=>Application_Model_Systemstatus::GetMediaMonitorStatus(), - "rabbitmq-server"=>Application_Model_Systemstatus::GetRabbitMqStatus() ); $partitions = Application_Model_Systemstatus::GetDiskInfo(); diff --git a/airtime_mvc/application/controllers/UserController.php b/airtime_mvc/application/controllers/UserController.php index 395156f97..bfbe8a258 100644 --- a/airtime_mvc/application/controllers/UserController.php +++ b/airtime_mvc/application/controllers/UserController.php @@ -48,13 +48,7 @@ class UserController extends Zend_Controller_Action if ($form->isValid($formData)) { - if (isset($CC_CONFIG['demo']) && $CC_CONFIG['demo'] == 1 - && $formData['login'] == 'admin' - && $formData['user_id'] != 0) { - $this->view->form = $form; - $this->view->successMessage = "
"._("Specific action is not allowed in demo version!")."
"; - die(json_encode(array("valid"=>"false", "html"=>$this->view->render('user/add-user.phtml')))); - } elseif ($form->validateLogin($formData)) { + if ($form->validateLogin($formData)) { $user = new Application_Model_User($formData['user_id']); if (empty($formData['user_id'])) { $user->setLogin($formData['login']); @@ -89,14 +83,14 @@ class UserController extends Zend_Controller_Action $this->view->successMessage = "
"._("User updated successfully!")."
"; } - die(json_encode(array("valid"=>"true", "html"=>$this->view->render('user/add-user.phtml')))); + $this->_helper->json->sendJson(array("valid"=>"true", "html"=>$this->view->render('user/add-user.phtml'))); } else { $this->view->form = $form; - die(json_encode(array("valid"=>"false", "html"=>$this->view->render('user/add-user.phtml')))); + $this->_helper->json->sendJson(array("valid"=>"false", "html"=>$this->view->render('user/add-user.phtml'))); } } else { $this->view->form = $form; - die(json_encode(array("valid"=>"false", "html"=>$this->view->render('user/add-user.phtml')))); + $this->_helper->json->sendJson(array("valid"=>"false", "html"=>$this->view->render('user/add-user.phtml'))); } } @@ -115,7 +109,7 @@ class UserController extends Zend_Controller_Action $post = $this->getRequest()->getPost(); $users = Application_Model_User::getUsersDataTablesInfo($post); - die(json_encode($users)); + $this->_helper->json->sendJson($users); } public function getUserDataAction() @@ -131,12 +125,7 @@ class UserController extends Zend_Controller_Action if ($request->isPost()) { $formData = $request->getPost(); - if (isset($CC_CONFIG['demo']) && $CC_CONFIG['demo'] == 1 - && $formData['cu_login'] == 'admin') { - $this->view->form = $form; - $this->view->successMessage = "
"._("Specific action is not allowed in demo version!")."
"; - die(json_encode(array("html"=>$this->view->render('user/edit-user.phtml')))); - } else if ($form->isValid($formData) && + if ($form->isValid($formData) && $form->validateLogin($formData['cu_login'], $formData['cu_user_id'])) { $user = new Application_Model_User($formData['cu_user_id']); $user->setFirstName($formData['cu_first_name']); diff --git a/airtime_mvc/application/controllers/UsersettingsController.php b/airtime_mvc/application/controllers/UsersettingsController.php index 238e67f3b..9d8154578 100644 --- a/airtime_mvc/application/controllers/UsersettingsController.php +++ b/airtime_mvc/application/controllers/UsersettingsController.php @@ -15,6 +15,7 @@ class UsersettingsController extends Zend_Controller_Action ->addActionContext('remindme', 'json') ->addActionContext('remindme-never', 'json') ->addActionContext('donotshowregistrationpopup', 'json') + ->addActionContext('set-library-screen-settings', 'json') ->initContext(); } @@ -54,6 +55,7 @@ class UsersettingsController extends Zend_Controller_Action { $request = $this->getRequest(); $settings = $request->getParam("settings"); + Application_Model_Preference::setTimelineDatatableSetting($settings); } @@ -91,4 +93,11 @@ class UsersettingsController extends Zend_Controller_Action // unset session Zend_Session::namespaceUnset('referrer'); } + + public function setLibraryScreenSettingsAction() + { + $request = $this->getRequest(); + $settings = $request->getParam("settings"); + Application_Model_Preference::setLibraryScreenSettings($settings); + } } diff --git a/airtime_mvc/application/controllers/plugins/Acl_plugin.php b/airtime_mvc/application/controllers/plugins/Acl_plugin.php index 4cadba9db..44555e533 100644 --- a/airtime_mvc/application/controllers/plugins/Acl_plugin.php +++ b/airtime_mvc/application/controllers/plugins/Acl_plugin.php @@ -110,7 +110,7 @@ class Zend_Controller_Plugin_Acl extends Zend_Controller_Plugin_Abstract { $controller = strtolower($request->getControllerName()); - if (in_array($controller, array("api", "auth"))) { + if (in_array($controller, array("api", "auth", "locale"))) { $this->setRoleName("G"); } elseif (!Zend_Auth::getInstance()->hasIdentity()) { diff --git a/airtime_mvc/application/forms/GeneralPreferences.php b/airtime_mvc/application/forms/GeneralPreferences.php index 48a561b06..3d249ce47 100644 --- a/airtime_mvc/application/forms/GeneralPreferences.php +++ b/airtime_mvc/application/forms/GeneralPreferences.php @@ -7,6 +7,7 @@ class Application_Form_GeneralPreferences extends Zend_Form_SubForm { $notEmptyValidator = Application_Form_Helper_ValidationTypes::overrideNotEmptyValidator(); + $rangeValidator = Application_Form_Helper_ValidationTypes::overrideBetweenValidator(0, 59.9); $this->setDecorators(array( array('ViewScript', array('viewScript' => 'form/preferences_general.phtml')) )); @@ -34,9 +35,13 @@ class Application_Form_GeneralPreferences extends Zend_Form_SubForm 'label' => _('Default Fade (s):'), 'required' => true, 'filters' => array('StringTrim'), - 'validators' => array(array($notEmptyValidator, 'regex', false, - array('/^[0-9]{1,2}(\.\d{1})?$/', - 'messages' => _('enter a time in seconds 0{.0}')))), + 'validators' => array( + array( + $rangeValidator, + $notEmptyValidator, + 'regex', false, array('/^[0-9]{1,2}(\.\d{1})?$/', 'messages' => _('enter a time in seconds 0{.0}')) + ) + ), 'value' => $defaultFade, 'decorators' => array( 'ViewHelper' diff --git a/airtime_mvc/application/forms/RegisterAirtime.php b/airtime_mvc/application/forms/RegisterAirtime.php index d1557612a..2da7083c8 100644 --- a/airtime_mvc/application/forms/RegisterAirtime.php +++ b/airtime_mvc/application/forms/RegisterAirtime.php @@ -7,7 +7,7 @@ class Application_Form_RegisterAirtime extends Zend_Form public function init() { - $this->setAction(Application_Common_OsPath::getBaseDir().'/Showbuilder'); + $this->setAction(Application_Common_OsPath::getBaseDir().'Showbuilder'); $this->setMethod('post'); $country_list = Application_Model_Preference::GetCountryList(); diff --git a/airtime_mvc/application/forms/SmartBlockCriteria.php b/airtime_mvc/application/forms/SmartBlockCriteria.php index f47117b63..d981fdb49 100644 --- a/airtime_mvc/application/forms/SmartBlockCriteria.php +++ b/airtime_mvc/application/forms/SmartBlockCriteria.php @@ -5,6 +5,11 @@ class Application_Form_SmartBlockCriteria extends Zend_Form_SubForm private $stringCriteriaOptions; private $numericCriteriaOptions; private $limitOptions; + + /* We need to know if the criteria value will be a string + * or numeric value in order to populate the modifier + * select list + */ private $criteriaTypes = array( 0 => "", "album_title" => "s", @@ -13,6 +18,8 @@ class Application_Form_SmartBlockCriteria extends Zend_Form_SubForm "composer" => "s", "conductor" => "s", "copyright" => "s", + "cuein" => "n", + "cueout" => "n", "artist_name" => "s", "encoded_by" => "s", "utime" => "n", @@ -45,6 +52,8 @@ class Application_Form_SmartBlockCriteria extends Zend_Form_SubForm "composer" => _("Composer"), "conductor" => _("Conductor"), "copyright" => _("Copyright"), + "cuein" => _("Cue In"), + "cueout" => _("Cue Out"), "artist_name" => _("Creator"), "encoded_by" => _("Encoded By"), "genre" => _("Genre"), @@ -416,32 +425,34 @@ class Application_Form_SmartBlockCriteria extends Zend_Form_SubForm $isValid = true; $data = $this->preValidation($params); $criteria2PeerMap = array( - 0 => "Select criteria", - "album_title" => "DbAlbumTitle", - "artist_name" => "DbArtistName", - "bit_rate" => "DbBitRate", - "bpm" => "DbBpm", - "composer" => "DbComposer", - "conductor" => "DbConductor", - "copyright" => "DbCopyright", - "encoded_by" => "DbEncodedBy", - "utime" => "DbUtime", - "mtime" => "DbMtime", - "lptime" => "DbLPtime", - "genre" => "DbGenre", - "info_url" => "DbInfoUrl", - "isrc_number" => "DbIsrcNumber", - "label" => "DbLabel", - "language" => "DbLanguage", - "length" => "DbLength", - "mime" => "DbMime", - "mood" => "DbMood", - "owner_id" => "DbOwnerId", - "replay_gain" => "DbReplayGain", - "sample_rate" => "DbSampleRate", - "track_title" => "DbTrackTitle", - "track_number" => "DbTrackNumber", - "year" => "DbYear" + 0 => "Select criteria", + "album_title" => "DbAlbumTitle", + "artist_name" => "DbArtistName", + "bit_rate" => "DbBitRate", + "bpm" => "DbBpm", + "composer" => "DbComposer", + "conductor" => "DbConductor", + "copyright" => "DbCopyright", + "cuein" => "DbCuein", + "cueout" => "DbCueout", + "encoded_by" => "DbEncodedBy", + "utime" => "DbUtime", + "mtime" => "DbMtime", + "lptime" => "DbLPtime", + "genre" => "DbGenre", + "info_url" => "DbInfoUrl", + "isrc_number" => "DbIsrcNumber", + "label" => "DbLabel", + "language" => "DbLanguage", + "length" => "DbLength", + "mime" => "DbMime", + "mood" => "DbMood", + "owner_id" => "DbOwnerId", + "replay_gain" => "DbReplayGain", + "sample_rate" => "DbSampleRate", + "track_title" => "DbTrackTitle", + "track_number" => "DbTrackNumber", + "year" => "DbYear" ); // things we need to check @@ -492,7 +503,7 @@ class Application_Form_SmartBlockCriteria extends Zend_Form_SubForm } else { $column = CcFilesPeer::getTableMap()->getColumnByPhpName($criteria2PeerMap[$d['sp_criteria_field']]); // validation on type of column - if ($d['sp_criteria_field'] == 'length') { + if (in_array($d['sp_criteria_field'], array('length', 'cuein', 'cueout'))) { if (!preg_match("/^(\d{2}):(\d{2}):(\d{2})/", $d['sp_criteria_value'])) { $element->addError(_("'Length' should be in '00:00:00' format")); $isValid = false; diff --git a/airtime_mvc/application/layouts/scripts/layout.phtml b/airtime_mvc/application/layouts/scripts/layout.phtml index 29d04c0d6..dedda7c88 100644 --- a/airtime_mvc/application/layouts/scripts/layout.phtml +++ b/airtime_mvc/application/layouts/scripts/layout.phtml @@ -24,7 +24,7 @@ diff --git a/airtime_mvc/application/logging/Logging.php b/airtime_mvc/application/logging/Logging.php index dfe7e1fbe..65a8f6dc2 100644 --- a/airtime_mvc/application/logging/Logging.php +++ b/airtime_mvc/application/logging/Logging.php @@ -32,6 +32,8 @@ class Logging { { if (is_array($p_msg) || is_object($p_msg)) { return print_r($p_msg, true); + } else if (is_bool($p_msg)) { + return $p_msg ? "true" : "false"; } else { return $p_msg; } diff --git a/airtime_mvc/application/models/Block.php b/airtime_mvc/application/models/Block.php index 7053e658d..b364e5eb5 100644 --- a/airtime_mvc/application/models/Block.php +++ b/airtime_mvc/application/models/Block.php @@ -63,6 +63,8 @@ class Application_Model_Block implements Application_Model_LibraryEditable "composer" => "DbComposer", "conductor" => "DbConductor", "copyright" => "DbCopyright", + "cuein" => "DbCuein", + "cueout" => "DbCueout", "encoded_by" => "DbEncodedBy", "utime" => "DbUtime", "mtime" => "DbMtime", @@ -257,6 +259,10 @@ SQL; //format original length $formatter = new LengthFormatter($row['orig_length']); $row['orig_length'] = $formatter->format(); + + // XSS exploit prevention + $row["track_title"] = htmlspecialchars($row["track_title"]); + $row["creator"] = htmlspecialchars($row["creator"]); } return $rows; @@ -399,10 +405,13 @@ SQL; $entry = $this->blockItem; $entry["id"] = $file->getDbId(); $entry["pos"] = $pos; - $entry["cliplength"] = $file->getDbLength(); $entry["cueout"] = $file->getDbCueout(); $entry["cuein"] = $file->getDbCuein(); + $cue_out = Application_Common_DateHelper::calculateLengthInSeconds($entry['cueout']); + $cue_in = Application_Common_DateHelper::calculateLengthInSeconds($entry['cuein']); + $entry["cliplength"] = Application_Common_DateHelper::secondsToPlaylistTime($cue_out-$cue_in); + return $entry; } else { throw new Exception("trying to add a file that does not exist."); @@ -476,10 +485,19 @@ SQL; try { if (is_array($ac) && $ac[1] == 'audioclip') { $res = $this->insertBlockElement($this->buildEntry($ac[0], $pos)); + + // update is_playlist flag in cc_files to indicate the + // file belongs to a playlist or block (in this case a block) + $db_file = CcFilesQuery::create()->findPk($ac[0], $this->con); + $db_file->setDbIsPlaylist(true)->save($this->con); + $pos = $pos + 1; } elseif (!is_array($ac)) { $res = $this->insertBlockElement($this->buildEntry($ac, $pos)); $pos = $pos + 1; + + $db_file = CcFilesQuery::create()->findPk($ac, $this->con); + $db_file->setDbIsPlaylist(true)->save($this->con); } } catch (Exception $e) { Logging::info($e->getMessage()); @@ -592,10 +610,21 @@ SQL; try { + // we need to get the file id of the item we are deleting + // before the item gets deleted from the block + $itemsToDelete = CcBlockcontentsQuery::create() + ->filterByPrimaryKeys($p_items) + ->filterByDbFileId(null, Criteria::NOT_EQUAL) + ->find($this->con); + CcBlockcontentsQuery::create() ->findPKs($p_items) ->delete($this->con); + // now that the items have been deleted we can update the + // is_playlist flag in cc_files + Application_Model_StoredFile::setIsPlaylist($itemsToDelete, 'block', false); + $contents = CcBlockcontentsQuery::create() ->filterByDbBlockId($this->id) ->orderByDbPosition() @@ -965,16 +994,36 @@ SQL; $user = new Application_Model_User($userInfo->id); $isAdminOrPM = $user->isUserType(array(UTYPE_ADMIN, UTYPE_PROGRAM_MANAGER)); + // get only the files from the blocks + // we are about to delete + $itemsToDelete = CcBlockcontentsQuery::create() + ->filterByDbBlockId($p_ids) + ->filterByDbFileId(null, Criteria::NOT_EQUAL) + ->find(); + + $updateIsPlaylistFlag = false; + if (!$isAdminOrPM) { $leftOver = self::blocksNotOwnedByUser($p_ids, $p_userId); if (count($leftOver) == 0) { CcBlockQuery::create()->findPKs($p_ids)->delete(); + $updateIsPlaylistFlag = true; } else { throw new BlockNoPermissionException; } } else { CcBlockQuery::create()->findPKs($p_ids)->delete(); + $updateIsPlaylistFlag = true; + } + + if ($updateIsPlaylistFlag) { + // update is_playlist flag in cc_files + Application_Model_StoredFile::setIsPlaylist( + $itemsToDelete, + 'block', + false + ); } } @@ -1000,8 +1049,26 @@ SQL; */ public function deleteAllFilesFromBlock() { + // get only the files from the playlist + // we are about to clear out + $itemsToDelete = CcBlockcontentsQuery::create() + ->filterByDbBlockId($this->id) + ->filterByDbFileId(null, Criteria::NOT_EQUAL) + ->find(); + CcBlockcontentsQuery::create()->findByDbBlockId($this->id)->delete(); - $this->block->reload(); + + // update is_playlist flag in cc_files + Application_Model_StoredFile::setIsPlaylist( + $itemsToDelete, + 'block', + false + ); + + //$this->block->reload(); + $this->block->setDbMtime(new DateTime("now", new DateTimeZone("UTC"))); + $this->block->save($this->con); + $this->con->commit(); } // smart block functions start @@ -1213,6 +1280,8 @@ SQL; "composer" => _("Composer"), "conductor" => _("Conductor"), "copyright" => _("Copyright"), + "cuein" => _("Cue In"), + "cueout" => _("Cue Out"), "artist_name" => _("Creator"), "encoded_by" => _("Encoded By"), "genre" => _("Genre"), @@ -1241,7 +1310,7 @@ SQL; foreach ($out as $crit) { $criteria = $crit->getDbCriteria(); $modifier = $crit->getDbModifier(); - $value = $crit->getDbValue(); + $value = htmlspecialchars($crit->getDbValue()); $extra = $crit->getDbExtra(); if ($criteria == "limit") { @@ -1305,7 +1374,7 @@ SQL; * user only sees the rounded version (i.e. 4:02.7 is 4:02.761625 * in the database) */ - } elseif ($spCriteria == 'length' && $spCriteriaModifier == "is") { + } elseif (in_array($spCriteria, array('length', 'cuein', 'cueout')) && $spCriteriaModifier == "is") { $spCriteriaModifier = "starts with"; $spCriteria = $spCriteria.'::text'; $spCriteriaValue = $criteria['value']; @@ -1434,6 +1503,20 @@ SQL; return $output; } + public static function getAllBlockFiles() + { + $con = Propel::getConnection(); + $sql = <<query($sql)->fetchAll(); + $real_files = array(); + foreach ($files as $f) { + $real_files[] = $f['file_id']; + } + return $real_files; + } // smart block functions end } diff --git a/airtime_mvc/application/models/Playlist.php b/airtime_mvc/application/models/Playlist.php index f4ea01e4a..ea584b76c 100644 --- a/airtime_mvc/application/models/Playlist.php +++ b/airtime_mvc/application/models/Playlist.php @@ -269,6 +269,10 @@ SQL; //format original length $formatter = new LengthFormatter($row['orig_length']); $row['orig_length'] = $formatter->format(); + + // XSS exploit prevention + $row["track_title"] = htmlspecialchars($row["track_title"]); + $row["creator"] = htmlspecialchars($row["creator"]); } return $rows; @@ -398,6 +402,13 @@ SQL; if ($obj instanceof CcFiles && $obj) { $entry["cuein"] = $obj->getDbCuein(); $entry["cueout"] = $obj->getDbCueout(); + + $cue_out = Application_Common_DateHelper::calculateLengthInSeconds($entry['cueout']); + $cue_in = Application_Common_DateHelper::calculateLengthInSeconds($entry['cuein']); + $entry["cliplength"] = Application_Common_DateHelper::secondsToPlaylistTime($cue_out-$cue_in); + } elseif ($obj instanceof CcWebstream && $obj) { + $entry["cuein"] = "00:00:00"; + $entry["cueout"] = $entry["cliplength"]; } $entry["ftype"] = $objType; } @@ -466,6 +477,12 @@ SQL; foreach ($p_items as $ac) { $res = $this->insertPlaylistElement($this->buildEntry($ac, $pos)); + + // update is_playlist flag in cc_files to indicate the + // file belongs to a playlist or block (in this case a playlist) + $db_file = CcFilesQuery::create()->findPk($ac[0], $this->con); + $db_file->setDbIsPlaylist(true)->save($this->con); + $pos = $pos + 1; Logging::info("Adding $ac[1] $ac[0]"); @@ -574,10 +591,21 @@ SQL; try { + // we need to get the file id of the item we are deleting + // before the item gets deleted from the playlist + $itemsToDelete = CcPlaylistcontentsQuery::create() + ->filterByPrimaryKeys($p_items) + ->filterByDbFileId(null, Criteria::NOT_EQUAL) + ->find($this->con); + CcPlaylistcontentsQuery::create() ->findPKs($p_items) ->delete($this->con); + // now that the items have been deleted we can update the + // is_playlist flag in cc_files + Application_Model_StoredFile::setIsPlaylist($itemsToDelete, 'playlist', false); + $contents = CcPlaylistcontentsQuery::create() ->filterByDbPlaylistId($this->id) ->orderByDbPosition() @@ -892,15 +920,36 @@ SQL; $user = new Application_Model_User($userInfo->id); $isAdminOrPM = $user->isUserType(array(UTYPE_ADMIN, UTYPE_PROGRAM_MANAGER)); + // get only the files from the playlists + // we are about to delete + $itemsToDelete = CcPlaylistcontentsQuery::create() + ->filterByDbPlaylistId($p_ids) + ->filterByDbFileId(null, Criteria::NOT_EQUAL) + ->find(); + + $updateIsPlaylistFlag = false; + if (!$isAdminOrPM) { $leftOver = self::playlistsNotOwnedByUser($p_ids, $p_userId); if (count($leftOver) == 0) { CcPlaylistQuery::create()->findPKs($p_ids)->delete(); + $updateIsPlaylistFlag = true; + } else { throw new PlaylistNoPermissionException; } } else { CcPlaylistQuery::create()->findPKs($p_ids)->delete(); + $updateIsPlaylistFlag = true; + } + + if ($updateIsPlaylistFlag) { + // update is_playlist flag in cc_files + Application_Model_StoredFile::setIsPlaylist( + $itemsToDelete, + 'playlist', + false + ); } } @@ -927,7 +976,25 @@ SQL; */ public function deleteAllFilesFromPlaylist() { + // get only the files from the playlist + // we are about to clear out + $itemsToDelete = CcPlaylistcontentsQuery::create() + ->filterByDbPlaylistId($this->id) + ->filterByDbFileId(null, Criteria::NOT_EQUAL) + ->find(); + CcPlaylistcontentsQuery::create()->findByDbPlaylistId($this->id)->delete(); + + // update is_playlist flag in cc_files + Application_Model_StoredFile::setIsPlaylist( + $itemsToDelete, + 'playlist', + false + ); + + $this->pl->setDbMtime(new DateTime("now", new DateTimeZone("UTC"))); + $this->pl->save($this->con); + $this->con->commit(); } public function shuffle() @@ -953,6 +1020,38 @@ SQL; return $result; } + public static function getAllPlaylistFiles() + { + $con = Propel::getConnection(); + $sql = <<query($sql)->fetchAll(); + $real_files = array(); + foreach ($files as $f) { + $real_files[] = $f['file_id']; + } + return $real_files; + } + + public static function getAllPlaylistStreams() + { + $con = Propel::getConnection(); + $sql = <<query($sql)->fetchAll(); + $real_streams = array(); + foreach ($streams as $s) { + $real_streams[] = $s['stream_id']; + } + return $real_streams; + } + } // class Playlist class PlaylistNotFoundException extends Exception {} diff --git a/airtime_mvc/application/models/Preference.php b/airtime_mvc/application/models/Preference.php index 08bd14137..2af97d193 100644 --- a/airtime_mvc/application/models/Preference.php +++ b/airtime_mvc/application/models/Preference.php @@ -1223,9 +1223,9 @@ class Application_Model_Preference $num_columns = count(Application_Model_StoredFile::getLibraryColumns()); $new_columns_num = count($settings['abVisCols']); - if ($num_columns != $new_columns_num) { + /*if ($num_columns != $new_columns_num) { throw new Exception("Trying to write a user column preference with incorrect number of columns!"); - } + }*/ $data = serialize($settings); $v = self::setValue("library_datatable", $data, true); @@ -1262,7 +1262,19 @@ class Application_Model_Preference $data = self::getValue("nowplaying_screen", true); return ($data != "") ? unserialize($data) : null; } - + + public static function setLibraryScreenSettings($settings) + { + $data = serialize($settings); + self::setValue("library_screen", $data, true); + } + + public static function getLibraryScreenSettings() + { + $data = self::getValue("library_screen", true); + return ($data != "") ? unserialize($data) : null; + } + public static function SetEnableReplayGain($value) { self::setValue("enable_replay_gain", $value, false); } diff --git a/airtime_mvc/application/models/RabbitMq.php b/airtime_mvc/application/models/RabbitMq.php index af20d473e..371fab0b9 100644 --- a/airtime_mvc/application/models/RabbitMq.php +++ b/airtime_mvc/application/models/RabbitMq.php @@ -22,6 +22,11 @@ class Application_Model_RabbitMq $CC_CONFIG["rabbitmq"]["user"], $CC_CONFIG["rabbitmq"]["password"], $CC_CONFIG["rabbitmq"]["vhost"]); + + if (!isset($conn)) { + throw new Exception("Cannot connect to RabbitMQ server"); + } + $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 481f22b2d..1aac2566e 100644 --- a/airtime_mvc/application/models/Schedule.php +++ b/airtime_mvc/application/models/Schedule.php @@ -20,6 +20,41 @@ SQL; return (is_numeric($count) && ($count != '0')); } + public static function getAllFutureScheduledFiles() + { + $con = Propel::getConnection(); + $sql = << now() AT TIME ZONE 'UTC' +AND file_id is not null +SQL; + $files = $con->query($sql)->fetchAll(); + $real_files = array(); + foreach ($files as $f) { + $real_files[] = $f['file_id']; + } + + return $real_files; + } + + public static function getAllFutureScheduledWebstreams() + { + $con = Propel::getConnection(); + $sql = << now() AT TIME ZONE 'UTC' +AND stream_id is not null +SQL; + $streams = $con->query($sql)->fetchAll(); + $real_streams = array(); + foreach ($streams as $s) { + $real_streams[] = $s['stream_id']; + } + + return $real_streams; + } /** * Returns data related to the scheduled items. * @@ -696,6 +731,10 @@ SQL; 'replay_gain' => $replay_gain, 'independent_event' => $independent_event, ); + + if ($schedule_item['cue_in'] > $schedule_item['cue_out']) { + $schedule_item['cue_in'] = $schedule_item['cue_out']; + } self::appendScheduleItem($data, $start, $schedule_item); } @@ -906,7 +945,6 @@ SQL; self::createScheduledEvents($data, $range_start, $range_end); self::foldData($data["media"]); - return $data; } diff --git a/airtime_mvc/application/models/Scheduler.php b/airtime_mvc/application/models/Scheduler.php index 2530eb7bf..ee8263c2c 100644 --- a/airtime_mvc/application/models/Scheduler.php +++ b/airtime_mvc/application/models/Scheduler.php @@ -136,13 +136,17 @@ class Application_Model_Scheduler if ($type === "audioclip") { $file = CcFilesQuery::create()->findPK($id, $this->con); + $storedFile = new Application_Model_StoredFile($file->getDbId()); if (is_null($file) || !$file->visible()) { throw new Exception(_("A selected File does not exist!")); } else { $data = $this->fileInfo; $data["id"] = $id; - $data["cliplength"] = $file->getDbLength(); + $data["cliplength"] = $storedFile->getRealClipLength( + $file->getDbCuein(), + $file->getDbCueout()); + $data["cuein"] = $file->getDbCuein(); $data["cueout"] = $file->getDbCueout(); @@ -199,9 +203,12 @@ class Application_Model_Scheduler $file = CcFilesQuery::create()->findPk($fileId); if (isset($file) && $file->visible()) { $data["id"] = $file->getDbId(); - $data["cliplength"] = $file->getDbLength(); - $data["cuein"] = "00:00:00"; - $data["cueout"] = $file->getDbLength(); + $data["cuein"] = $file->getDbCuein(); + $data["cueout"] = $file->getDbCueout(); + + $cuein = Application_Common_DateHelper::calculateLengthInSeconds($data["cuein"]); + $cueout = Application_Common_DateHelper::calculateLengthInSeconds($data["cueout"]); + $data["cliplength"] = Application_Common_DateHelper::secondsToPlaylistTime($cueout - $cuein); $defaultFade = Application_Model_Preference::GetDefaultFade(); if (isset($defaultFade)) { //fade is in format SS.uuuuuu @@ -257,9 +264,12 @@ class Application_Model_Scheduler $file = CcFilesQuery::create()->findPk($fileId); if (isset($file) && $file->visible()) { $data["id"] = $file->getDbId(); - $data["cliplength"] = $file->getDbLength(); - $data["cuein"] = "00:00:00"; - $data["cueout"] = $file->getDbLength(); + $data["cuein"] = $file->getDbCuein(); + $data["cueout"] = $file->getDbCueout(); + + $cuein = Application_Common_DateHelper::calculateLengthInSeconds($data["cuein"]); + $cueout = Application_Common_DateHelper::calculateLengthInSeconds($data["cueout"]); + $data["cliplength"] = Application_Common_DateHelper::secondsToPlaylistTime($cueout - $cuein); $defaultFade = Application_Model_Preference::GetDefaultFade(); if (isset($defaultFade)) { //fade is in format SS.uuuuuu @@ -321,6 +331,8 @@ class Application_Model_Scheduler $filler->setDbStarts($DT) ->setDbEnds($this->nowDT) ->setDbClipLength($cliplength) + ->setDbCueIn('00:00:00') + ->setDbCueOut('00:00:00') ->setDbPlayoutStatus(-1) ->setDbInstanceId($instance->getDbId()) ->save($this->con); @@ -438,7 +450,6 @@ class Application_Model_Scheduler } foreach ($schedFiles as $file) { - $endTimeDT = $this->findEndTime($nextStartDT, $file['cliplength']); //item existed previously and is being moved. @@ -514,6 +525,13 @@ class Application_Model_Scheduler $instance->updateScheduleStatus($this->con); } + // update is_scheduled flag for each cc_file + foreach ($schedFiles as $file) { + $db_file = CcFilesQuery::create()->findPk($file['id'], $this->con); + $db_file->setDbIsScheduled(true); + $db_file->save($this->con); + } + $endProfile = microtime(true); Logging::debug("updating show instances status."); Logging::debug(floatval($endProfile) - floatval($startProfile)); @@ -718,6 +736,16 @@ class Application_Model_Scheduler } else { $removedItem->delete($this->con); } + + // update is_scheduled in cc_files but only if + // the file is not scheduled somewhere else + $fileId = $removedItem->getDbFileId(); + // check if the removed item is scheduled somewhere else + $futureScheduledFiles = Application_Model_Schedule::getAllFutureScheduledFiles(); + if (!is_null($fileId) && !in_array($fileId, $futureScheduledFiles)) { + $db_file = CcFilesQuery::create()->findPk($fileId, $this->con); + $db_file->setDbIsScheduled(false)->save($this->con); + } } if ($adjustSched === true) { diff --git a/airtime_mvc/application/models/Show.php b/airtime_mvc/application/models/Show.php index 9db5e5f0b..f485e41bc 100644 --- a/airtime_mvc/application/models/Show.php +++ b/airtime_mvc/application/models/Show.php @@ -663,6 +663,30 @@ SQL; $con->exec($sql); } + public function getNextFutureRepeatShowTime() + { + $sql = << now() at time zone 'UTC' +AND show_id = :showId +ORDER BY starts +LIMIT 1 +SQL; + $result = Application_Common_Database::prepareAndExecute( $sql, + array( 'showId' => $this->getId() ), 'all' ); + + foreach ($result as $r) { + $show["starts"] = new DateTime($r["starts"], new DateTimeZone('UTC')); + $show["ends"] = new DateTime($r["ends"], new DateTimeZone('UTC')); + } + $currentUser = Application_Model_User::getCurrentUser(); + $currentUserId = $currentUser->getId(); + $userTimezone = Application_Model_Preference::GetUserTimezone($currentUserId); + $show["starts"]->setTimezone(new DateTimeZone($userTimezone)); + $show["ends"]->setTimezone(new DateTimeZone($userTimezone)); + return $show; + } + /** * Get the start date of the current show in UTC timezone. * @@ -1750,12 +1774,15 @@ SQL; $interval = $p_start->diff($p_end); $days = $interval->format('%a'); $shows = Application_Model_Show::getShows($p_start, $p_end); - $nowEpoch = time(); $content_count = Application_Model_ShowInstance::getContentCount( $p_start, $p_end); + $isFull = Application_Model_ShowInstance::getIsFull($p_start, $p_end); $timezone = date_default_timezone_get(); + $current_timezone = new DateTimeZone($timezone); + $utc = new DateTimeZone("UTC"); + $now = new DateTime("now", $utc); - foreach ($shows as $show) { + foreach ($shows as &$show) { $options = array(); //only bother calculating percent for week or day view. @@ -1763,11 +1790,8 @@ SQL; $options["percent"] = Application_Model_Show::getPercentScheduled($show["starts"], $show["ends"], $show["time_filled"]); } - $utc = new DateTimeZone("UTC"); - if (isset($show["parent_starts"])) { $parentStartsDT = new DateTime($show["parent_starts"], $utc); - $parentStartsEpoch = intval($parentStartsDT->format("U")); } $startsDT = DateTime::createFromFormat("Y-m-d G:i:s", @@ -1775,39 +1799,53 @@ SQL; $endsDT = DateTime::createFromFormat("Y-m-d G:i:s", $show["ends"], $utc); - $startsEpochStr = $startsDT->format("U"); - $endsEpochStr = $endsDT->format("U"); - - $startsEpoch = intval($startsEpochStr); - $endsEpoch = intval($endsEpochStr); - - $startsDT->setTimezone(new DateTimeZone($timezone)); - $endsDT->setTimezone(new DateTimeZone($timezone)); - if( $p_editable ) { - if ($show["record"] && $nowEpoch > $startsEpoch) { + if ($show["record"] && $now > $startsDT) { $options["editable"] = false; } elseif ($show["rebroadcast"] && - $nowEpoch > $parentStartsEpoch) { + $now > $parentStartsDT) { $options["editable"] = false; - } elseif ($nowEpoch < $endsEpoch) { + } elseif ($now < $endsDT) { $options["editable"] = true; } } - - $showInstance = new Application_Model_ShowInstance( - $show["instance_id"]); + $startsDT->setTimezone($current_timezone); + $endsDT->setTimezone($current_timezone); $options["show_empty"] = (array_key_exists($show['instance_id'], $content_count)) ? 0 : 1; - - $options["show_partial_filled"] = $showInstance->showPartialFilled(); - $events[] = &self::makeFullCalendarEvent($show, $options, - $startsDT, $endsDT, $startsEpochStr, $endsEpochStr); + $options["show_partial_filled"] = !$isFull[$show['instance_id']]; + + $event = array(); + + $event["id"] = intval($show["instance_id"]); + $event["title"] = $show["name"]; + $event["start"] = $startsDT->format("Y-m-d H:i:s"); + $event["end"] = $endsDT->format("Y-m-d H:i:s"); + $event["allDay"] = false; + $event["showId"] = intval($show["show_id"]); + $event["record"] = intval($show["record"]); + $event["rebroadcast"] = intval($show["rebroadcast"]); + $event["soundcloud_id"] = is_null($show["soundcloud_id"]) + ? -1 : $show["soundcloud_id"]; + + //event colouring + if ($show["color"] != "") { + $event["textColor"] = "#".$show["color"]; + } + + if ($show["background_color"] != "") { + $event["color"] = "#".$show["background_color"]; + } + + foreach ($options as $key => $value) { + $event[$key] = $value; + } + + $events[] = $event; } - return $events; } @@ -1824,7 +1862,7 @@ SQL; return $percent; } - private static function &makeFullCalendarEvent(&$show, $options=array(), $startDateTime, $endDateTime, $startsEpoch, $endsEpoch) +/* private static function &makeFullCalendarEvent(&$show, $options=array(), $startDateTime, $endDateTime, $startsEpoch, $endsEpoch) { $event = array(); @@ -1855,7 +1893,7 @@ SQL; } return $event; - } + }*/ /* Takes in a UTC DateTime object. * Converts this to local time, since cc_show days @@ -2162,4 +2200,42 @@ SQL; } return $assocArray; } + + public static function getStartEndCurrentMonthView() { + $first_day_of_calendar_month_view = mktime(0, 0, 0, date("n"), 1); + $weekStart = Application_Model_Preference::GetWeekStartDay(); + while (date('w', $first_day_of_calendar_month_view) != $weekStart) { + $first_day_of_calendar_month_view -= 60*60*24; + } + $last_day_of_calendar_view = $first_day_of_calendar_month_view + 3600*24*42; + + $start = new DateTime("@".$first_day_of_calendar_month_view); + $end = new DateTime("@".$last_day_of_calendar_view); + + return array($start, $end); + } + + public static function getStartEndCurrentWeekView() { + $first_day_of_calendar_week_view = mktime(0, 0, 0, date("n"), date("j")); + $weekStart = Application_Model_Preference::GetWeekStartDay(); + while (date('w', $first_day_of_calendar_week_view) != $weekStart) { + $first_day_of_calendar_week_view -= 60*60*24; + } + $last_day_of_calendar_view = $first_day_of_calendar_week_view + 3600*24*7; + + $start = new DateTime("@".$first_day_of_calendar_week_view); + $end = new DateTime("@".$last_day_of_calendar_view); + + return array($start, $end); + } + + public static function getStartEndCurrentDayView() { + $today = mktime(0, 0, 0, date("n"), date("j")); + $tomorrow = $today + 3600*24; + + $start = new DateTime("@".$today); + $end = new DateTime("@".$tomorrow); + + return array($start, $end); + } } diff --git a/airtime_mvc/application/models/ShowBuilder.php b/airtime_mvc/application/models/ShowBuilder.php index a1ef7c588..fd85487db 100644 --- a/airtime_mvc/application/models/ShowBuilder.php +++ b/airtime_mvc/application/models/ShowBuilder.php @@ -227,7 +227,7 @@ class Application_Model_ShowBuilder $row["endDate"] = $showEndDT->format("Y-m-d"); $row["endTime"] = $showEndDT->format("H:i"); $row["duration"] = floatval($showEndDT->format("U.u")) - floatval($showStartDT->format("U.u")); - $row["title"] = $p_item["show_name"]; + $row["title"] = htmlspecialchars($p_item["show_name"]); $row["instance"] = intval($p_item["si_id"]); $row["image"] = ''; @@ -275,9 +275,9 @@ class Application_Model_ShowBuilder $formatter = new LengthFormatter(Application_Common_DateHelper::ConvertMSToHHMMSSmm($run_time*1000)); $row['runtime'] = $formatter->format(); - $row["title"] = $p_item["file_track_title"]; - $row["creator"] = $p_item["file_artist_name"]; - $row["album"] = $p_item["file_album_title"]; + $row["title"] = htmlspecialchars($p_item["file_track_title"]); + $row["creator"] = htmlspecialchars($p_item["file_artist_name"]); + $row["album"] = htmlspecialchars($p_item["file_album_title"]); $row["cuein"] = $p_item["cue_in"]; $row["cueout"] = $p_item["cue_out"]; diff --git a/airtime_mvc/application/models/ShowInstance.php b/airtime_mvc/application/models/ShowInstance.php index 14def6321..e1892d4c2 100644 --- a/airtime_mvc/application/models/ShowInstance.php +++ b/airtime_mvc/application/models/ShowInstance.php @@ -661,10 +661,8 @@ SQL; return $returnStr; } - - public static function getContentCount($p_start, $p_end) - { + { $sql = << '00:00:00' -AND time_filled < ends - starts -AND file_id IS null AS partial_filled -FROM cc_show_instances -WHERE id = :instance_id +SELECT id, ends-starts-'00:00:05' < time_filled as filled +from cc_show_instances +WHERE ends > :p_start::TIMESTAMP +AND starts < :p_end::TIMESTAMP SQL; - $res = Application_Common_Database::prepareAndExecute($sql, - array(':instance_id' => $this->_instanceId), 'all'); + $res = Application_Common_Database::prepareAndExecute($sql, array( + ':p_start' => $p_start->format("Y-m-d G:i:s"), + ':p_end' => $p_end->format("Y-m-d G:i:s")) + , 'all'); - return $res[0]["partial_filled"]; + $isFilled = array(); + foreach ($res as $r) { + $isFilled[$r['id']] = $r['filled']; + } + + return $isFilled; } public function showEmpty() diff --git a/airtime_mvc/application/models/StoredFile.php b/airtime_mvc/application/models/StoredFile.php index bd50f2826..6f5ed142d 100644 --- a/airtime_mvc/application/models/StoredFile.php +++ b/airtime_mvc/application/models/StoredFile.php @@ -368,7 +368,12 @@ SQL; if (file_exists($filepath) && $type == "stor") { $data = array("filepath" => $filepath, "delete" => 1); - Application_Model_RabbitMq::SendMessageToMediaMonitor("file_delete", $data); + try { + Application_Model_RabbitMq::SendMessageToMediaMonitor("file_delete", $data); + } catch (Exception $e) { + Logging::error($e->getMessage()); + return; + } } @@ -645,7 +650,8 @@ SQL; "track_number", "mood", "bpm", "composer", "info_url", "bit_rate", "sample_rate", "isrc_number", "encoded_by", "label", "copyright", "mime", "language", "filepath", "owner_id", - "conductor", "replay_gain", "lptime" ); + "conductor", "replay_gain", "lptime", "is_playlist", "is_scheduled", + "cuein", "cueout" ); } public static function searchLibraryFiles($datatables) @@ -697,6 +703,16 @@ SQL; $blSelect[] = "NULL::TIMESTAMP AS ".$key; $fileSelect[] = $key; $streamSelect[] = $key; + } elseif ($key === "is_scheduled" || $key === "is_playlist") { + $plSelect[] = "NULL::boolean AS ".$key; + $blSelect[] = "NULL::boolean AS ".$key; + $fileSelect[] = $key; + $streamSelect[] = "NULL::boolean AS ".$key; + } elseif ($key === "cuein" || $key === "cueout") { + $plSelect[] = "NULL::INTERVAL AS ".$key; + $blSelect[] = "NULL::INTERVAL AS ".$key; + $fileSelect[] = $key; + $streamSelect[] = "NULL::INTERVAL AS ".$key; } //same columns in each table. else if (in_array($key, array("length", "utime", "mtime"))) { @@ -770,14 +786,22 @@ SQL; $fromTable = $unionTable; } + // update is_scheduled to false for tracks that + // have already played out + self::updatePastFilesIsScheduled(); $results = Application_Model_Datatables::findEntries($con, $displayColumns, $fromTable, $datatables); - //Used by the audio preview functionality in the library. foreach ($results['aaData'] as &$row) { $row['id'] = intval($row['id']); - $formatter = new LengthFormatter($row['length']); - $row['length'] = $formatter->format(); + $len_formatter = new LengthFormatter($row['length']); + $row['length'] = $len_formatter->format(); + + $cuein_formatter = new LengthFormatter($row["cuein"]); + $row["cuein"] = $cuein_formatter->format(); + + $cueout_formatter = new LengthFormatter($row["cueout"]); + $row["cueout"] = $cueout_formatter->format(); if ($row['ftype'] === "audioclip") { $formatter = new SamplerateFormatter($row['sample_rate']); @@ -785,6 +809,15 @@ SQL; $formatter = new BitrateFormatter($row['bit_rate']); $row['bit_rate'] = $formatter->format(); + + //soundcloud status + $file = Application_Model_StoredFile::Recall($row['id']); + $row['soundcloud_status'] = $file->getSoundCloudId(); + + // for audio preview + $row['audioFile'] = $row['id'].".".pathinfo($row['filepath'], PATHINFO_EXTENSION); + } else { + $row['audioFile'] = $row['id']; } //convert mtime and utime to localtime @@ -795,31 +828,13 @@ SQL; $row['utime']->setTimeZone(new DateTimeZone(date_default_timezone_get())); $row['utime'] = $row['utime']->format('Y-m-d H:i:s'); - // add checkbox row - $row['checkbox'] = ""; + // we need to initalize the checkbox and image row because we do not retrieve + // any data from the db for these and datatables will complain + $row['checkbox'] = ""; + $row['image'] = ""; $type = substr($row['ftype'], 0, 2); - $row['tr_id'] = "{$type}_{$row['id']}"; - - //TODO url like this to work on both playlist/showbuilder - //screens. datatable stuff really needs to be pulled out and - //generalized within the project access to zend view methods - //to access url helpers is needed. - - // TODO : why is there inline html here? breaks abstraction and is - // ugly - if ($type == "au") { - $row['audioFile'] = $row['id'].".".pathinfo($row['filepath'], PATHINFO_EXTENSION); - $row['image'] = ''; - } elseif ($type == "pl") { - $row['image'] = ''; - } elseif ($type == "st") { - $row['audioFile'] = $row['id']; - $row['image'] = ''; - } elseif ($type == "bl") { - $row['image'] = ''; - } } return $results; @@ -1026,8 +1041,10 @@ SQL; $LIQUIDSOAP_ERRORS = array('TagLib: MPEG::Properties::read() -- Could not find a valid last MPEG frame in the stream.'); // Ask Liquidsoap if file is playable - $command = sprintf("/usr/bin/airtime-liquidsoap -c 'output.dummy(audio_to_stereo(single(\"%s\")))' 2>&1", $audio_file); + $ls_command = sprintf('/usr/bin/airtime-liquidsoap -v -c "output.dummy(audio_to_stereo(single(%s)))" 2>&1', + escapeshellarg($audio_file)); + $command = "export PATH=/usr/local/bin:/usr/bin:/bin/usr/bin/ && $ls_command"; exec($command, $output, $rv); $isError = count($output) > 0 && in_array($output[0], $LIQUIDSOAP_ERRORS); @@ -1285,6 +1302,65 @@ SQL; } } } + + public static function setIsPlaylist($p_playlistItems, $p_type, $p_status) { + foreach ($p_playlistItems as $item) { + $file = self::Recall($item->getDbFileId()); + $fileId = $file->_file->getDbId(); + if ($p_type == 'playlist') { + // we have to check if the file is in another playlist before + // we can update + if (!is_null($fileId) && !in_array($fileId, Application_Model_Playlist::getAllPlaylistFiles())) { + $file->_file->setDbIsPlaylist($p_status)->save(); + } + } elseif ($p_type == 'block') { + if (!is_null($fileId) && !in_array($fileId, Application_Model_Block::getAllBlockFiles())) { + $file->_file->setDbIsPlaylist($p_status)->save(); + } + } + } + } + + public static function setIsScheduled($p_scheduleItem, $p_status, $p_fileId=null) { + if (is_null($p_fileId)) { + $fileId = Application_Model_Schedule::GetFileId($p_scheduleItem); + } else { + $fileId = $p_fileId; + } + $file = self::Recall($fileId); + $updateIsScheduled = false; + + if (!is_null($fileId) && !in_array($fileId, Application_Model_Schedule::getAllFutureScheduledFiles())) { + $file->_file->setDbIsScheduled($p_status)->save(); + $updateIsScheduled = true; + } + + return $updateIsScheduled; + } + + public static function updatePastFilesIsScheduled() + { + $con = Propel::getConnection(); + $sql = <<query($sql)->fetchAll(); + foreach ($files as $file) { + if (!is_null($file['file_id'])) { + self::setIsScheduled(null, false, $file['file_id']); + } + } + + } + + public function getRealClipLength($p_cuein, $p_cueout) { + $sql = "SELECT :cueout::INTERVAL - :cuein::INTERVAL"; + + return Application_Common_Database::prepareAndExecute($sql, array( + ':cueout' => $p_cueout, + ':cuein' => $p_cuein), 'column'); + } } class DeleteScheduledFileException extends Exception {} diff --git a/airtime_mvc/application/models/Systemstatus.php b/airtime_mvc/application/models/Systemstatus.php index ef694ccf2..6f6a05fff 100644 --- a/airtime_mvc/application/models/Systemstatus.php +++ b/airtime_mvc/application/models/Systemstatus.php @@ -214,35 +214,22 @@ class Application_Model_Systemstatus { $partions = array(); - if (isset($_SERVER['AIRTIME_SRV'])) { - //connect to DB and find how much total space user has allocated. - $totalSpace = Application_Model_Preference::GetDiskQuota(); + /* First lets get all the watched directories. Then we can group them + * into the same partitions by comparing the partition sizes. */ + $musicDirs = Application_Model_MusicDir::getWatchedDirs(); + $musicDirs[] = Application_Model_MusicDir::getStorDir(); - $storPath = Application_Model_MusicDir::getStorDir()->getDirectory(); + foreach ($musicDirs as $md) { + $totalSpace = disk_total_space($md->getDirectory()); - list($usedSpace,) = preg_split("/[\s]+/", exec("du -bs $storPath")); + if (!isset($partitions[$totalSpace])) { + $partitions[$totalSpace] = new StdClass; + $partitions[$totalSpace]->totalSpace = $totalSpace; + $partitions[$totalSpace]->totalFreeSpace = disk_free_space($md->getDirectory()); - $partitions[$totalSpace]->totalSpace = $totalSpace; - $partitions[$totalSpace]->totalFreeSpace = $totalSpace - $usedSpace; - Logging::info($partitions[$totalSpace]->totalFreeSpace); - } else { - /* First lets get all the watched directories. Then we can group them - * into the same partitions by comparing the partition sizes. */ - $musicDirs = Application_Model_MusicDir::getWatchedDirs(); - $musicDirs[] = Application_Model_MusicDir::getStorDir(); - - foreach ($musicDirs as $md) { - $totalSpace = disk_total_space($md->getDirectory()); - - if (!isset($partitions[$totalSpace])) { - $partitions[$totalSpace] = new StdClass; - $partitions[$totalSpace]->totalSpace = $totalSpace; - $partitions[$totalSpace]->totalFreeSpace = disk_free_space($md->getDirectory()); - - } - - $partitions[$totalSpace]->dirs[] = $md->getDirectory(); } + + $partitions[$totalSpace]->dirs[] = $md->getDirectory(); } return array_values($partitions); diff --git a/airtime_mvc/application/models/User.php b/airtime_mvc/application/models/User.php index 63b82820a..97c9ca3ad 100644 --- a/airtime_mvc/application/models/User.php +++ b/airtime_mvc/application/models/User.php @@ -335,6 +335,8 @@ class Application_Model_User } else { $record['delete'] = ""; } + + $record = array_map('htmlspecialchars', $record); } return $res; diff --git a/airtime_mvc/application/models/airtime/map/CcFilesTableMap.php b/airtime_mvc/application/models/airtime/map/CcFilesTableMap.php index 46f79b71e..56e7a5fff 100644 --- a/airtime_mvc/application/models/airtime/map/CcFilesTableMap.php +++ b/airtime_mvc/application/models/airtime/map/CcFilesTableMap.php @@ -106,6 +106,8 @@ class CcFilesTableMap extends TableMap { $this->addColumn('CUEOUT', 'DbCueout', 'VARCHAR', false, null, '00:00:00'); $this->addColumn('SILAN_CHECK', 'DbSilanCheck', 'BOOLEAN', false, null, false); $this->addColumn('HIDDEN', 'DbHidden', 'BOOLEAN', false, null, false); + $this->addColumn('IS_SCHEDULED', 'DbIsScheduled', 'BOOLEAN', false, null, false); + $this->addColumn('IS_PLAYLIST', 'DbIsPlaylist', 'BOOLEAN', false, null, false); // validators } // initialize() diff --git a/airtime_mvc/application/models/airtime/map/CcScheduleTableMap.php b/airtime_mvc/application/models/airtime/map/CcScheduleTableMap.php index 5478ac8d2..8c1d00dd2 100644 --- a/airtime_mvc/application/models/airtime/map/CcScheduleTableMap.php +++ b/airtime_mvc/application/models/airtime/map/CcScheduleTableMap.php @@ -46,8 +46,8 @@ class CcScheduleTableMap extends TableMap { $this->addColumn('CLIP_LENGTH', 'DbClipLength', 'VARCHAR', false, null, '00:00:00'); $this->addColumn('FADE_IN', 'DbFadeIn', 'TIME', false, null, '00:00:00'); $this->addColumn('FADE_OUT', 'DbFadeOut', 'TIME', false, null, '00:00:00'); - $this->addColumn('CUE_IN', 'DbCueIn', 'VARCHAR', false, null, '00:00:00'); - $this->addColumn('CUE_OUT', 'DbCueOut', 'VARCHAR', false, null, '00:00:00'); + $this->addColumn('CUE_IN', 'DbCueIn', 'VARCHAR', true, null, null); + $this->addColumn('CUE_OUT', 'DbCueOut', 'VARCHAR', true, null, null); $this->addColumn('MEDIA_ITEM_PLAYED', 'DbMediaItemPlayed', 'BOOLEAN', false, null, false); $this->addForeignKey('INSTANCE_ID', 'DbInstanceId', 'INTEGER', 'cc_show_instances', 'ID', true, null, null); $this->addColumn('PLAYOUT_STATUS', 'DbPlayoutStatus', 'SMALLINT', true, null, 1); diff --git a/airtime_mvc/application/models/airtime/om/BaseCcFiles.php b/airtime_mvc/application/models/airtime/om/BaseCcFiles.php index da3b2cc20..55f868769 100644 --- a/airtime_mvc/application/models/airtime/om/BaseCcFiles.php +++ b/airtime_mvc/application/models/airtime/om/BaseCcFiles.php @@ -444,6 +444,20 @@ abstract class BaseCcFiles extends BaseObject implements Persistent */ protected $hidden; + /** + * The value for the is_scheduled field. + * Note: this column has a database default value of: false + * @var boolean + */ + protected $is_scheduled; + + /** + * The value for the is_playlist field. + * Note: this column has a database default value of: false + * @var boolean + */ + protected $is_playlist; + /** * @var CcSubjs */ @@ -513,6 +527,8 @@ abstract class BaseCcFiles extends BaseObject implements Persistent $this->cueout = '00:00:00'; $this->silan_check = false; $this->hidden = false; + $this->is_scheduled = false; + $this->is_playlist = false; } /** @@ -1297,6 +1313,26 @@ abstract class BaseCcFiles extends BaseObject implements Persistent return $this->hidden; } + /** + * Get the [is_scheduled] column value. + * + * @return boolean + */ + public function getDbIsScheduled() + { + return $this->is_scheduled; + } + + /** + * Get the [is_playlist] column value. + * + * @return boolean + */ + public function getDbIsPlaylist() + { + return $this->is_playlist; + } + /** * Set the value of [id] column. * @@ -2785,6 +2821,46 @@ abstract class BaseCcFiles extends BaseObject implements Persistent return $this; } // setDbHidden() + /** + * Set the value of [is_scheduled] column. + * + * @param boolean $v new value + * @return CcFiles The current object (for fluent API support) + */ + public function setDbIsScheduled($v) + { + if ($v !== null) { + $v = (boolean) $v; + } + + if ($this->is_scheduled !== $v || $this->isNew()) { + $this->is_scheduled = $v; + $this->modifiedColumns[] = CcFilesPeer::IS_SCHEDULED; + } + + return $this; + } // setDbIsScheduled() + + /** + * Set the value of [is_playlist] column. + * + * @param boolean $v new value + * @return CcFiles The current object (for fluent API support) + */ + public function setDbIsPlaylist($v) + { + if ($v !== null) { + $v = (boolean) $v; + } + + if ($this->is_playlist !== $v || $this->isNew()) { + $this->is_playlist = $v; + $this->modifiedColumns[] = CcFilesPeer::IS_PLAYLIST; + } + + return $this; + } // setDbIsPlaylist() + /** * Indicates whether the columns in this object are only set to default values. * @@ -2843,6 +2919,14 @@ abstract class BaseCcFiles extends BaseObject implements Persistent return false; } + if ($this->is_scheduled !== false) { + return false; + } + + if ($this->is_playlist !== false) { + return false; + } + // otherwise, everything was equal, so return TRUE return true; } // hasOnlyDefaultValues() @@ -2933,6 +3017,8 @@ abstract class BaseCcFiles extends BaseObject implements Persistent $this->cueout = ($row[$startcol + 65] !== null) ? (string) $row[$startcol + 65] : null; $this->silan_check = ($row[$startcol + 66] !== null) ? (boolean) $row[$startcol + 66] : null; $this->hidden = ($row[$startcol + 67] !== null) ? (boolean) $row[$startcol + 67] : null; + $this->is_scheduled = ($row[$startcol + 68] !== null) ? (boolean) $row[$startcol + 68] : null; + $this->is_playlist = ($row[$startcol + 69] !== null) ? (boolean) $row[$startcol + 69] : null; $this->resetModified(); $this->setNew(false); @@ -2941,7 +3027,7 @@ abstract class BaseCcFiles extends BaseObject implements Persistent $this->ensureConsistency(); } - return $startcol + 68; // 68 = CcFilesPeer::NUM_COLUMNS - CcFilesPeer::NUM_LAZY_LOAD_COLUMNS). + return $startcol + 70; // 70 = CcFilesPeer::NUM_COLUMNS - CcFilesPeer::NUM_LAZY_LOAD_COLUMNS). } catch (Exception $e) { throw new PropelException("Error populating CcFiles object", $e); @@ -3578,6 +3664,12 @@ abstract class BaseCcFiles extends BaseObject implements Persistent case 67: return $this->getDbHidden(); break; + case 68: + return $this->getDbIsScheduled(); + break; + case 69: + return $this->getDbIsPlaylist(); + break; default: return null; break; @@ -3670,6 +3762,8 @@ abstract class BaseCcFiles extends BaseObject implements Persistent $keys[65] => $this->getDbCueout(), $keys[66] => $this->getDbSilanCheck(), $keys[67] => $this->getDbHidden(), + $keys[68] => $this->getDbIsScheduled(), + $keys[69] => $this->getDbIsPlaylist(), ); if ($includeForeignObjects) { if (null !== $this->aFkOwner) { @@ -3916,6 +4010,12 @@ abstract class BaseCcFiles extends BaseObject implements Persistent case 67: $this->setDbHidden($value); break; + case 68: + $this->setDbIsScheduled($value); + break; + case 69: + $this->setDbIsPlaylist($value); + break; } // switch() } @@ -4008,6 +4108,8 @@ abstract class BaseCcFiles extends BaseObject implements Persistent if (array_key_exists($keys[65], $arr)) $this->setDbCueout($arr[$keys[65]]); if (array_key_exists($keys[66], $arr)) $this->setDbSilanCheck($arr[$keys[66]]); if (array_key_exists($keys[67], $arr)) $this->setDbHidden($arr[$keys[67]]); + if (array_key_exists($keys[68], $arr)) $this->setDbIsScheduled($arr[$keys[68]]); + if (array_key_exists($keys[69], $arr)) $this->setDbIsPlaylist($arr[$keys[69]]); } /** @@ -4087,6 +4189,8 @@ abstract class BaseCcFiles extends BaseObject implements Persistent if ($this->isColumnModified(CcFilesPeer::CUEOUT)) $criteria->add(CcFilesPeer::CUEOUT, $this->cueout); if ($this->isColumnModified(CcFilesPeer::SILAN_CHECK)) $criteria->add(CcFilesPeer::SILAN_CHECK, $this->silan_check); if ($this->isColumnModified(CcFilesPeer::HIDDEN)) $criteria->add(CcFilesPeer::HIDDEN, $this->hidden); + if ($this->isColumnModified(CcFilesPeer::IS_SCHEDULED)) $criteria->add(CcFilesPeer::IS_SCHEDULED, $this->is_scheduled); + if ($this->isColumnModified(CcFilesPeer::IS_PLAYLIST)) $criteria->add(CcFilesPeer::IS_PLAYLIST, $this->is_playlist); return $criteria; } @@ -4215,6 +4319,8 @@ abstract class BaseCcFiles extends BaseObject implements Persistent $copyObj->setDbCueout($this->cueout); $copyObj->setDbSilanCheck($this->silan_check); $copyObj->setDbHidden($this->hidden); + $copyObj->setDbIsScheduled($this->is_scheduled); + $copyObj->setDbIsPlaylist($this->is_playlist); if ($deepCopy) { // important: temporarily setNew(false) because this affects the behavior of @@ -5121,6 +5227,8 @@ abstract class BaseCcFiles extends BaseObject implements Persistent $this->cueout = null; $this->silan_check = null; $this->hidden = null; + $this->is_scheduled = null; + $this->is_playlist = null; $this->alreadyInSave = false; $this->alreadyInValidation = false; $this->clearAllReferences(); diff --git a/airtime_mvc/application/models/airtime/om/BaseCcFilesPeer.php b/airtime_mvc/application/models/airtime/om/BaseCcFilesPeer.php index 714cec847..82ebc7851 100644 --- a/airtime_mvc/application/models/airtime/om/BaseCcFilesPeer.php +++ b/airtime_mvc/application/models/airtime/om/BaseCcFilesPeer.php @@ -26,7 +26,7 @@ abstract class BaseCcFilesPeer { const TM_CLASS = 'CcFilesTableMap'; /** The total number of columns. */ - const NUM_COLUMNS = 68; + const NUM_COLUMNS = 70; /** The number of lazy-loaded columns. */ const NUM_LAZY_LOAD_COLUMNS = 0; @@ -235,6 +235,12 @@ abstract class BaseCcFilesPeer { /** the column name for the HIDDEN field */ const HIDDEN = 'cc_files.HIDDEN'; + /** the column name for the IS_SCHEDULED field */ + const IS_SCHEDULED = 'cc_files.IS_SCHEDULED'; + + /** the column name for the IS_PLAYLIST field */ + const IS_PLAYLIST = 'cc_files.IS_PLAYLIST'; + /** * An identiy map to hold any loaded instances of CcFiles objects. * This must be public so that other peer classes can access this when hydrating from JOIN @@ -251,12 +257,12 @@ abstract class BaseCcFilesPeer { * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' */ private static $fieldNames = array ( - BasePeer::TYPE_PHPNAME => array ('DbId', 'DbName', 'DbMime', 'DbFtype', 'DbDirectory', 'DbFilepath', 'DbState', 'DbCurrentlyaccessing', 'DbEditedby', 'DbMtime', 'DbUtime', 'DbLPtime', 'DbMd5', 'DbTrackTitle', 'DbArtistName', 'DbBitRate', 'DbSampleRate', 'DbFormat', 'DbLength', 'DbAlbumTitle', 'DbGenre', 'DbComments', 'DbYear', 'DbTrackNumber', 'DbChannels', 'DbUrl', 'DbBpm', 'DbRating', 'DbEncodedBy', 'DbDiscNumber', 'DbMood', 'DbLabel', 'DbComposer', 'DbEncoder', 'DbChecksum', 'DbLyrics', 'DbOrchestra', 'DbConductor', 'DbLyricist', 'DbOriginalLyricist', 'DbRadioStationName', 'DbInfoUrl', 'DbArtistUrl', 'DbAudioSourceUrl', 'DbRadioStationUrl', 'DbBuyThisUrl', 'DbIsrcNumber', 'DbCatalogNumber', 'DbOriginalArtist', 'DbCopyright', 'DbReportDatetime', 'DbReportLocation', 'DbReportOrganization', 'DbSubject', 'DbContributor', 'DbLanguage', 'DbFileExists', 'DbSoundcloudId', 'DbSoundcloudErrorCode', 'DbSoundcloudErrorMsg', 'DbSoundcloudLinkToFile', 'DbSoundCloundUploadTime', 'DbReplayGain', 'DbOwnerId', 'DbCuein', 'DbCueout', 'DbSilanCheck', 'DbHidden', ), - BasePeer::TYPE_STUDLYPHPNAME => array ('dbId', 'dbName', 'dbMime', 'dbFtype', 'dbDirectory', 'dbFilepath', 'dbState', 'dbCurrentlyaccessing', 'dbEditedby', 'dbMtime', 'dbUtime', 'dbLPtime', 'dbMd5', 'dbTrackTitle', 'dbArtistName', 'dbBitRate', 'dbSampleRate', 'dbFormat', 'dbLength', 'dbAlbumTitle', 'dbGenre', 'dbComments', 'dbYear', 'dbTrackNumber', 'dbChannels', 'dbUrl', 'dbBpm', 'dbRating', 'dbEncodedBy', 'dbDiscNumber', 'dbMood', 'dbLabel', 'dbComposer', 'dbEncoder', 'dbChecksum', 'dbLyrics', 'dbOrchestra', 'dbConductor', 'dbLyricist', 'dbOriginalLyricist', 'dbRadioStationName', 'dbInfoUrl', 'dbArtistUrl', 'dbAudioSourceUrl', 'dbRadioStationUrl', 'dbBuyThisUrl', 'dbIsrcNumber', 'dbCatalogNumber', 'dbOriginalArtist', 'dbCopyright', 'dbReportDatetime', 'dbReportLocation', 'dbReportOrganization', 'dbSubject', 'dbContributor', 'dbLanguage', 'dbFileExists', 'dbSoundcloudId', 'dbSoundcloudErrorCode', 'dbSoundcloudErrorMsg', 'dbSoundcloudLinkToFile', 'dbSoundCloundUploadTime', 'dbReplayGain', 'dbOwnerId', 'dbCuein', 'dbCueout', 'dbSilanCheck', 'dbHidden', ), - BasePeer::TYPE_COLNAME => array (self::ID, self::NAME, self::MIME, self::FTYPE, self::DIRECTORY, self::FILEPATH, self::STATE, self::CURRENTLYACCESSING, self::EDITEDBY, self::MTIME, self::UTIME, self::LPTIME, self::MD5, self::TRACK_TITLE, self::ARTIST_NAME, self::BIT_RATE, self::SAMPLE_RATE, self::FORMAT, self::LENGTH, self::ALBUM_TITLE, self::GENRE, self::COMMENTS, self::YEAR, self::TRACK_NUMBER, self::CHANNELS, self::URL, self::BPM, self::RATING, self::ENCODED_BY, self::DISC_NUMBER, self::MOOD, self::LABEL, self::COMPOSER, self::ENCODER, self::CHECKSUM, self::LYRICS, self::ORCHESTRA, self::CONDUCTOR, self::LYRICIST, self::ORIGINAL_LYRICIST, self::RADIO_STATION_NAME, self::INFO_URL, self::ARTIST_URL, self::AUDIO_SOURCE_URL, self::RADIO_STATION_URL, self::BUY_THIS_URL, self::ISRC_NUMBER, self::CATALOG_NUMBER, self::ORIGINAL_ARTIST, self::COPYRIGHT, self::REPORT_DATETIME, self::REPORT_LOCATION, self::REPORT_ORGANIZATION, self::SUBJECT, self::CONTRIBUTOR, self::LANGUAGE, self::FILE_EXISTS, self::SOUNDCLOUD_ID, self::SOUNDCLOUD_ERROR_CODE, self::SOUNDCLOUD_ERROR_MSG, self::SOUNDCLOUD_LINK_TO_FILE, self::SOUNDCLOUD_UPLOAD_TIME, self::REPLAY_GAIN, self::OWNER_ID, self::CUEIN, self::CUEOUT, self::SILAN_CHECK, self::HIDDEN, ), - BasePeer::TYPE_RAW_COLNAME => array ('ID', 'NAME', 'MIME', 'FTYPE', 'DIRECTORY', 'FILEPATH', 'STATE', 'CURRENTLYACCESSING', 'EDITEDBY', 'MTIME', 'UTIME', 'LPTIME', 'MD5', 'TRACK_TITLE', 'ARTIST_NAME', 'BIT_RATE', 'SAMPLE_RATE', 'FORMAT', 'LENGTH', 'ALBUM_TITLE', 'GENRE', 'COMMENTS', 'YEAR', 'TRACK_NUMBER', 'CHANNELS', 'URL', 'BPM', 'RATING', 'ENCODED_BY', 'DISC_NUMBER', 'MOOD', 'LABEL', 'COMPOSER', 'ENCODER', 'CHECKSUM', 'LYRICS', 'ORCHESTRA', 'CONDUCTOR', 'LYRICIST', 'ORIGINAL_LYRICIST', 'RADIO_STATION_NAME', 'INFO_URL', 'ARTIST_URL', 'AUDIO_SOURCE_URL', 'RADIO_STATION_URL', 'BUY_THIS_URL', 'ISRC_NUMBER', 'CATALOG_NUMBER', 'ORIGINAL_ARTIST', 'COPYRIGHT', 'REPORT_DATETIME', 'REPORT_LOCATION', 'REPORT_ORGANIZATION', 'SUBJECT', 'CONTRIBUTOR', 'LANGUAGE', 'FILE_EXISTS', 'SOUNDCLOUD_ID', 'SOUNDCLOUD_ERROR_CODE', 'SOUNDCLOUD_ERROR_MSG', 'SOUNDCLOUD_LINK_TO_FILE', 'SOUNDCLOUD_UPLOAD_TIME', 'REPLAY_GAIN', 'OWNER_ID', 'CUEIN', 'CUEOUT', 'SILAN_CHECK', 'HIDDEN', ), - BasePeer::TYPE_FIELDNAME => array ('id', 'name', 'mime', 'ftype', 'directory', 'filepath', 'state', 'currentlyaccessing', 'editedby', 'mtime', 'utime', 'lptime', 'md5', 'track_title', 'artist_name', 'bit_rate', 'sample_rate', 'format', 'length', 'album_title', 'genre', 'comments', 'year', 'track_number', 'channels', 'url', 'bpm', 'rating', 'encoded_by', 'disc_number', 'mood', 'label', 'composer', 'encoder', 'checksum', 'lyrics', 'orchestra', 'conductor', 'lyricist', 'original_lyricist', 'radio_station_name', 'info_url', 'artist_url', 'audio_source_url', 'radio_station_url', 'buy_this_url', 'isrc_number', 'catalog_number', 'original_artist', 'copyright', 'report_datetime', 'report_location', 'report_organization', 'subject', 'contributor', 'language', 'file_exists', 'soundcloud_id', 'soundcloud_error_code', 'soundcloud_error_msg', 'soundcloud_link_to_file', 'soundcloud_upload_time', 'replay_gain', 'owner_id', 'cuein', 'cueout', 'silan_check', 'hidden', ), - BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, ) + BasePeer::TYPE_PHPNAME => array ('DbId', 'DbName', 'DbMime', 'DbFtype', 'DbDirectory', 'DbFilepath', 'DbState', 'DbCurrentlyaccessing', 'DbEditedby', 'DbMtime', 'DbUtime', 'DbLPtime', 'DbMd5', 'DbTrackTitle', 'DbArtistName', 'DbBitRate', 'DbSampleRate', 'DbFormat', 'DbLength', 'DbAlbumTitle', 'DbGenre', 'DbComments', 'DbYear', 'DbTrackNumber', 'DbChannels', 'DbUrl', 'DbBpm', 'DbRating', 'DbEncodedBy', 'DbDiscNumber', 'DbMood', 'DbLabel', 'DbComposer', 'DbEncoder', 'DbChecksum', 'DbLyrics', 'DbOrchestra', 'DbConductor', 'DbLyricist', 'DbOriginalLyricist', 'DbRadioStationName', 'DbInfoUrl', 'DbArtistUrl', 'DbAudioSourceUrl', 'DbRadioStationUrl', 'DbBuyThisUrl', 'DbIsrcNumber', 'DbCatalogNumber', 'DbOriginalArtist', 'DbCopyright', 'DbReportDatetime', 'DbReportLocation', 'DbReportOrganization', 'DbSubject', 'DbContributor', 'DbLanguage', 'DbFileExists', 'DbSoundcloudId', 'DbSoundcloudErrorCode', 'DbSoundcloudErrorMsg', 'DbSoundcloudLinkToFile', 'DbSoundCloundUploadTime', 'DbReplayGain', 'DbOwnerId', 'DbCuein', 'DbCueout', 'DbSilanCheck', 'DbHidden', 'DbIsScheduled', 'DbIsPlaylist', ), + BasePeer::TYPE_STUDLYPHPNAME => array ('dbId', 'dbName', 'dbMime', 'dbFtype', 'dbDirectory', 'dbFilepath', 'dbState', 'dbCurrentlyaccessing', 'dbEditedby', 'dbMtime', 'dbUtime', 'dbLPtime', 'dbMd5', 'dbTrackTitle', 'dbArtistName', 'dbBitRate', 'dbSampleRate', 'dbFormat', 'dbLength', 'dbAlbumTitle', 'dbGenre', 'dbComments', 'dbYear', 'dbTrackNumber', 'dbChannels', 'dbUrl', 'dbBpm', 'dbRating', 'dbEncodedBy', 'dbDiscNumber', 'dbMood', 'dbLabel', 'dbComposer', 'dbEncoder', 'dbChecksum', 'dbLyrics', 'dbOrchestra', 'dbConductor', 'dbLyricist', 'dbOriginalLyricist', 'dbRadioStationName', 'dbInfoUrl', 'dbArtistUrl', 'dbAudioSourceUrl', 'dbRadioStationUrl', 'dbBuyThisUrl', 'dbIsrcNumber', 'dbCatalogNumber', 'dbOriginalArtist', 'dbCopyright', 'dbReportDatetime', 'dbReportLocation', 'dbReportOrganization', 'dbSubject', 'dbContributor', 'dbLanguage', 'dbFileExists', 'dbSoundcloudId', 'dbSoundcloudErrorCode', 'dbSoundcloudErrorMsg', 'dbSoundcloudLinkToFile', 'dbSoundCloundUploadTime', 'dbReplayGain', 'dbOwnerId', 'dbCuein', 'dbCueout', 'dbSilanCheck', 'dbHidden', 'dbIsScheduled', 'dbIsPlaylist', ), + BasePeer::TYPE_COLNAME => array (self::ID, self::NAME, self::MIME, self::FTYPE, self::DIRECTORY, self::FILEPATH, self::STATE, self::CURRENTLYACCESSING, self::EDITEDBY, self::MTIME, self::UTIME, self::LPTIME, self::MD5, self::TRACK_TITLE, self::ARTIST_NAME, self::BIT_RATE, self::SAMPLE_RATE, self::FORMAT, self::LENGTH, self::ALBUM_TITLE, self::GENRE, self::COMMENTS, self::YEAR, self::TRACK_NUMBER, self::CHANNELS, self::URL, self::BPM, self::RATING, self::ENCODED_BY, self::DISC_NUMBER, self::MOOD, self::LABEL, self::COMPOSER, self::ENCODER, self::CHECKSUM, self::LYRICS, self::ORCHESTRA, self::CONDUCTOR, self::LYRICIST, self::ORIGINAL_LYRICIST, self::RADIO_STATION_NAME, self::INFO_URL, self::ARTIST_URL, self::AUDIO_SOURCE_URL, self::RADIO_STATION_URL, self::BUY_THIS_URL, self::ISRC_NUMBER, self::CATALOG_NUMBER, self::ORIGINAL_ARTIST, self::COPYRIGHT, self::REPORT_DATETIME, self::REPORT_LOCATION, self::REPORT_ORGANIZATION, self::SUBJECT, self::CONTRIBUTOR, self::LANGUAGE, self::FILE_EXISTS, self::SOUNDCLOUD_ID, self::SOUNDCLOUD_ERROR_CODE, self::SOUNDCLOUD_ERROR_MSG, self::SOUNDCLOUD_LINK_TO_FILE, self::SOUNDCLOUD_UPLOAD_TIME, self::REPLAY_GAIN, self::OWNER_ID, self::CUEIN, self::CUEOUT, self::SILAN_CHECK, self::HIDDEN, self::IS_SCHEDULED, self::IS_PLAYLIST, ), + BasePeer::TYPE_RAW_COLNAME => array ('ID', 'NAME', 'MIME', 'FTYPE', 'DIRECTORY', 'FILEPATH', 'STATE', 'CURRENTLYACCESSING', 'EDITEDBY', 'MTIME', 'UTIME', 'LPTIME', 'MD5', 'TRACK_TITLE', 'ARTIST_NAME', 'BIT_RATE', 'SAMPLE_RATE', 'FORMAT', 'LENGTH', 'ALBUM_TITLE', 'GENRE', 'COMMENTS', 'YEAR', 'TRACK_NUMBER', 'CHANNELS', 'URL', 'BPM', 'RATING', 'ENCODED_BY', 'DISC_NUMBER', 'MOOD', 'LABEL', 'COMPOSER', 'ENCODER', 'CHECKSUM', 'LYRICS', 'ORCHESTRA', 'CONDUCTOR', 'LYRICIST', 'ORIGINAL_LYRICIST', 'RADIO_STATION_NAME', 'INFO_URL', 'ARTIST_URL', 'AUDIO_SOURCE_URL', 'RADIO_STATION_URL', 'BUY_THIS_URL', 'ISRC_NUMBER', 'CATALOG_NUMBER', 'ORIGINAL_ARTIST', 'COPYRIGHT', 'REPORT_DATETIME', 'REPORT_LOCATION', 'REPORT_ORGANIZATION', 'SUBJECT', 'CONTRIBUTOR', 'LANGUAGE', 'FILE_EXISTS', 'SOUNDCLOUD_ID', 'SOUNDCLOUD_ERROR_CODE', 'SOUNDCLOUD_ERROR_MSG', 'SOUNDCLOUD_LINK_TO_FILE', 'SOUNDCLOUD_UPLOAD_TIME', 'REPLAY_GAIN', 'OWNER_ID', 'CUEIN', 'CUEOUT', 'SILAN_CHECK', 'HIDDEN', 'IS_SCHEDULED', 'IS_PLAYLIST', ), + BasePeer::TYPE_FIELDNAME => array ('id', 'name', 'mime', 'ftype', 'directory', 'filepath', 'state', 'currentlyaccessing', 'editedby', 'mtime', 'utime', 'lptime', 'md5', 'track_title', 'artist_name', 'bit_rate', 'sample_rate', 'format', 'length', 'album_title', 'genre', 'comments', 'year', 'track_number', 'channels', 'url', 'bpm', 'rating', 'encoded_by', 'disc_number', 'mood', 'label', 'composer', 'encoder', 'checksum', 'lyrics', 'orchestra', 'conductor', 'lyricist', 'original_lyricist', 'radio_station_name', 'info_url', 'artist_url', 'audio_source_url', 'radio_station_url', 'buy_this_url', 'isrc_number', 'catalog_number', 'original_artist', 'copyright', 'report_datetime', 'report_location', 'report_organization', 'subject', 'contributor', 'language', 'file_exists', 'soundcloud_id', 'soundcloud_error_code', 'soundcloud_error_msg', 'soundcloud_link_to_file', 'soundcloud_upload_time', 'replay_gain', 'owner_id', 'cuein', 'cueout', 'silan_check', 'hidden', 'is_scheduled', 'is_playlist', ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, ) ); /** @@ -266,12 +272,12 @@ abstract class BaseCcFilesPeer { * e.g. self::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 */ private static $fieldKeys = array ( - BasePeer::TYPE_PHPNAME => array ('DbId' => 0, 'DbName' => 1, 'DbMime' => 2, 'DbFtype' => 3, 'DbDirectory' => 4, 'DbFilepath' => 5, 'DbState' => 6, 'DbCurrentlyaccessing' => 7, 'DbEditedby' => 8, 'DbMtime' => 9, 'DbUtime' => 10, 'DbLPtime' => 11, 'DbMd5' => 12, 'DbTrackTitle' => 13, 'DbArtistName' => 14, 'DbBitRate' => 15, 'DbSampleRate' => 16, 'DbFormat' => 17, 'DbLength' => 18, 'DbAlbumTitle' => 19, 'DbGenre' => 20, 'DbComments' => 21, 'DbYear' => 22, 'DbTrackNumber' => 23, 'DbChannels' => 24, 'DbUrl' => 25, 'DbBpm' => 26, 'DbRating' => 27, 'DbEncodedBy' => 28, 'DbDiscNumber' => 29, 'DbMood' => 30, 'DbLabel' => 31, 'DbComposer' => 32, 'DbEncoder' => 33, 'DbChecksum' => 34, 'DbLyrics' => 35, 'DbOrchestra' => 36, 'DbConductor' => 37, 'DbLyricist' => 38, 'DbOriginalLyricist' => 39, 'DbRadioStationName' => 40, 'DbInfoUrl' => 41, 'DbArtistUrl' => 42, 'DbAudioSourceUrl' => 43, 'DbRadioStationUrl' => 44, 'DbBuyThisUrl' => 45, 'DbIsrcNumber' => 46, 'DbCatalogNumber' => 47, 'DbOriginalArtist' => 48, 'DbCopyright' => 49, 'DbReportDatetime' => 50, 'DbReportLocation' => 51, 'DbReportOrganization' => 52, 'DbSubject' => 53, 'DbContributor' => 54, 'DbLanguage' => 55, 'DbFileExists' => 56, 'DbSoundcloudId' => 57, 'DbSoundcloudErrorCode' => 58, 'DbSoundcloudErrorMsg' => 59, 'DbSoundcloudLinkToFile' => 60, 'DbSoundCloundUploadTime' => 61, 'DbReplayGain' => 62, 'DbOwnerId' => 63, 'DbCuein' => 64, 'DbCueout' => 65, 'DbSilanCheck' => 66, 'DbHidden' => 67, ), - BasePeer::TYPE_STUDLYPHPNAME => array ('dbId' => 0, 'dbName' => 1, 'dbMime' => 2, 'dbFtype' => 3, 'dbDirectory' => 4, 'dbFilepath' => 5, 'dbState' => 6, 'dbCurrentlyaccessing' => 7, 'dbEditedby' => 8, 'dbMtime' => 9, 'dbUtime' => 10, 'dbLPtime' => 11, 'dbMd5' => 12, 'dbTrackTitle' => 13, 'dbArtistName' => 14, 'dbBitRate' => 15, 'dbSampleRate' => 16, 'dbFormat' => 17, 'dbLength' => 18, 'dbAlbumTitle' => 19, 'dbGenre' => 20, 'dbComments' => 21, 'dbYear' => 22, 'dbTrackNumber' => 23, 'dbChannels' => 24, 'dbUrl' => 25, 'dbBpm' => 26, 'dbRating' => 27, 'dbEncodedBy' => 28, 'dbDiscNumber' => 29, 'dbMood' => 30, 'dbLabel' => 31, 'dbComposer' => 32, 'dbEncoder' => 33, 'dbChecksum' => 34, 'dbLyrics' => 35, 'dbOrchestra' => 36, 'dbConductor' => 37, 'dbLyricist' => 38, 'dbOriginalLyricist' => 39, 'dbRadioStationName' => 40, 'dbInfoUrl' => 41, 'dbArtistUrl' => 42, 'dbAudioSourceUrl' => 43, 'dbRadioStationUrl' => 44, 'dbBuyThisUrl' => 45, 'dbIsrcNumber' => 46, 'dbCatalogNumber' => 47, 'dbOriginalArtist' => 48, 'dbCopyright' => 49, 'dbReportDatetime' => 50, 'dbReportLocation' => 51, 'dbReportOrganization' => 52, 'dbSubject' => 53, 'dbContributor' => 54, 'dbLanguage' => 55, 'dbFileExists' => 56, 'dbSoundcloudId' => 57, 'dbSoundcloudErrorCode' => 58, 'dbSoundcloudErrorMsg' => 59, 'dbSoundcloudLinkToFile' => 60, 'dbSoundCloundUploadTime' => 61, 'dbReplayGain' => 62, 'dbOwnerId' => 63, 'dbCuein' => 64, 'dbCueout' => 65, 'dbSilanCheck' => 66, 'dbHidden' => 67, ), - BasePeer::TYPE_COLNAME => array (self::ID => 0, self::NAME => 1, self::MIME => 2, self::FTYPE => 3, self::DIRECTORY => 4, self::FILEPATH => 5, self::STATE => 6, self::CURRENTLYACCESSING => 7, self::EDITEDBY => 8, self::MTIME => 9, self::UTIME => 10, self::LPTIME => 11, self::MD5 => 12, self::TRACK_TITLE => 13, self::ARTIST_NAME => 14, self::BIT_RATE => 15, self::SAMPLE_RATE => 16, self::FORMAT => 17, self::LENGTH => 18, self::ALBUM_TITLE => 19, self::GENRE => 20, self::COMMENTS => 21, self::YEAR => 22, self::TRACK_NUMBER => 23, self::CHANNELS => 24, self::URL => 25, self::BPM => 26, self::RATING => 27, self::ENCODED_BY => 28, self::DISC_NUMBER => 29, self::MOOD => 30, self::LABEL => 31, self::COMPOSER => 32, self::ENCODER => 33, self::CHECKSUM => 34, self::LYRICS => 35, self::ORCHESTRA => 36, self::CONDUCTOR => 37, self::LYRICIST => 38, self::ORIGINAL_LYRICIST => 39, self::RADIO_STATION_NAME => 40, self::INFO_URL => 41, self::ARTIST_URL => 42, self::AUDIO_SOURCE_URL => 43, self::RADIO_STATION_URL => 44, self::BUY_THIS_URL => 45, self::ISRC_NUMBER => 46, self::CATALOG_NUMBER => 47, self::ORIGINAL_ARTIST => 48, self::COPYRIGHT => 49, self::REPORT_DATETIME => 50, self::REPORT_LOCATION => 51, self::REPORT_ORGANIZATION => 52, self::SUBJECT => 53, self::CONTRIBUTOR => 54, self::LANGUAGE => 55, self::FILE_EXISTS => 56, self::SOUNDCLOUD_ID => 57, self::SOUNDCLOUD_ERROR_CODE => 58, self::SOUNDCLOUD_ERROR_MSG => 59, self::SOUNDCLOUD_LINK_TO_FILE => 60, self::SOUNDCLOUD_UPLOAD_TIME => 61, self::REPLAY_GAIN => 62, self::OWNER_ID => 63, self::CUEIN => 64, self::CUEOUT => 65, self::SILAN_CHECK => 66, self::HIDDEN => 67, ), - BasePeer::TYPE_RAW_COLNAME => array ('ID' => 0, 'NAME' => 1, 'MIME' => 2, 'FTYPE' => 3, 'DIRECTORY' => 4, 'FILEPATH' => 5, 'STATE' => 6, 'CURRENTLYACCESSING' => 7, 'EDITEDBY' => 8, 'MTIME' => 9, 'UTIME' => 10, 'LPTIME' => 11, 'MD5' => 12, 'TRACK_TITLE' => 13, 'ARTIST_NAME' => 14, 'BIT_RATE' => 15, 'SAMPLE_RATE' => 16, 'FORMAT' => 17, 'LENGTH' => 18, 'ALBUM_TITLE' => 19, 'GENRE' => 20, 'COMMENTS' => 21, 'YEAR' => 22, 'TRACK_NUMBER' => 23, 'CHANNELS' => 24, 'URL' => 25, 'BPM' => 26, 'RATING' => 27, 'ENCODED_BY' => 28, 'DISC_NUMBER' => 29, 'MOOD' => 30, 'LABEL' => 31, 'COMPOSER' => 32, 'ENCODER' => 33, 'CHECKSUM' => 34, 'LYRICS' => 35, 'ORCHESTRA' => 36, 'CONDUCTOR' => 37, 'LYRICIST' => 38, 'ORIGINAL_LYRICIST' => 39, 'RADIO_STATION_NAME' => 40, 'INFO_URL' => 41, 'ARTIST_URL' => 42, 'AUDIO_SOURCE_URL' => 43, 'RADIO_STATION_URL' => 44, 'BUY_THIS_URL' => 45, 'ISRC_NUMBER' => 46, 'CATALOG_NUMBER' => 47, 'ORIGINAL_ARTIST' => 48, 'COPYRIGHT' => 49, 'REPORT_DATETIME' => 50, 'REPORT_LOCATION' => 51, 'REPORT_ORGANIZATION' => 52, 'SUBJECT' => 53, 'CONTRIBUTOR' => 54, 'LANGUAGE' => 55, 'FILE_EXISTS' => 56, 'SOUNDCLOUD_ID' => 57, 'SOUNDCLOUD_ERROR_CODE' => 58, 'SOUNDCLOUD_ERROR_MSG' => 59, 'SOUNDCLOUD_LINK_TO_FILE' => 60, 'SOUNDCLOUD_UPLOAD_TIME' => 61, 'REPLAY_GAIN' => 62, 'OWNER_ID' => 63, 'CUEIN' => 64, 'CUEOUT' => 65, 'SILAN_CHECK' => 66, 'HIDDEN' => 67, ), - BasePeer::TYPE_FIELDNAME => array ('id' => 0, 'name' => 1, 'mime' => 2, 'ftype' => 3, 'directory' => 4, 'filepath' => 5, 'state' => 6, 'currentlyaccessing' => 7, 'editedby' => 8, 'mtime' => 9, 'utime' => 10, 'lptime' => 11, 'md5' => 12, 'track_title' => 13, 'artist_name' => 14, 'bit_rate' => 15, 'sample_rate' => 16, 'format' => 17, 'length' => 18, 'album_title' => 19, 'genre' => 20, 'comments' => 21, 'year' => 22, 'track_number' => 23, 'channels' => 24, 'url' => 25, 'bpm' => 26, 'rating' => 27, 'encoded_by' => 28, 'disc_number' => 29, 'mood' => 30, 'label' => 31, 'composer' => 32, 'encoder' => 33, 'checksum' => 34, 'lyrics' => 35, 'orchestra' => 36, 'conductor' => 37, 'lyricist' => 38, 'original_lyricist' => 39, 'radio_station_name' => 40, 'info_url' => 41, 'artist_url' => 42, 'audio_source_url' => 43, 'radio_station_url' => 44, 'buy_this_url' => 45, 'isrc_number' => 46, 'catalog_number' => 47, 'original_artist' => 48, 'copyright' => 49, 'report_datetime' => 50, 'report_location' => 51, 'report_organization' => 52, 'subject' => 53, 'contributor' => 54, 'language' => 55, 'file_exists' => 56, 'soundcloud_id' => 57, 'soundcloud_error_code' => 58, 'soundcloud_error_msg' => 59, 'soundcloud_link_to_file' => 60, 'soundcloud_upload_time' => 61, 'replay_gain' => 62, 'owner_id' => 63, 'cuein' => 64, 'cueout' => 65, 'silan_check' => 66, 'hidden' => 67, ), - BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, ) + BasePeer::TYPE_PHPNAME => array ('DbId' => 0, 'DbName' => 1, 'DbMime' => 2, 'DbFtype' => 3, 'DbDirectory' => 4, 'DbFilepath' => 5, 'DbState' => 6, 'DbCurrentlyaccessing' => 7, 'DbEditedby' => 8, 'DbMtime' => 9, 'DbUtime' => 10, 'DbLPtime' => 11, 'DbMd5' => 12, 'DbTrackTitle' => 13, 'DbArtistName' => 14, 'DbBitRate' => 15, 'DbSampleRate' => 16, 'DbFormat' => 17, 'DbLength' => 18, 'DbAlbumTitle' => 19, 'DbGenre' => 20, 'DbComments' => 21, 'DbYear' => 22, 'DbTrackNumber' => 23, 'DbChannels' => 24, 'DbUrl' => 25, 'DbBpm' => 26, 'DbRating' => 27, 'DbEncodedBy' => 28, 'DbDiscNumber' => 29, 'DbMood' => 30, 'DbLabel' => 31, 'DbComposer' => 32, 'DbEncoder' => 33, 'DbChecksum' => 34, 'DbLyrics' => 35, 'DbOrchestra' => 36, 'DbConductor' => 37, 'DbLyricist' => 38, 'DbOriginalLyricist' => 39, 'DbRadioStationName' => 40, 'DbInfoUrl' => 41, 'DbArtistUrl' => 42, 'DbAudioSourceUrl' => 43, 'DbRadioStationUrl' => 44, 'DbBuyThisUrl' => 45, 'DbIsrcNumber' => 46, 'DbCatalogNumber' => 47, 'DbOriginalArtist' => 48, 'DbCopyright' => 49, 'DbReportDatetime' => 50, 'DbReportLocation' => 51, 'DbReportOrganization' => 52, 'DbSubject' => 53, 'DbContributor' => 54, 'DbLanguage' => 55, 'DbFileExists' => 56, 'DbSoundcloudId' => 57, 'DbSoundcloudErrorCode' => 58, 'DbSoundcloudErrorMsg' => 59, 'DbSoundcloudLinkToFile' => 60, 'DbSoundCloundUploadTime' => 61, 'DbReplayGain' => 62, 'DbOwnerId' => 63, 'DbCuein' => 64, 'DbCueout' => 65, 'DbSilanCheck' => 66, 'DbHidden' => 67, 'DbIsScheduled' => 68, 'DbIsPlaylist' => 69, ), + BasePeer::TYPE_STUDLYPHPNAME => array ('dbId' => 0, 'dbName' => 1, 'dbMime' => 2, 'dbFtype' => 3, 'dbDirectory' => 4, 'dbFilepath' => 5, 'dbState' => 6, 'dbCurrentlyaccessing' => 7, 'dbEditedby' => 8, 'dbMtime' => 9, 'dbUtime' => 10, 'dbLPtime' => 11, 'dbMd5' => 12, 'dbTrackTitle' => 13, 'dbArtistName' => 14, 'dbBitRate' => 15, 'dbSampleRate' => 16, 'dbFormat' => 17, 'dbLength' => 18, 'dbAlbumTitle' => 19, 'dbGenre' => 20, 'dbComments' => 21, 'dbYear' => 22, 'dbTrackNumber' => 23, 'dbChannels' => 24, 'dbUrl' => 25, 'dbBpm' => 26, 'dbRating' => 27, 'dbEncodedBy' => 28, 'dbDiscNumber' => 29, 'dbMood' => 30, 'dbLabel' => 31, 'dbComposer' => 32, 'dbEncoder' => 33, 'dbChecksum' => 34, 'dbLyrics' => 35, 'dbOrchestra' => 36, 'dbConductor' => 37, 'dbLyricist' => 38, 'dbOriginalLyricist' => 39, 'dbRadioStationName' => 40, 'dbInfoUrl' => 41, 'dbArtistUrl' => 42, 'dbAudioSourceUrl' => 43, 'dbRadioStationUrl' => 44, 'dbBuyThisUrl' => 45, 'dbIsrcNumber' => 46, 'dbCatalogNumber' => 47, 'dbOriginalArtist' => 48, 'dbCopyright' => 49, 'dbReportDatetime' => 50, 'dbReportLocation' => 51, 'dbReportOrganization' => 52, 'dbSubject' => 53, 'dbContributor' => 54, 'dbLanguage' => 55, 'dbFileExists' => 56, 'dbSoundcloudId' => 57, 'dbSoundcloudErrorCode' => 58, 'dbSoundcloudErrorMsg' => 59, 'dbSoundcloudLinkToFile' => 60, 'dbSoundCloundUploadTime' => 61, 'dbReplayGain' => 62, 'dbOwnerId' => 63, 'dbCuein' => 64, 'dbCueout' => 65, 'dbSilanCheck' => 66, 'dbHidden' => 67, 'dbIsScheduled' => 68, 'dbIsPlaylist' => 69, ), + BasePeer::TYPE_COLNAME => array (self::ID => 0, self::NAME => 1, self::MIME => 2, self::FTYPE => 3, self::DIRECTORY => 4, self::FILEPATH => 5, self::STATE => 6, self::CURRENTLYACCESSING => 7, self::EDITEDBY => 8, self::MTIME => 9, self::UTIME => 10, self::LPTIME => 11, self::MD5 => 12, self::TRACK_TITLE => 13, self::ARTIST_NAME => 14, self::BIT_RATE => 15, self::SAMPLE_RATE => 16, self::FORMAT => 17, self::LENGTH => 18, self::ALBUM_TITLE => 19, self::GENRE => 20, self::COMMENTS => 21, self::YEAR => 22, self::TRACK_NUMBER => 23, self::CHANNELS => 24, self::URL => 25, self::BPM => 26, self::RATING => 27, self::ENCODED_BY => 28, self::DISC_NUMBER => 29, self::MOOD => 30, self::LABEL => 31, self::COMPOSER => 32, self::ENCODER => 33, self::CHECKSUM => 34, self::LYRICS => 35, self::ORCHESTRA => 36, self::CONDUCTOR => 37, self::LYRICIST => 38, self::ORIGINAL_LYRICIST => 39, self::RADIO_STATION_NAME => 40, self::INFO_URL => 41, self::ARTIST_URL => 42, self::AUDIO_SOURCE_URL => 43, self::RADIO_STATION_URL => 44, self::BUY_THIS_URL => 45, self::ISRC_NUMBER => 46, self::CATALOG_NUMBER => 47, self::ORIGINAL_ARTIST => 48, self::COPYRIGHT => 49, self::REPORT_DATETIME => 50, self::REPORT_LOCATION => 51, self::REPORT_ORGANIZATION => 52, self::SUBJECT => 53, self::CONTRIBUTOR => 54, self::LANGUAGE => 55, self::FILE_EXISTS => 56, self::SOUNDCLOUD_ID => 57, self::SOUNDCLOUD_ERROR_CODE => 58, self::SOUNDCLOUD_ERROR_MSG => 59, self::SOUNDCLOUD_LINK_TO_FILE => 60, self::SOUNDCLOUD_UPLOAD_TIME => 61, self::REPLAY_GAIN => 62, self::OWNER_ID => 63, self::CUEIN => 64, self::CUEOUT => 65, self::SILAN_CHECK => 66, self::HIDDEN => 67, self::IS_SCHEDULED => 68, self::IS_PLAYLIST => 69, ), + BasePeer::TYPE_RAW_COLNAME => array ('ID' => 0, 'NAME' => 1, 'MIME' => 2, 'FTYPE' => 3, 'DIRECTORY' => 4, 'FILEPATH' => 5, 'STATE' => 6, 'CURRENTLYACCESSING' => 7, 'EDITEDBY' => 8, 'MTIME' => 9, 'UTIME' => 10, 'LPTIME' => 11, 'MD5' => 12, 'TRACK_TITLE' => 13, 'ARTIST_NAME' => 14, 'BIT_RATE' => 15, 'SAMPLE_RATE' => 16, 'FORMAT' => 17, 'LENGTH' => 18, 'ALBUM_TITLE' => 19, 'GENRE' => 20, 'COMMENTS' => 21, 'YEAR' => 22, 'TRACK_NUMBER' => 23, 'CHANNELS' => 24, 'URL' => 25, 'BPM' => 26, 'RATING' => 27, 'ENCODED_BY' => 28, 'DISC_NUMBER' => 29, 'MOOD' => 30, 'LABEL' => 31, 'COMPOSER' => 32, 'ENCODER' => 33, 'CHECKSUM' => 34, 'LYRICS' => 35, 'ORCHESTRA' => 36, 'CONDUCTOR' => 37, 'LYRICIST' => 38, 'ORIGINAL_LYRICIST' => 39, 'RADIO_STATION_NAME' => 40, 'INFO_URL' => 41, 'ARTIST_URL' => 42, 'AUDIO_SOURCE_URL' => 43, 'RADIO_STATION_URL' => 44, 'BUY_THIS_URL' => 45, 'ISRC_NUMBER' => 46, 'CATALOG_NUMBER' => 47, 'ORIGINAL_ARTIST' => 48, 'COPYRIGHT' => 49, 'REPORT_DATETIME' => 50, 'REPORT_LOCATION' => 51, 'REPORT_ORGANIZATION' => 52, 'SUBJECT' => 53, 'CONTRIBUTOR' => 54, 'LANGUAGE' => 55, 'FILE_EXISTS' => 56, 'SOUNDCLOUD_ID' => 57, 'SOUNDCLOUD_ERROR_CODE' => 58, 'SOUNDCLOUD_ERROR_MSG' => 59, 'SOUNDCLOUD_LINK_TO_FILE' => 60, 'SOUNDCLOUD_UPLOAD_TIME' => 61, 'REPLAY_GAIN' => 62, 'OWNER_ID' => 63, 'CUEIN' => 64, 'CUEOUT' => 65, 'SILAN_CHECK' => 66, 'HIDDEN' => 67, 'IS_SCHEDULED' => 68, 'IS_PLAYLIST' => 69, ), + BasePeer::TYPE_FIELDNAME => array ('id' => 0, 'name' => 1, 'mime' => 2, 'ftype' => 3, 'directory' => 4, 'filepath' => 5, 'state' => 6, 'currentlyaccessing' => 7, 'editedby' => 8, 'mtime' => 9, 'utime' => 10, 'lptime' => 11, 'md5' => 12, 'track_title' => 13, 'artist_name' => 14, 'bit_rate' => 15, 'sample_rate' => 16, 'format' => 17, 'length' => 18, 'album_title' => 19, 'genre' => 20, 'comments' => 21, 'year' => 22, 'track_number' => 23, 'channels' => 24, 'url' => 25, 'bpm' => 26, 'rating' => 27, 'encoded_by' => 28, 'disc_number' => 29, 'mood' => 30, 'label' => 31, 'composer' => 32, 'encoder' => 33, 'checksum' => 34, 'lyrics' => 35, 'orchestra' => 36, 'conductor' => 37, 'lyricist' => 38, 'original_lyricist' => 39, 'radio_station_name' => 40, 'info_url' => 41, 'artist_url' => 42, 'audio_source_url' => 43, 'radio_station_url' => 44, 'buy_this_url' => 45, 'isrc_number' => 46, 'catalog_number' => 47, 'original_artist' => 48, 'copyright' => 49, 'report_datetime' => 50, 'report_location' => 51, 'report_organization' => 52, 'subject' => 53, 'contributor' => 54, 'language' => 55, 'file_exists' => 56, 'soundcloud_id' => 57, 'soundcloud_error_code' => 58, 'soundcloud_error_msg' => 59, 'soundcloud_link_to_file' => 60, 'soundcloud_upload_time' => 61, 'replay_gain' => 62, 'owner_id' => 63, 'cuein' => 64, 'cueout' => 65, 'silan_check' => 66, 'hidden' => 67, 'is_scheduled' => 68, 'is_playlist' => 69, ), + BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, ) ); /** @@ -411,6 +417,8 @@ abstract class BaseCcFilesPeer { $criteria->addSelectColumn(CcFilesPeer::CUEOUT); $criteria->addSelectColumn(CcFilesPeer::SILAN_CHECK); $criteria->addSelectColumn(CcFilesPeer::HIDDEN); + $criteria->addSelectColumn(CcFilesPeer::IS_SCHEDULED); + $criteria->addSelectColumn(CcFilesPeer::IS_PLAYLIST); } else { $criteria->addSelectColumn($alias . '.ID'); $criteria->addSelectColumn($alias . '.NAME'); @@ -480,6 +488,8 @@ abstract class BaseCcFilesPeer { $criteria->addSelectColumn($alias . '.CUEOUT'); $criteria->addSelectColumn($alias . '.SILAN_CHECK'); $criteria->addSelectColumn($alias . '.HIDDEN'); + $criteria->addSelectColumn($alias . '.IS_SCHEDULED'); + $criteria->addSelectColumn($alias . '.IS_PLAYLIST'); } } diff --git a/airtime_mvc/application/models/airtime/om/BaseCcFilesQuery.php b/airtime_mvc/application/models/airtime/om/BaseCcFilesQuery.php index 775895eb8..fe42ad88c 100644 --- a/airtime_mvc/application/models/airtime/om/BaseCcFilesQuery.php +++ b/airtime_mvc/application/models/airtime/om/BaseCcFilesQuery.php @@ -74,6 +74,8 @@ * @method CcFilesQuery orderByDbCueout($order = Criteria::ASC) Order by the cueout column * @method CcFilesQuery orderByDbSilanCheck($order = Criteria::ASC) Order by the silan_check column * @method CcFilesQuery orderByDbHidden($order = Criteria::ASC) Order by the hidden column + * @method CcFilesQuery orderByDbIsScheduled($order = Criteria::ASC) Order by the is_scheduled column + * @method CcFilesQuery orderByDbIsPlaylist($order = Criteria::ASC) Order by the is_playlist column * * @method CcFilesQuery groupByDbId() Group by the id column * @method CcFilesQuery groupByDbName() Group by the name column @@ -143,6 +145,8 @@ * @method CcFilesQuery groupByDbCueout() Group by the cueout column * @method CcFilesQuery groupByDbSilanCheck() Group by the silan_check column * @method CcFilesQuery groupByDbHidden() Group by the hidden column + * @method CcFilesQuery groupByDbIsScheduled() Group by the is_scheduled column + * @method CcFilesQuery groupByDbIsPlaylist() Group by the is_playlist column * * @method CcFilesQuery leftJoin($relation) Adds a LEFT JOIN clause to the query * @method CcFilesQuery rightJoin($relation) Adds a RIGHT JOIN clause to the query @@ -247,6 +251,8 @@ * @method CcFiles findOneByDbCueout(string $cueout) Return the first CcFiles filtered by the cueout column * @method CcFiles findOneByDbSilanCheck(boolean $silan_check) Return the first CcFiles filtered by the silan_check column * @method CcFiles findOneByDbHidden(boolean $hidden) Return the first CcFiles filtered by the hidden column + * @method CcFiles findOneByDbIsScheduled(boolean $is_scheduled) Return the first CcFiles filtered by the is_scheduled column + * @method CcFiles findOneByDbIsPlaylist(boolean $is_playlist) Return the first CcFiles filtered by the is_playlist column * * @method array findByDbId(int $id) Return CcFiles objects filtered by the id column * @method array findByDbName(string $name) Return CcFiles objects filtered by the name column @@ -316,6 +322,8 @@ * @method array findByDbCueout(string $cueout) Return CcFiles objects filtered by the cueout column * @method array findByDbSilanCheck(boolean $silan_check) Return CcFiles objects filtered by the silan_check column * @method array findByDbHidden(boolean $hidden) Return CcFiles objects filtered by the hidden column + * @method array findByDbIsScheduled(boolean $is_scheduled) Return CcFiles objects filtered by the is_scheduled column + * @method array findByDbIsPlaylist(boolean $is_playlist) Return CcFiles objects filtered by the is_playlist column * * @package propel.generator.airtime.om */ @@ -2045,6 +2053,40 @@ abstract class BaseCcFilesQuery extends ModelCriteria return $this->addUsingAlias(CcFilesPeer::HIDDEN, $dbHidden, $comparison); } + /** + * Filter the query on the is_scheduled column + * + * @param boolean|string $dbIsScheduled The value to use as filter. + * Accepts strings ('false', 'off', '-', 'no', 'n', and '0' are false, the rest is true) + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return CcFilesQuery The current query, for fluid interface + */ + public function filterByDbIsScheduled($dbIsScheduled = null, $comparison = null) + { + if (is_string($dbIsScheduled)) { + $is_scheduled = in_array(strtolower($dbIsScheduled), array('false', 'off', '-', 'no', 'n', '0')) ? false : true; + } + return $this->addUsingAlias(CcFilesPeer::IS_SCHEDULED, $dbIsScheduled, $comparison); + } + + /** + * Filter the query on the is_playlist column + * + * @param boolean|string $dbIsPlaylist The value to use as filter. + * Accepts strings ('false', 'off', '-', 'no', 'n', and '0' are false, the rest is true) + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return CcFilesQuery The current query, for fluid interface + */ + public function filterByDbIsPlaylist($dbIsPlaylist = null, $comparison = null) + { + if (is_string($dbIsPlaylist)) { + $is_playlist = in_array(strtolower($dbIsPlaylist), array('false', 'off', '-', 'no', 'n', '0')) ? false : true; + } + return $this->addUsingAlias(CcFilesPeer::IS_PLAYLIST, $dbIsPlaylist, $comparison); + } + /** * Filter the query by a related CcSubjs object * diff --git a/airtime_mvc/application/models/airtime/om/BaseCcSchedule.php b/airtime_mvc/application/models/airtime/om/BaseCcSchedule.php index 4f7edcebf..13a15093f 100644 --- a/airtime_mvc/application/models/airtime/om/BaseCcSchedule.php +++ b/airtime_mvc/application/models/airtime/om/BaseCcSchedule.php @@ -77,14 +77,12 @@ abstract class BaseCcSchedule extends BaseObject implements Persistent /** * The value for the cue_in field. - * Note: this column has a database default value of: '00:00:00' * @var string */ protected $cue_in; /** * The value for the cue_out field. - * Note: this column has a database default value of: '00:00:00' * @var string */ protected $cue_out; @@ -161,8 +159,6 @@ abstract class BaseCcSchedule extends BaseObject implements Persistent $this->clip_length = '00:00:00'; $this->fade_in = '00:00:00'; $this->fade_out = '00:00:00'; - $this->cue_in = '00:00:00'; - $this->cue_out = '00:00:00'; $this->media_item_played = false; $this->playout_status = 1; $this->broadcasted = 0; @@ -708,7 +704,7 @@ abstract class BaseCcSchedule extends BaseObject implements Persistent $v = (string) $v; } - if ($this->cue_in !== $v || $this->isNew()) { + if ($this->cue_in !== $v) { $this->cue_in = $v; $this->modifiedColumns[] = CcSchedulePeer::CUE_IN; } @@ -728,7 +724,7 @@ abstract class BaseCcSchedule extends BaseObject implements Persistent $v = (string) $v; } - if ($this->cue_out !== $v || $this->isNew()) { + if ($this->cue_out !== $v) { $this->cue_out = $v; $this->modifiedColumns[] = CcSchedulePeer::CUE_OUT; } @@ -842,14 +838,6 @@ abstract class BaseCcSchedule extends BaseObject implements Persistent return false; } - if ($this->cue_in !== '00:00:00') { - return false; - } - - if ($this->cue_out !== '00:00:00') { - return false; - } - if ($this->media_item_played !== false) { return false; } diff --git a/airtime_mvc/application/views/scripts/form/edit-user.phtml b/airtime_mvc/application/views/scripts/form/edit-user.phtml index cd4b70bd9..79a0081fc 100644 --- a/airtime_mvc/application/views/scripts/form/edit-user.phtml +++ b/airtime_mvc/application/views/scripts/form/edit-user.phtml @@ -1,4 +1,4 @@ -

currentUser) ?>

+

escape($this->currentUser)) ?>

@@ -160,4 +160,4 @@
-
\ No newline at end of file + diff --git a/airtime_mvc/application/views/scripts/form/preferences_watched_dirs.phtml b/airtime_mvc/application/views/scripts/form/preferences_watched_dirs.phtml index 4889892dd..6c3030903 100644 --- a/airtime_mvc/application/views/scripts/form/preferences_watched_dirs.phtml +++ b/airtime_mvc/application/views/scripts/form/preferences_watched_dirs.phtml @@ -11,7 +11,7 @@ element->getElement('storageFolder')->hasErrors()) : ?>
    element->getElement('storageFolder')->getMessages() as $error): ?> -
  • +
  • escape($error); ?>
@@ -29,7 +29,7 @@ element->getElement('watchedFolder')->hasErrors()) : ?>
    element->getElement('watchedFolder')->getMessages() as $error): ?> -
  • +
  • escape($error); ?>
@@ -39,7 +39,7 @@ 0): ?>
- getExistsFlag())?"":""?>getDirectory();?> + getExistsFlag())?"":""?>getDirectory());?> " class="ui-icon ui-icon-refresh"> " class="ui-icon ui-icon-close"> diff --git a/airtime_mvc/application/views/scripts/library/get-file-metadata.ajax.phtml b/airtime_mvc/application/views/scripts/library/get-file-metadata.ajax.phtml index 4b1a38839..0e0d9cbcb 100644 --- a/airtime_mvc/application/views/scripts/library/get-file-metadata.ajax.phtml +++ b/airtime_mvc/application/views/scripts/library/get-file-metadata.ajax.phtml @@ -1,3 +1,9 @@ +md as $key => &$value) { + $value = $this->escape($value); +} +?> type == "audioclip") : ?> @@ -41,9 +47,18 @@ o
o + type == "playlist" || ($this->type == "block" && $this->blType == "Static")) {?> + contents as &$item) { + foreach ($item as $key => &$value) { + $value = $this->escape($value); + } + }*/ + ?> type == "playlist") { ?>
@@ -88,9 +103,13 @@ blType == "Dynamic") { ?>
md["MDATA_KEY_TITLE"]);?>
- contents["crit"] as $criterias) : ?> - + contents["crit"] as &$criterias) : ?> + $valMaxStrLen) { $crit["value"] = substr($crit["value"], 0, 24)."..."; diff --git a/airtime_mvc/application/views/scripts/library/index.phtml b/airtime_mvc/application/views/scripts/library/index.phtml index 30c18e365..a00a32149 100644 --- a/airtime_mvc/application/views/scripts/library/index.phtml +++ b/airtime_mvc/application/views/scripts/library/index.phtml @@ -2,7 +2,14 @@ render('library/library.phtml') ?> -
+showPlaylist) { + $display = ""; +} else { + $display = "display:none"; +} +?> +
type == 'block') { echo $this->render('playlist/smart-block.phtml'); } else if ($this->type == 'playlist') { diff --git a/airtime_mvc/application/views/scripts/playlist/playlist.phtml b/airtime_mvc/application/views/scripts/playlist/playlist.phtml index f8496d926..ead87942e 100644 --- a/airtime_mvc/application/views/scripts/playlist/playlist.phtml +++ b/airtime_mvc/application/views/scripts/playlist/playlist.phtml @@ -4,6 +4,7 @@ if (isset($this->obj)) { $count = count($contents); } ?> +
obj)) : ?> +
+ +
@@ -39,7 +43,7 @@ if (isset($this->obj)) { diff --git a/airtime_mvc/application/views/scripts/playlist/smart-block.phtml b/airtime_mvc/application/views/scripts/playlist/smart-block.phtml index b1ca48da5..97779bc61 100644 --- a/airtime_mvc/application/views/scripts/playlist/smart-block.phtml +++ b/airtime_mvc/application/views/scripts/playlist/smart-block.phtml @@ -4,6 +4,7 @@ if (isset($this->obj)) { $count = count($contents); } ?> +
obj)) : ?> +
+ +
@@ -39,7 +43,7 @@ if (isset($this->obj)) { unsavedName)) echo $this->unsavedName; - else echo $this->obj->getName(); + else echo $this->escape($this->obj->getName()); ?> diff --git a/airtime_mvc/application/views/scripts/schedule/show-content-dialog.phtml b/airtime_mvc/application/views/scripts/schedule/show-content-dialog.phtml index 09aadb4d8..3f0ae83c7 100644 --- a/airtime_mvc/application/views/scripts/schedule/show-content-dialog.phtml +++ b/airtime_mvc/application/views/scripts/schedule/show-content-dialog.phtml @@ -13,9 +13,9 @@ showContent as $row): ?>
" class=""> - - - + + + diff --git a/airtime_mvc/application/views/scripts/webstream/webstream.phtml b/airtime_mvc/application/views/scripts/webstream/webstream.phtml index 34131aabd..ee80adf30 100644 --- a/airtime_mvc/application/views/scripts/webstream/webstream.phtml +++ b/airtime_mvc/application/views/scripts/webstream/webstream.phtml @@ -1,3 +1,4 @@ +
"); } - if (criteriaTypes[ele.mDataProp] == "s") { + if (libraryColumnTypes[ele.mDataProp] == "s") { var obj = { sSelector: "#"+ele.mDataProp } } else { var obj = { sSelector: "#"+ele.mDataProp, type: "number-range" } @@ -435,10 +460,15 @@ var AIRTIME = (function(AIRTIME) { // put hidden columns at the top to insure they can never be visible // on the table through column reordering. + + //IMPORTANT: WHEN ADDING A NEW COLUMN PLEASE CONSULT WITH THE WIKI + // https://wiki.sourcefabric.org/display/CC/Adding+a+new+library+datatable+column "aoColumns": [ /* ftype */ { "sTitle" : "" , "mDataProp" : "ftype" , "bSearchable" : false , "bVisible" : false } , /* Checkbox */ { "sTitle" : "" , "mDataProp" : "checkbox" , "bSortable" : false , "bSearchable" : false , "sWidth" : "25px" , "sClass" : "library_checkbox" } , /* Type */ { "sTitle" : "" , "mDataProp" : "image" , "bSearchable" : false , "sWidth" : "25px" , "sClass" : "library_type" , "iDataSort" : 0 } , + /* Is Scheduled */ { "sTitle" : $.i18n._("Scheduled") , "mDataProp" : "is_scheduled" , "bSearchable" : false , "sWidth" : "90px" , "sClass" : "library_is_scheduled"} , + /* Is Playlist */ { "sTitle" : $.i18n._("Playlist") , "mDataProp" : "is_playlist" , "bSearchable" : false , "sWidth" : "70px" , "sClass" : "library_is_playlist"} , /* Title */ { "sTitle" : $.i18n._("Title") , "mDataProp" : "track_title" , "sClass" : "library_title" , "sWidth" : "170px" } , /* Creator */ { "sTitle" : $.i18n._("Creator") , "mDataProp" : "artist_name" , "sClass" : "library_creator" , "sWidth" : "160px" } , /* Album */ { "sTitle" : $.i18n._("Album") , "mDataProp" : "album_title" , "sClass" : "library_album" , "sWidth" : "150px" } , @@ -447,6 +477,8 @@ var AIRTIME = (function(AIRTIME) { /* Composer */ { "sTitle" : $.i18n._("Composer") , "mDataProp" : "composer" , "bVisible" : false , "sClass" : "library_composer" , "sWidth" : "150px" }, /* Conductor */ { "sTitle" : $.i18n._("Conductor") , "mDataProp" : "conductor" , "bVisible" : false , "sClass" : "library_conductor" , "sWidth" : "125px" }, /* Copyright */ { "sTitle" : $.i18n._("Copyright") , "mDataProp" : "copyright" , "bVisible" : false , "sClass" : "library_copyright" , "sWidth" : "125px" }, + /* Cue In */ { "sTitle" : $.i18n._("Cue In") , "mDataProp" : "cuein" , "bVisible" : false , "sClass" : "library_length" , "sWidth" : "80px" }, + /* Cue Out */ { "sTitle" : $.i18n._("Cue Out") , "mDataProp" : "cueout" , "bVisible" : false , "sClass" : "library_length" , "sWidth" : "80px" }, /* Encoded */ { "sTitle" : $.i18n._("Encoded By") , "mDataProp" : "encoded_by" , "bVisible" : false , "sClass" : "library_encoded" , "sWidth" : "150px" }, /* Genre */ { "sTitle" : $.i18n._("Genre") , "mDataProp" : "genre" , "bVisible" : false , "sClass" : "library_genre" , "sWidth" : "100px" }, /* ISRC Number */ { "sTitle" : $.i18n._("ISRC") , "mDataProp" : "isrc_number" , "bVisible" : false , "sClass" : "library_isrc" , "sWidth" : "150px" }, @@ -491,9 +523,11 @@ var AIRTIME = (function(AIRTIME) { }, "fnStateLoad": function fnLibStateLoad(oSettings) { var settings = localStorage.getItem('datatables-library'); - - if (settings !== "") { + + try { return JSON.parse(settings); + } catch (e) { + return null; } }, "fnStateLoadParams": function (oSettings, oData) { @@ -501,18 +535,22 @@ var AIRTIME = (function(AIRTIME) { length, a = oData.abVisCols; - // putting serialized data back into the correct js type to make - // sure everything works properly. - for (i = 0, length = a.length; i < length; i++) { - if (typeof(a[i]) === "string") { - a[i] = (a[i] === "true") ? true : false; - } + if (a) { + // putting serialized data back into the correct js type to make + // sure everything works properly. + for (i = 0, length = a.length; i < length; i++) { + if (typeof(a[i]) === "string") { + a[i] = (a[i] === "true") ? true : false; + } + } } - + a = oData.ColReorder; - for (i = 0, length = a.length; i < length; i++) { - if (typeof(a[i]) === "string") { - a[i] = parseInt(a[i], 10); + if (a) { + for (i = 0, length = a.length; i < length; i++) { + if (typeof(a[i]) === "string") { + a[i] = parseInt(a[i], 10); + } } } @@ -554,12 +592,46 @@ var AIRTIME = (function(AIRTIME) { }, "fnRowCallback": AIRTIME.library.fnRowCallback, "fnCreatedRow": function( nRow, aData, iDataIndex ) { - + //add soundcloud icon + if (aData.soundcloud_status !== undefined) { + if (aData.soundcloud_status === "-2") { + $(nRow).find("td.library_title").append(''); + } else if (aData.soundcloud_status === "-3") { + $(nRow).find("td.library_title").append(''); + } else if (aData.soundcloud_status !== null) { + $(nRow).find("td.library_title").append(''); + } + } + + // add checkbox + $(nRow).find('td.library_checkbox').html(""); + + // add audio preview image/button + if (aData.ftype === "audioclip") { + $(nRow).find('td.library_type').html(''); + } else if (aData.ftype === "playlist") { + $(nRow).find('td.library_type').html(''); + } else if (aData.ftype === "block") { + $(nRow).find('td.library_type').html(''); + } else if (aData.ftype === "stream") { + $(nRow).find('td.library_type').html(''); + } + + if (aData.is_scheduled) { + $(nRow).find("td.library_is_scheduled").html(''); + } else if (!aData.is_scheduled) { + $(nRow).find("td.library_is_scheduled").html(''); + } + if (aData.is_playlist) { + $(nRow).find("td.library_is_playlist").html(''); + } else if (!aData.is_playlist) { + $(nRow).find("td.library_is_playlist").html(''); + } + // add the play function to the library_type td $(nRow).find('td.library_type').click(function(){ if (aData.ftype === 'playlist' && aData.length !== '0.0'){ - playlistIndex = $(this).parent().attr('id').substring(3); - open_playlist_preview(playlistIndex, 0); + open_playlist_preview(aData.audioFile, 0); } else if (aData.ftype === 'audioclip') { if (isAudioSupported(aData.mime)) { open_audio_preview(aData.ftype, aData.audioFile, aData.track_title, aData.artist_name); @@ -569,8 +641,7 @@ var AIRTIME = (function(AIRTIME) { open_audio_preview(aData.ftype, aData.audioFile, aData.track_title, aData.artist_name); } } else if (aData.ftype == 'block' && aData.bl_type == 'static') { - blockIndex = $(this).parent().attr('id').substring(3); - open_block_preview(blockIndex, 0); + open_block_preview(aData.audioFile, 0); } return false; }); @@ -605,7 +676,28 @@ var AIRTIME = (function(AIRTIME) { } return false; }); - + + /*$(nRow).find(".media-item-in-use").qtip({ + content: { + text: aData.status_msg + }, + hide: { + delay: 500, + fixed: true + }, + style: { + border: { + width: 0, + radius: 4 + }, + classes: "ui-tooltip-dark ui-tooltip-rounded" + }, + position: { + my: "left bottom", + at: "right center" + }, + });*/ + // add a tool tip to appear when the user clicks on the type // icon. $(nRow).find("td:not(.library_checkbox, .library_type)").qtip({ @@ -702,8 +794,19 @@ var AIRTIME = (function(AIRTIME) { $simpleSearch.addClass("sp-invisible"); } else { - //clear the advanced search fields and reset datatable - $(".filter_column input").val("").keyup(); + // clear the advanced search fields + var divs = $("div#advanced_search").children(':visible'); + $.each(divs, function(i, div){ + fields = $(div).children().find('input'); + $.each(fields, function(i, field){ + if ($(field).val() !== "") { + $(field).val(""); + // we need to reset the results when removing + // an advanced search field + $(field).keyup(); + } + }); + }); //reset datatable with previous simple search results (if any) $(".dataTables_filter input").val(simpleSearchText).keyup(); @@ -757,8 +860,7 @@ var AIRTIME = (function(AIRTIME) { }); checkImportStatus(); - setInterval(checkImportStatus, 5000); - setInterval(checkLibrarySCUploadStatus, 5000); + checkLibrarySCUploadStatus(); addQtipToSCIcons(); @@ -986,6 +1088,7 @@ function checkImportStatus() { } div.hide(); } + setTimeout(checkImportStatus, 5000); }); } @@ -1019,6 +1122,7 @@ function checkLibrarySCUploadStatus(){ else if (json.sc_id == "-3") { span.removeClass("progress").addClass("sc-error"); } + setTimeout(checkLibrarySCUploadStatus, 5000); } function checkSCUploadStatusRequest() { @@ -1252,6 +1356,8 @@ var validationTypes = { "composer" : "s", "conductor" : "s", "copyright" : "s", + "cuein" : "l", + "cueout" : "l", "encoded_by" : "s", "utime" : "t", "mtime" : "t", @@ -1283,12 +1389,23 @@ $(document).ready(function() { data = $("#edit-md-dialog form").serializeArray(); $.post(baseUrl+'library/edit-file-md', {format: "json", id: file_id, data: data}, function() { $("#edit-md-dialog").dialog().remove(); - oTable.fnStandingRedraw(); + + // don't redraw the library table if we are on calendar page + // we would be on calendar if viewing recorded file metadata + if ($("#schedule_calendar").length === 0) { + oTable.fnStandingRedraw(); + } }); }); $('#editmdcancel').live("click", function() { $("#edit-md-dialog").dialog().remove(); }); + + $('#edit-md-dialog').live("keyup", function(event) { + if (event.keyCode === 13) { + $('#editmdsave').click(); + } + }); }); diff --git a/airtime_mvc/public/js/airtime/library/plupload.js b/airtime_mvc/public/js/airtime/library/plupload.js index b429c5602..91fdc63ee 100644 --- a/airtime_mvc/public/js/airtime/library/plupload.js +++ b/airtime_mvc/public/js/airtime/library/plupload.js @@ -30,8 +30,7 @@ $(document).ready(function() { var tempFileName = j.tempfilepath; $.get(baseUrl+'Plupload/copyfile/format/json/name/'+ encodeURIComponent(file.name)+'/tempname/' + - encodeURIComponent(tempFileName), function(json){ - var jr = jQuery.parseJSON(json); + encodeURIComponent(tempFileName), function(jr){ if(jr.error !== undefined) { var row = $("
") .append('') diff --git a/airtime_mvc/public/js/airtime/library/spl.js b/airtime_mvc/public/js/airtime/library/spl.js index 2839ab45d..93d1cd80d 100644 --- a/airtime_mvc/public/js/airtime/library/spl.js +++ b/airtime_mvc/public/js/airtime/library/spl.js @@ -12,6 +12,7 @@ var AIRTIME = (function(AIRTIME){ viewport, $lib, $pl, + $togglePl = $(""), widgetHeight, resizeTimeout, width; @@ -363,6 +364,17 @@ var AIRTIME = (function(AIRTIME){ removeButtonCheck(); } + function openPlaylistPanel() { + var screenWidth = Math.floor(viewport.width - 40); + viewport = AIRTIME.utilities.findViewportDimensions(); + widgetHeight = viewport.height - 185; + + $lib.width(Math.floor(screenWidth * 0.53)); + $pl.show().width(Math.floor(screenWidth * 0.44)); + $pl.height(widgetHeight); + $("#pl_edit").hide(); + } + //Purpose of this function is to iterate over all playlist elements //and verify whether they can be previewed by the browser or not. If not //then the playlist element is greyed out @@ -450,9 +462,8 @@ var AIRTIME = (function(AIRTIME){ if ($(this).hasClass('close')) { var sUrl = baseUrl+"playlist/get-block-info"; mod.disableUI(); - $.post(sUrl, {format:"json", id:blockId}, function(json){ + $.post(sUrl, {format:"json", id:blockId}, function(data){ $html = ""; - var data = $.parseJSON(json); var isStatic = data.isStatic; delete data.type; if (isStatic) { @@ -643,8 +654,7 @@ var AIRTIME = (function(AIRTIME){ obj_id = $('input[id="obj_id"]').val(); url = baseUrl+"Playlist/shuffle"; enableLoadingIcon(); - $.post(url, {format: "json", obj_id: obj_id}, function(data){ - var json = $.parseJSON(data) + $.post(url, {format: "json", obj_id: obj_id}, function(json){ if (json.error !== undefined) { alert(json.error); @@ -711,7 +721,40 @@ var AIRTIME = (function(AIRTIME){ }); - + + $lib.on("click", "#pl_edit", function() { + openPlaylistPanel(); + $.ajax( { + url : baseUrl+"usersettings/set-library-screen-settings", + type : "POST", + data : { + settings : { + playlist : true + }, + format : "json" + }, + dataType : "json" + }); + }); + + $pl.on("click", "#lib_pl_close", function() { + var screenWidth = Math.floor(viewport.width - 40); + $pl.hide(); + $lib.width(screenWidth).find("#library_display_length").append($togglePl.show()); + + $.ajax( { + url : baseUrl+"usersettings/set-library-screen-settings", + type : "POST", + data : { + settings : { + playlist : false + }, + format : "json" + }, + dataType : "json" + }); + }); + $('#save_button').live("click", function(event){ /* Smart blocks: get name, description, and criteria * Playlists: get name, description @@ -727,8 +770,7 @@ var AIRTIME = (function(AIRTIME){ enableLoadingIcon(); $.post(save_action, {format: "json", data: criteria, name: block_name, description: block_desc, obj_id: obj_id, type: obj_type, modified: lastMod}, - function(data){ - var json = $.parseJSON(data); + function(json){ if (json.error !== undefined) { alert(json.error); } @@ -737,7 +779,7 @@ var AIRTIME = (function(AIRTIME){ } setModified(json.modified); if (obj_type == "block") { - callback(data, "save"); + callback(json, "save"); } else { $('.success').text($.i18n._('Playlist saved')); $('.success').show(); @@ -749,6 +791,12 @@ var AIRTIME = (function(AIRTIME){ } ); }); + + $("#pl-bl-clear-content").live("click", function(event) { + var sUrl = baseUrl+"playlist/empty-content", + oData = {}; + playlistRequest(sUrl, oData); + }); } function setUpPlaylist() { @@ -884,7 +932,9 @@ var AIRTIME = (function(AIRTIME){ }; mod.fnEdit = function(id, type, url) { - + if ($pl.is(":hidden")) { + openPlaylistPanel(); + } stopAudioPreview(); $.post(url, @@ -1049,31 +1099,45 @@ var AIRTIME = (function(AIRTIME){ }; function setWidgetSize() { - viewport = AIRTIME.utilities.findViewportDimensions(); - widgetHeight = viewport.height - 185; - width = Math.floor(viewport.width - 80); - - var libTableHeight = widgetHeight - 130; + viewport = AIRTIME.utilities.findViewportDimensions(); + widgetHeight = viewport.height - 185; + width = Math.floor(viewport.width - 80); - $lib.height(widgetHeight) - .find(".dataTables_scrolling") - .css("max-height", libTableHeight) - .end() - .width(Math.floor(width * 0.55)); - - $pl.height(widgetHeight) - .width(Math.floor(width * 0.45)); + var libTableHeight = widgetHeight - 130; + + if (!$pl.is(':hidden')) { + $lib.height(widgetHeight) + .find(".dataTables_scrolling") + .css("max-height", libTableHeight) + .end() + .width(Math.floor(width * 0.55)); + + $pl.height(widgetHeight) + .width(Math.floor(width * 0.45)); + } else { + $lib.height(widgetHeight) + .find(".dataTables_scrolling") + .css("max-height", libTableHeight) + .end() + .width(width + 40); + } } mod.onReady = function() { $lib = $("#library_content"); $pl = $("#side_playlist"); + + setWidgetSize(); AIRTIME.library.libraryInit(); AIRTIME.playlist.init(); - + + if ($pl.is(':hidden')) { + $lib.find("#library_display_length").append($togglePl.show()); + } + $pl.find(".ui-icon-alert").qtip({ content: { text: $.i18n._("Airtime is unsure about the status of this file. This can happen when the file is on a remote drive that is unaccessible or the file is in a directory that isn't 'watched' anymore.") diff --git a/airtime_mvc/public/js/airtime/listenerstat/listenerstat.js b/airtime_mvc/public/js/airtime/listenerstat/listenerstat.js index 926368966..bebfd1471 100644 --- a/airtime_mvc/public/js/airtime/listenerstat/listenerstat.js +++ b/airtime_mvc/public/js/airtime/listenerstat/listenerstat.js @@ -23,7 +23,6 @@ $(document).ready(function() { function getDataAndPlot(startTimestamp, endTimestamp){ // get data $.get(baseUrl+'Listenerstat/get-data', {startTimestamp: startTimestamp, endTimestamp: endTimestamp}, function(data){ - data = JSON.parse(data); out = new Object(); $.each(data, function(mpName, v){ plotData = new Object(); diff --git a/airtime_mvc/public/js/airtime/login/login.js b/airtime_mvc/public/js/airtime/login/login.js index a37210b35..f21043c31 100644 --- a/airtime_mvc/public/js/airtime/login/login.js +++ b/airtime_mvc/public/js/airtime/login/login.js @@ -1,6 +1,6 @@ $(window).load(function(){ $("#username").focus(); - $("#locale").val($.cookie("airtime_locale")!== null?$.cookie("airtime_locale"):'en_CA'); + $("#locale").val($.cookie("airtime_locale")!== null?$.cookie("airtime_locale"):$.cookie("default_airtime_locale")); }); $(document).ready(function() { diff --git a/airtime_mvc/public/js/airtime/login/password-restore.js b/airtime_mvc/public/js/airtime/login/password-restore.js index 04d78f98b..4b45a59ff 100644 --- a/airtime_mvc/public/js/airtime/login/password-restore.js +++ b/airtime_mvc/public/js/airtime/login/password-restore.js @@ -1,3 +1,3 @@ function redirectToLogin(){ - window.location = baseUrl+"/Login" + window.location = baseUrl+"Login" } \ No newline at end of file diff --git a/airtime_mvc/public/js/airtime/playlist/smart_blockbuilder.js b/airtime_mvc/public/js/airtime/playlist/smart_blockbuilder.js index 68bb71fd5..f47a7b8ed 100644 --- a/airtime_mvc/public/js/airtime/playlist/smart_blockbuilder.js +++ b/airtime_mvc/public/js/airtime/playlist/smart_blockbuilder.js @@ -351,7 +351,7 @@ function setupUI() { * It is only active if playlist is not empty */ var plContents = $('#spl_sortable').children(); - var shuffleButton = $('button[id="shuffle_button"], button[id="playlist_shuffle_button"]'); + var shuffleButton = $('button[id="shuffle_button"], button[id="playlist_shuffle_button"], button[id="pl-bl-clear-content"]'); if (!plContents.hasClass('spl_empty')) { if (shuffleButton.hasClass('ui-state-disabled')) { @@ -480,9 +480,8 @@ function getCriteriaOptionType(e) { return criteriaTypes[criteria]; } -function callback(data, type) { - var json = $.parseJSON(data), - dt = $('table[id="library_display"]').dataTable(); +function callback(json, type) { + var dt = $('table[id="library_display"]').dataTable(); if (type == 'shuffle' || type == 'generate') { if (json.error !== undefined) { @@ -560,7 +559,9 @@ function enableLoadingIcon() { function disableLoadingIcon() { $("#side_playlist").unblock() } - +// We need to know if the criteria value will be a string +// or numeric value in order to populate the modifier +// select list var criteriaTypes = { 0 : "", "album_title" : "s", @@ -569,6 +570,8 @@ var criteriaTypes = { "composer" : "s", "conductor" : "s", "copyright" : "s", + "cuein" : "n", + "cueout" : "n", "artist_name" : "s", "encoded_by" : "s", "utime" : "n", diff --git a/airtime_mvc/public/js/airtime/preferences/preferences.js b/airtime_mvc/public/js/airtime/preferences/preferences.js index 1d529617d..50466f462 100644 --- a/airtime_mvc/public/js/airtime/preferences/preferences.js +++ b/airtime_mvc/public/js/airtime/preferences/preferences.js @@ -108,9 +108,9 @@ $(document).ready(function() { var data = $('#pref_form').serialize(); var url = baseUrl+'Preference/index'; - $.post(url, {format: "json", data: data}, function(data){ - var json = $.parseJSON(data); + $.post(url, {format: "json", data: data}, function(json){ $('#content').empty().append(json.html); + $.cookie("default_airtime_locale", $('#locale').val(), {path: '/'}); setTimeout(removeSuccessMsg, 5000); showErrorSections(); }); diff --git a/airtime_mvc/public/js/airtime/preferences/streamsetting.js b/airtime_mvc/public/js/airtime/preferences/streamsetting.js index 54bb986ca..01d4717b3 100644 --- a/airtime_mvc/public/js/airtime/preferences/streamsetting.js +++ b/airtime_mvc/public/js/airtime/preferences/streamsetting.js @@ -28,7 +28,7 @@ function rebuildStreamURL(ele){ }else{ streamurl = "http://"+host+":"+port+"/" } - div.find("#stream_url").html(streamurl) + div.find("#stream_url").text(streamurl) } function restrictOggBitrate(ele, on){ var div = ele.closest("div") @@ -71,14 +71,13 @@ function showForIcecast(ele){ div.find("#outputMountpoint-element").show() div.find("#outputUser-label").show() div.find("#outputUser-element").show() - div.find("select[id$=data-type]").find("option[value='ogg']").attr("disabled",""); + div.find("select[id$=data-type]").find("option[value='ogg']").removeAttr("disabled"); } function checkLiquidsoapStatus(){ var url = baseUrl+'Preference/get-liquidsoap-status/format/json'; var id = $(this).attr("id"); - $.post(url, function(json){ - var json_obj = jQuery.parseJSON(json); + $.post(url, function(json_obj){ for(var i=0;i'); - } else if ((view.name === 'agendaDay' || view.name === 'agendaWeek') && event.record === 1 && event.soundcloud_id > 0) { - $(element).find(".fc-event-time").before(''); - } else if ((view.name === 'agendaDay' || view.name === 'agendaWeek') && event.record === 1 && event.soundcloud_id === -2) { - $(element).find(".fc-event-time").before(''); - } else if ((view.name === 'agendaDay' || view.name === 'agendaWeek') && event.record === 1 && event.soundcloud_id === -3) { - $(element).find(".fc-event-time").before(''); - } - - if(view.name === 'month' && event.record === 1 && event.soundcloud_id === -1) { - $(element).find(".fc-event-title").after(''); - } else if (view.name === 'month' && event.record === 1 && event.soundcloud_id > 0) { - $(element).find(".fc-event-title").after(''); - } else if (view.name === 'month' && event.record === 1 && event.soundcloud_id === -2) { - $(element).find(".fc-event-title").after(''); - } else if (view.name === 'month' && event.record === 1 && event.soundcloud_id === -3) { - $(element).find(".fc-event-title").after(''); - } - - if (view.name === 'agendaDay' || view.name === 'agendaWeek') { - if (event.show_empty === 1 && event.record === 0 && event.rebroadcast === 0) { - $(element) - .find(".fc-event-time") - .before(''); - } else if (event.show_partial_filled === true) { - $(element) - .find(".fc-event-time") - .before(''); + if (event.record === 1) { + if (view.name === 'agendaDay' || view.name === 'agendaWeek') { + if (event.soundcloud_id === -1) { + $(element).find(".fc-event-time").before(''); + } else if ( event.soundcloud_id > 0) { + $(element).find(".fc-event-time").before(''); + } else if (event.soundcloud_id === -2) { + $(element).find(".fc-event-time").before(''); + } else if (event.soundcloud_id === -3) { + $(element).find(".fc-event-time").before(''); + } + } else if (view.name === 'month') { + if(event.soundcloud_id === -1) { + $(element).find(".fc-event-title").after(''); + } else if (event.soundcloud_id > 0) { + $(element).find(".fc-event-title").after(''); + } else if (event.soundcloud_id === -2) { + $(element).find(".fc-event-title").after(''); + } else if (event.soundcloud_id === -3) { + $(element).find(".fc-event-title").after(''); + } } - } else if (view.name === 'month') { - if (event.show_empty === 1 && event.record === 0 && event.rebroadcast === 0) { - $(element) - .find(".fc-event-title") - .after(''); - } else if (event.show_partial_filled === true) { - $(element) - .find(".fc-event-title") - .after(''); + } + + if (event.record === 0 && event.rebroadcast === 0) { + if (view.name === 'agendaDay' || view.name === 'agendaWeek') { + if (event.show_empty === 1) { + $(element) + .find(".fc-event-time") + .before(''); + } else if (event.show_partial_filled === true) { + $(element) + .find(".fc-event-time") + .before(''); + } + } else if (view.name === 'month') { + if (event.show_empty === 1) { + $(element) + .find(".fc-event-title") + .after(''); + } else if (event.show_partial_filled === true) { + $(element) + .find(".fc-event-title") + .after(''); + } } } //rebroadcast icon - if((view.name === 'agendaDay' || view.name === 'agendaWeek') && event.rebroadcast === 1) { - $(element).find(".fc-event-time").before(''); - } - - if(view.name === 'month' && event.rebroadcast === 1) { - $(element).find(".fc-event-title").after(''); + if (event.rebroadcast === 1) { + if (view.name === 'agendaDay' || view.name === 'agendaWeek') { + $(element).find(".fc-event-time").before(''); + } else if (view.name === 'month') { + $(element).find(".fc-event-title").after(''); + } } } @@ -326,21 +336,36 @@ function eventResize( event, dayDelta, minuteDelta, revertFunc, jsEvent, ui, vie }); } -function getFullCalendarEvents(start, end, callback) { - var url, start_date, end_date; - - start_date = makeTimeStamp(start); - end_date = makeTimeStamp(end); - - url = baseUrl+'Schedule/event-feed'; - +function preloadEventFeed () { + var url = baseUrl+'Schedule/event-feed-preload'; var d = new Date(); - - $.post(url, {format: "json", start: start_date, end: end_date, cachep: d.getTime()}, function(json){ - callback(json.events); + + $.post(url, {format: "json", cachep: d.getTime()}, function(json){ + calendarEvents = json.events; + createFullCalendar({calendarInit: calendarPref}); }); } +var initialLoad = true; +function getFullCalendarEvents(start, end, callback) { + + if (initialLoad) { + initialLoad = false; + callback(calendarEvents); + } else { + var url, start_date, end_date; + + start_date = makeTimeStamp(start); + end_date = makeTimeStamp(end); + url = baseUrl+'Schedule/event-feed'; + + var d = new Date(); + $.post(url, {format: "json", start: start_date, end: end_date, cachep: d.getTime()}, function(json){ + callback(json.events); + }); + } +} + function checkSCUploadStatus(){ var url = baseUrl+'Library/get-upload-to-soundcloud-status/format/json'; $("span[class*=progress]").each(function(){ @@ -351,6 +376,7 @@ function checkSCUploadStatus(){ }else if(json.sc_id == "-3"){ $("span[id="+id+"]:not(.recording)").removeClass("progress").addClass("sc-error"); } + setTimeout(checkSCUploadStatus, 5000); }); }); } @@ -403,6 +429,7 @@ function getCurrentShow(){ $(this).remove("span[small-icon now-playing]"); } }); + setTimeout(getCurrentShow, 5000); }); } @@ -541,9 +568,10 @@ function alertShowErrorAndReload(){ window.location.reload(); } +preloadEventFeed(); $(document).ready(function(){ - setInterval( "checkSCUploadStatus()", 5000 ); - setInterval( "getCurrentShow()", 5000 ); + checkSCUploadStatus(); + getCurrentShow(); }); var view_name; diff --git a/airtime_mvc/public/js/airtime/schedule/schedule.js b/airtime_mvc/public/js/airtime/schedule/schedule.js index 2de53cdb5..57dc8def5 100644 --- a/airtime_mvc/public/js/airtime/schedule/schedule.js +++ b/airtime_mvc/public/js/airtime/schedule/schedule.js @@ -93,6 +93,8 @@ function checkCalendarSCUploadStatus(){ else if (json.sc_id == "-3") { span.removeClass("progress").addClass("sc-error"); } + + setTimeout(checkCalendarSCUploadStatus, 5000); } function checkSCUploadStatusRequest() { @@ -328,10 +330,7 @@ function alertShowErrorAndReload(){ } $(document).ready(function() { - $.ajax({ url: baseUrl+"Api/calendar-init/format/json", dataType:"json", success:createFullCalendar - , error:function(jqXHR, textStatus, errorThrown){}}); - - setInterval(checkCalendarSCUploadStatus, 5000); + checkCalendarSCUploadStatus(); $.contextMenu({ selector: 'div.fc-event', @@ -402,7 +401,7 @@ $(document).ready(function() { oItems.edit.callback = callback; } } - + //define a content callback. if (oItems.content !== undefined) { @@ -443,9 +442,11 @@ $(document).ready(function() { //define a view recorded callback. if (oItems.view_recorded !== undefined) { - callback = function() { - document.location.href = oItems.view_recorded.url; + $.get(oItems.view_recorded.url, {format: "json"}, function(json){ + //in library.js + buildEditMetadataDialog(json); + }); }; oItems.view_recorded.callback = callback; } diff --git a/airtime_mvc/public/js/airtime/showbuilder/builder.js b/airtime_mvc/public/js/airtime/showbuilder/builder.js index b7d4bda7f..9bbc4db92 100644 --- a/airtime_mvc/public/js/airtime/showbuilder/builder.js +++ b/airtime_mvc/public/js/airtime/showbuilder/builder.js @@ -81,9 +81,20 @@ var AIRTIME = (function(AIRTIME){ return mod.showInstances; }; - mod.refresh = function() { + mod.refresh = function(schedId) { mod.resetTimestamp(); - oSchedTable.fnDraw(); + + // once a track plays out we need to check if we can update + // the is_scheduled flag in cc_files + if (schedId > 0) { + $.post(baseUrl+"schedule/update-future-is-scheduled", + {"format": "json", "schedId": schedId}, function(data) { + if (data.redrawLibTable !== undefined && data.redrawLibTable) { + $("#library_content").find("#library_display").dataTable().fnStandingRedraw(); + } + }); + oSchedTable.fnDraw(); + } }; mod.checkSelectButton = function() { @@ -251,10 +262,11 @@ var AIRTIME = (function(AIRTIME){ mod.fnItemCallback = function(json) { checkError(json); - mod.getSelectedCursors(); + mod.getSelectedCursors(); oSchedTable.fnDraw(); - + mod.enableUI(); + $("#library_content").find("#library_display").dataTable().fnStandingRedraw(); }; mod.getSelectedCursors = function() { @@ -796,7 +808,7 @@ var AIRTIME = (function(AIRTIME){ if(refreshInterval > maxRefreshInterval){ refreshInterval = maxRefreshInterval; } - mod.timeout = setTimeout(mod.refresh, refreshInterval); //need refresh in milliseconds + mod.timeout = setTimeout(function() {mod.refresh(aData.id)}, refreshInterval); //need refresh in milliseconds break; } } @@ -1066,6 +1078,7 @@ var AIRTIME = (function(AIRTIME){ url: url, data: {format: "json", id: data.instance}, success: function(data){ + $("#library_content").find("#library_display").dataTable().fnStandingRedraw(); var oTable = $sbTable.dataTable(); oTable.fnDraw(); } diff --git a/airtime_mvc/public/js/airtime/showbuilder/main_builder.js b/airtime_mvc/public/js/airtime/showbuilder/main_builder.js index 214bc9714..ee19e85fd 100644 --- a/airtime_mvc/public/js/airtime/showbuilder/main_builder.js +++ b/airtime_mvc/public/js/airtime/showbuilder/main_builder.js @@ -86,7 +86,7 @@ AIRTIME = (function(AIRTIME) { .end(); oTable = $('#show_builder_table').dataTable(); - oTable.fnDraw(); + //oTable.fnDraw(); } } @@ -277,12 +277,13 @@ AIRTIME = (function(AIRTIME) { if (json.update === true) { oTable.fnDraw(); } + setTimeout(checkScheduleUpdates, 5000); } }); } //check if the timeline view needs updating. - setInterval(checkScheduleUpdates, 5 * 1000); //need refresh in milliseconds + checkScheduleUpdates(); }; mod.onResize = function() { diff --git a/airtime_mvc/public/js/airtime/status/status.js b/airtime_mvc/public/js/airtime/status/status.js index 9b5e4d3ea..ef3358e7a 100644 --- a/airtime_mvc/public/js/airtime/status/status.js +++ b/airtime_mvc/public/js/airtime/status/status.js @@ -66,6 +66,7 @@ function success(data, textStatus, jqXHR){ if (data.status.partitions){ generatePartitions(data.status.partitions); } + setTimeout(function(){updateStatus(false);}, 5000); } function updateStatus(getDiskInfo){ @@ -75,5 +76,4 @@ function updateStatus(getDiskInfo){ $(document).ready(function() { updateStatus(true); - setInterval(function(){updateStatus(false);}, 5000); }); diff --git a/airtime_mvc/public/js/airtime/user/user.js b/airtime_mvc/public/js/airtime/user/user.js index fd129be79..71f9eed6e 100644 --- a/airtime_mvc/public/js/airtime/user/user.js +++ b/airtime_mvc/public/js/airtime/user/user.js @@ -189,8 +189,7 @@ $(document).ready(function() { var data = $('#user_form').serialize(); var url = baseUrl+'User/add-user'; - $.post(url, {format: "json", data: data}, function(data){ - var json = $.parseJSON(data); + $.post(url, {format: "json", data: data}, function(json){ if (json.valid === "true") { $('#content').empty().append(json.html); populateUserTable(); diff --git a/airtime_mvc/public/js/datatables/i18n/el_GR.txt b/airtime_mvc/public/js/datatables/i18n/el_GR.txt new file mode 100644 index 000000000..03f52058f --- /dev/null +++ b/airtime_mvc/public/js/datatables/i18n/el_GR.txt @@ -0,0 +1,18 @@ +// Greek +{ + "sProcessing": "Επεξεργασία...", + "sLengthMenu": "Δείξε _MENU_ εγγραφές", + "sZeroRecords": "Δεν βρέθηκαν εγγραφές που να ταιριάζουν", + "sInfo": "Δείχνοντας _START_ εως _END_ από _TOTAL_ εγγραφές", + "sInfoEmpty": "Δείχνοντας 0 εως 0 από 0 εγγραφές", + "sInfoFiltered": "(φιλτραρισμένες από _MAX_ συνολικά εγγραφές)", + "sInfoPostFix": "", + "sSearch": "", + "sUrl": "", + "oPaginate": { + "sFirst": "Πρώτη", + "sPrevious": "Προηγούμενη", + "sNext": "Επόμενη", + "sLast": "Τελευταία" + } +} \ No newline at end of file diff --git a/airtime_mvc/public/js/datatables/i18n/pl_PL.txt b/airtime_mvc/public/js/datatables/i18n/pl_PL.txt new file mode 100644 index 000000000..5d73fcc24 --- /dev/null +++ b/airtime_mvc/public/js/datatables/i18n/pl_PL.txt @@ -0,0 +1,18 @@ +//Polish +{ + "sProcessing": "Proszę czekać...", + "sLengthMenu": "Pokaż _MENU_ pozycji", + "sZeroRecords": "Nie znaleziono żadnych pasujących indeksów", + "sInfo": "Pozycje od _START_ do _END_ z _TOTAL_ łącznie", + "sInfoEmpty": "Pozycji 0 z 0 dostępnych", + "sInfoFiltered": "(filtrowanie spośród _MAX_ dostępnych pozycji)", + "sInfoPostFix": "", + "sSearch": "", + "sUrl": "", + "oPaginate": { + "sFirst": "Pierwsza", + "sPrevious": "Poprzednia", + "sNext": "Następna", + "sLast": "Ostatnia" + } +} \ No newline at end of file diff --git a/airtime_mvc/public/js/datatables/js/jquery.dataTables.js b/airtime_mvc/public/js/datatables/js/jquery.dataTables.js index ab61ea58e..02694a4a5 100644 --- a/airtime_mvc/public/js/datatables/js/jquery.dataTables.js +++ b/airtime_mvc/public/js/datatables/js/jquery.dataTables.js @@ -1,12 +1,10 @@ -/** - * @summary DataTables - * @description Paginate, search and sort HTML tables - * @version 1.9.1 - * @file jquery.dataTables.js - * @author Allan Jardine (www.sprymedia.co.uk) - * @contact www.sprymedia.co.uk/contact - * - * @copyright Copyright 2008-2012 Allan Jardine, all rights reserved. +/* + * File: jquery.dataTables.min.js + * Version: 1.9.4 + * Author: Allan Jardine (www.sprymedia.co.uk) + * Info: www.datatables.net + * + * Copyright 2008-2012 Allan Jardine, all rights reserved. * * This source file is free software, under either the GPL v2 license or a * BSD style license, available at: @@ -16,11823 +14,142 @@ * This source file is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details. - * - * For details please refer to: http://www.datatables.net */ - -/*jslint evil: true, undef: true, browser: true */ -/*globals $, jQuery,_fnExternApiFunc,_fnInitialise,_fnInitComplete,_fnLanguageCompat,_fnAddColumn,_fnColumnOptions,_fnAddData,_fnCreateTr,_fnGatherData,_fnBuildHead,_fnDrawHead,_fnDraw,_fnReDraw,_fnAjaxUpdate,_fnAjaxParameters,_fnAjaxUpdateDraw,_fnServerParams,_fnAddOptionsHtml,_fnFeatureHtmlTable,_fnScrollDraw,_fnAdjustColumnSizing,_fnFeatureHtmlFilter,_fnFilterComplete,_fnFilterCustom,_fnFilterColumn,_fnFilter,_fnBuildSearchArray,_fnBuildSearchRow,_fnFilterCreateSearch,_fnDataToSearch,_fnSort,_fnSortAttachListener,_fnSortingClasses,_fnFeatureHtmlPaginate,_fnPageChange,_fnFeatureHtmlInfo,_fnUpdateInfo,_fnFeatureHtmlLength,_fnFeatureHtmlProcessing,_fnProcessingDisplay,_fnVisibleToColumnIndex,_fnColumnIndexToVisible,_fnNodeToDataIndex,_fnVisbleColumns,_fnCalculateEnd,_fnConvertToWidth,_fnCalculateColumnWidths,_fnScrollingWidthAdjust,_fnGetWidestNode,_fnGetMaxLenString,_fnStringToCss,_fnDetectType,_fnSettingsFromNode,_fnGetDataMaster,_fnGetTrNodes,_fnGetTdNodes,_fnEscapeRegex,_fnDeleteIndex,_fnReOrderIndex,_fnColumnOrdering,_fnLog,_fnClearTable,_fnSaveState,_fnLoadState,_fnCreateCookie,_fnReadCookie,_fnDetectHeader,_fnGetUniqueThs,_fnScrollBarWidth,_fnApplyToChildren,_fnMap,_fnGetRowData,_fnGetCellData,_fnSetCellData,_fnGetObjectDataFn,_fnSetObjectDataFn,_fnApplyColumnDefs,_fnBindAction,_fnCallbackReg,_fnCallbackFire,_fnJsonString,_fnRender,_fnNodeToColumnIndex,_fnInfoMacros*/ - -(/** @lends */function($, window, document, undefined) { - /** - * DataTables is a plug-in for the jQuery Javascript library. It is a - * highly flexible tool, based upon the foundations of progressive - * enhancement, which will add advanced interaction controls to any - * HTML table. For a full list of features please refer to - * DataTables.net. - * - * Note that the DataTable object is not a global variable but is - * aliased to jQuery.fn.DataTable and jQuery.fn.dataTable through which - * it may be accessed. - * - * @class - * @param {object} [oInit={}] Configuration object for DataTables. Options - * are defined by {@link DataTable.defaults} - * @requires jQuery 1.3+ - * - * @example - * // Basic initialisation - * $(document).ready( function { - * $('#example').dataTable(); - * } ); - * - * @example - * // Initialisation with configuration options - in this case, disable - * // pagination and sorting. - * $(document).ready( function { - * $('#example').dataTable( { - * "bPaginate": false, - * "bSort": false - * } ); - * } ); - */ - var DataTable = function( oInit ) - { - - - /** - * Add a column to the list used for the table with default values - * @param {object} oSettings dataTables settings object - * @param {node} nTh The th element for this column - * @memberof DataTable#oApi - */ - function _fnAddColumn( oSettings, nTh ) - { - var oDefaults = DataTable.defaults.columns; - var iCol = oSettings.aoColumns.length; - var oCol = $.extend( {}, DataTable.models.oColumn, oDefaults, { - "sSortingClass": oSettings.oClasses.sSortable, - "sSortingClassJUI": oSettings.oClasses.sSortJUI, - "nTh": nTh ? nTh : document.createElement('th'), - "sTitle": oDefaults.sTitle ? oDefaults.sTitle : nTh ? nTh.innerHTML : '', - "aDataSort": oDefaults.aDataSort ? oDefaults.aDataSort : [iCol], - "mDataProp": oDefaults.mDataProp ? oDefaults.oDefaults : iCol - } ); - oSettings.aoColumns.push( oCol ); - - /* Add a column specific filter */ - if ( oSettings.aoPreSearchCols[ iCol ] === undefined || oSettings.aoPreSearchCols[ iCol ] === null ) - { - oSettings.aoPreSearchCols[ iCol ] = $.extend( {}, DataTable.models.oSearch ); - } - else - { - var oPre = oSettings.aoPreSearchCols[ iCol ]; - - /* Don't require that the user must specify bRegex, bSmart or bCaseInsensitive */ - if ( oPre.bRegex === undefined ) - { - oPre.bRegex = true; - } - - if ( oPre.bSmart === undefined ) - { - oPre.bSmart = true; - } - - if ( oPre.bCaseInsensitive === undefined ) - { - oPre.bCaseInsensitive = true; - } - } - - /* Use the column options function to initialise classes etc */ - _fnColumnOptions( oSettings, iCol, null ); - } - - - /** - * Apply options for a column - * @param {object} oSettings dataTables settings object - * @param {int} iCol column index to consider - * @param {object} oOptions object with sType, bVisible and bSearchable - * @memberof DataTable#oApi - */ - function _fnColumnOptions( oSettings, iCol, oOptions ) - { - var oCol = oSettings.aoColumns[ iCol ]; - - /* User specified column options */ - if ( oOptions !== undefined && oOptions !== null ) - { - if ( oOptions.sType !== undefined ) - { - oCol.sType = oOptions.sType; - oCol._bAutoType = false; - } - - $.extend( oCol, oOptions ); - _fnMap( oCol, oOptions, "sWidth", "sWidthOrig" ); - - /* iDataSort to be applied (backwards compatibility), but aDataSort will take - * priority if defined - */ - if ( oOptions.iDataSort !== undefined ) - { - oCol.aDataSort = [ oOptions.iDataSort ]; - } - _fnMap( oCol, oOptions, "aDataSort" ); - } - - /* Cache the data get and set functions for speed */ - oCol.fnGetData = _fnGetObjectDataFn( oCol.mDataProp ); - oCol.fnSetData = _fnSetObjectDataFn( oCol.mDataProp ); - - /* Feature sorting overrides column specific when off */ - if ( !oSettings.oFeatures.bSort ) - { - oCol.bSortable = false; - } - - /* Check that the class assignment is correct for sorting */ - if ( !oCol.bSortable || - ($.inArray('asc', oCol.asSorting) == -1 && $.inArray('desc', oCol.asSorting) == -1) ) - { - oCol.sSortingClass = oSettings.oClasses.sSortableNone; - oCol.sSortingClassJUI = ""; - } - else if ( oCol.bSortable || - ($.inArray('asc', oCol.asSorting) == -1 && $.inArray('desc', oCol.asSorting) == -1) ) - { - oCol.sSortingClass = oSettings.oClasses.sSortable; - oCol.sSortingClassJUI = oSettings.oClasses.sSortJUI; - } - else if ( $.inArray('asc', oCol.asSorting) != -1 && $.inArray('desc', oCol.asSorting) == -1 ) - { - oCol.sSortingClass = oSettings.oClasses.sSortableAsc; - oCol.sSortingClassJUI = oSettings.oClasses.sSortJUIAscAllowed; - } - else if ( $.inArray('asc', oCol.asSorting) == -1 && $.inArray('desc', oCol.asSorting) != -1 ) - { - oCol.sSortingClass = oSettings.oClasses.sSortableDesc; - oCol.sSortingClassJUI = oSettings.oClasses.sSortJUIDescAllowed; - } - } - - - /** - * Adjust the table column widths for new data. Note: you would probably want to - * do a redraw after calling this function! - * @param {object} oSettings dataTables settings object - * @memberof DataTable#oApi - */ - function _fnAdjustColumnSizing ( oSettings ) - { - /* Not interested in doing column width calculation if autowidth is disabled */ - if ( oSettings.oFeatures.bAutoWidth === false ) - { - return false; - } - - _fnCalculateColumnWidths( oSettings ); - for ( var i=0 , iLen=oSettings.aoColumns.length ; i
escape($row["track_title"]) ?>escape($row["creator"]) ?>escape($row["album"]) ?>
' + file.name +'