diff --git a/airtime_mvc/application/Bootstrap.php b/airtime_mvc/application/Bootstrap.php index f16183157..abc9ad99b 100644 --- a/airtime_mvc/application/Bootstrap.php +++ b/airtime_mvc/application/Bootstrap.php @@ -30,6 +30,7 @@ require_once "Timezone.php"; require_once "Auth.php"; require_once "interface/OAuth2.php"; require_once "TaskManager.php"; +require_once "UsabilityHints.php"; require_once __DIR__.'/services/CeleryService.php'; require_once __DIR__.'/services/SoundcloudService.php'; require_once __DIR__.'/forms/helpers/ValidationTypes.php'; diff --git a/airtime_mvc/application/cloud_storage/Amazon_S3StorageBackend.php b/airtime_mvc/application/cloud_storage/Amazon_S3StorageBackend.php index 0d86ef52c..2f023aeea 100644 --- a/airtime_mvc/application/cloud_storage/Amazon_S3StorageBackend.php +++ b/airtime_mvc/application/cloud_storage/Amazon_S3StorageBackend.php @@ -46,7 +46,7 @@ class Amazon_S3StorageBackend extends StorageBackend { $urls = array(); - $s3args = array('ResponseContentDisposition' => 'attachment; filename="' . $contentDispositionFilename. '"'); + $s3args = array('ResponseContentDisposition' => 'attachment; filename="' . urlencode($contentDispositionFilename) . '"'); $signedS3Url = $this->s3Client->getObjectUrl($this->getBucket(), $resourceId, '+60 minutes', $s3args); //If we're using the proxy cache, we need to modify the request URL after it has @@ -65,7 +65,7 @@ class Amazon_S3StorageBackend extends StorageBackend $p["path"] = substr($p["path"], 1 + strlen($this->getBucket())); } $proxyUrl = $p["scheme"] . "://" . $p["host"] . $p["path"] . "?" . $p["query"]; - //Add this proxy cache URL to the list of download URLs. + //Add this proxy cache URL to the list of download URLs.s array_push($urls, $proxyUrl); } diff --git a/airtime_mvc/application/common/FileDataHelper.php b/airtime_mvc/application/common/FileDataHelper.php index 2c5648f9f..25318333b 100644 --- a/airtime_mvc/application/common/FileDataHelper.php +++ b/airtime_mvc/application/common/FileDataHelper.php @@ -4,22 +4,23 @@ class FileDataHelper { public static function getAudioMimeTypeArray() { return array( - "audio/ogg" => "ogg", - "application/ogg" => "ogg", - "audio/vorbis" => "ogg", - "audio/mp3" => "mp3", - "audio/mpeg" => "mp3", - "audio/mpeg3" => "mp3", - "audio/aac" => "aac", - "audio/aacp" => "aac", - "audio/mp4" => "mp4", - "audio/x-flac" => "flac", - "audio/wav" => "wav", - "audio/x-wav" => "wav", - "audio/mp2" => "mp2", - "audio/mp1" => "mp1", - "audio/x-ms-wma" => "wma", - "audio/basic" => "au", + "audio/ogg" => "ogg", + "application/ogg" => "ogg", + "audio/vorbis" => "ogg", + "audio/mp3" => "mp3", + "audio/mpeg" => "mp3", + "audio/mpeg3" => "mp3", + "audio/x-aac" => "aac", + "audio/aac" => "aac", + "audio/aacp" => "aac", + "audio/mp4" => "mp4", + "audio/x-flac" => "flac", + "audio/wav" => "wav", + "audio/x-wav" => "wav", + "audio/mp2" => "mp2", + "audio/mp1" => "mp1", + "audio/x-ms-wma" => "wma", + "audio/basic" => "au", ); } diff --git a/airtime_mvc/application/common/UsabilityHints.php b/airtime_mvc/application/common/UsabilityHints.php new file mode 100644 index 000000000..38f09356d --- /dev/null +++ b/airtime_mvc/application/common/UsabilityHints.php @@ -0,0 +1,184 @@ +getRequest()->getControllerName()); + + if ($currentController == "schedule") { + $userIsOnCalendarPage = true; + } + + if ($currentController == "plupload") { + $userIsOnAddMediaPage = true; + } + } + + if (self::zeroFilesUploaded()) { + if ($userIsOnAddMediaPage) { + return _("Click the 'Add files' button and select files from your computer to upload."); + } else { + return sprintf(_("It looks like you have not uploaded any audio files yet. %sUpload a file now.%s "), + "", + ""); + } + } else if (!self::isFutureOrCurrentShowScheduled()) { + if ($userIsOnCalendarPage) { + return _("Click the 'Create New Show' button and fill out the required fields."); + } else { + return sprintf(_("It looks like you don't have any shows scheduled. %sCreate a show now.%s"), + "", + ""); + } + } else if (self::isCurrentShowEmpty()) { + if ($userIsOnCalendarPage) { + return _("To start broadcasting, click on the current show and select 'Add / Remove Content'"); + } else { + return sprintf(_("It looks like the current show needs more tracks. %sAdd tracks to your show now.%s"), + "", + ""); + } + } else if (!self::getCurrentShow() && self::isNextShowEmpty()) { + if ($userIsOnCalendarPage) { + return _("Click on the show starting next and select 'Add / Remove Content'"); + } else { + return sprintf(_("It looks like the next show is empty. %sAdd tracks to your show now.%s"), + "", + ""); + } + } else { + return ""; + } + } + + /** + * Returns true if no files have been uploaded. + */ + private static function zeroFilesUploaded() + { + $fileCount = CcFilesQuery::create() + ->filterByDbFileExists(true) + ->filterByDbHidden(false) + ->count(); + + if ($fileCount == 0) { + return true; + } else { + return false; + } + } + + /** + * Returns true if there is at least one show currently scheduled + * or in the future. + */ + private static function isFutureOrCurrentShowScheduled() + { + $futureShow = self::getNextFutureShow(); + $currentShow = self::getCurrentShow(); + + if (is_null($futureShow) && is_null($currentShow)) { + return false; + } else { + return true; + } + } + + private static function isCurrentShowEmpty() + { + $currentShow = self::getCurrentShow(); + + if (is_null($currentShow)) { + return false; + } else { + $now = new DateTime("now", new DateTimeZone("UTC")); + $scheduledTracks = CcScheduleQuery::create() + ->filterByDbInstanceId($currentShow->getDbId()) + ->filterByDbEnds($now, Criteria::GREATER_EQUAL) + ->find(); + if ($scheduledTracks->count() == 0) { + return true; + } else { + return false; + } + } + } + + private static function isNextShowEmpty() + { + $futureShow = self::getNextFutureShow(); + + if (is_null($futureShow)) { + return false; + } else { + $now = new DateTime("now", new DateTimeZone("UTC")); + $scheduledTracks = CcScheduleQuery::create() + ->filterByDbInstanceId($futureShow->getDbId()) + ->filterByDbStarts($now, Criteria::GREATER_EQUAL) + ->find(); + if ($scheduledTracks->count() == 0) { + return true; + } else { + return false; + } + } + } + + private static function getCurrentShow() + { + $now = new DateTime("now", new DateTimeZone("UTC")); + + return CcShowInstancesQuery::create() + ->filterByDbStarts($now, Criteria::LESS_THAN) + ->filterByDbEnds($now, Criteria::GREATER_THAN) + ->filterByDbModifiedInstance(false) + ->findOne(); + } + + private static function getNextFutureShow() + { + $now = new DateTime("now", new DateTimeZone("UTC")); + + return CcShowInstancesQuery::create() + ->filterByDbStarts($now, Criteria::GREATER_THAN) + ->filterByDbModifiedInstance(false) + ->orderByDbStarts() + ->findOne(); + } +} \ No newline at end of file diff --git a/airtime_mvc/application/configs/constants.php b/airtime_mvc/application/configs/constants.php index aaed5d901..c7c062066 100644 --- a/airtime_mvc/application/configs/constants.php +++ b/airtime_mvc/application/configs/constants.php @@ -103,6 +103,7 @@ define('PROVISIONING_STATUS_ACTIVE' , 'Active'); define("TUNEIN_API_URL", "http://air.radiotime.com/Playing.ashx"); // SoundCloud +define('SOUNDCLOUD', 'SoundCloud'); define('DEFAULT_SOUNDCLOUD_LICENSE_TYPE', 'all-rights-reserved'); define('DEFAULT_SOUNDCLOUD_SHARING_TYPE', 'public'); diff --git a/airtime_mvc/application/controllers/ApiController.php b/airtime_mvc/application/controllers/ApiController.php index 60b1e186b..cf1241e1e 100644 --- a/airtime_mvc/application/controllers/ApiController.php +++ b/airtime_mvc/application/controllers/ApiController.php @@ -64,6 +64,7 @@ class ApiController extends Zend_Controller_Action ->addActionContext('update-stream-setting-table' , 'json') ->addActionContext('update-replay-gain-value' , 'json') ->addActionContext('update-cue-values-by-silan' , 'json') + ->addActionContext('get-usability-hint' , 'json') ->initContext(); } @@ -1466,5 +1467,13 @@ class ApiController extends Zend_Controller_Action } $this->_helper->json->sendJson(array(1)); } + + public function getUsabilityHintAction() + { + $userPath = $this->_getParam("userPath"); + + $hint = Application_Common_UsabilityHints::getUsabilityHint($userPath); + $this->_helper->json->sendJson($hint); + } } diff --git a/airtime_mvc/application/controllers/LibraryController.php b/airtime_mvc/application/controllers/LibraryController.php index d0f7f0f09..70bfd2d7b 100644 --- a/airtime_mvc/application/controllers/LibraryController.php +++ b/airtime_mvc/application/controllers/LibraryController.php @@ -17,8 +17,6 @@ class LibraryController extends Zend_Controller_Action ->addActionContext('delete-group', 'json') ->addActionContext('context-menu', 'json') ->addActionContext('get-file-metadata', 'html') - ->addActionContext('upload-file-soundcloud', 'json') - ->addActionContext('get-upload-to-soundcloud-status', 'json') ->addActionContext('set-num-entries', 'json') ->addActionContext('edit-file-md', 'json') ->initContext(); @@ -276,7 +274,7 @@ class LibraryController extends Zend_Controller_Action $menu["sep1"] = "-----------"; //create a sub menu for Soundcloud actions. - $menu["soundcloud"] = array("name" => _("Soundcloud"), "icon" => "soundcloud", "items" => array()); + $menu["soundcloud"] = array("name" => _(SOUNDCLOUD), "icon" => "soundcloud", "items" => array()); $serviceId = $soundcloudService->getServiceId($id); if (!is_null($file) && $serviceId != 0) { diff --git a/airtime_mvc/application/controllers/ScheduleController.php b/airtime_mvc/application/controllers/ScheduleController.php index 4760e7f3d..157d86f14 100644 --- a/airtime_mvc/application/controllers/ScheduleController.php +++ b/airtime_mvc/application/controllers/ScheduleController.php @@ -98,6 +98,9 @@ class ScheduleController extends Zend_Controller_Action $this->view->headScript()->appendFile($baseUrl.'js/datatables/plugin/dataTables.FixedColumns.js?'.$CC_CONFIG['airtime_version'],'text/javascript'); $this->view->headScript()->appendFile($baseUrl.'js/datatables/plugin/dataTables.columnFilter.js?'.$CC_CONFIG['airtime_version'], 'text/javascript'); + $this->view->headScript()->appendFile($baseUrl.'js/libs/moment.min.js?'.$CC_CONFIG['airtime_version'], 'text/javascript'); + $this->view->headScript()->appendFile($baseUrl.'js/libs/moment-timezone-with-data-2010-2020.min.js?'.$CC_CONFIG['airtime_version'], 'text/javascript'); + $this->view->headScript()->appendFile($baseUrl.'js/airtime/buttons/buttons.js?'.$CC_CONFIG['airtime_version'],'text/javascript'); $this->view->headScript()->appendFile($baseUrl.'js/airtime/library/events/library_showbuilder.js?'.$CC_CONFIG['airtime_version'],'text/javascript'); $this->view->headScript()->appendFile($baseUrl.'js/airtime/library/library.js?'.$CC_CONFIG['airtime_version'],'text/javascript'); @@ -584,7 +587,20 @@ class ScheduleController extends Zend_Controller_Action $forms = $this->createShowFormAction(); $this->view->addNewShow = true; - + + if ($data['add_show_start_now'] == "now") { + + //have to use the timezone the user has entered in the form to check past/present + $showTimezone = new DateTimeZone($data["add_show_timezone"]); + $nowDateTime = new DateTime("now", $showTimezone); + //$showStartDateTime = new DateTime($start_time, $showTimezone); + //$showEndDateTime = new DateTime($end_time, $showTimezone); + + $data['add_show_start_time'] = $nowDateTime->format("H:i"); + $data['add_show_start_date'] = $nowDateTime->format("Y-m-d"); + } + + if ($service_showForm->validateShowForms($forms, $data)) { // Get the show ID from the show service to pass as a parameter to the RESTful ShowImageController $this->view->showId = $service_show->addUpdateShow($data); diff --git a/airtime_mvc/application/forms/AddShowWhen.php b/airtime_mvc/application/forms/AddShowWhen.php index d6edbe0cd..0f8f4094e 100644 --- a/airtime_mvc/application/forms/AddShowWhen.php +++ b/airtime_mvc/application/forms/AddShowWhen.php @@ -15,11 +15,26 @@ class Application_Form_AddShowWhen extends Zend_Form_SubForm "/^[0-2]?[0-9]:[0-5][0-9]$/", _("'%value%' does not fit the time format 'HH:mm'")); + + // Add start date element + $startNow = new Zend_Form_Element_Radio('add_show_start_now'); + $startNow->setRequired(false) + ->setLabel(_('Start Time:')) + ->addMultiOptions(array( + 'now' => 'Now', + 'future' => 'In the Future:' + )) + ->setValue('future') + ->setDecorators(array('ViewHelper')); + //$startDate->setAttrib('alt', 'date'); + $this->addElement($startNow); + + // Add start date element $startDate = new Zend_Form_Element_Text('add_show_start_date'); $startDate->class = 'input_text'; $startDate->setRequired(true) - ->setLabel(_('Date/Time Start:')) + ->setLabel(_('In the Future:')) ->setValue(date("Y-m-d")) ->setFilters(array('StringTrim')) ->setValidators(array( @@ -46,7 +61,7 @@ class Application_Form_AddShowWhen extends Zend_Form_SubForm $endDate = new Zend_Form_Element_Text('add_show_end_date_no_repeat'); $endDate->class = 'input_text'; $endDate->setRequired(true) - ->setLabel(_('Date/Time End:')) + ->setLabel(_('End Time:')) ->setValue(date("Y-m-d")) ->setFilters(array('StringTrim')) ->setValidators(array( @@ -119,7 +134,7 @@ class Application_Form_AddShowWhen extends Zend_Form_SubForm $showStartDateTime = new DateTime($start_time, $showTimezone); $showEndDateTime = new DateTime($end_time, $showTimezone); - if ($validateStartDate) { + if ($validateStartDate && ($formData['add_show_start_now'] != "now")) { if ($showStartDateTime < $nowDateTime) { $this->getElement('add_show_start_time')->setErrors(array(_('Cannot create show in the past'))); $valid = false; diff --git a/airtime_mvc/application/layouts/scripts/layout.phtml b/airtime_mvc/application/layouts/scripts/layout.phtml index 780a5f69e..3bb782dee 100644 --- a/airtime_mvc/application/layouts/scripts/layout.phtml +++ b/airtime_mvc/application/layouts/scripts/layout.phtml @@ -70,7 +70,13 @@ j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= -