CC-4961: Show linking

This commit is contained in:
denise 2013-04-18 16:12:26 -04:00
parent 1a2a05c3cf
commit a9b5d00d87
5 changed files with 240 additions and 129 deletions

View File

@ -385,6 +385,7 @@ SELECT showt.name AS show_name,
showt.color AS show_color, showt.color AS show_color,
showt.background_color AS show_background_color, showt.background_color AS show_background_color,
showt.id AS show_id, showt.id AS show_id,
showt.linked AS linked,
si.starts AS si_starts, si.starts AS si_starts,
si.ends AS si_ends, si.ends AS si_ends,
si.time_filled AS si_time_filled, si.time_filled AS si_time_filled,

View File

@ -52,6 +52,8 @@ class Application_Model_Scheduler
foreach ($itemsToMove as $itemToMove) { foreach ($itemsToMove as $itemToMove) {
$ccShowInstance = CcShowInstancesQuery::create() $ccShowInstance = CcShowInstancesQuery::create()
->findPk($itemToMove["instance"]); ->findPk($itemToMove["instance"]);
//does the item being moved belong to a linked show
$linked = $ccShowInstance->getCcShow()->isLinked(); $linked = $ccShowInstance->getCcShow()->isLinked();
if ($linked && $itemToMove["instance"] != $afterInstanceId) { if ($linked && $itemToMove["instance"] != $afterInstanceId) {
@ -65,8 +67,10 @@ class Application_Model_Scheduler
* *
* @param array $items, an array containing pks of cc_schedule items. * @param array $items, an array containing pks of cc_schedule items.
*/ */
private function validateRequest($items) private function validateRequest($items, $addAction=false)
{ {
//$items is where tracks get inserted (they are schedule locations)
$nowEpoch = floatval($this->nowDT->format("U.u")); $nowEpoch = floatval($this->nowDT->format("U.u"));
for ($i = 0; $i < count($items); $i++) { for ($i = 0; $i < count($items); $i++) {
@ -78,7 +82,6 @@ class Application_Model_Scheduler
$schedInfo[$id] = $items[$i]["instance"]; $schedInfo[$id] = $items[$i]["instance"];
} }
//what is timestamp for?
//format is instance_id => timestamp //format is instance_id => timestamp
$instanceInfo[$items[$i]["instance"]] = $items[$i]["timestamp"]; $instanceInfo[$items[$i]["instance"]] = $items[$i]["timestamp"];
} }
@ -122,7 +125,7 @@ class Application_Model_Scheduler
if ($this->checkUserPermissions && $this->user->canSchedule($show->getDbId()) === false) { if ($this->checkUserPermissions && $this->user->canSchedule($show->getDbId()) === false) {
throw new Exception(sprintf(_("You are not allowed to schedule show %s."), $show->getDbName())); throw new Exception(sprintf(_("You are not allowed to schedule show %s."), $show->getDbName()));
} }
if ($instance->getDbRecord()) { if ($instance->getDbRecord()) {
throw new Exception(_("You cannot add files to recording shows.")); throw new Exception(_("You cannot add files to recording shows."));
} }
@ -139,6 +142,28 @@ class Application_Model_Scheduler
Logging::info("ts {$ts} last sched {$lastSchedTs}"); Logging::info("ts {$ts} last sched {$lastSchedTs}");
throw new OutDatedScheduleException(sprintf(_("The show %s has been previously updated!"), $show->getDbName())); throw new OutDatedScheduleException(sprintf(_("The show %s has been previously updated!"), $show->getDbName()));
} }
/*
* Does the afterItem belong to a show that is linked AND
* currently playing?
* If yes, throw an exception
*/
if ($addAction) {
$ccShow = $instance->getCcShow();
if ($ccShow->isLinked()) {
//get all the linked shows instances and check if
//any of them are currently playing
$ccShowInstances = $ccShow->getCcShowInstancess();
$timeNowUTC = gmdate("Y-m-d H:i:s");
foreach ($ccShowInstances as $ccShowInstance) {
if ($ccShowInstance->getDbStarts() <= $timeNowUTC &&
$ccShowInstance->getDbEnds() > $timeNowUTC) {
throw new Exception(_("Content in linked shows must be scheduled before or after any one is broadcasted"));
}
}
}
}
} }
} }
@ -409,35 +434,37 @@ class Application_Model_Scheduler
*/ */
private function insertAfter($scheduleItems, $filesToInsert, $adjustSched = true) private function insertAfter($scheduleItems, $filesToInsert, $adjustSched = true)
{ {
Logging::info($scheduleItems);
//Logging::info($filesToInsert);
try { try {
$affectedShowInstances = array(); $affectedShowInstances = array();
//dont want to recalculate times for moved items //dont want to recalculate times for moved items
//only moved items have a sched_id //only moved items have a sched_id
$excludeIds = array(); $excludeIds = array();
foreach ($filesToInsert as $file) { /*foreach ($filesToInsert as $file) {
if (isset($file["sched_id"])) { if (isset($file["sched_id"])) {
$excludeIds[] = intval($file["sched_id"]); $excludeIds[] = intval($file["sched_id"]);
} }
} }*/
$startProfile = microtime(true); $startProfile = microtime(true);
/*
* We need to prevent items getting added to linked shows more
* than once. This can happen if a cursor is selected in the same
* position on 2 or more linked shows
*/
$temp = array(); $temp = array();
$instance = null; $instance = null;
/* Items in shows are ordered by position number. We need to know
* the position when adding/moving items in linked shows so they are
* added or moved in the correct position
*/
$pos = 0; $pos = 0;
foreach ($scheduleItems as $schedule) { foreach ($scheduleItems as $schedule) {
$id = intval($schedule["id"]); $id = intval($schedule["id"]);
/* Find out if the show where the cursor position (where an item will
* be inserted) is located is linked or not. If the show is linked,
* we need to make sure there isn't another cursor selection in one of it's
* linked shows. If there is that will cause a duplication, in the least,
* of inserted items
*/
if ($id != 0) { if ($id != 0) {
$ccSchedule = CcScheduleQuery::create()->findPk($schedule["id"]); $ccSchedule = CcScheduleQuery::create()->findPk($schedule["id"]);
$ccShowInstance = CcShowInstancesQuery::create()->findPk($ccSchedule->getDbInstanceId()); $ccShowInstance = CcShowInstancesQuery::create()->findPk($ccSchedule->getDbInstanceId());
@ -463,124 +490,158 @@ class Application_Model_Scheduler
} }
} }
/* If the show where the cursor position is located is linked
* we need to insert the items for each linked instance belonging
* to that show
*/
$instances = $this->getInstances($schedule["instance"]); $instances = $this->getInstances($schedule["instance"]);
foreach($instances as $instance) { foreach($instances as $instance) {
Logging::info($instance->getDbId()); if ($id !== 0) {
if ($id !== 0) { $schedItem = CcScheduleQuery::create()->findPK($id, $this->con);
$schedItem = CcScheduleQuery::create()->findPK($id, $this->con); /* We use the selected cursor's position to find the same
$pos = $schedItem->getDbPosition(); * positions in every other linked instance
*/
$pos = $schedItem->getDbPosition();
$ccSchedule = CcScheduleQuery::create() $ccSchedule = CcScheduleQuery::create()
->filterByDbInstanceId($instance->getDbId()) ->filterByDbInstanceId($instance->getDbId())
->filterByDbPosition($pos) ->filterByDbPosition($pos)
->findOne(); ->findOne();
//$schedItemEndDT = $schedItem->getDbEnds(null); //$schedItemEndDT = $schedItem->getDbEnds(null);
$schedItemEndDT = $ccSchedule->getDbEnds(null); $schedItemEndDT = $ccSchedule->getDbEnds(null);
$nextStartDT = $this->findNextStartTime($schedItemEndDT, $instance); $nextStartDT = $this->findNextStartTime($schedItemEndDT, $instance);
$pos++;
}
//selected empty row to add after
else {
//$instance = CcShowInstancesQuery::create()->findPK($schedule["instance"], $this->con);
$showStartDT = $instance->getDbStarts(null);
$nextStartDT = $this->findNextStartTime($showStartDT, $instance);
//show is empty so start position counter at 0
$pos = 0;
}
if (!in_array($instance->getDbId(), $affectedShowInstances)) {
$affectedShowInstances[] = $instance->getDbId();
}
/*
* $adjustSched is true if there are schedule items
* following the item just inserted, per show instance
*/
if ($adjustSched === true) {
$pstart = microtime(true);
$followingSchedItems = CcScheduleQuery::create()
->filterByDBStarts($nextStartDT->format("Y-m-d H:i:s.u"), Criteria::GREATER_EQUAL)
->filterByDbInstanceId($instance->getDbId())
->filterByDbId($excludeIds, Criteria::NOT_IN)
->orderByDbStarts()
->find($this->con);
$pend = microtime(true);
Logging::debug("finding all following items.");
Logging::debug(floatval($pend) - floatval($pstart));
}
foreach ($filesToInsert as $file) {
Logging::info("INSERTING FILE ----- ".$instance->getDbId());
$endTimeDT = $this->findEndTime($nextStartDT, $file['cliplength']);
//item existed previously and is being moved.
//need to keep same id for resources if we want REST.
if (isset($file['sched_id'])) {
$sched = CcScheduleQuery::create()->findPK($file['sched_id'], $this->con);
} else {
$sched = new CcSchedule();
}
// default fades are in seconds
// we need to convert to '00:00:00' format
$file['fadein'] = Application_Common_DateHelper::secondsToPlaylistTime($file['fadein']);
$file['fadeout'] = Application_Common_DateHelper::secondsToPlaylistTime($file['fadeout']);
$sched->setDbStarts($nextStartDT)
->setDbEnds($endTimeDT)
->setDbCueIn($file['cuein'])
->setDbCueOut($file['cueout'])
->setDbFadeIn($file['fadein'])
->setDbFadeOut($file['fadeout'])
->setDbClipLength($file['cliplength'])
->setDbPosition($pos)
->setDbInstanceId($instance->getDbId());
switch ($file["type"]) {
case 0:
$sched->setDbFileId($file['id']);
break;
case 1:
$sched->setDbStreamId($file['id']);
break;
default: break;
}
$sched->save($this->con);
$nextStartDT = $endTimeDT;
$pos++;
}//all files have been inserted/moved
if ($adjustSched === true) {
$pstart = microtime(true);
//recalculate the start/end times after the inserted items.
foreach ($followingSchedItems as $item) {
$endTimeDT = $this->findEndTime($nextStartDT, $item->getDbClipLength());
$item->setDbStarts($nextStartDT);
$item->setDbEnds($endTimeDT);
$item->setDbPosition($pos);
$item->save($this->con);
$nextStartDT = $endTimeDT;
$pos++; $pos++;
} }
//selected empty row to add after
else {
$pend = microtime(true); //$instance = CcShowInstancesQuery::create()->findPK($schedule["instance"], $this->con);
Logging::debug("adjusting all following items.");
Logging::debug(floatval($pend) - floatval($pstart)); $showStartDT = $instance->getDbStarts(null);
} $nextStartDT = $this->findNextStartTime($showStartDT, $instance);
}//for each instance
//show is empty so start position counter at 0
$pos = 0;
}
if (!in_array($instance->getDbId(), $affectedShowInstances)) {
$affectedShowInstances[] = $instance->getDbId();
}
/*
* $adjustSched is true if there are schedule items
* following the item just inserted, per show instance
*/
if ($adjustSched === true) {
$pstart = microtime(true);
$initalStartDT = clone $nextStartDT;
/*$followingSchedItems = CcScheduleQuery::create()
->filterByDBStarts($nextStartDT->format("Y-m-d H:i:s.u"), Criteria::GREATER_EQUAL)
->filterByDbInstanceId($instance->getDbId())
->filterByDbId($excludeIds, Criteria::NOT_IN)
->orderByDbStarts()
->find($this->con);*/
$pend = microtime(true);
Logging::debug("finding all following items.");
Logging::debug(floatval($pend) - floatval($pstart));
}
foreach ($filesToInsert as $file) {
Logging::info("INSERTING AT POSITION --- ".$pos);
//$endTimeDT = $this->findEndTime($nextStartDT, $file['cliplength']);
//item existed previously and is being moved.
//need to keep same id for resources if we want REST.
if (isset($file['sched_id'])) {
//$sched = CcScheduleQuery::create()->findPK($file['sched_id'], $this->con);
$sched = CcScheduleQuery::create()
->filterByDbInstanceId($instance->getDbId())
->filterByDbFileId($file["id"])
->findOne();
$excludeIds[] = intval($sched->getDbId());
$file["cliplength"] = $sched->getDbClipLength();
$file["cuein"] = $sched->getDbCueIn();
$file["cueout"] = $sched->getDbCueOut();
$file["fadein"] = $sched->getDbFadeIn();
$file["fadeout"] = $sched->getDbFadeOut();
} else {
$sched = new CcSchedule();
}
$endTimeDT = $this->findEndTime($nextStartDT, $file['cliplength']);
// default fades are in seconds
// we need to convert to '00:00:00' format
$file['fadein'] = Application_Common_DateHelper::secondsToPlaylistTime($file['fadein']);
$file['fadeout'] = Application_Common_DateHelper::secondsToPlaylistTime($file['fadeout']);
$sched->setDbStarts($nextStartDT)
->setDbEnds($endTimeDT)
->setDbCueIn($file['cuein'])
->setDbCueOut($file['cueout'])
->setDbFadeIn($file['fadein'])
->setDbFadeOut($file['fadeout'])
->setDbClipLength($file['cliplength'])
->setDbPosition($pos)
->setDbInstanceId($instance->getDbId());
switch ($file["type"]) {
case 0:
$sched->setDbFileId($file['id']);
break;
case 1:
$sched->setDbStreamId($file['id']);
break;
default: break;
}
$sched->save($this->con);
$nextStartDT = $endTimeDT;
$pos++;
}//all files have been inserted/moved
/* If we are adjusting start and end times for items
* after the insert location, we need to exclude the
* schedule item we just inserted because it has correct
* start and end times*/
$excludeIds[] = $sched->getDbId();
if ($adjustSched === true) {
$followingSchedItems = CcScheduleQuery::create()
->filterByDBStarts($initalStartDT->format("Y-m-d H:i:s.u"), Criteria::GREATER_EQUAL)
->filterByDbInstanceId($instance->getDbId())
->filterByDbId($excludeIds, Criteria::NOT_IN)
->orderByDbStarts()
->find($this->con);
$pstart = microtime(true);
//recalculate the start/end times after the inserted items.
foreach ($followingSchedItems as $item) {
$endTimeDT = $this->findEndTime($nextStartDT, $item->getDbClipLength());
$item->setDbStarts($nextStartDT);
$item->setDbEnds($endTimeDT);
$item->setDbPosition($pos);
$item->save($this->con);
$nextStartDT = $endTimeDT;
$pos++;
}
$pend = microtime(true);
Logging::debug("adjusting all following items.");
Logging::debug(floatval($pend) - floatval($pstart));
}
}//for each instance
}//for each schedule location }//for each schedule location
@ -648,7 +709,7 @@ class Application_Model_Scheduler
$filesToInsert = array(); $filesToInsert = array();
try { try {
$this->validateRequest($scheduleItems); $this->validateRequest($scheduleItems, true);
/* /*
* create array of arrays * create array of arrays
@ -744,7 +805,7 @@ class Application_Model_Scheduler
$modifiedMap[$showInstanceId] = array($schedId); $modifiedMap[$showInstanceId] = array($schedId);
} }
} }
Logging::info($movedData); //Logging::info($movedData);
//calculate times excluding the to be moved items. //calculate times excluding the to be moved items.
foreach ($modifiedMap as $instance => $schedIds) { foreach ($modifiedMap as $instance => $schedIds) {
$startProfile = microtime(true); $startProfile = microtime(true);

View File

@ -19,6 +19,7 @@ class Application_Model_ShowBuilder
private $contentDT; private $contentDT;
private $epoch_now; private $epoch_now;
private $currentShow; private $currentShow;
private $currentShowId;
private $showInstances = array(); private $showInstances = array();
@ -27,6 +28,7 @@ class Application_Model_ShowBuilder
"footer" => false, "footer" => false,
"empty" => false, "empty" => false,
"allowed" => false, "allowed" => false,
"linked_allowed" => true,
"id" => 0, "id" => 0,
"instance" => "", "instance" => "",
"starts" => "", "starts" => "",
@ -85,6 +87,18 @@ class Application_Model_ShowBuilder
return; return;
} }
if ($this->currentShow) {
$this->currentShowId = $p_item["show_id"];
}
/* If any linked show instance is currently playing
* we have to disable editing, or else the times
* will not make sense for shows scheduled in the future
*/
if ($p_item["linked"] && $p_item["show_id"] == $this->currentShowId) {
$row["linked_allowed"] = false;
}
if ($this->user->canSchedule($p_item["show_id"]) == true) { if ($this->user->canSchedule($p_item["show_id"]) == true) {
$row["allowed"] = true; $row["allowed"] = true;
} }
@ -174,7 +188,7 @@ class Application_Model_ShowBuilder
private function makeHeaderRow($p_item) private function makeHeaderRow($p_item)
{ {
$row = $this->defaultRowArray; $row = $this->defaultRowArray;
$this->isAllowed($p_item, $row); //$this->isAllowed($p_item, $row);
$this->getRowTimestamp($p_item, $row); $this->getRowTimestamp($p_item, $row);
$this->getItemColor($p_item, $row); $this->getItemColor($p_item, $row);
@ -218,6 +232,8 @@ class Application_Model_ShowBuilder
$this->currentShow = false; $this->currentShow = false;
} }
$this->isAllowed($p_item, $row);
$row["header"] = true; $row["header"] = true;
$row["starts"] = $showStartDT->format("Y-m-d H:i"); $row["starts"] = $showStartDT->format("Y-m-d H:i");
$row["startDate"] = $showStartDT->format("Y-m-d"); $row["startDate"] = $showStartDT->format("Y-m-d");

View File

@ -133,4 +133,39 @@ class CcShow extends BaseCcShow {
{ {
return $this->getDbLinked(); return $this->getDbLinked();
} }
/**
* Gets an array of CcShowInstances objects which contain a foreign key that references this object.
*
* If the $criteria is not null, it is used to always fetch the results from the database.
* Otherwise the results are fetched from the database the first time, then cached.
* Next time the same method is called without $criteria, the cached collection is returned.
* If this CcShow is new, it will return
* an empty collection or the current collection; the criteria is ignored on a new object.
*
* @param Criteria $criteria optional Criteria object to narrow the query
* @param PropelPDO $con optional connection object
* @return PropelCollection|array CcShowInstances[] List of CcShowInstances objects
* @throws PropelException
*/
public function getCcShowInstancess($criteria = null, PropelPDO $con = null)
{
if(null === $this->collCcShowInstancess || null !== $criteria) {
if ($this->isNew() && null === $this->collCcShowInstancess) {
// return empty collection
$this->initCcShowInstancess();
} else {
$collCcShowInstancess = CcShowInstancesQuery::create(null, $criteria)
->filterByCcShow($this)
->filterByDbModifiedInstance(false)
->orderByDbId()
->find($con);
if (null !== $criteria) {
return $collCcShowInstancess;
}
$this->collCcShowInstancess = $collCcShowInstancess;
}
}
return $this->collCcShowInstancess;
}
} // CcShow } // CcShow

View File

@ -170,7 +170,6 @@ var AIRTIME = (function(AIRTIME){
}; };
mod.checkToolBarIcons = function() { mod.checkToolBarIcons = function() {
AIRTIME.library.checkAddButton(); AIRTIME.library.checkAddButton();
mod.checkSelectButton(); mod.checkSelectButton();
mod.checkTrimButton(); mod.checkTrimButton();
@ -297,7 +296,6 @@ var AIRTIME = (function(AIRTIME){
}; };
mod.fnAdd = function(aMediaIds, aSchedIds) { mod.fnAdd = function(aMediaIds, aSchedIds) {
mod.disableUI(); mod.disableUI();
$.post(baseUrl+"showbuilder/schedule-add", $.post(baseUrl+"showbuilder/schedule-add",
@ -644,7 +642,7 @@ var AIRTIME = (function(AIRTIME){
//save some info for reordering purposes. //save some info for reordering purposes.
$nRow.data({"aData": aData}); $nRow.data({"aData": aData});
if (aData.scheduled === 1) { if (aData.scheduled === 1) {
$nRow.addClass(NOW_PLAYING_CLASS); $nRow.addClass(NOW_PLAYING_CLASS);
} }
@ -655,7 +653,7 @@ var AIRTIME = (function(AIRTIME){
$nRow.addClass("sb-future"); $nRow.addClass("sb-future");
} }
if (aData.allowed !== true) { if (aData.allowed !== true || aData.linked_allowed === false) {
$nRow.addClass("sb-not-allowed"); $nRow.addClass("sb-not-allowed");
} }
else { else {