CC-5405: When editing a single show instance from a repeating series, should not create a new cc_show

- Fixed resizing repeating shows to not include edited instances
- Fixed context menu on repeating shows with edited instances
- Fixed populated the show form when editing a single instance
This commit is contained in:
drigato 2013-12-02 07:19:31 -05:00
parent 6f9254e655
commit b4f016681e
4 changed files with 146 additions and 27 deletions

View File

@ -184,16 +184,84 @@ SQL;
$nowDateTime = new DateTime("now", $utc); $nowDateTime = new DateTime("now", $utc);
$showInstances = CcShowInstancesQuery::create() //keep track of cc_show_day entries we need to update
->filterByDbShowId($this->_showId) $showDayIds = array();
->find($con);
/*
* If the resized show is an edited instance of a repeating show we
* need to treat it as a separate show and not resize the other instances
*
* Also, if the resized show has edited instances, we need to exclude
* those from the resize
*/
$ccShow = CcShowQuery::create()->findPk($this->_showId);
if ($ccShow->isRepeating()) {
//convert instance to local timezone
$ccShowInstance = CcShowInstancesQuery::create()->findPk($instanceId);
$startsDT = new DateTime($ccShowInstance->getDbStarts(),
new DateTimeZone("UTC"));
$timezone = $ccShow->getFirstCcShowDay()->getDbTimezone();
$startsDT->setTimezone(new DateTimeZone($timezone));
/* Get cc_show_day for the current instance. If we don't find one
* we know it is a repeat interval of one of cc_show_days first
* show and we can assume we aren't resizing a modified instance
*/
$ccShowDay = CcShowDaysQuery::create()
->filterByDbFirstShow($startsDT->format("Y-m-d"))
->filterByDbStartTime($startsDT->format("H:i:s"))
->filterByDbShowId($this->_showId)
->findOne();
/* Check if this cc_show_day rule is non-repeating. If it is, then
* we know this instance was edited out of the repeating sequence
*/
if (!$ccShowDay || $ccShowDay->getDbRepeatType() != -1) {
$ccShowDays = $ccShow->getRepeatingCcShowDays();
foreach ($ccShowDays as $day) {
array_push($showDayIds, $day->getDbId());
}
$excludeIds = $ccShow->getEditedRepeatingInstanceIds();
//exlcude edited instances from resize
$showInstances = CcShowInstancesQuery::create()
->filterByDbShowId($this->_showId)
->filterByDbModifiedInstance(false)
->filterByDbId($excludeIds, criteria::NOT_IN)
->find();
} elseif ($ccShowDay->getDbRepeatType() == -1) {
array_push($showDayIds, $ccShowDay->getDbId());
//treat edited instance as separate show for resize
$showInstances = CcShowInstancesQuery::create()
->filterByDbId($instanceId)
->find();
}
} else {
$ccShowDays = $ccShow->getCcShowDayss();
foreach ($ccShowDays as $day) {
array_push($showDayIds, $day->getDbId());
}
$showInstances = CcShowInstancesQuery::create()
->filterByDbShowId($this->_showId)
->find($con);
}
/* Check two things: /* Check two things:
1. If the show being resized and any of its repeats end in the past 1. If the show being resized and any of its repeats end in the past
2. If the show being resized and any of its repeats overlap 2. If the show being resized and any of its repeats overlap
with other scheduled shows */ with other scheduled shows */
//keep track of instance ids for update show instances start/end times
$instanceIds = array();
//check if new show time overlaps with any other shows
foreach ($showInstances as $si) { foreach ($showInstances as $si) {
array_push($instanceIds, $si->getDbId());
$startsDateTime = new DateTime($si->getDbStarts(), new DateTimeZone("UTC")); $startsDateTime = new DateTime($si->getDbStarts(), new DateTimeZone("UTC"));
$endsDateTime = new DateTime($si->getDbEnds(), new DateTimeZone("UTC")); $endsDateTime = new DateTime($si->getDbEnds(), new DateTimeZone("UTC"));
@ -204,19 +272,19 @@ SQL;
$startsDateTime->setTimezone(new DateTimeZone(date_default_timezone_get())); $startsDateTime->setTimezone(new DateTimeZone(date_default_timezone_get()));
$endsDateTime->setTimezone(new DateTimeZone(date_default_timezone_get())); $endsDateTime->setTimezone(new DateTimeZone(date_default_timezone_get()));
$newStartsDateTime = Application_Model_ShowInstance::addDeltas($startsDateTime, $deltaDay, $deltaMin); //$newStartsDateTime = Application_Model_ShowInstance::addDeltas($startsDateTime, $deltaDay, $deltaMin);
$newEndsDateTime = Application_Model_ShowInstance::addDeltas($endsDateTime, $deltaDay, $deltaMin); $newEndsDateTime = Application_Model_ShowInstance::addDeltas($endsDateTime, $deltaDay, $deltaMin);
if ($newEndsDateTime->getTimestamp() < $nowDateTime->getTimestamp()) { if ($newEndsDateTime->getTimestamp() < $nowDateTime->getTimestamp()) {
return _("End date/time cannot be in the past"); return _("End date/time cannot be in the past");
} }
//convert our new starts/ends to UTC. //convert our new starts/ends to UTC.
$newStartsDateTime->setTimezone($utc); //$newStartsDateTime->setTimezone($utc);
$newEndsDateTime->setTimezone($utc); $newEndsDateTime->setTimezone($utc);
$overlapping = Application_Model_Schedule::checkOverlappingShows( $overlapping = Application_Model_Schedule::checkOverlappingShows(
$newStartsDateTime, $newEndsDateTime, true, $si->getDbId()); $startsDateTime, $newEndsDateTime, true, $si->getDbId());
if ($overlapping) { if ($overlapping) {
return _("Cannot schedule overlapping shows.\nNote: Resizing a repeating show ". return _("Cannot schedule overlapping shows.\nNote: Resizing a repeating show ".
@ -231,36 +299,30 @@ SQL;
//current timesamp in UTC. //current timesamp in UTC.
$current_timestamp = gmdate("Y-m-d H:i:s"); $current_timestamp = gmdate("Y-m-d H:i:s");
$sql_gen = <<<SQL $sql_gen = "UPDATE cc_show_instances ".
UPDATE cc_show_instances "SET ends = (ends + :deltaDay1::INTERVAL + :interval1::INTERVAL) ".
SET ends = (ends + :deltaDay1::INTERVAL + :interval1::INTERVAL) "WHERE (id IN (".implode($instanceIds, ",").") ".
WHERE (show_id = :show_id1 "AND ends > :current_timestamp1) ".
AND ends > :current_timestamp1) "AND ((ends + :deltaDay2::INTERVAL + :interval2::INTERVAL - starts) <= interval '24:00')";
AND ((ends + :deltaDay2::INTERVAL + :interval2::INTERVAL - starts) <= interval '24:00')
SQL;
Application_Common_Database::prepareAndExecute($sql_gen, Application_Common_Database::prepareAndExecute($sql_gen,
array( array(
':deltaDay1' => "$deltaDay days", ':deltaDay1' => "$deltaDay days",
':interval1' => "$hours:$mins", ':interval1' => "$hours:$mins",
':show_id1' => $this->_showId,
':current_timestamp1' => $current_timestamp, ':current_timestamp1' => $current_timestamp,
':deltaDay2' => "$deltaDay days", ':deltaDay2' => "$deltaDay days",
':interval2' => "$hours:$mins" ':interval2' => "$hours:$mins"
), "execute"); ), "execute");
$sql_gen = <<<SQL $sql_gen = "UPDATE cc_show_days ".
UPDATE cc_show_days "SET duration = (CAST(duration AS interval) + :deltaDay3::INTERVAL + :interval3::INTERVAL) ".
SET duration = (CAST(duration AS interval) + :deltaDay3::INTERVAL + :interval3::INTERVAL) "WHERE id IN (".implode($showDayIds, ",").") ".
WHERE show_id = :show_id2 "AND ((CAST(duration AS interval) + :deltaDay4::INTERVAL + :interval4::INTERVAL) <= interval '24:00')";
AND ((CAST(duration AS interval) + :deltaDay4::INTERVAL + :interval4::INTERVAL) <= interval '24:00')
SQL;
Application_Common_Database::prepareAndExecute($sql_gen, Application_Common_Database::prepareAndExecute($sql_gen,
array( array(
':deltaDay3' => "$deltaDay days", ':deltaDay3' => "$deltaDay days",
':interval3' => "$hours:$mins", ':interval3' => "$hours:$mins",
':show_id2' => $this->_showId,
':deltaDay4' => "$deltaDay days", ':deltaDay4' => "$deltaDay days",
':interval4' => "$hours:$mins" ':interval4' => "$hours:$mins"
), "execute"); ), "execute");
@ -279,7 +341,7 @@ SQL;
$instances = CcShowInstancesQuery::create() $instances = CcShowInstancesQuery::create()
->filterByDbEnds($current_timestamp, Criteria::GREATER_THAN) ->filterByDbEnds($current_timestamp, Criteria::GREATER_THAN)
->filterByDbShowId($this->_showId) ->filterByDbId($instanceIds, Criteria::IN)
->find($con); ->find($con);
foreach ($instances as $instance) { foreach ($instances as $instance) {

View File

@ -109,6 +109,44 @@ class CcShow extends BaseCcShow {
return false; return false;
} }
/**
* Returns all cc_show_instances that have been edited out of
* a repeating sequence
*/
public function getEditedRepeatingInstanceIds()
{
//get cc_show_days that have been edited (not repeating)
$ccShowDays = CcShowDaysQuery::create()
->filterByDbShowId($this->id)
->filterByDbRepeatType(-1)
->find();
$startsUTC = array();
$utc = new DateTimeZone("UTC");
foreach ($ccShowDays as $day) {
//convert to UTC
$starts = new DateTime(
$day->getDbFirstShow()." ".$day->getDbStartTime(),
new DateTimeZone($day->getDbTimezone())
);
$starts->setTimezone($utc);
array_push($startsUTC, $starts->format("Y-m-d H:i:s"));
}
$excludeInstances = CcShowInstancesQuery::create()
->filterByDbShowId($this->id)
->filterByDbStarts($startsUTC, criteria::IN)
->find();
$excludeIds = array();
foreach ($excludeInstances as $instance) {
array_push($excludeIds, $instance->getDbId());
}
return $excludeIds;
}
/** /**
* Gets an array of CcShowInstances objects which contain a foreign key that references this object. * Gets an array of CcShowInstances objects which contain a foreign key that references this object.
* *

View File

@ -126,7 +126,15 @@ class Application_Service_CalendarService
} }
} }
$isRepeating = $this->ccShow->getFirstCcShowDay()->isRepeating(); $excludeIds = $this->ccShow->getEditedRepeatingInstanceIds();
$isRepeating = true;
$populateInstance = false;
if (in_array($this->ccShowInstance->getDbId(), $excludeIds)) {
$populateInstance = true;
$isRepeating = false;
}
if (!$this->ccShowInstance->isRebroadcast() && $isAdminOrPM) { if (!$this->ccShowInstance->isRebroadcast() && $isAdminOrPM) {
if ($isRepeating) { if ($isRepeating) {
$menu["edit"] = array( $menu["edit"] = array(
@ -143,6 +151,7 @@ class Application_Service_CalendarService
"name" => _("Edit This Instance"), "name" => _("Edit This Instance"),
"icon" => "edit", "icon" => "edit",
"url" => $baseUrl."Schedule/populate-repeating-show-instance-form"); "url" => $baseUrl."Schedule/populate-repeating-show-instance-form");
} else { } else {
$menu["edit"] = array( $menu["edit"] = array(
"name"=> _("Edit Show"), "name"=> _("Edit Show"),

View File

@ -159,7 +159,11 @@ class Application_Service_ShowService
*/ */
private function storeOrigLocalShowInfo() private function storeOrigLocalShowInfo()
{ {
$this->origCcShowDay = $this->ccShow->getFirstRepeatingCcShowDay(); if ($this->ccShow->isRepeating()) {
$this->origCcShowDay = $this->ccShow->getFirstRepeatingCcShowDay();
} else {
$this->origCcShowDay = $this->ccShow->getFirstCcShowDay();
}
$this->oldShowTimezone = $this->origCcShowDay->getDbTimezone(); $this->oldShowTimezone = $this->origCcShowDay->getDbTimezone();
@ -404,7 +408,11 @@ SQL;
$daysAdded = array(); $daysAdded = array();
//CcShowDay object //CcShowDay object
$currentShowDay = $this->ccShow->getFirstRepeatingCcShowDay(); if ($this->ccShow->isRepeating()) {
$currentShowDay = $this->ccShow->getFirstRepeatingCcShowDay();
} else {
$currentShowDay = $this->ccShow->getFirstCcShowDay();
}
//new end date in users' local time //new end date in users' local time
$endDateTime = $this->calculateEndDate($showData); $endDateTime = $this->calculateEndDate($showData);
@ -1387,6 +1395,8 @@ SQL;
*/ */
private function setCcShowDays($showData) private function setCcShowDays($showData)
{ {
Logging::info($showData);
Logging::info($this->repeatType);
$showId = $this->ccShow->getDbId(); $showId = $this->ccShow->getDbId();
$startDateTime = new DateTime($showData['add_show_start_date']." ".$showData['add_show_start_time']); $startDateTime = new DateTime($showData['add_show_start_date']." ".$showData['add_show_start_time']);
@ -1451,7 +1461,7 @@ SQL;
if ($this->isUpdate) { if ($this->isUpdate) {
$showDay = CcShowDaysQuery::create() $showDay = CcShowDaysQuery::create()
->filterByDbShowId($showId) ->filterByDbShowId($showId)
->filterByDbRepeatType($showData['add_show_repeat_type']) ->filterByDbRepeatType($this->repeatType)
->filterByDbDay($day) ->filterByDbDay($day)
->findOne(); ->findOne();
if (!$showDay) { if (!$showDay) {