diff --git a/airtime_mvc/application/controllers/ScheduleController.php b/airtime_mvc/application/controllers/ScheduleController.php index b970b55f3..37b347064 100644 --- a/airtime_mvc/application/controllers/ScheduleController.php +++ b/airtime_mvc/application/controllers/ScheduleController.php @@ -22,6 +22,7 @@ class ScheduleController extends Zend_Controller_Action ->addActionContext('edit-show', 'json') ->addActionContext('add-show', 'json') ->addActionContext('cancel-show', 'json') + ->addActionContext('cancel-current-show', 'json') ->addActionContext('get-form', 'json') ->addActionContext('upload-to-sound-cloud', 'json') ->addActionContext('content-context-menu', 'json') @@ -816,21 +817,21 @@ class ScheduleController extends Zend_Controller_Action public function cancelCurrentShowAction() { - $userInfo = Zend_Auth::getInstance()->getStorage()->read(); - $user = new Application_Model_User($userInfo->id); + $user = Application_Model_User::GetCurrentUser(); - if($user->isUserType(array(UTYPE_ADMIN, UTYPE_PROGRAM_MANAGER))) { - $showInstanceId = $this->_getParam('id'); - try{ - $showInstance = new Application_Model_ShowInstance($showInstanceId); - }catch(Exception $e){ - $this->view->show_error = true; - return false; + if ($user->isUserType(array(UTYPE_ADMIN, UTYPE_PROGRAM_MANAGER))) { + $id = $this->_getParam('id'); + + try { + $scheduler = new Application_Model_Scheduler(); + $scheduler->cancelShow($id); + } + catch (Exception $e) { + $this->view->error = $e->getMessage(); + Logging::log($e->getMessage()); + Logging::log("{$e->getFile()}"); + Logging::log("{$e->getLine()}"); } - $showInstance->clearShow(); - $showInstance->delete(); - - Application_Model_RabbitMq::PushSchedule(); } } diff --git a/airtime_mvc/application/models/Scheduler.php b/airtime_mvc/application/models/Scheduler.php index 1e7a27752..c5adc6c6e 100644 --- a/airtime_mvc/application/models/Scheduler.php +++ b/airtime_mvc/application/models/Scheduler.php @@ -93,10 +93,10 @@ class Application_Model_Scheduler { throw new OutDatedScheduleException("The show {$show->getDbName()} is over and cannot be scheduled."); } - $origTs = intval($instanceInfo[$id]); - $currTs = intval($instance->getDbLastScheduled("U")) ? : 0; - if ($origTs !== $currTs) { - Logging::log("orig {$origTs} current {$currTs}"); + $ts = intval($instanceInfo[$id]); + $lastSchedTs = intval($instance->getDbLastScheduled("U")) ? : 0; + if ($ts < $lastSchedTs) { + Logging::log("ts {$ts} last sched {$lastSchedTs}"); throw new OutDatedScheduleException("The show {$show->getDbName()} has been previously updated!"); } } @@ -215,6 +215,41 @@ class Application_Model_Scheduler { return $nextDT; } + + /* + * @param int $showInstance + * @param array $exclude + * ids of sched items to remove from the calulation. + */ + private function removeGaps($showInstance, $exclude=null) { + + Logging::log("removing gaps from show instance #".$showInstance); + + $instance = CcShowInstancesQuery::create()->findPK($showInstance, $this->con); + if (is_null($instance)) { + throw new OutDatedScheduleException("The schedule you're viewing is out of date!"); + } + + $itemStartDT = $instance->getDbStarts(null); + + $schedule = CcScheduleQuery::create() + ->filterByDbInstanceId($showInstance) + ->filterByDbId($exclude, Criteria::NOT_IN) + ->orderByDbStarts() + ->find($this->con); + + + foreach ($schedule as $item) { + + $itemEndDT = $this->findEndTime($itemStartDT, $item->getDbClipLength()); + + $item->setDbStarts($itemStartDT) + ->setDbEnds($itemEndDT) + ->save($this->con); + + $itemStartDT = $itemEndDT; + } + } /* * @param array $scheduledIds @@ -280,16 +315,16 @@ class Application_Model_Scheduler { $sched = new CcSchedule(); } - $sched->setDbStarts($nextStartDT); - $sched->setDbEnds($endTimeDT); - $sched->setDbFileId($file['id']); - $sched->setDbCueIn($file['cuein']); - $sched->setDbCueOut($file['cueout']); - $sched->setDbFadeIn($file['fadein']); - $sched->setDbFadeOut($file['fadeout']); - $sched->setDbClipLength($file['cliplength']); - $sched->setDbInstanceId($instance->getDbId()); - $sched->save($this->con); + $sched->setDbStarts($nextStartDT) + ->setDbEnds($endTimeDT) + ->setDbFileId($file['id']) + ->setDbCueIn($file['cuein']) + ->setDbCueOut($file['cueout']) + ->setDbFadeIn($file['fadein']) + ->setDbFadeOut($file['fadeout']) + ->setDbClipLength($file['cliplength']) + ->setDbInstanceId($instance->getDbId()) + ->save($this->con); $nextStartDT = $endTimeDT; } @@ -504,40 +539,45 @@ class Application_Model_Scheduler { throw $e; } } - + /* - * @param int $showInstance - * @param array $exclude - * ids of sched items to remove from the calulation. + * Used for cancelling the current show instance. + * + * @param $p_id id of the show instance to cancel. */ - private function removeGaps($showInstance, $exclude=null) { - - Logging::log("removing gaps from show instance #".$showInstance); - - $instance = CcShowInstancesQuery::create()->findPK($showInstance, $this->con); - if (is_null($instance)) { - throw new OutDatedScheduleException("The schedule you're viewing is out of date!"); - } - - $itemStartDT = $instance->getDbStarts(null); - - $schedule = CcScheduleQuery::create() - ->filterByDbInstanceId($showInstance) - ->filterByDbId($exclude, Criteria::NOT_IN) - ->orderByDbStarts() - ->find($this->con); - - - foreach ($schedule as $item) { - - $itemEndDT = $this->findEndTime($itemStartDT, $item->getDbClipLength()); - - $item->setDbStarts($itemStartDT); - $item->setDbEnds($itemEndDT); - $item->save($this->con); - - $itemStartDT = $itemEndDT; + public function cancelShow($p_id) { + + $this->con->beginTransaction(); + + try { + + $instance = CcShowInstancesQuery::create()->findPK($p_id); + + $items = CcScheduleQuery::create() + ->filterByDbInstanceId($p_id) + ->filterByDbEnds($this->nowDT, Criteria::GREATER_THAN) + ->find($this->con); + + $remove = array(); + $ts = $this->nowDT->format('U'); + + for($i = 0; $i < count($items); $i++) { + $remove[$i]["instance"] = $p_id; + $remove[$i]["timestamp"] = $ts; + $remove[$i]["id"] = $items[$i]->getDbId(); + } + + $this->removeItems($remove, false); + + $instance->setDbEnds($this->nowDT); + $instance->save($this->con); + + $this->con->commit(); } + catch (Exception $e) { + $this->con->rollback(); + throw $e; + } } } diff --git a/airtime_mvc/application/models/ShowBuilder.php b/airtime_mvc/application/models/ShowBuilder.php index 8ccf59aa6..e1e5af664 100644 --- a/airtime_mvc/application/models/ShowBuilder.php +++ b/airtime_mvc/application/models/ShowBuilder.php @@ -18,6 +18,7 @@ class Application_Model_ShowBuilder { private $pos; private $contentDT; private $epoch_now; + private $currentShow; private $defaultRowArray = array( "header" => false, @@ -54,6 +55,7 @@ class Application_Model_ShowBuilder { $this->user = Application_Model_User::GetCurrentUser(); $this->opts = $p_opts; $this->epoch_now = floatval(microtime(true)); + $this->currentShow = false; } //check to see if this row should be editable by the user. @@ -118,7 +120,7 @@ class Application_Model_ShowBuilder { else if ($row["footer"] === true && $this->epoch_now < $p_epochItemEnd) { $row["scheduled"] = 2; } - else if ($row["header"] === true && $this->epoch_now > $p_epochItemStart) { + else if ($row["header"] === true && $this->epoch_now >= $p_epochItemStart) { $row["scheduled"] = 0; } else if ($row["header"] === true && $this->epoch_now < $p_epochItemEnd) { @@ -156,6 +158,14 @@ class Application_Model_ShowBuilder { $showEndDT = new DateTime($p_item["si_ends"], new DateTimeZone("UTC")); $showEndDT->setTimezone(new DateTimeZone($this->timezone)); $endsEpoch = floatval($showEndDT->format("U.u")); + + if ($startsEpoch < $this->epoch_now && $endsEpoch > $this->epoch_now) { + $row["currentShow"] = true; + $this->currentShow = true; + } + else { + $this->currentShow = false; + } $row["header"] = true; $row["starts"] = $showStartDT->format("Y-m-d H:i"); @@ -224,6 +234,10 @@ class Application_Model_ShowBuilder { $row["id"] = 0 ; $row["instance"] = intval($p_item["si_id"]); } + + if ($this->currentShow = true) { + $row["currentShow"] = true; + } $this->getItemColor($p_item, $row); $this->getRowTimestamp($p_item, $row); @@ -256,6 +270,10 @@ class Application_Model_ShowBuilder { $endsEpoch = floatval($showEndDT->format("U.u")); $row["refresh"] = floatval($showEndDT->format("U.u")) - $this->epoch_now; + + if ($this->currentShow = true) { + $row["currentShow"] = true; + } $this->getScheduledStatus($startsEpoch, $endsEpoch, $row); $this->isAllowed($p_item, $row); diff --git a/airtime_mvc/public/css/showbuilder.css b/airtime_mvc/public/css/showbuilder.css index aa03fe85c..ff66a83ae 100644 --- a/airtime_mvc/public/css/showbuilder.css +++ b/airtime_mvc/public/css/showbuilder.css @@ -24,7 +24,7 @@ .sb-content .fg-toolbar ul { float: left; padding: 0; - margin: 0.5em 0 0 0; + margin: 0.5em 10px 0 0; cursor: pointer; } @@ -176,6 +176,10 @@ table.datatable tr.sb-header.odd:hover td, table.datatable tr.sb-header.even:hov border-bottom-color:#6b6a6a !important; } +.sb-header div.ui-state-default { + float: left; +} + .sb-content table th.ui-state-default { background: -moz-linear-gradient(top, #b2b2b2 0, #a2a2a2 100%); background: -webkit-gradient(linear, left top, left bottom, color-stop(0, #b2b2b2), color-stop(100%, #a2a2a2)); diff --git a/airtime_mvc/public/js/airtime/schedule/schedule.js b/airtime_mvc/public/js/airtime/schedule/schedule.js index 6513bb056..a720dd164 100644 --- a/airtime_mvc/public/js/airtime/schedule/schedule.js +++ b/airtime_mvc/public/js/airtime/schedule/schedule.js @@ -1,8 +1,14 @@ -/** -* -* Schedule Dialog creation methods. -* -*/ +var AIRTIME = (function(AIRTIME){ + var mod; + + if (AIRTIME.schedule === undefined) { + AIRTIME.schedule = {}; + } + mod = AIRTIME.schedule; + + return AIRTIME; + +}(AIRTIME || {})); var serverTimezoneOffset = 0; @@ -27,21 +33,27 @@ function checkShowLength(json) { } function confirmCancelShow(show_instance_id){ - if (confirm('Erase current show and stop playback?')){ - var url = "/Schedule/cancel-current-show/id/"+show_instance_id; + if (confirm('Cancel Current Show?')) { + var url = "/Schedule/cancel-current-show"; $.ajax({ - url: url, - success: function(data){scheduleRefetchEvents(data);} + url: url, + data: {format: "json", id: show_instance_id}, + success: function(data){ + scheduleRefetchEvents(data); + } }); } } function confirmCancelRecordedShow(show_instance_id){ - if (confirm('Erase current show and stop recording?')){ - var url = "/Schedule/cancel-current-show/id/"+show_instance_id; + if (confirm('Erase current show and stop recording?')) { + var url = "/Schedule/cancel-current-show"; $.ajax({ - url: url, - success: function(data){scheduleRefetchEvents(data);} + url: url, + data: {format: "json", id: show_instance_id}, + success: function(data){ + scheduleRefetchEvents(data); + } }); } } diff --git a/airtime_mvc/public/js/airtime/showbuilder/builder.js b/airtime_mvc/public/js/airtime/showbuilder/builder.js index 7e625f05c..02470e6db 100644 --- a/airtime_mvc/public/js/airtime/showbuilder/builder.js +++ b/airtime_mvc/public/js/airtime/showbuilder/builder.js @@ -363,6 +363,10 @@ var AIRTIME = (function(AIRTIME){ else if (aData.status === 0) { $(nRow).addClass("sb-over"); } + + if (aData.currentShow === true) { + $(nRow).addClass("sb-current-show"); + } //call the context menu so we can prevent the event from propagating. $(nRow).find('td:gt(1)').click(function(e){ @@ -372,6 +376,20 @@ var AIRTIME = (function(AIRTIME){ return false; }); }, + //remove any selected nodes before the draw. + "fnPreDrawCallback": function( oSettings ) { + var oTT; + + oTT = TableTools.fnGetInstance('show_builder_table'); + oTT.fnSelectNone(); + + //disable jump to current button. + AIRTIME.button.disableButton("sb-button-current"); + //disable deleting of overbooked tracks. + AIRTIME.button.disableButton("sb-button-trim"); + //disable cancelling current show. + AIRTIME.button.disableButton("sb-button-cancel"); + }, "fnDrawCallback": function(oSettings, json) { var wrapperDiv, markerDiv, @@ -454,22 +472,16 @@ var AIRTIME = (function(AIRTIME){ //enable deleting of overbooked tracks. AIRTIME.button.enableButton("sb-button-trim"); } + + $tr = $sbTable.find('tr.sb-future:first'); + if ($tr.hasClass('sb-current-show')) { + //enable cancelling current show. + AIRTIME.button.enableButton("sb-button-cancel"); + } }, "fnHeaderCallback": function(nHead) { $(nHead).find("input[type=checkbox]").attr("checked", false); }, - //remove any selected nodes before the draw. - "fnPreDrawCallback": function( oSettings ) { - var oTT; - - oTT = TableTools.fnGetInstance('show_builder_table'); - oTT.fnSelectNone(); - - //disable jump to current button. - AIRTIME.button.disableButton("sb-button-current"); - //disable deleting of overbooked tracks. - AIRTIME.button.disableButton("sb-button-trim"); - }, "oColVis": { "aiExclude": [ 0, 1 ] @@ -707,12 +719,44 @@ var AIRTIME = (function(AIRTIME){ //start setup of the builder toolbar. $toolbar = $(".sb-content .fg-toolbar"); - $toolbar - .append("