2012-01-27 21:06:04 +01:00
|
|
|
<?php
|
|
|
|
|
2017-03-22 12:26:18 +01:00
|
|
|
final class Application_Model_Scheduler
|
2012-07-16 03:17:13 +02:00
|
|
|
{
|
2012-01-31 18:59:27 +01:00
|
|
|
private $con;
|
2021-10-11 16:10:47 +02:00
|
|
|
private $fileInfo = [
|
|
|
|
'id' => '',
|
|
|
|
'cliplength' => '',
|
|
|
|
'cuein' => '00:00:00',
|
|
|
|
'cueout' => '00:00:00',
|
|
|
|
'fadein' => '00:00:00',
|
|
|
|
'fadeout' => '00:00:00',
|
|
|
|
'sched_id' => null,
|
2022-03-14 11:15:04 +01:00
|
|
|
'type' => 0, // default type of '0' to represent files. type '1' represents a webstream
|
2021-10-11 16:10:47 +02:00
|
|
|
];
|
2012-07-11 00:51:32 +02:00
|
|
|
|
2012-03-29 19:20:02 +02:00
|
|
|
private $epochNow;
|
2012-03-28 10:50:02 +02:00
|
|
|
private $nowDT;
|
2012-03-28 14:23:25 +02:00
|
|
|
private $user;
|
2013-06-24 17:09:03 +02:00
|
|
|
|
2013-05-02 22:15:21 +02:00
|
|
|
private $crossfadeDuration;
|
2013-10-10 18:11:23 +02:00
|
|
|
private $applyCrossfades = true;
|
2012-07-11 00:51:32 +02:00
|
|
|
|
2012-04-12 18:00:38 +02:00
|
|
|
private $checkUserPermissions = true;
|
2012-01-27 21:06:04 +01:00
|
|
|
|
2021-10-11 16:10:47 +02:00
|
|
|
public function __construct($checkUserPermissions = true)
|
2012-07-16 03:17:13 +02:00
|
|
|
{
|
2012-02-02 23:15:39 +01:00
|
|
|
$this->con = Propel::getConnection(CcSchedulePeer::DATABASE_NAME);
|
2012-07-11 00:51:32 +02:00
|
|
|
|
2022-03-14 11:15:04 +01:00
|
|
|
// subtracting one because sometimes when we cancel a track, we set its end time
|
|
|
|
// to epochNow and then send the new schedule to pypo. Sometimes the currently cancelled
|
|
|
|
// track can still be included in the new schedule because it may have a few ms left to play.
|
|
|
|
// subtracting 1 second from epochNow resolves this issue.
|
2021-10-11 16:10:47 +02:00
|
|
|
$this->epochNow = microtime(true) - 1;
|
|
|
|
$this->nowDT = DateTime::createFromFormat('U.u', $this->epochNow, new DateTimeZone('UTC'));
|
2012-07-11 00:51:32 +02:00
|
|
|
|
2012-07-16 03:17:13 +02:00
|
|
|
if ($this->nowDT === false) {
|
2012-05-06 21:34:41 +02:00
|
|
|
// DateTime::createFromFormat does not support millisecond string formatting in PHP 5.3.2 (Ubuntu 10.04).
|
|
|
|
// In PHP 5.3.3 (Ubuntu 10.10), this has been fixed.
|
2021-10-11 16:10:47 +02:00
|
|
|
$this->nowDT = DateTime::createFromFormat('U', time(), new DateTimeZone('UTC'));
|
2012-07-11 00:51:32 +02:00
|
|
|
}
|
|
|
|
|
2017-03-22 12:26:18 +01:00
|
|
|
$this->setCheckUserPermissions($checkUserPermissions);
|
|
|
|
|
|
|
|
if ($this->checkUserPermissions) {
|
|
|
|
$this->user = Application_Model_User::getCurrentUser();
|
|
|
|
}
|
2013-06-24 17:09:03 +02:00
|
|
|
|
2013-05-02 22:15:21 +02:00
|
|
|
$this->crossfadeDuration = Application_Model_Preference::GetDefaultCrossfadeDuration();
|
2012-03-28 14:23:25 +02:00
|
|
|
}
|
2012-07-11 00:51:32 +02:00
|
|
|
|
2012-07-16 03:17:13 +02:00
|
|
|
public function setCheckUserPermissions($value)
|
|
|
|
{
|
2012-04-12 18:00:38 +02:00
|
|
|
$this->checkUserPermissions = $value;
|
|
|
|
}
|
2012-07-11 00:51:32 +02:00
|
|
|
|
2013-04-26 22:10:01 +02:00
|
|
|
private function validateItemMove($itemsToMove, $destination)
|
2013-04-12 22:34:36 +02:00
|
|
|
{
|
2021-10-11 16:10:47 +02:00
|
|
|
$destinationInstanceId = $destination['instance'];
|
2013-04-26 22:10:01 +02:00
|
|
|
$destinationCcShowInstance = CcShowInstancesQuery::create()
|
2022-01-23 19:15:55 +01:00
|
|
|
->findPk($destinationInstanceId);
|
2013-04-26 22:10:01 +02:00
|
|
|
$isDestinationLinked = $destinationCcShowInstance->getCcShow()->isLinked();
|
2013-04-12 22:34:36 +02:00
|
|
|
|
|
|
|
foreach ($itemsToMove as $itemToMove) {
|
2021-10-11 16:10:47 +02:00
|
|
|
$sourceInstanceId = $itemToMove['instance'];
|
2013-04-12 22:34:36 +02:00
|
|
|
$ccShowInstance = CcShowInstancesQuery::create()
|
2022-01-23 19:15:55 +01:00
|
|
|
->findPk($sourceInstanceId);
|
2013-04-18 22:12:26 +02:00
|
|
|
|
2022-03-14 11:15:04 +01:00
|
|
|
// does the item being moved belong to a linked show
|
2013-04-26 22:10:01 +02:00
|
|
|
$isSourceLinked = $ccShowInstance->getCcShow()->isLinked();
|
2013-04-12 22:34:36 +02:00
|
|
|
|
2013-04-29 21:27:14 +02:00
|
|
|
if ($isDestinationLinked && !$isSourceLinked) {
|
2021-10-11 16:10:47 +02:00
|
|
|
throw new Exception('Cannot move items into linked shows');
|
|
|
|
}
|
|
|
|
if (!$isDestinationLinked && $isSourceLinked) {
|
|
|
|
throw new Exception('Cannot move items out of linked shows');
|
|
|
|
}
|
|
|
|
if ($isSourceLinked && $sourceInstanceId != $destinationInstanceId) {
|
|
|
|
throw new Exception(_('Cannot move items out of linked shows'));
|
2013-04-29 21:27:14 +02:00
|
|
|
}
|
2013-04-12 22:34:36 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-07-16 03:17:13 +02:00
|
|
|
/*
|
2017-03-21 20:02:31 +01:00
|
|
|
* make sure any incoming requests for scheduling are legit.
|
2012-07-16 03:17:13 +02:00
|
|
|
*
|
|
|
|
* @param array $items, an array containing pks of cc_schedule items.
|
|
|
|
*/
|
2021-10-11 16:10:47 +02:00
|
|
|
private function validateRequest($items, $addRemoveAction = false, $cancelShow = false)
|
2012-07-16 03:17:13 +02:00
|
|
|
{
|
2022-03-14 11:15:04 +01:00
|
|
|
// $items is where tracks get inserted (they are schedule locations)
|
2013-04-18 22:12:26 +02:00
|
|
|
|
2021-10-11 16:10:47 +02:00
|
|
|
$nowEpoch = floatval($this->nowDT->format('U.u'));
|
2012-07-11 00:51:32 +02:00
|
|
|
|
2021-10-11 16:10:47 +02:00
|
|
|
$schedInfo = [];
|
|
|
|
$instanceInfo = [];
|
2013-05-28 23:30:48 +02:00
|
|
|
|
2021-10-11 16:10:47 +02:00
|
|
|
for ($i = 0; $i < count($items); ++$i) {
|
|
|
|
$id = $items[$i]['id'];
|
2012-07-11 00:51:32 +02:00
|
|
|
|
2022-03-14 11:15:04 +01:00
|
|
|
// could be added to the beginning of a show, which sends id = 0;
|
2012-03-28 14:23:25 +02:00
|
|
|
if ($id > 0) {
|
2022-03-14 11:15:04 +01:00
|
|
|
// schedule_id of where we are inserting after?
|
2021-10-11 16:10:47 +02:00
|
|
|
$schedInfo[$id] = $items[$i]['instance'];
|
2012-03-28 14:23:25 +02:00
|
|
|
}
|
|
|
|
|
2022-03-14 11:15:04 +01:00
|
|
|
// format is instance_id => timestamp
|
2021-10-11 16:10:47 +02:00
|
|
|
$instanceInfo[$items[$i]['instance']] = $items[$i]['timestamp'];
|
2012-03-28 14:23:25 +02:00
|
|
|
}
|
2012-07-11 00:51:32 +02:00
|
|
|
|
2012-03-28 14:23:25 +02:00
|
|
|
if (count($instanceInfo) === 0) {
|
2021-10-11 16:10:47 +02:00
|
|
|
throw new Exception('Invalid Request.');
|
2012-03-28 14:23:25 +02:00
|
|
|
}
|
2012-07-11 00:51:32 +02:00
|
|
|
|
2021-10-11 16:10:47 +02:00
|
|
|
$schedIds = [];
|
2013-05-28 23:30:48 +02:00
|
|
|
if (count($schedInfo) > 0) {
|
2012-03-28 18:43:44 +02:00
|
|
|
$schedIds = array_keys($schedInfo);
|
|
|
|
}
|
2012-03-28 14:23:25 +02:00
|
|
|
$schedItems = CcScheduleQuery::create()->findPKs($schedIds, $this->con);
|
|
|
|
$instanceIds = array_keys($instanceInfo);
|
|
|
|
$showInstances = CcShowInstancesQuery::create()->findPKs($instanceIds, $this->con);
|
2012-07-11 00:51:32 +02:00
|
|
|
|
2022-03-14 11:15:04 +01:00
|
|
|
// an item has been deleted
|
2012-07-16 03:17:13 +02:00
|
|
|
if (count($schedIds) !== count($schedItems)) {
|
2012-11-15 21:52:51 +01:00
|
|
|
throw new OutDatedScheduleException(_("The schedule you're viewing is out of date! (sched mismatch)"));
|
2012-03-28 14:23:25 +02:00
|
|
|
}
|
2012-07-11 00:51:32 +02:00
|
|
|
|
2022-03-14 11:15:04 +01:00
|
|
|
// a show has been deleted
|
2015-10-26 20:55:03 +01:00
|
|
|
if (count($instanceIds) !== count($showInstances)) {
|
2012-11-15 21:52:51 +01:00
|
|
|
throw new OutDatedScheduleException(_("The schedule you're viewing is out of date! (instance mismatch)"));
|
2012-03-28 14:23:25 +02:00
|
|
|
}
|
2012-07-11 00:51:32 +02:00
|
|
|
|
2012-03-28 14:23:25 +02:00
|
|
|
foreach ($schedItems as $schedItem) {
|
|
|
|
$id = $schedItem->getDbId();
|
|
|
|
$instance = $schedItem->getCcShowInstances($this->con);
|
2012-07-11 00:51:32 +02:00
|
|
|
|
2012-07-16 03:17:13 +02:00
|
|
|
if (intval($schedInfo[$id]) !== $instance->getDbId()) {
|
2012-11-15 21:52:51 +01:00
|
|
|
throw new OutDatedScheduleException(_("The schedule you're viewing is out of date!"));
|
2012-03-28 14:23:25 +02:00
|
|
|
}
|
|
|
|
}
|
2012-07-11 00:51:32 +02:00
|
|
|
|
2012-03-28 14:23:25 +02:00
|
|
|
foreach ($showInstances as $instance) {
|
|
|
|
$id = $instance->getDbId();
|
|
|
|
$show = $instance->getCcShow($this->con);
|
2012-07-11 00:51:32 +02:00
|
|
|
|
2012-07-16 03:17:13 +02:00
|
|
|
if ($this->checkUserPermissions && $this->user->canSchedule($show->getDbId()) === false) {
|
2021-10-11 16:10:47 +02:00
|
|
|
throw new Exception(sprintf(_('You are not allowed to schedule show %s.'), $show->getDbName()));
|
2012-03-28 14:23:25 +02:00
|
|
|
}
|
2013-04-18 22:12:26 +02:00
|
|
|
|
2012-11-02 18:24:47 +01:00
|
|
|
if ($instance->getDbRecord()) {
|
2021-10-11 16:10:47 +02:00
|
|
|
throw new Exception(_('You cannot add files to recording shows.'));
|
2012-11-02 18:24:47 +01:00
|
|
|
}
|
2012-07-11 00:51:32 +02:00
|
|
|
|
2021-10-11 16:10:47 +02:00
|
|
|
$showEndEpoch = floatval($instance->getDbEnds('U.u'));
|
2012-07-16 03:17:13 +02:00
|
|
|
|
|
|
|
if ($showEndEpoch < $nowEpoch) {
|
2021-10-11 16:10:47 +02:00
|
|
|
throw new OutDatedScheduleException(sprintf(_('The show %s is over and cannot be scheduled.'), $show->getDbName()));
|
2012-03-28 14:23:25 +02:00
|
|
|
}
|
2012-07-11 00:51:32 +02:00
|
|
|
|
2012-04-02 15:20:13 +02:00
|
|
|
$ts = intval($instanceInfo[$id]);
|
2021-10-11 16:10:47 +02:00
|
|
|
$lastSchedTs = intval($instance->getDbLastScheduled('U')) ?: 0;
|
2012-04-02 15:20:13 +02:00
|
|
|
if ($ts < $lastSchedTs) {
|
2012-08-22 00:41:56 +02:00
|
|
|
Logging::info("ts {$ts} last sched {$lastSchedTs}");
|
2021-10-11 16:10:47 +02:00
|
|
|
|
|
|
|
throw new OutDatedScheduleException(sprintf(_('The show %s has been previously updated!'), $show->getDbName()));
|
2012-03-28 14:23:25 +02:00
|
|
|
}
|
2013-04-18 22:12:26 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Does the afterItem belong to a show that is linked AND
|
|
|
|
* currently playing?
|
|
|
|
* If yes, throw an exception
|
2019-04-23 04:47:37 +02:00
|
|
|
* unless it is a cancel show action then we don't check because otherwise
|
|
|
|
* ongoing linked shows can't be cancelled
|
2013-04-18 22:12:26 +02:00
|
|
|
*/
|
2019-04-23 04:47:37 +02:00
|
|
|
if ($addRemoveAction && !$cancelShow) {
|
2013-04-18 22:12:26 +02:00
|
|
|
$ccShow = $instance->getCcShow();
|
|
|
|
if ($ccShow->isLinked()) {
|
2022-03-14 11:15:04 +01:00
|
|
|
// get all the linked shows instances and check if
|
|
|
|
// any of them are currently playing
|
2013-04-18 22:12:26 +02:00
|
|
|
$ccShowInstances = $ccShow->getCcShowInstancess();
|
2015-06-26 20:42:52 +02:00
|
|
|
$timeNowUTC = gmdate(DEFAULT_TIMESTAMP_FORMAT);
|
2013-04-18 22:12:26 +02:00
|
|
|
foreach ($ccShowInstances as $ccShowInstance) {
|
2022-07-07 20:01:15 +02:00
|
|
|
if (
|
|
|
|
$ccShowInstance->getDbStarts() <= $timeNowUTC
|
|
|
|
&& $ccShowInstance->getDbEnds() > $timeNowUTC
|
|
|
|
) {
|
2021-10-11 16:10:47 +02:00
|
|
|
throw new Exception(_('Content in linked shows cannot be changed while on air!'));
|
2013-04-18 22:12:26 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2012-07-16 03:17:13 +02:00
|
|
|
}
|
2012-01-27 21:06:04 +01:00
|
|
|
}
|
2021-10-11 16:10:47 +02:00
|
|
|
|
2014-05-30 23:11:12 +02:00
|
|
|
private function validateMediaItems($mediaItems)
|
|
|
|
{
|
2021-10-11 16:10:47 +02:00
|
|
|
foreach ($mediaItems as $mediaItem) {
|
|
|
|
$id = $mediaItem['id'];
|
|
|
|
if ($mediaItem['type'] === 'playlist') {
|
2014-05-30 23:11:12 +02:00
|
|
|
$playlist = new Application_Model_Playlist($id, $this->con);
|
|
|
|
if ($playlist->containsMissingFiles()) {
|
2021-10-11 16:10:47 +02:00
|
|
|
throw new Exception(_('Cannot schedule a playlist that contains missing files.'));
|
2014-05-30 23:11:12 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-10-11 16:10:47 +02:00
|
|
|
|
2014-05-30 23:11:12 +02:00
|
|
|
return true;
|
|
|
|
}
|
2012-01-27 21:06:04 +01:00
|
|
|
|
|
|
|
/*
|
2012-01-31 18:59:27 +01:00
|
|
|
* @param $id
|
|
|
|
* @param $type
|
2018-11-24 23:08:39 +01:00
|
|
|
* @param $show
|
2012-01-31 18:59:27 +01:00
|
|
|
*
|
|
|
|
* @return $files
|
|
|
|
*/
|
2018-11-24 23:08:39 +01:00
|
|
|
private function retrieveMediaFiles($id, $type, $show)
|
2012-07-16 03:17:13 +02:00
|
|
|
{
|
2019-04-22 21:26:09 +02:00
|
|
|
// if there is a show we need to set a show limit to pass to smart blocks in case they use time remaining
|
|
|
|
$showInstance = new Application_Model_ShowInstance($show);
|
|
|
|
$showLimit = $showInstance->getSecondsRemaining();
|
fix: playlist allocates inaccurate time to smartblocks (#3026)
### Description
In the existing logic of `retrieveMediaFiles`, the time remaining in
show is calculated incorrectly in some scenarios. Each time a duration
is subtracted from `showLimit`, it is not the duration of the files just
added, but instead the length of all files scheduled. This can cause
cases where a smart block set to "time remaining in show" fails to
completely fill the program.
For example, given a 30 minute show, and a playlist like follows:
1. a 5 minute track
2. another 5 minute track
3. smart block, set to time remaining in show
When item 1 is added, `showLimit` is reduced by 5 minutes as expected.
When item 2 is added, `showLimit` is reduced by 10 minutes (as both
items 1 and 2 are counted). As a result, the smart block is only run to
fill 15 minutes, leaving 5 minutes unfilled.
This PR resolves this issue, by recalculating `showLimit` from the
original duration rather than subtracting from a running total.
This change not does implement a new feature and should not require any
changes to documentation.
### Testing Notes
**What I did:**
- On a dev environment, set up a playlist as described above.
- Before applying this PR, created a show and scheduled playlist, and
confirmed issue was reproducible
- Applied PR and repeated, and confirmed show was filled completely.
Also repeated this testing with sample data from our production
instance.
Here is a sample schedule of the "before" case with sample data, showing
the issue

The smartblock that scheduled the music is set to allow last track to
overflow, but 3m55s was left unscheduled.
Using the same playlist and same track library, here is a sample
schedule after the PR applied:

As expected, the show is fully scheduled with the last track
overflowing.
Additionally, I've applied this PR as a hot fix to our production
instance, where it has been running for a week without issue.
Also performed spot tests of playlists without smart blocks, smart
blocks scheduled directly (not in playlists) and autoloading playlists,
with no change in behaviour observed as a result of this change.
**How you can replicate my testing:**
Same test steps as I followed should be able to reproduce issue &
validate fix on any instance.
### **Links**
Not directly related to issue fixed by #3019, but also addresses the
issue of dead air left at end of blocks.
Co-authored-by: Kyle Robbertze <paddatrapper@users.noreply.github.com>
2024-06-05 18:01:57 +02:00
|
|
|
$originalShowLimit = $showLimit;
|
2019-04-22 21:26:09 +02:00
|
|
|
|
2021-10-11 16:10:47 +02:00
|
|
|
$files = [];
|
|
|
|
if ($type === 'audioclip') {
|
2012-02-02 23:15:39 +01:00
|
|
|
$file = CcFilesQuery::create()->findPK($id, $this->con);
|
2012-01-31 18:59:27 +01:00
|
|
|
|
2012-11-05 16:57:18 +01:00
|
|
|
if (is_null($file) || !$file->visible()) {
|
2021-10-11 16:10:47 +02:00
|
|
|
throw new Exception(_('A selected File does not exist!'));
|
|
|
|
}
|
|
|
|
$data = $this->fileInfo;
|
|
|
|
$data['id'] = $id;
|
2013-06-24 17:09:03 +02:00
|
|
|
|
2021-10-11 16:10:47 +02:00
|
|
|
$cuein = Application_Common_DateHelper::playlistTimeToSeconds($file->getDbCuein());
|
|
|
|
$cueout = Application_Common_DateHelper::playlistTimeToSeconds($file->getDbCueout());
|
|
|
|
$row_length = Application_Common_DateHelper::secondsToPlaylistTime($cueout - $cuein);
|
2013-06-24 17:09:03 +02:00
|
|
|
|
2021-10-11 16:10:47 +02:00
|
|
|
$data['cliplength'] = $row_length;
|
2013-01-28 20:21:11 +01:00
|
|
|
|
2021-10-11 16:10:47 +02:00
|
|
|
$data['cuein'] = $file->getDbCuein();
|
|
|
|
$data['cueout'] = $file->getDbCueout();
|
2012-01-31 18:59:27 +01:00
|
|
|
|
2022-03-14 11:15:04 +01:00
|
|
|
// fade is in format SS.uuuuuu
|
2021-10-11 16:10:47 +02:00
|
|
|
$data['fadein'] = Application_Model_Preference::GetDefaultFadeIn();
|
|
|
|
$data['fadeout'] = Application_Model_Preference::GetDefaultFadeOut();
|
2012-02-27 21:29:02 +01:00
|
|
|
|
2021-10-11 16:10:47 +02:00
|
|
|
$files[] = $data;
|
|
|
|
} elseif ($type === 'playlist') {
|
2012-07-27 17:51:50 +02:00
|
|
|
$pl = new Application_Model_Playlist($id);
|
|
|
|
$contents = $pl->getContents();
|
2019-04-22 21:26:09 +02:00
|
|
|
// because the time remaining is not updated until after the schedule inserts we need to track it for
|
|
|
|
// the entire add vs. querying on the smartblock level
|
2012-08-29 16:58:03 +02:00
|
|
|
foreach ($contents as $plItem) {
|
|
|
|
if ($plItem['type'] == 0) {
|
2021-10-11 16:10:47 +02:00
|
|
|
$data['id'] = $plItem['item_id'];
|
|
|
|
$data['cliplength'] = $plItem['length'];
|
|
|
|
$data['cuein'] = $plItem['cuein'];
|
|
|
|
$data['cueout'] = $plItem['cueout'];
|
|
|
|
$data['fadein'] = $plItem['fadein'];
|
|
|
|
$data['fadeout'] = $plItem['fadeout'];
|
|
|
|
$data['type'] = 0;
|
2012-08-29 16:58:03 +02:00
|
|
|
$files[] = $data;
|
2012-08-30 20:36:23 +02:00
|
|
|
} elseif ($plItem['type'] == 1) {
|
2021-10-11 16:10:47 +02:00
|
|
|
$data['id'] = $plItem['item_id'];
|
|
|
|
$data['cliplength'] = $plItem['length'];
|
|
|
|
$data['cuein'] = $plItem['cuein'];
|
|
|
|
$data['cueout'] = $plItem['cueout'];
|
2022-03-14 11:15:04 +01:00
|
|
|
$data['fadein'] = '00.500000'; // $plItem['fadein'];
|
|
|
|
$data['fadeout'] = '00.500000'; // $plItem['fadeout'];
|
2021-10-11 16:10:47 +02:00
|
|
|
$data['type'] = 1;
|
2012-08-30 20:36:23 +02:00
|
|
|
$files[] = $data;
|
2012-08-29 16:58:03 +02:00
|
|
|
} elseif ($plItem['type'] == 2) {
|
2012-07-27 17:51:50 +02:00
|
|
|
// if it's a block
|
2012-08-29 16:58:03 +02:00
|
|
|
$bl = new Application_Model_Block($plItem['item_id']);
|
|
|
|
if ($bl->isStatic()) {
|
2012-07-27 17:51:50 +02:00
|
|
|
foreach ($bl->getContents() as $track) {
|
2021-10-11 16:10:47 +02:00
|
|
|
$data['id'] = $track['item_id'];
|
|
|
|
$data['cliplength'] = $track['length'];
|
|
|
|
$data['cuein'] = $track['cuein'];
|
|
|
|
$data['cueout'] = $track['cueout'];
|
|
|
|
$data['fadein'] = $track['fadein'];
|
|
|
|
$data['fadeout'] = $track['fadeout'];
|
|
|
|
$data['type'] = 0;
|
2012-08-29 16:58:03 +02:00
|
|
|
$files[] = $data;
|
|
|
|
}
|
2012-07-27 17:51:50 +02:00
|
|
|
} else {
|
2013-05-15 21:32:29 +02:00
|
|
|
$defaultFadeIn = Application_Model_Preference::GetDefaultFadeIn();
|
|
|
|
$defaultFadeOut = Application_Model_Preference::GetDefaultFadeOut();
|
2019-04-22 21:26:09 +02:00
|
|
|
$dynamicFiles = $bl->getListOfFilesUnderLimit($showLimit);
|
2012-11-06 22:32:00 +01:00
|
|
|
foreach ($dynamicFiles as $f) {
|
|
|
|
$fileId = $f['id'];
|
2012-07-27 17:51:50 +02:00
|
|
|
$file = CcFilesQuery::create()->findPk($fileId);
|
2012-11-05 16:57:18 +01:00
|
|
|
if (isset($file) && $file->visible()) {
|
2021-10-11 16:10:47 +02:00
|
|
|
$data['id'] = $file->getDbId();
|
|
|
|
$data['cuein'] = $file->getDbCuein();
|
|
|
|
$data['cueout'] = $file->getDbCueout();
|
2013-02-11 20:17:18 +01:00
|
|
|
|
2021-10-11 16:10:47 +02:00
|
|
|
$cuein = Application_Common_DateHelper::calculateLengthInSeconds($data['cuein']);
|
|
|
|
$cueout = Application_Common_DateHelper::calculateLengthInSeconds($data['cueout']);
|
|
|
|
$data['cliplength'] = Application_Common_DateHelper::secondsToPlaylistTime($cueout - $cuein);
|
2013-06-24 17:09:03 +02:00
|
|
|
|
2022-03-14 11:15:04 +01:00
|
|
|
// fade is in format SS.uuuuuu
|
2021-10-11 16:10:47 +02:00
|
|
|
$data['fadein'] = $defaultFadeIn;
|
|
|
|
$data['fadeout'] = $defaultFadeOut;
|
2013-06-24 17:09:03 +02:00
|
|
|
|
2021-10-11 16:10:47 +02:00
|
|
|
$data['type'] = 0;
|
2012-08-29 16:58:03 +02:00
|
|
|
$files[] = $data;
|
2012-07-27 17:51:50 +02:00
|
|
|
}
|
|
|
|
}
|
2012-08-29 16:58:03 +02:00
|
|
|
}
|
|
|
|
}
|
2019-04-22 21:26:09 +02:00
|
|
|
// if this is a playlist it might contain multiple time remaining smart blocks
|
|
|
|
// since the schedule isn't updated until after this insert we need to keep tally
|
fix: playlist allocates inaccurate time to smartblocks (#3026)
### Description
In the existing logic of `retrieveMediaFiles`, the time remaining in
show is calculated incorrectly in some scenarios. Each time a duration
is subtracted from `showLimit`, it is not the duration of the files just
added, but instead the length of all files scheduled. This can cause
cases where a smart block set to "time remaining in show" fails to
completely fill the program.
For example, given a 30 minute show, and a playlist like follows:
1. a 5 minute track
2. another 5 minute track
3. smart block, set to time remaining in show
When item 1 is added, `showLimit` is reduced by 5 minutes as expected.
When item 2 is added, `showLimit` is reduced by 10 minutes (as both
items 1 and 2 are counted). As a result, the smart block is only run to
fill 15 minutes, leaving 5 minutes unfilled.
This PR resolves this issue, by recalculating `showLimit` from the
original duration rather than subtracting from a running total.
This change not does implement a new feature and should not require any
changes to documentation.
### Testing Notes
**What I did:**
- On a dev environment, set up a playlist as described above.
- Before applying this PR, created a show and scheduled playlist, and
confirmed issue was reproducible
- Applied PR and repeated, and confirmed show was filled completely.
Also repeated this testing with sample data from our production
instance.
Here is a sample schedule of the "before" case with sample data, showing
the issue

The smartblock that scheduled the music is set to allow last track to
overflow, but 3m55s was left unscheduled.
Using the same playlist and same track library, here is a sample
schedule after the PR applied:

As expected, the show is fully scheduled with the last track
overflowing.
Additionally, I've applied this PR as a hot fix to our production
instance, where it has been running for a week without issue.
Also performed spot tests of playlists without smart blocks, smart
blocks scheduled directly (not in playlists) and autoloading playlists,
with no change in behaviour observed as a result of this change.
**How you can replicate my testing:**
Same test steps as I followed should be able to reproduce issue &
validate fix on any instance.
### **Links**
Not directly related to issue fixed by #3019, but also addresses the
issue of dead air left at end of blocks.
Co-authored-by: Kyle Robbertze <paddatrapper@users.noreply.github.com>
2024-06-05 18:01:57 +02:00
|
|
|
$showLimit = $originalShowLimit - $this->timeLengthOfFiles($files);
|
2012-07-27 17:51:50 +02:00
|
|
|
}
|
2021-10-11 16:10:47 +02:00
|
|
|
} elseif ($type == 'stream') {
|
2022-03-14 11:15:04 +01:00
|
|
|
// need to return
|
2021-10-11 16:10:47 +02:00
|
|
|
$stream = CcWebstreamQuery::create()->findPK($id, $this->con);
|
2012-07-25 04:24:08 +02:00
|
|
|
|
2012-11-05 16:57:18 +01:00
|
|
|
if (is_null($stream) /* || !$file->visible() */) {
|
2021-10-11 16:10:47 +02:00
|
|
|
throw new Exception(_('A selected File does not exist!'));
|
2012-02-02 23:15:39 +01:00
|
|
|
}
|
2021-10-11 16:10:47 +02:00
|
|
|
$data = $this->fileInfo;
|
|
|
|
$data['id'] = $id;
|
|
|
|
$data['cliplength'] = $stream->getDbLength();
|
|
|
|
$data['cueout'] = $stream->getDbLength();
|
|
|
|
$data['type'] = 1;
|
|
|
|
|
2022-03-14 11:15:04 +01:00
|
|
|
// fade is in format SS.uuuuuu
|
2021-10-11 16:10:47 +02:00
|
|
|
$data['fadein'] = Application_Model_Preference::GetDefaultFadeIn();
|
|
|
|
$data['fadeout'] = Application_Model_Preference::GetDefaultFadeOut();
|
|
|
|
|
|
|
|
$files[] = $data;
|
|
|
|
} elseif ($type == 'block') {
|
2012-08-29 16:58:03 +02:00
|
|
|
$bl = new Application_Model_Block($id);
|
|
|
|
if ($bl->isStatic()) {
|
|
|
|
foreach ($bl->getContents() as $track) {
|
2021-10-11 16:10:47 +02:00
|
|
|
$data['id'] = $track['item_id'];
|
|
|
|
$data['cliplength'] = $track['length'];
|
|
|
|
$data['cuein'] = $track['cuein'];
|
|
|
|
$data['cueout'] = $track['cueout'];
|
|
|
|
$data['fadein'] = $track['fadein'];
|
|
|
|
$data['fadeout'] = $track['fadeout'];
|
|
|
|
$data['type'] = 0;
|
2012-08-29 16:58:03 +02:00
|
|
|
$files[] = $data;
|
|
|
|
}
|
|
|
|
} else {
|
2013-05-15 21:32:29 +02:00
|
|
|
$defaultFadeIn = Application_Model_Preference::GetDefaultFadeIn();
|
|
|
|
$defaultFadeOut = Application_Model_Preference::GetDefaultFadeOut();
|
2019-04-22 21:26:09 +02:00
|
|
|
$dynamicFiles = $bl->getListOfFilesUnderLimit($showLimit);
|
2012-11-06 22:32:00 +01:00
|
|
|
foreach ($dynamicFiles as $f) {
|
|
|
|
$fileId = $f['id'];
|
2012-08-29 16:58:03 +02:00
|
|
|
$file = CcFilesQuery::create()->findPk($fileId);
|
2012-11-05 16:57:18 +01:00
|
|
|
if (isset($file) && $file->visible()) {
|
2021-10-11 16:10:47 +02:00
|
|
|
$data['id'] = $file->getDbId();
|
|
|
|
$data['cuein'] = $file->getDbCuein();
|
|
|
|
$data['cueout'] = $file->getDbCueout();
|
2013-02-11 19:45:51 +01:00
|
|
|
|
2021-10-11 16:10:47 +02:00
|
|
|
$cuein = Application_Common_DateHelper::calculateLengthInSeconds($data['cuein']);
|
|
|
|
$cueout = Application_Common_DateHelper::calculateLengthInSeconds($data['cueout']);
|
|
|
|
$data['cliplength'] = Application_Common_DateHelper::secondsToPlaylistTime($cueout - $cuein);
|
2013-06-24 17:09:03 +02:00
|
|
|
|
2022-03-14 11:15:04 +01:00
|
|
|
// fade is in format SS.uuuuuu
|
2021-10-11 16:10:47 +02:00
|
|
|
$data['fadein'] = $defaultFadeIn;
|
|
|
|
$data['fadeout'] = $defaultFadeOut;
|
2013-06-24 17:09:03 +02:00
|
|
|
|
2021-10-11 16:10:47 +02:00
|
|
|
$data['type'] = 0;
|
2012-08-29 16:58:03 +02:00
|
|
|
$files[] = $data;
|
|
|
|
}
|
|
|
|
}
|
2012-07-30 23:18:33 +02:00
|
|
|
}
|
2012-01-31 18:59:27 +01:00
|
|
|
}
|
2012-08-29 16:58:03 +02:00
|
|
|
|
2012-01-31 18:59:27 +01:00
|
|
|
return $files;
|
|
|
|
}
|
2013-06-24 17:09:03 +02:00
|
|
|
|
2013-05-02 22:52:30 +02:00
|
|
|
/*
|
|
|
|
* @param DateTime startDT in UTC
|
|
|
|
* @param string duration
|
|
|
|
* in format H:i:s.u (could be more that 24 hours)
|
|
|
|
*
|
|
|
|
* @return DateTime endDT in UTC
|
|
|
|
*/
|
|
|
|
private function findTimeDifference($p_startDT, $p_seconds)
|
|
|
|
{
|
2021-10-11 16:10:47 +02:00
|
|
|
$startEpoch = $p_startDT->format('U.u');
|
2013-06-24 17:09:03 +02:00
|
|
|
|
2022-03-14 11:15:04 +01:00
|
|
|
// add two float numbers to 6 subsecond precision
|
|
|
|
// DateTime::createFromFormat("U.u") will have a problem if there is no decimal in the resulting number.
|
2021-10-11 16:10:47 +02:00
|
|
|
$newEpoch = bcsub($startEpoch, (string) $p_seconds, 6);
|
2013-06-24 17:09:03 +02:00
|
|
|
|
2021-10-11 16:10:47 +02:00
|
|
|
$dt = DateTime::createFromFormat('U.u', $newEpoch, new DateTimeZone('UTC'));
|
2013-06-24 17:09:03 +02:00
|
|
|
|
2021-10-11 16:10:47 +02:00
|
|
|
if ($dt === false) {
|
2022-03-14 11:15:04 +01:00
|
|
|
// PHP 5.3.2 problem
|
2021-10-11 16:10:47 +02:00
|
|
|
$dt = DateTime::createFromFormat('U', intval($newEpoch), new DateTimeZone('UTC'));
|
|
|
|
}
|
2013-06-24 17:09:03 +02:00
|
|
|
|
2021-10-11 16:10:47 +02:00
|
|
|
return $dt;
|
2013-05-02 22:15:21 +02:00
|
|
|
}
|
2012-01-31 18:59:27 +01:00
|
|
|
|
2021-10-11 16:10:47 +02:00
|
|
|
private function findTimeDifference2($p_startDT, $p_endDT)
|
|
|
|
{
|
|
|
|
$startEpoch = $p_startDT->format('U.u');
|
|
|
|
$endEpoch = $p_endDT->format('U.u');
|
2015-11-03 19:04:22 +01:00
|
|
|
|
2022-03-14 11:15:04 +01:00
|
|
|
// add two float numbers to 6 subsecond precision
|
|
|
|
// DateTime::createFromFormat("U.u") will have a problem if there is no decimal in the resulting number.
|
2021-10-11 16:10:47 +02:00
|
|
|
$newEpoch = bcsub($endEpoch, (string) $startEpoch, 6);
|
2015-11-03 19:04:22 +01:00
|
|
|
|
2021-10-11 16:10:47 +02:00
|
|
|
$dt = DateTime::createFromFormat('U.u', $newEpoch, new DateTimeZone('UTC'));
|
2015-11-03 19:04:22 +01:00
|
|
|
|
|
|
|
if ($dt === false) {
|
2022-03-14 11:15:04 +01:00
|
|
|
// PHP 5.3.2 problem
|
2021-10-11 16:10:47 +02:00
|
|
|
$dt = DateTime::createFromFormat('U', intval($newEpoch), new DateTimeZone('UTC'));
|
2015-11-03 19:04:22 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return $dt;
|
|
|
|
}
|
|
|
|
|
2012-02-01 18:47:08 +01:00
|
|
|
/*
|
2012-02-07 17:29:52 +01:00
|
|
|
* @param DateTime startDT in UTC
|
2012-02-01 18:47:08 +01:00
|
|
|
* @param string duration
|
|
|
|
* in format H:i:s.u (could be more that 24 hours)
|
2012-02-07 17:29:52 +01:00
|
|
|
*
|
|
|
|
* @return DateTime endDT in UTC
|
2012-02-01 18:47:08 +01:00
|
|
|
*/
|
2012-07-16 03:17:13 +02:00
|
|
|
private function findEndTime($p_startDT, $p_duration)
|
|
|
|
{
|
2021-10-11 16:10:47 +02:00
|
|
|
$startEpoch = $p_startDT->format('U.u');
|
2012-07-26 20:41:09 +02:00
|
|
|
$durationSeconds = Application_Common_DateHelper::playlistTimeToSeconds($p_duration);
|
2012-02-07 17:29:52 +01:00
|
|
|
|
2022-03-14 11:15:04 +01:00
|
|
|
// add two float numbers to 6 subsecond precision
|
|
|
|
// DateTime::createFromFormat("U.u") will have a problem if there is no decimal in the resulting number.
|
2021-10-11 16:10:47 +02:00
|
|
|
$endEpoch = bcadd($startEpoch, (string) $durationSeconds, 6);
|
2012-02-07 17:29:52 +01:00
|
|
|
|
2021-10-11 16:10:47 +02:00
|
|
|
$dt = DateTime::createFromFormat('U.u', $endEpoch, new DateTimeZone('UTC'));
|
2012-07-11 00:51:32 +02:00
|
|
|
|
2012-05-06 21:34:41 +02:00
|
|
|
if ($dt === false) {
|
2022-03-14 11:15:04 +01:00
|
|
|
// PHP 5.3.2 problem
|
2021-10-11 16:10:47 +02:00
|
|
|
$dt = DateTime::createFromFormat('U', intval($endEpoch), new DateTimeZone('UTC'));
|
2012-05-06 21:34:41 +02:00
|
|
|
}
|
2012-07-11 00:51:32 +02:00
|
|
|
|
2012-02-07 17:29:52 +01:00
|
|
|
return $dt;
|
2012-02-01 18:47:08 +01:00
|
|
|
}
|
2012-07-11 00:51:32 +02:00
|
|
|
|
2013-05-22 22:10:10 +02:00
|
|
|
private function findNextStartTime($DT, $instanceId)
|
2012-07-16 03:17:13 +02:00
|
|
|
{
|
2015-08-25 17:46:20 +02:00
|
|
|
// TODO: there is at least one case where this function creates a filler block with
|
|
|
|
// an incorrect length; should keep an eye on it
|
2021-10-11 16:10:47 +02:00
|
|
|
$sEpoch = $DT->format('U.u');
|
2012-03-30 12:24:55 +02:00
|
|
|
$nEpoch = $this->epochNow;
|
2012-07-16 03:17:13 +02:00
|
|
|
|
2022-03-14 11:15:04 +01:00
|
|
|
// check for if the show has started.
|
2021-10-11 16:10:47 +02:00
|
|
|
if (bccomp($nEpoch, $sEpoch, 6) === 1) {
|
2013-10-10 18:11:23 +02:00
|
|
|
$this->applyCrossfades = false;
|
2022-03-14 11:15:04 +01:00
|
|
|
// need some kind of placeholder for cc_schedule.
|
|
|
|
// playout_status will be -1.
|
2012-03-30 12:24:55 +02:00
|
|
|
$nextDT = $this->nowDT;
|
2012-07-11 00:51:32 +02:00
|
|
|
|
2021-10-11 16:10:47 +02:00
|
|
|
$length = bcsub($nEpoch, $sEpoch, 6);
|
2012-07-26 00:42:46 +02:00
|
|
|
$cliplength = Application_Common_DateHelper::secondsToPlaylistTime($length);
|
2012-07-16 03:17:13 +02:00
|
|
|
|
2022-03-14 11:15:04 +01:00
|
|
|
// fillers are for only storing a chunk of time space that has already passed.
|
2012-07-16 03:17:13 +02:00
|
|
|
$filler = new CcSchedule();
|
|
|
|
$filler->setDbStarts($DT)
|
|
|
|
->setDbEnds($this->nowDT)
|
|
|
|
->setDbClipLength($cliplength)
|
2013-02-05 23:57:21 +01:00
|
|
|
->setDbCueIn('00:00:00')
|
|
|
|
->setDbCueOut('00:00:00')
|
2012-07-16 03:17:13 +02:00
|
|
|
->setDbPlayoutStatus(-1)
|
2013-05-22 22:10:10 +02:00
|
|
|
->setDbInstanceId($instanceId)
|
2022-01-23 19:15:55 +01:00
|
|
|
->save($this->con);
|
2012-07-16 03:17:13 +02:00
|
|
|
} else {
|
|
|
|
$nextDT = $DT;
|
2012-03-26 19:08:52 +02:00
|
|
|
}
|
2012-07-11 00:51:32 +02:00
|
|
|
|
2012-03-26 19:08:52 +02:00
|
|
|
return $nextDT;
|
|
|
|
}
|
2013-06-24 17:09:03 +02:00
|
|
|
|
2013-05-02 22:52:30 +02:00
|
|
|
/*
|
|
|
|
* @param int $showInstance
|
2013-05-02 22:15:21 +02:00
|
|
|
* This function recalculates the start/end times of items in a gapless show to
|
2013-05-02 22:52:30 +02:00
|
|
|
* account for crossfade durations.
|
|
|
|
*/
|
2013-05-23 22:10:00 +02:00
|
|
|
private function calculateCrossfades($instanceId)
|
2013-05-02 22:52:30 +02:00
|
|
|
{
|
2021-10-11 16:10:47 +02:00
|
|
|
Logging::info('adjusting start, end times of scheduled items to account for crossfades show instance #' . $instanceId);
|
2015-08-25 17:46:20 +02:00
|
|
|
$instance = CcShowInstancesQuery::create()->findPk($instanceId);
|
2013-05-10 21:24:43 +02:00
|
|
|
|
2013-05-23 22:10:00 +02:00
|
|
|
if (is_null($instance)) {
|
|
|
|
throw new OutDatedScheduleException(_("The schedule you're viewing is out of date!"));
|
|
|
|
}
|
|
|
|
|
2015-08-25 17:46:20 +02:00
|
|
|
$schedule = CcScheduleQuery::create()
|
|
|
|
->filterByDbInstanceId($instanceId)
|
|
|
|
->orderByDbStarts()
|
2022-01-23 19:15:55 +01:00
|
|
|
->find($this->con);
|
2013-05-23 22:10:00 +02:00
|
|
|
|
2021-10-11 16:10:47 +02:00
|
|
|
$now = new DateTime('now', new DateTimeZone('UTC'));
|
2015-08-25 17:46:20 +02:00
|
|
|
$itemStartDT = $instance->getDbStarts(null);
|
2013-05-23 22:10:00 +02:00
|
|
|
foreach ($schedule as $item) {
|
2015-08-25 17:46:20 +02:00
|
|
|
$itemEndDT = $this->findEndTime($itemStartDT, $item->getDbClipLength());
|
2015-11-23 20:55:37 +01:00
|
|
|
// If the track has already ended, don't change it.
|
|
|
|
if ($itemEndDT < $now) {
|
|
|
|
$itemStartDT = $itemEndDT;
|
2021-10-11 16:10:47 +02:00
|
|
|
|
2015-11-23 20:55:37 +01:00
|
|
|
continue;
|
|
|
|
}
|
2015-08-25 17:46:20 +02:00
|
|
|
$item->setDbStarts($itemStartDT)
|
|
|
|
->setDbEnds($itemEndDT)
|
2022-01-23 19:15:55 +01:00
|
|
|
->save($this->con);
|
2013-05-23 22:10:00 +02:00
|
|
|
$itemStartDT = $this->findTimeDifference($itemEndDT, $this->crossfadeDuration);
|
|
|
|
}
|
2013-05-02 22:15:21 +02:00
|
|
|
}
|
2012-07-11 00:51:32 +02:00
|
|
|
|
2012-07-16 03:17:13 +02:00
|
|
|
/*
|
|
|
|
* @param int $showInstance
|
2015-08-25 17:46:20 +02:00
|
|
|
* @param array $exclude
|
|
|
|
* ids of sched items to remove from the calculation.
|
|
|
|
* This function squeezes all items of a show together so that
|
|
|
|
* there are no gaps between them.
|
|
|
|
*/
|
2021-10-11 16:10:47 +02:00
|
|
|
public function removeGaps($showInstance, $exclude = null)
|
2012-07-16 03:17:13 +02:00
|
|
|
{
|
2021-10-11 16:10:47 +02:00
|
|
|
Logging::info('removing gaps from show instance #' . $showInstance);
|
2012-07-16 03:17:13 +02:00
|
|
|
|
2015-08-25 17:46:20 +02:00
|
|
|
$instance = CcShowInstancesQuery::create()->findPk($showInstance, $this->con);
|
2012-07-16 03:17:13 +02:00
|
|
|
if (is_null($instance)) {
|
2012-11-15 21:52:51 +01:00
|
|
|
throw new OutDatedScheduleException(_("The schedule you're viewing is out of date!"));
|
2012-04-16 16:33:32 +02:00
|
|
|
}
|
2012-07-11 00:51:32 +02:00
|
|
|
|
2012-07-16 03:17:13 +02:00
|
|
|
$schedule = CcScheduleQuery::create()
|
|
|
|
->filterByDbInstanceId($showInstance)
|
|
|
|
->filterByDbId($exclude, Criteria::NOT_IN)
|
|
|
|
->orderByDbStarts()
|
2022-01-23 19:15:55 +01:00
|
|
|
->find($this->con);
|
2012-07-16 03:17:13 +02:00
|
|
|
|
2021-10-11 16:10:47 +02:00
|
|
|
$now = new DateTime('now', new DateTimeZone('UTC'));
|
2015-08-25 17:46:20 +02:00
|
|
|
$itemStartDT = $instance->getDbStarts(null);
|
2012-07-16 03:17:13 +02:00
|
|
|
foreach ($schedule as $item) {
|
2015-11-03 19:04:22 +01:00
|
|
|
$itemEndDT = $this->findEndTime($itemStartDT, $item->getDbClipLength());
|
2015-11-23 20:55:37 +01:00
|
|
|
// If the track has already ended, don't change it.
|
|
|
|
if ($itemEndDT < $now) {
|
|
|
|
$itemStartDT = $itemEndDT;
|
2021-10-11 16:10:47 +02:00
|
|
|
|
2015-11-23 20:55:37 +01:00
|
|
|
continue;
|
|
|
|
}
|
2015-11-03 19:04:22 +01:00
|
|
|
|
|
|
|
$item->setDbStarts($itemStartDT)
|
2022-01-23 19:15:55 +01:00
|
|
|
->setDbEnds($itemEndDT);
|
2015-11-03 19:04:22 +01:00
|
|
|
|
|
|
|
$itemStartDT = $itemEndDT;
|
|
|
|
}
|
|
|
|
|
|
|
|
$schedule->save($this->con);
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Temporary hack to copy the track cue in, out, and length from the cc_files table to fix
|
2021-10-11 16:10:47 +02:00
|
|
|
* incorrect track lengths (RKTN-260).
|
|
|
|
*
|
|
|
|
* @param mixed $showInstance
|
|
|
|
* @param null|mixed $exclude
|
2015-11-03 19:04:22 +01:00
|
|
|
*/
|
2021-10-11 16:10:47 +02:00
|
|
|
public function removeGaps2($showInstance, $exclude = null)
|
|
|
|
{
|
2015-11-03 19:04:22 +01:00
|
|
|
$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()
|
2022-01-23 19:15:55 +01:00
|
|
|
->find($this->con);
|
2015-11-03 19:04:22 +01:00
|
|
|
|
|
|
|
foreach ($schedule as $item) {
|
2022-03-14 11:15:04 +01:00
|
|
|
// START OF TIME RECALC HACK
|
2015-11-03 19:04:22 +01:00
|
|
|
|
2022-03-14 11:15:04 +01:00
|
|
|
// TODO: Copy the cue in, cue out, and track length from the cc_files table
|
2015-11-03 19:04:22 +01:00
|
|
|
$file = $item->getCcFiles($this->con);
|
2015-11-03 20:12:27 +01:00
|
|
|
if (!$file) {
|
|
|
|
continue;
|
|
|
|
}
|
2015-11-03 19:04:22 +01:00
|
|
|
$item->setDbCueIn($file->getDbCueIn());
|
|
|
|
$item->setDbCueOut($file->getDbCueOut());
|
|
|
|
|
|
|
|
$cueOut = new DateTime($file->getDbCueOut());
|
|
|
|
$cueIn = new DateTime($file->getDbCueIn());
|
|
|
|
$clipLength = $this->findTimeDifference2($cueIn, $cueOut);
|
|
|
|
|
2022-03-14 11:15:04 +01:00
|
|
|
// The clip length is supposed to be cue out - cue in:
|
|
|
|
// FIXME: How do we correctly do time arithmetic in PHP without losing the millseconds?
|
2015-11-03 19:04:22 +01:00
|
|
|
$item->setDbClipLength($clipLength->format(DEFAULT_INTERVAL_FORMAT));
|
|
|
|
$item->save($this->con);
|
2022-03-14 11:15:04 +01:00
|
|
|
// Ensure we don't get cached results
|
2015-11-03 19:04:22 +01:00
|
|
|
CcSchedulePeer::clearInstancePool();
|
2022-03-14 11:15:04 +01:00
|
|
|
// END OF TIME RECALC HACK
|
2015-11-03 19:04:22 +01:00
|
|
|
|
2012-07-16 03:17:13 +02:00
|
|
|
$itemEndDT = $this->findEndTime($itemStartDT, $item->getDbClipLength());
|
|
|
|
$item->setDbStarts($itemStartDT)
|
2015-08-25 17:46:20 +02:00
|
|
|
->setDbEnds($itemEndDT)
|
2022-01-23 19:15:55 +01:00
|
|
|
->save($this->con);
|
2015-08-25 17:46:20 +02:00
|
|
|
$itemStartDT = $this->findTimeDifference($itemEndDT, $this->crossfadeDuration);
|
2012-07-16 03:17:13 +02:00
|
|
|
}
|
2015-11-03 19:04:22 +01:00
|
|
|
|
2022-03-14 11:15:04 +01:00
|
|
|
$instance->updateDbTimeFilled($this->con); // FIXME: TIME RECALC HACK (Albert)
|
2015-11-03 19:04:22 +01:00
|
|
|
|
|
|
|
$schedule->save($this->con);
|
2012-04-02 15:20:13 +02:00
|
|
|
}
|
2012-02-01 18:47:08 +01:00
|
|
|
|
2013-04-04 22:30:33 +02:00
|
|
|
/**
|
|
|
|
* Enter description here ...
|
2021-10-11 16:10:47 +02:00
|
|
|
*
|
2024-01-07 13:59:02 +01:00
|
|
|
* @param $scheduleItems cc_schedule items, where the items get inserted after
|
|
|
|
* @param $filesToInsert array of schedule item info, what gets inserted into cc_schedule
|
2021-10-11 16:10:47 +02:00
|
|
|
* @param mixed $mediaItems
|
|
|
|
* @param mixed $moveAction
|
2022-10-12 17:02:14 +02:00
|
|
|
* @param mixed $adjustSched
|
2012-02-02 18:13:20 +01:00
|
|
|
*/
|
2021-10-11 16:10:47 +02:00
|
|
|
private function insertAfter($scheduleItems, $mediaItems, $filesToInsert = null, $adjustSched = true, $moveAction = false)
|
2012-07-16 03:17:13 +02:00
|
|
|
{
|
2012-02-02 18:13:20 +01:00
|
|
|
try {
|
2014-01-09 17:57:32 +01:00
|
|
|
// temporary fix for CC-5665
|
|
|
|
set_time_limit(180);
|
|
|
|
|
2021-10-11 16:10:47 +02:00
|
|
|
$affectedShowInstances = [];
|
2013-04-04 22:30:33 +02:00
|
|
|
|
2022-03-14 11:15:04 +01:00
|
|
|
// dont want to recalculate times for moved items
|
|
|
|
// only moved items have a sched_id
|
2021-10-11 16:10:47 +02:00
|
|
|
$excludeIds = [];
|
2012-02-06 01:51:22 +01:00
|
|
|
|
2012-04-16 16:33:32 +02:00
|
|
|
$startProfile = microtime(true);
|
2012-07-11 00:51:32 +02:00
|
|
|
|
2021-10-11 16:10:47 +02:00
|
|
|
$temp = [];
|
2013-04-12 22:34:36 +02:00
|
|
|
$instance = null;
|
2013-05-15 21:32:29 +02:00
|
|
|
|
2013-04-18 22:12:26 +02:00
|
|
|
/* 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
|
|
|
|
*/
|
2013-04-12 22:34:36 +02:00
|
|
|
$pos = 0;
|
|
|
|
|
2013-05-15 21:32:29 +02:00
|
|
|
$linked = false;
|
|
|
|
|
2012-02-01 18:47:08 +01:00
|
|
|
foreach ($scheduleItems as $schedule) {
|
2022-03-14 11:15:04 +01:00
|
|
|
// reset
|
2013-10-15 21:20:58 +02:00
|
|
|
$this->applyCrossfades = true;
|
|
|
|
|
2021-10-11 16:10:47 +02:00
|
|
|
$id = intval($schedule['id']);
|
2012-07-11 00:51:32 +02:00
|
|
|
|
2013-04-18 22:12:26 +02:00
|
|
|
/* 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
|
|
|
|
*/
|
2013-04-12 22:34:36 +02:00
|
|
|
if ($id != 0) {
|
2021-10-11 16:10:47 +02:00
|
|
|
$schedule_sql = 'SELECT * FROM cc_schedule WHERE id = ' . $id;
|
2013-05-22 22:10:10 +02:00
|
|
|
$ccSchedule = Application_Common_Database::prepareAndExecute(
|
2021-10-11 16:10:47 +02:00
|
|
|
$schedule_sql,
|
|
|
|
[],
|
|
|
|
Application_Common_Database::SINGLE
|
|
|
|
);
|
2013-05-22 22:10:10 +02:00
|
|
|
|
2021-10-11 16:10:47 +02:00
|
|
|
$show_sql = 'SELECT * FROM cc_show WHERE id IN (' .
|
|
|
|
'SELECT show_id FROM cc_show_instances WHERE id = ' . $ccSchedule['instance_id'] . ')';
|
2013-05-22 22:10:10 +02:00
|
|
|
$ccShow = Application_Common_Database::prepareAndExecute(
|
2021-10-11 16:10:47 +02:00
|
|
|
$show_sql,
|
|
|
|
[],
|
|
|
|
Application_Common_Database::SINGLE
|
|
|
|
);
|
2013-05-22 22:10:10 +02:00
|
|
|
|
2021-10-11 16:10:47 +02:00
|
|
|
$linked = $ccShow['linked'];
|
2013-05-15 21:32:29 +02:00
|
|
|
if ($linked) {
|
2021-10-11 16:10:47 +02:00
|
|
|
$unique = $ccShow['id'] . $ccSchedule['position'];
|
2013-04-12 22:34:36 +02:00
|
|
|
if (!in_array($unique, $temp)) {
|
|
|
|
$temp[] = $unique;
|
|
|
|
} else {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
2021-10-11 16:10:47 +02:00
|
|
|
$show_sql = 'SELECT * FROM cc_show WHERE id IN (' .
|
|
|
|
'SELECT show_id FROM cc_show_instances WHERE id = ' . $schedule['instance'] . ')';
|
2013-05-22 22:10:10 +02:00
|
|
|
$ccShow = Application_Common_Database::prepareAndExecute(
|
2021-10-11 16:10:47 +02:00
|
|
|
$show_sql,
|
|
|
|
[],
|
|
|
|
Application_Common_Database::SINGLE
|
|
|
|
);
|
2013-05-22 22:10:10 +02:00
|
|
|
|
2021-10-11 16:10:47 +02:00
|
|
|
$linked = $ccShow['linked'];
|
2013-05-15 21:32:29 +02:00
|
|
|
if ($linked) {
|
2021-10-11 16:10:47 +02:00
|
|
|
$unique = $ccShow['id'] . 'a';
|
2013-04-12 22:34:36 +02:00
|
|
|
if (!in_array($unique, $temp)) {
|
|
|
|
$temp[] = $unique;
|
|
|
|
} else {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
2012-02-16 19:46:14 +01:00
|
|
|
}
|
|
|
|
|
2013-04-18 22:12:26 +02:00
|
|
|
/* 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
|
|
|
|
*/
|
2013-05-15 21:32:29 +02:00
|
|
|
if ($linked) {
|
2014-03-05 19:12:27 +01:00
|
|
|
$instances = CcShowInstancesQuery::create()
|
2021-10-11 16:10:47 +02:00
|
|
|
->filterByDbShowId($ccShow['id'])
|
2015-06-26 20:42:52 +02:00
|
|
|
->filterByDbStarts(gmdate(DEFAULT_TIMESTAMP_FORMAT), Criteria::GREATER_THAN)
|
2022-01-23 19:15:55 +01:00
|
|
|
->find();
|
2013-05-15 21:32:29 +02:00
|
|
|
} else {
|
2014-03-05 20:50:35 +01:00
|
|
|
$instances = CcShowInstancesQuery::create()
|
2021-10-11 16:10:47 +02:00
|
|
|
->filterByDbId($schedule['instance'])
|
2022-01-23 19:15:55 +01:00
|
|
|
->find();
|
2013-05-15 21:32:29 +02:00
|
|
|
}
|
2013-05-27 16:39:31 +02:00
|
|
|
|
2021-10-11 16:10:47 +02:00
|
|
|
$excludePositions = [];
|
|
|
|
foreach ($instances as &$instance) {
|
2022-03-14 11:15:04 +01:00
|
|
|
// reset
|
2013-10-15 21:20:58 +02:00
|
|
|
$this->applyCrossfades = true;
|
|
|
|
|
2022-03-14 11:15:04 +01:00
|
|
|
// $instanceId = $instance["id"];
|
2014-03-05 19:12:27 +01:00
|
|
|
$instanceId = $instance->getDbId();
|
2013-04-18 22:12:26 +02:00
|
|
|
if ($id !== 0) {
|
|
|
|
/* We use the selected cursor's position to find the same
|
|
|
|
* positions in every other linked instance
|
|
|
|
*/
|
2021-10-11 16:10:47 +02:00
|
|
|
$pos = $ccSchedule['position'];
|
2013-04-12 22:34:36 +02:00
|
|
|
|
2021-10-11 16:10:47 +02:00
|
|
|
$linkedItem_sql = 'SELECT ends FROM cc_schedule ' .
|
|
|
|
"WHERE instance_id = {$instanceId} " .
|
|
|
|
"AND position = {$pos} " .
|
|
|
|
'AND playout_status != -1';
|
2013-05-22 22:10:10 +02:00
|
|
|
$linkedItemEnds = Application_Common_Database::prepareAndExecute(
|
2021-10-11 16:10:47 +02:00
|
|
|
$linkedItem_sql,
|
|
|
|
[],
|
|
|
|
Application_Common_Database::COLUMN
|
|
|
|
);
|
2012-07-11 00:51:32 +02:00
|
|
|
|
2013-11-22 15:39:19 +01:00
|
|
|
if (!$linkedItemEnds) {
|
2022-03-14 11:15:04 +01:00
|
|
|
// With dynamic smart blocks there may be different number of items in
|
|
|
|
// each show. In case the position does not exist we need to select
|
|
|
|
// the end time of the last position
|
2021-10-11 16:10:47 +02:00
|
|
|
$maxPos_sql = 'SELECT max(position) from cc_schedule ' .
|
2022-07-07 20:01:15 +02:00
|
|
|
"WHERE instance_id = {$instanceId}";
|
2013-11-22 15:39:19 +01:00
|
|
|
$pos = Application_Common_Database::prepareAndExecute(
|
2021-10-11 16:10:47 +02:00
|
|
|
$maxPos_sql,
|
|
|
|
[],
|
|
|
|
Application_Common_Database::COLUMN
|
|
|
|
);
|
2013-11-22 15:39:19 +01:00
|
|
|
|
2022-03-14 11:15:04 +01:00
|
|
|
// show instance has no scheduled tracks
|
2013-12-02 22:40:15 +01:00
|
|
|
if (empty($pos)) {
|
|
|
|
$pos = 0;
|
2021-10-11 16:10:47 +02:00
|
|
|
$nextStartDT = new DateTime($instance->getDbStarts(), new DateTimeZone('UTC'));
|
2013-12-02 22:40:15 +01:00
|
|
|
} else {
|
2021-10-11 16:10:47 +02:00
|
|
|
$linkedItem_sql = 'SELECT ends FROM cc_schedule ' .
|
|
|
|
"WHERE instance_id = {$instanceId} " .
|
|
|
|
"AND position = {$pos} " .
|
|
|
|
'AND playout_status != -1';
|
2013-12-02 22:40:15 +01:00
|
|
|
$linkedItemEnds = Application_Common_Database::prepareAndExecute(
|
2021-10-11 16:10:47 +02:00
|
|
|
$linkedItem_sql,
|
|
|
|
[],
|
|
|
|
Application_Common_Database::COLUMN
|
|
|
|
);
|
2013-12-02 22:40:15 +01:00
|
|
|
|
|
|
|
$nextStartDT = $this->findNextStartTime(
|
2021-10-11 16:10:47 +02:00
|
|
|
new DateTime($linkedItemEnds, new DateTimeZone('UTC')),
|
|
|
|
$instanceId
|
|
|
|
);
|
2013-12-02 22:40:15 +01:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
$nextStartDT = $this->findNextStartTime(
|
2021-10-11 16:10:47 +02:00
|
|
|
new DateTime($linkedItemEnds, new DateTimeZone('UTC')),
|
|
|
|
$instanceId
|
|
|
|
);
|
2013-11-22 15:39:19 +01:00
|
|
|
|
2021-10-11 16:10:47 +02:00
|
|
|
++$pos;
|
2013-12-02 22:40:15 +01:00
|
|
|
}
|
2013-04-18 22:12:26 +02:00
|
|
|
}
|
2022-03-14 11:15:04 +01:00
|
|
|
// selected empty row to add after
|
2013-04-18 22:12:26 +02:00
|
|
|
else {
|
2021-10-11 16:10:47 +02:00
|
|
|
$showStartDT = new DateTime($instance->getDbStarts(), new DateTimeZone('UTC'));
|
2013-05-22 22:10:10 +02:00
|
|
|
$nextStartDT = $this->findNextStartTime($showStartDT, $instanceId);
|
2012-02-01 18:47:08 +01:00
|
|
|
|
2022-03-14 11:15:04 +01:00
|
|
|
// first item in show so start position counter at 0
|
2013-04-18 22:12:26 +02:00
|
|
|
$pos = 0;
|
2013-05-29 15:41:06 +02:00
|
|
|
|
|
|
|
/* Show is empty so we don't need to calculate crossfades
|
|
|
|
* for the first inserted item
|
|
|
|
*/
|
2013-10-10 18:11:23 +02:00
|
|
|
$this->applyCrossfades = false;
|
2012-02-02 18:13:20 +01:00
|
|
|
}
|
2012-07-11 00:51:32 +02:00
|
|
|
|
2013-05-22 22:10:10 +02:00
|
|
|
if (!in_array($instanceId, $affectedShowInstances)) {
|
2013-05-15 21:32:29 +02:00
|
|
|
$affectedShowInstances[] = $instanceId;
|
2012-07-25 04:24:08 +02:00
|
|
|
}
|
2012-07-11 00:51:32 +02:00
|
|
|
|
2013-04-18 22:12:26 +02:00
|
|
|
/*
|
|
|
|
* $adjustSched is true if there are schedule items
|
|
|
|
* following the item just inserted, per show instance
|
|
|
|
*/
|
|
|
|
if ($adjustSched === true) {
|
|
|
|
$pstart = microtime(true);
|
2012-01-31 18:59:27 +01:00
|
|
|
|
2013-10-10 18:11:23 +02:00
|
|
|
if ($this->applyCrossfades) {
|
2013-05-29 17:42:02 +02:00
|
|
|
$initalStartDT = clone $this->findTimeDifference(
|
2021-10-11 16:10:47 +02:00
|
|
|
$nextStartDT,
|
|
|
|
$this->crossfadeDuration
|
|
|
|
);
|
2013-05-29 17:42:02 +02:00
|
|
|
} else {
|
|
|
|
$initalStartDT = clone $nextStartDT;
|
|
|
|
}
|
2012-01-31 18:59:27 +01:00
|
|
|
|
2013-04-18 22:12:26 +02:00
|
|
|
$pend = microtime(true);
|
2021-10-11 16:10:47 +02:00
|
|
|
Logging::debug('finding all following items.');
|
2013-04-18 22:12:26 +02:00
|
|
|
Logging::debug(floatval($pend) - floatval($pstart));
|
2012-02-02 18:13:20 +01:00
|
|
|
}
|
2013-01-18 20:28:45 +01:00
|
|
|
|
2018-11-24 23:08:39 +01:00
|
|
|
// passing $schedule["instance"] so that the instance being scheduled
|
|
|
|
// can be used to determine the remaining time
|
|
|
|
// in the case of a fill remaining time smart block
|
2013-04-25 15:00:37 +02:00
|
|
|
if (is_null($filesToInsert)) {
|
2021-10-11 16:10:47 +02:00
|
|
|
$filesToInsert = [];
|
2013-04-25 15:00:37 +02:00
|
|
|
foreach ($mediaItems as $media) {
|
2021-10-11 16:10:47 +02:00
|
|
|
$filesToInsert = array_merge(
|
|
|
|
$filesToInsert,
|
|
|
|
$this->retrieveMediaFiles($media['id'], $media['type'], $schedule['instance'])
|
|
|
|
);
|
2013-04-25 15:00:37 +02:00
|
|
|
}
|
2012-07-25 04:24:08 +02:00
|
|
|
}
|
2013-05-07 20:49:24 +02:00
|
|
|
|
2013-05-22 22:10:10 +02:00
|
|
|
$doInsert = false;
|
|
|
|
$doUpdate = false;
|
2021-10-11 16:10:47 +02:00
|
|
|
$values = [];
|
2013-05-27 16:39:31 +02:00
|
|
|
|
2022-03-14 11:15:04 +01:00
|
|
|
// array that stores the cc_file ids so we can update the is_scheduled flag
|
2021-10-11 16:10:47 +02:00
|
|
|
$fileIds = [];
|
2014-02-24 23:46:16 +01:00
|
|
|
|
2013-05-15 21:32:29 +02:00
|
|
|
foreach ($filesToInsert as &$file) {
|
2022-03-14 11:15:04 +01:00
|
|
|
// item existed previously and is being moved.
|
|
|
|
// need to keep same id for resources if we want REST.
|
2013-04-18 22:12:26 +02:00
|
|
|
if (isset($file['sched_id'])) {
|
2013-05-27 21:34:54 +02:00
|
|
|
$adjustFromDT = clone $nextStartDT;
|
2013-05-22 22:10:10 +02:00
|
|
|
$doUpdate = true;
|
|
|
|
|
2021-10-11 16:10:47 +02:00
|
|
|
$movedItem_sql = 'SELECT * FROM cc_schedule ' .
|
|
|
|
'WHERE id = ' . $file['sched_id'];
|
2013-05-22 22:10:10 +02:00
|
|
|
$sched = Application_Common_Database::prepareAndExecute(
|
2021-10-11 16:10:47 +02:00
|
|
|
$movedItem_sql,
|
|
|
|
[],
|
|
|
|
Application_Common_Database::SINGLE
|
|
|
|
);
|
2013-04-26 22:10:01 +02:00
|
|
|
|
2013-05-07 20:49:24 +02:00
|
|
|
/* We need to keep a record of the original positon a track
|
|
|
|
* is being moved from so we can use it to retrieve the correct
|
|
|
|
* items in linked instances
|
|
|
|
*/
|
|
|
|
if (!isset($originalPosition)) {
|
2021-10-11 16:10:47 +02:00
|
|
|
$originalPosition = $sched['position'];
|
2013-05-07 20:49:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* If we are moving an item in a linked show we need to get
|
|
|
|
* the relative item to move in each instance. We know what the
|
|
|
|
* relative item is by its position
|
|
|
|
*/
|
2013-05-22 22:10:10 +02:00
|
|
|
if ($linked) {
|
2021-10-11 16:10:47 +02:00
|
|
|
$movedItem_sql = 'SELECT * FROM cc_schedule ' .
|
|
|
|
"WHERE position = {$originalPosition} " .
|
2013-05-22 22:10:10 +02:00
|
|
|
"AND instance_id = {$instanceId}";
|
|
|
|
|
|
|
|
$sched = Application_Common_Database::prepareAndExecute(
|
2021-10-11 16:10:47 +02:00
|
|
|
$movedItem_sql,
|
|
|
|
[],
|
|
|
|
Application_Common_Database::SINGLE
|
|
|
|
);
|
2013-05-07 20:49:24 +02:00
|
|
|
}
|
2013-12-02 22:40:15 +01:00
|
|
|
/* If we don't find a schedule item it means the linked
|
|
|
|
* shows have a different amount of items (dyanmic block)
|
|
|
|
* and we should skip the item move for this show instance
|
|
|
|
*/
|
|
|
|
if (!$sched) {
|
|
|
|
continue;
|
|
|
|
}
|
2021-10-11 16:10:47 +02:00
|
|
|
$excludeIds[] = intval($sched['id']);
|
2013-04-18 22:12:26 +02:00
|
|
|
|
2021-10-11 16:10:47 +02:00
|
|
|
$file['cliplength'] = $sched['clip_length'];
|
|
|
|
$file['cuein'] = $sched['cue_in'];
|
|
|
|
$file['cueout'] = $sched['cue_out'];
|
|
|
|
$file['fadein'] = $sched['fade_in'];
|
|
|
|
$file['fadeout'] = $sched['fade_out'];
|
2013-04-18 22:12:26 +02:00
|
|
|
} else {
|
2013-05-22 22:10:10 +02:00
|
|
|
$doInsert = true;
|
2013-04-18 22:12:26 +02:00
|
|
|
}
|
2012-08-29 16:58:03 +02:00
|
|
|
|
2013-04-18 22:12:26 +02:00
|
|
|
// default fades are in seconds
|
|
|
|
// we need to convert to '00:00:00' format
|
2021-10-11 16:10:47 +02:00
|
|
|
// added a check to only run the conversion if they are in seconds format
|
2019-03-03 02:36:02 +01:00
|
|
|
// otherwise php > 7.1 throws errors
|
|
|
|
if (is_numeric($file['fadein'])) {
|
|
|
|
$file['fadein'] = Application_Common_DateHelper::secondsToPlaylistTime($file['fadein']);
|
|
|
|
}
|
|
|
|
if (is_numeric($file['fadeout'])) {
|
|
|
|
$file['fadeout'] = Application_Common_DateHelper::secondsToPlaylistTime($file['fadeout']);
|
|
|
|
}
|
2013-04-18 22:12:26 +02:00
|
|
|
|
2021-10-11 16:10:47 +02:00
|
|
|
switch ($file['type']) {
|
2013-04-18 22:12:26 +02:00
|
|
|
case 0:
|
2021-10-11 16:10:47 +02:00
|
|
|
$fileId = $file['id'];
|
|
|
|
$streamId = 'null';
|
2014-01-30 18:38:18 +01:00
|
|
|
$fileIds[] = $fileId;
|
2021-10-11 16:10:47 +02:00
|
|
|
|
2013-04-18 22:12:26 +02:00
|
|
|
break;
|
2021-10-11 16:10:47 +02:00
|
|
|
|
2013-04-18 22:12:26 +02:00
|
|
|
case 1:
|
2021-10-11 16:10:47 +02:00
|
|
|
$streamId = $file['id'];
|
|
|
|
$fileId = 'null';
|
|
|
|
|
2013-04-18 22:12:26 +02:00
|
|
|
break;
|
2021-10-11 16:10:47 +02:00
|
|
|
|
2022-07-07 20:01:15 +02:00
|
|
|
default:
|
|
|
|
break;
|
2013-04-18 22:12:26 +02:00
|
|
|
}
|
2012-07-11 00:51:32 +02:00
|
|
|
|
2013-10-10 18:11:23 +02:00
|
|
|
if ($this->applyCrossfades) {
|
2021-10-11 16:10:47 +02:00
|
|
|
$nextStartDT = $this->findTimeDifference(
|
|
|
|
$nextStartDT,
|
|
|
|
$this->crossfadeDuration
|
|
|
|
);
|
2013-05-29 19:16:14 +02:00
|
|
|
$endTimeDT = $this->findEndTime($nextStartDT, $file['cliplength']);
|
2013-05-29 19:14:44 +02:00
|
|
|
$endTimeDT = $this->findTimeDifference($endTimeDT, $this->crossfadeDuration);
|
2013-05-29 15:41:06 +02:00
|
|
|
/* Set it to false because the rest of the crossfades
|
|
|
|
* will be applied after we insert each item
|
|
|
|
*/
|
2013-10-10 18:11:23 +02:00
|
|
|
$this->applyCrossfades = false;
|
2013-05-29 15:41:06 +02:00
|
|
|
}
|
|
|
|
|
2013-05-29 19:14:44 +02:00
|
|
|
$endTimeDT = $this->findEndTime($nextStartDT, $file['cliplength']);
|
2013-05-22 22:10:10 +02:00
|
|
|
if ($doInsert) {
|
2021-10-11 16:10:47 +02:00
|
|
|
$values[] = '(' .
|
|
|
|
"'{$nextStartDT->format(DEFAULT_MICROTIME_FORMAT)}', " .
|
|
|
|
"'{$endTimeDT->format(DEFAULT_MICROTIME_FORMAT)}', " .
|
|
|
|
"'{$file['cuein']}', " .
|
|
|
|
"'{$file['cueout']}', " .
|
|
|
|
"'{$file['fadein']}', " .
|
|
|
|
"'{$file['fadeout']}', " .
|
|
|
|
"'{$file['cliplength']}', " .
|
|
|
|
"{$pos}, " .
|
|
|
|
"{$instanceId}, " .
|
|
|
|
"{$fileId}, " .
|
2013-05-22 22:10:10 +02:00
|
|
|
"{$streamId})";
|
|
|
|
} elseif ($doUpdate) {
|
2021-10-11 16:10:47 +02:00
|
|
|
$update_sql = 'UPDATE cc_schedule SET ' .
|
|
|
|
"starts = '{$nextStartDT->format(DEFAULT_MICROTIME_FORMAT)}', " .
|
|
|
|
"ends = '{$endTimeDT->format(DEFAULT_MICROTIME_FORMAT)}', " .
|
|
|
|
"cue_in = '{$file['cuein']}', " .
|
|
|
|
"cue_out = '{$file['cueout']}', " .
|
|
|
|
"fade_in = '{$file['fadein']}', " .
|
|
|
|
"fade_out = '{$file['fadeout']}', " .
|
|
|
|
"clip_length = '{$file['cliplength']}', " .
|
|
|
|
"position = {$pos}, " .
|
|
|
|
"instance_id = {$instanceId} " .
|
|
|
|
"WHERE id = {$sched['id']}";
|
2013-05-22 22:10:10 +02:00
|
|
|
|
|
|
|
Application_Common_Database::prepareAndExecute(
|
2021-10-11 16:10:47 +02:00
|
|
|
$update_sql,
|
|
|
|
[],
|
|
|
|
Application_Common_Database::EXECUTE
|
|
|
|
);
|
2013-05-22 22:10:10 +02:00
|
|
|
}
|
2012-07-11 00:51:32 +02:00
|
|
|
|
2013-05-27 16:39:31 +02:00
|
|
|
$nextStartDT = $this->findTimeDifference($endTimeDT, $this->crossfadeDuration);
|
2021-10-11 16:10:47 +02:00
|
|
|
++$pos;
|
2022-07-07 20:01:15 +02:00
|
|
|
} // all files have been inserted/moved
|
2013-05-22 22:10:10 +02:00
|
|
|
if ($doInsert) {
|
2021-10-11 16:10:47 +02:00
|
|
|
$insert_sql = 'INSERT INTO cc_schedule ' .
|
|
|
|
'(starts, ends, cue_in, cue_out, fade_in, fade_out, ' .
|
|
|
|
'clip_length, position, instance_id, file_id, stream_id) VALUES ' .
|
Feature: Support php7.4 (#1354)
* Run CI tests against php 7.4
* Sort composer dependencies
* Remove unused Aws S3 php library
* Pin simplepie dependency to ^1.5
* Pin getid3 dependency to ^1.9
* Pin composer semver to ^3.2
* Pin php-amqplib to ^2.12
* Drop sentry logging support
* Update composer dependencies
* Move propel regenerate to Makefile
* Regenerate propel files with v1.7.0
* Pin propel orm to ^1.7
* Regenerate propel files with v1.7.2
* fix: generator_version in airtime-conf-production.php
* Replace propel/propel1 with jooola/propel1
* Regenerate propel files with v1.7.3-dev
* Fix php7.4 compatibility
Using php-cs-fixer:
'@PhpCsFixer' => true,
'concat_space' => ['spacing' => 'one'],
'ordered_class_elements' => false,
'yoda_style' => false,
'@PHP74Migration' => true,
'assign_null_coalescing_to_coalesce_equal' => false,
'ternary_to_null_coalescing' => false,
'heredoc_indentation' => false,
'@PHP74Migration:risky' => true,
'declare_strict_types' => false,
'void_return' => false,
'use_arrow_functions' => false,
* Fix pre-commit
2021-10-17 17:19:53 +02:00
|
|
|
implode(',', $values) . ' RETURNING id';
|
2013-05-27 21:34:54 +02:00
|
|
|
|
2013-05-28 17:25:37 +02:00
|
|
|
$stmt = $this->con->prepare($insert_sql);
|
|
|
|
if ($stmt->execute()) {
|
|
|
|
foreach ($stmt->fetchAll() as $row) {
|
2021-10-11 16:10:47 +02:00
|
|
|
$excludeIds[] = $row['id'];
|
2013-05-28 17:25:37 +02:00
|
|
|
}
|
2021-10-11 16:10:47 +02:00
|
|
|
}
|
2013-05-22 22:10:10 +02:00
|
|
|
}
|
2014-01-30 18:38:18 +01:00
|
|
|
|
2013-05-15 21:32:29 +02:00
|
|
|
$selectCriteria = new Criteria();
|
|
|
|
$selectCriteria->add(CcFilesPeer::ID, $fileIds, Criteria::IN);
|
|
|
|
$selectCriteria->addAnd(CcFilesPeer::IS_SCHEDULED, false);
|
|
|
|
$updateCriteria = new Criteria();
|
|
|
|
$updateCriteria->add(CcFilesPeer::IS_SCHEDULED, true);
|
|
|
|
BasePeer::doUpdate($selectCriteria, $updateCriteria, $this->con);
|
|
|
|
|
2013-04-25 15:00:37 +02:00
|
|
|
/* Reset files to insert so we can get a new set of files. We have
|
|
|
|
* to do this in case we are inserting a dynamic block
|
|
|
|
*/
|
2013-04-26 19:43:30 +02:00
|
|
|
if (!$moveAction) {
|
|
|
|
$filesToInsert = null;
|
2012-01-31 18:59:27 +01:00
|
|
|
}
|
2012-07-11 00:51:32 +02:00
|
|
|
|
2013-04-18 22:12:26 +02:00
|
|
|
if ($adjustSched === true) {
|
2021-10-11 16:10:47 +02:00
|
|
|
$followingItems_sql = 'SELECT * FROM cc_schedule ' .
|
|
|
|
"WHERE starts >= '{$initalStartDT->format(DEFAULT_MICROTIME_FORMAT)}' " .
|
2013-05-22 22:10:10 +02:00
|
|
|
"AND instance_id = {$instanceId} ";
|
|
|
|
if (count($excludeIds) > 0) {
|
Feature: Support php7.4 (#1354)
* Run CI tests against php 7.4
* Sort composer dependencies
* Remove unused Aws S3 php library
* Pin simplepie dependency to ^1.5
* Pin getid3 dependency to ^1.9
* Pin composer semver to ^3.2
* Pin php-amqplib to ^2.12
* Drop sentry logging support
* Update composer dependencies
* Move propel regenerate to Makefile
* Regenerate propel files with v1.7.0
* Pin propel orm to ^1.7
* Regenerate propel files with v1.7.2
* fix: generator_version in airtime-conf-production.php
* Replace propel/propel1 with jooola/propel1
* Regenerate propel files with v1.7.3-dev
* Fix php7.4 compatibility
Using php-cs-fixer:
'@PhpCsFixer' => true,
'concat_space' => ['spacing' => 'one'],
'ordered_class_elements' => false,
'yoda_style' => false,
'@PHP74Migration' => true,
'assign_null_coalescing_to_coalesce_equal' => false,
'ternary_to_null_coalescing' => false,
'heredoc_indentation' => false,
'@PHP74Migration:risky' => true,
'declare_strict_types' => false,
'void_return' => false,
'use_arrow_functions' => false,
* Fix pre-commit
2021-10-17 17:19:53 +02:00
|
|
|
$followingItems_sql .= 'AND id NOT IN (' . implode(',', $excludeIds) . ') ';
|
2013-05-22 22:10:10 +02:00
|
|
|
}
|
2021-10-11 16:10:47 +02:00
|
|
|
$followingItems_sql .= 'ORDER BY starts';
|
2013-05-22 22:10:10 +02:00
|
|
|
$followingSchedItems = Application_Common_Database::prepareAndExecute(
|
2021-10-11 16:10:47 +02:00
|
|
|
$followingItems_sql
|
|
|
|
);
|
2013-04-18 22:12:26 +02:00
|
|
|
|
|
|
|
$pstart = microtime(true);
|
|
|
|
|
2022-03-14 11:15:04 +01:00
|
|
|
// recalculate the start/end times after the inserted items.
|
2013-04-18 22:12:26 +02:00
|
|
|
foreach ($followingSchedItems as $item) {
|
2021-10-11 16:10:47 +02:00
|
|
|
$endTimeDT = $this->findEndTime($nextStartDT, $item['clip_length']);
|
2013-05-29 18:49:48 +02:00
|
|
|
$endTimeDT = $this->findTimeDifference($endTimeDT, $this->crossfadeDuration);
|
2021-10-11 16:10:47 +02:00
|
|
|
$update_sql = 'UPDATE cc_schedule SET ' .
|
|
|
|
"starts = '{$nextStartDT->format(DEFAULT_MICROTIME_FORMAT)}', " .
|
|
|
|
"ends = '{$endTimeDT->format(DEFAULT_MICROTIME_FORMAT)}', " .
|
|
|
|
"position = {$pos} " .
|
|
|
|
"WHERE id = {$item['id']}";
|
2013-05-22 22:10:10 +02:00
|
|
|
Application_Common_Database::prepareAndExecute(
|
2021-10-11 16:10:47 +02:00
|
|
|
$update_sql,
|
|
|
|
[],
|
|
|
|
Application_Common_Database::EXECUTE
|
|
|
|
);
|
2013-05-22 22:10:10 +02:00
|
|
|
|
2013-05-27 16:39:31 +02:00
|
|
|
$nextStartDT = $this->findTimeDifference($endTimeDT, $this->crossfadeDuration);
|
2021-10-11 16:10:47 +02:00
|
|
|
++$pos;
|
2013-04-18 22:12:26 +02:00
|
|
|
}
|
2012-07-11 00:51:32 +02:00
|
|
|
|
2013-04-18 22:12:26 +02:00
|
|
|
$pend = microtime(true);
|
2021-10-11 16:10:47 +02:00
|
|
|
Logging::debug('adjusting all following items.');
|
2013-04-18 22:12:26 +02:00
|
|
|
Logging::debug(floatval($pend) - floatval($pstart));
|
|
|
|
}
|
2013-06-07 19:07:08 +02:00
|
|
|
if ($moveAction) {
|
|
|
|
$this->calculateCrossfades($instanceId);
|
|
|
|
}
|
2022-07-07 20:01:15 +02:00
|
|
|
} // for each instance
|
|
|
|
} // for each schedule location
|
2012-07-11 00:51:32 +02:00
|
|
|
|
2012-07-16 03:17:13 +02:00
|
|
|
$endProfile = microtime(true);
|
2021-10-11 16:10:47 +02:00
|
|
|
Logging::debug('finished adding scheduled items.');
|
2012-04-16 16:33:32 +02:00
|
|
|
Logging::debug(floatval($endProfile) - floatval($startProfile));
|
2012-02-01 18:47:08 +01:00
|
|
|
|
2022-03-14 11:15:04 +01:00
|
|
|
// update the status flag in cc_schedule.
|
2012-03-01 14:59:06 +01:00
|
|
|
$instances = CcShowInstancesQuery::create()
|
|
|
|
->filterByPrimaryKeys($affectedShowInstances)
|
2022-01-23 19:15:55 +01:00
|
|
|
->find($this->con);
|
2012-03-01 14:59:06 +01:00
|
|
|
|
2012-04-16 16:33:32 +02:00
|
|
|
$startProfile = microtime(true);
|
2012-07-11 00:51:32 +02:00
|
|
|
|
2012-03-01 14:59:06 +01:00
|
|
|
foreach ($instances as $instance) {
|
|
|
|
$instance->updateScheduleStatus($this->con);
|
|
|
|
}
|
2012-07-11 00:51:32 +02:00
|
|
|
|
2012-07-16 03:17:13 +02:00
|
|
|
$endProfile = microtime(true);
|
2021-10-11 16:10:47 +02:00
|
|
|
Logging::debug('updating show instances status.');
|
2012-04-16 16:33:32 +02:00
|
|
|
Logging::debug(floatval($endProfile) - floatval($startProfile));
|
2012-03-01 14:59:06 +01:00
|
|
|
|
2012-04-16 16:33:32 +02:00
|
|
|
$startProfile = microtime(true);
|
2012-07-11 00:51:32 +02:00
|
|
|
|
2022-03-14 11:15:04 +01:00
|
|
|
// update the last scheduled timestamp.
|
2012-02-16 19:46:14 +01:00
|
|
|
CcShowInstancesQuery::create()
|
2012-02-17 11:14:44 +01:00
|
|
|
->filterByPrimaryKeys($affectedShowInstances)
|
2022-01-23 19:15:55 +01:00
|
|
|
->update(['DbLastScheduled' => new DateTime('now', new DateTimeZone('UTC'))], $this->con);
|
2012-07-11 00:51:32 +02:00
|
|
|
|
2012-07-16 03:17:13 +02:00
|
|
|
$endProfile = microtime(true);
|
2021-10-11 16:10:47 +02:00
|
|
|
Logging::debug('updating last scheduled timestamp.');
|
2012-04-16 16:33:32 +02:00
|
|
|
Logging::debug(floatval($endProfile) - floatval($startProfile));
|
2012-07-16 03:17:13 +02:00
|
|
|
} catch (Exception $e) {
|
2012-03-26 19:08:52 +02:00
|
|
|
Logging::debug($e->getMessage());
|
2021-10-11 16:10:47 +02:00
|
|
|
|
2012-02-02 18:13:20 +01:00
|
|
|
throw $e;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-08 15:45:24 +02:00
|
|
|
private function updateMovedItem() {}
|
2013-05-22 22:10:10 +02:00
|
|
|
|
2013-04-12 22:34:36 +02:00
|
|
|
private function getInstances($instanceId)
|
|
|
|
{
|
|
|
|
$ccShowInstance = CcShowInstancesQuery::create()->findPk($instanceId);
|
|
|
|
$ccShow = $ccShowInstance->getCcShow();
|
|
|
|
if ($ccShow->isLinked()) {
|
2014-08-16 17:05:55 +02:00
|
|
|
return $ccShow->getFutureCcShowInstancess();
|
2013-04-12 22:34:36 +02:00
|
|
|
}
|
2021-10-11 16:10:47 +02:00
|
|
|
|
|
|
|
return [$ccShowInstance];
|
2013-04-12 22:34:36 +02:00
|
|
|
}
|
|
|
|
|
2012-02-02 18:38:56 +01:00
|
|
|
/*
|
2013-04-04 22:30:33 +02:00
|
|
|
* @param array $scheduleItems (schedule_id and instance_id it belongs to)
|
|
|
|
* @param array $mediaItems (file|block|playlist|webstream)
|
2012-02-02 18:38:56 +01:00
|
|
|
*/
|
2012-07-16 03:17:13 +02:00
|
|
|
public function scheduleAfter($scheduleItems, $mediaItems, $adjustSched = true)
|
|
|
|
{
|
2012-02-02 18:38:56 +01:00
|
|
|
$this->con->beginTransaction();
|
|
|
|
|
|
|
|
try {
|
2022-03-14 11:15:04 +01:00
|
|
|
// Increase the transaction isolation level to prevent two concurrent requests from potentially resulting
|
|
|
|
// in tracks scheduled at the same time.
|
2021-10-11 16:10:47 +02:00
|
|
|
$this->con->exec('SET TRANSACTION ISOLATION LEVEL SERIALIZABLE');
|
2015-10-19 23:31:26 +02:00
|
|
|
|
2022-03-14 11:15:04 +01:00
|
|
|
$this->validateMediaItems($mediaItems); // Check for missing files, etc.
|
2013-04-18 22:12:26 +02:00
|
|
|
$this->validateRequest($scheduleItems, true);
|
2012-02-02 18:38:56 +01:00
|
|
|
|
2013-04-04 22:30:33 +02:00
|
|
|
/*
|
|
|
|
* create array of arrays
|
|
|
|
* array of schedule item info
|
|
|
|
* (sched_id is the cc_schedule id and is set if an item is being
|
|
|
|
* moved because it is already in cc_schedule)
|
|
|
|
* [0] = Array(
|
|
|
|
* id => 1,
|
|
|
|
* cliplength => 00:04:32,
|
|
|
|
* cuein => 00:00:00,
|
|
|
|
* cueout => 00:04:32,
|
|
|
|
* fadein => 00.5,
|
|
|
|
* fadeout => 00.5,
|
|
|
|
* sched_id => ,
|
|
|
|
* type => 0)
|
|
|
|
* [1] = Array(
|
|
|
|
* id => 2,
|
|
|
|
* cliplength => 00:05:07,
|
|
|
|
* cuein => 00:00:00,
|
|
|
|
* cueout => 00:05:07,
|
|
|
|
* fadein => 00.5,
|
|
|
|
* fadeout => 00.5,
|
|
|
|
* sched_id => ,
|
|
|
|
* type => 0)
|
|
|
|
*/
|
2013-04-25 15:00:37 +02:00
|
|
|
$this->insertAfter($scheduleItems, $mediaItems, null, $adjustSched);
|
2012-02-02 18:38:56 +01:00
|
|
|
|
|
|
|
$this->con->commit();
|
2012-02-09 21:19:21 +01:00
|
|
|
|
|
|
|
Application_Model_RabbitMq::PushSchedule();
|
2012-07-16 03:17:13 +02:00
|
|
|
} catch (Exception $e) {
|
2012-02-02 18:38:56 +01:00
|
|
|
$this->con->rollback();
|
2021-10-11 16:10:47 +02:00
|
|
|
|
2012-02-02 18:38:56 +01:00
|
|
|
throw $e;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-02-02 18:13:20 +01:00
|
|
|
/*
|
|
|
|
* @param array $selectedItem
|
|
|
|
* @param array $afterItem
|
|
|
|
*/
|
2012-07-16 03:17:13 +02:00
|
|
|
public function moveItem($selectedItems, $afterItems, $adjustSched = true)
|
|
|
|
{
|
2022-03-14 11:15:04 +01:00
|
|
|
// $startProfile = microtime(true);
|
2012-07-11 00:51:32 +02:00
|
|
|
|
2012-02-02 18:13:20 +01:00
|
|
|
$this->con->beginTransaction();
|
2022-03-14 11:15:04 +01:00
|
|
|
// $this->con->useDebug(true);
|
2012-07-11 00:51:32 +02:00
|
|
|
|
2012-02-02 18:13:20 +01:00
|
|
|
try {
|
2022-03-14 11:15:04 +01:00
|
|
|
// Increase the transaction isolation level to prevent two concurrent requests from potentially resulting
|
|
|
|
// in tracks scheduled at the same time.
|
2021-10-11 16:10:47 +02:00
|
|
|
$this->con->exec('SET TRANSACTION ISOLATION LEVEL SERIALIZABLE');
|
2012-07-11 00:51:32 +02:00
|
|
|
|
2013-04-12 22:34:36 +02:00
|
|
|
$this->validateItemMove($selectedItems, $afterItems[0]);
|
2012-03-28 14:23:25 +02:00
|
|
|
$this->validateRequest($selectedItems);
|
|
|
|
$this->validateRequest($afterItems);
|
2012-07-11 00:51:32 +02:00
|
|
|
|
2012-07-16 03:17:13 +02:00
|
|
|
$endProfile = microtime(true);
|
2022-03-14 11:15:04 +01:00
|
|
|
// Logging::debug("validating move request took:");
|
|
|
|
// Logging::debug(floatval($endProfile) - floatval($startProfile));
|
2012-07-16 03:17:13 +02:00
|
|
|
|
2021-10-11 16:10:47 +02:00
|
|
|
$afterInstance = CcShowInstancesQuery::create()->findPK($afterItems[0]['instance'], $this->con);
|
2012-07-11 00:51:32 +02:00
|
|
|
|
2022-03-14 11:15:04 +01:00
|
|
|
// map show instances to cc_schedule primary keys.
|
2021-10-11 16:10:47 +02:00
|
|
|
$modifiedMap = [];
|
|
|
|
$movedData = [];
|
2012-07-11 00:51:32 +02:00
|
|
|
|
2022-03-14 11:15:04 +01:00
|
|
|
// prepare each of the selected items.
|
2021-10-11 16:10:47 +02:00
|
|
|
for ($i = 0; $i < count($selectedItems); ++$i) {
|
|
|
|
$selected = CcScheduleQuery::create()->findPk($selectedItems[$i]['id'], $this->con);
|
2012-07-16 03:17:13 +02:00
|
|
|
$selectedInstance = $selected->getCcShowInstances($this->con);
|
2012-07-11 00:51:32 +02:00
|
|
|
|
2012-07-16 03:17:13 +02:00
|
|
|
$data = $this->fileInfo;
|
2021-10-11 16:10:47 +02:00
|
|
|
$data['id'] = $selected->getDbFileId();
|
|
|
|
$data['cliplength'] = $selected->getDbClipLength();
|
|
|
|
$data['cuein'] = $selected->getDbCueIn();
|
|
|
|
$data['cueout'] = $selected->getDbCueOut();
|
|
|
|
$data['fadein'] = $selected->getDbFadeIn();
|
|
|
|
$data['fadeout'] = $selected->getDbFadeOut();
|
|
|
|
$data['sched_id'] = $selected->getDbId();
|
2012-07-11 00:51:32 +02:00
|
|
|
|
2012-03-20 17:55:35 +01:00
|
|
|
$movedData[] = $data;
|
2012-07-11 00:51:32 +02:00
|
|
|
|
2022-03-14 11:15:04 +01:00
|
|
|
// figure out which items must be removed from calculated show times.
|
2012-03-20 17:55:35 +01:00
|
|
|
$showInstanceId = $selectedInstance->getDbId();
|
|
|
|
$schedId = $selected->getDbId();
|
|
|
|
if (isset($modifiedMap[$showInstanceId])) {
|
2012-07-11 00:51:32 +02:00
|
|
|
array_push($modifiedMap[$showInstanceId], $schedId);
|
2012-07-16 03:17:13 +02:00
|
|
|
} else {
|
2021-10-11 16:10:47 +02:00
|
|
|
$modifiedMap[$showInstanceId] = [$schedId];
|
2012-03-20 17:55:35 +01:00
|
|
|
}
|
2012-07-11 00:51:32 +02:00
|
|
|
}
|
2012-02-02 18:13:20 +01:00
|
|
|
|
2022-03-14 11:15:04 +01:00
|
|
|
// calculate times excluding the to be moved items.
|
2012-03-20 17:55:35 +01:00
|
|
|
foreach ($modifiedMap as $instance => $schedIds) {
|
2012-04-16 16:33:32 +02:00
|
|
|
$startProfile = microtime(true);
|
2012-07-11 00:51:32 +02:00
|
|
|
|
2012-03-20 17:55:35 +01:00
|
|
|
$this->removeGaps($instance, $schedIds);
|
2012-07-11 00:51:32 +02:00
|
|
|
|
2022-03-14 11:15:04 +01:00
|
|
|
// $endProfile = microtime(true);
|
|
|
|
// Logging::debug("removing gaps from instance $instance:");
|
|
|
|
// Logging::debug(floatval($endProfile) - floatval($startProfile));
|
2012-02-02 18:13:20 +01:00
|
|
|
}
|
2012-07-11 00:51:32 +02:00
|
|
|
|
2022-03-14 11:15:04 +01:00
|
|
|
// $startProfile = microtime(true);
|
2012-07-11 00:51:32 +02:00
|
|
|
|
2013-04-26 19:43:30 +02:00
|
|
|
$this->insertAfter($afterItems, null, $movedData, $adjustSched, true);
|
2012-07-11 00:51:32 +02:00
|
|
|
|
2022-03-14 11:15:04 +01:00
|
|
|
// $endProfile = microtime(true);
|
|
|
|
// Logging::debug("inserting after removing gaps.");
|
|
|
|
// Logging::debug(floatval($endProfile) - floatval($startProfile));
|
2012-07-11 00:51:32 +02:00
|
|
|
|
2012-04-16 16:33:32 +02:00
|
|
|
$modified = array_keys($modifiedMap);
|
2022-03-14 11:15:04 +01:00
|
|
|
// need to adjust shows we have moved items from.
|
2012-07-16 03:17:13 +02:00
|
|
|
foreach ($modified as $instanceId) {
|
2012-04-16 16:33:32 +02:00
|
|
|
$instance = CcShowInstancesQuery::create()->findPK($instanceId, $this->con);
|
|
|
|
$instance->updateScheduleStatus($this->con);
|
|
|
|
}
|
2012-07-11 00:51:32 +02:00
|
|
|
|
2022-03-14 11:15:04 +01:00
|
|
|
// $this->con->useDebug(false);
|
2012-02-01 18:47:08 +01:00
|
|
|
$this->con->commit();
|
2012-02-09 21:19:21 +01:00
|
|
|
|
|
|
|
Application_Model_RabbitMq::PushSchedule();
|
2012-07-16 03:17:13 +02:00
|
|
|
} catch (Exception $e) {
|
2012-02-01 18:47:08 +01:00
|
|
|
$this->con->rollback();
|
2021-10-11 16:10:47 +02:00
|
|
|
|
2012-01-31 18:59:27 +01:00
|
|
|
throw $e;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-11 16:10:47 +02:00
|
|
|
public function removeItems($scheduledItems, $adjustSched = true, $cancelShow = false)
|
2012-07-16 03:17:13 +02:00
|
|
|
{
|
2021-10-11 16:10:47 +02:00
|
|
|
$showInstances = [];
|
2012-01-31 18:59:27 +01:00
|
|
|
$this->con->beginTransaction();
|
|
|
|
|
|
|
|
try {
|
2019-04-23 04:47:37 +02:00
|
|
|
$this->validateRequest($scheduledItems, true, true);
|
2012-07-11 00:51:32 +02:00
|
|
|
|
2021-10-11 16:10:47 +02:00
|
|
|
$scheduledIds = [];
|
2012-02-15 18:27:59 +01:00
|
|
|
foreach ($scheduledItems as $item) {
|
2021-10-11 16:10:47 +02:00
|
|
|
$scheduledIds[] = $item['id'];
|
2012-02-16 16:29:11 +01:00
|
|
|
}
|
|
|
|
|
2012-03-28 14:23:25 +02:00
|
|
|
$removedItems = CcScheduleQuery::create()->findPks($scheduledIds);
|
2012-02-16 16:29:11 +01:00
|
|
|
|
2014-11-19 20:10:53 +01:00
|
|
|
// This array is used to keep track of every show instance that was
|
|
|
|
// effected by the track deletion. It will be used later on to
|
|
|
|
// remove gaps in the schedule and adjust crossfade times.
|
2021-10-11 16:10:47 +02:00
|
|
|
$effectedInstanceIds = [];
|
2012-07-11 00:51:32 +02:00
|
|
|
|
2014-11-19 20:10:53 +01:00
|
|
|
foreach ($removedItems as $removedItem) {
|
2012-02-16 16:29:11 +01:00
|
|
|
$instance = $removedItem->getCcShowInstances($this->con);
|
2015-11-23 20:55:37 +01:00
|
|
|
$effectedInstanceIds[$instance->getDbId()] = $instance->getDbId();
|
2012-07-11 00:51:32 +02:00
|
|
|
|
2022-03-14 11:15:04 +01:00
|
|
|
// check if instance is linked and if so get the schedule items
|
|
|
|
// for all linked instances so we can delete them too
|
2013-04-29 21:27:14 +02:00
|
|
|
if (!$cancelShow && $instance->getCcShow()->isLinked()) {
|
2022-03-14 11:15:04 +01:00
|
|
|
// returns all linked instances if linked
|
2013-04-12 22:34:36 +02:00
|
|
|
$ccShowInstances = $this->getInstances($instance->getDbId());
|
2014-11-19 20:10:53 +01:00
|
|
|
|
2021-10-11 16:10:47 +02:00
|
|
|
$instanceIds = [];
|
2013-04-12 22:34:36 +02:00
|
|
|
foreach ($ccShowInstances as $ccShowInstance) {
|
|
|
|
$instanceIds[] = $ccShowInstance->getDbId();
|
|
|
|
}
|
2014-11-19 20:10:53 +01:00
|
|
|
$effectedInstanceIds = array_merge($effectedInstanceIds, $instanceIds);
|
2021-10-11 16:10:47 +02:00
|
|
|
|
2014-11-19 20:10:53 +01:00
|
|
|
// Delete the same track, represented by $removedItem, in
|
|
|
|
// each linked show instance.
|
2013-04-12 22:34:36 +02:00
|
|
|
$itemsToDelete = CcScheduleQuery::create()
|
|
|
|
->filterByDbPosition($removedItem->getDbPosition())
|
|
|
|
->filterByDbInstanceId($instanceIds, Criteria::IN)
|
2014-11-19 20:10:53 +01:00
|
|
|
->filterByDbId($removedItem->getDbId(), Criteria::NOT_EQUAL)
|
2022-01-23 19:15:55 +01:00
|
|
|
->delete($this->con);
|
2013-04-12 22:34:36 +02:00
|
|
|
}
|
|
|
|
|
2022-03-14 11:15:04 +01:00
|
|
|
// check to truncate the currently playing item instead of deleting it.
|
2012-03-29 19:20:02 +02:00
|
|
|
if ($removedItem->isCurrentItem($this->epochNow)) {
|
|
|
|
$nEpoch = $this->epochNow;
|
2012-03-30 12:24:55 +02:00
|
|
|
$sEpoch = $removedItem->getDbStarts('U.u');
|
2012-07-11 00:51:32 +02:00
|
|
|
|
2021-10-11 16:10:47 +02:00
|
|
|
$length = bcsub($nEpoch, $sEpoch, 6);
|
2012-07-26 00:42:46 +02:00
|
|
|
$cliplength = Application_Common_DateHelper::secondsToPlaylistTime($length);
|
2012-07-11 00:51:32 +02:00
|
|
|
|
2012-07-26 20:41:09 +02:00
|
|
|
$cueinSec = Application_Common_DateHelper::playlistTimeToSeconds($removedItem->getDbCueIn());
|
2021-10-11 16:10:47 +02:00
|
|
|
$cueOutSec = bcadd($cueinSec, $length, 6);
|
2012-07-26 00:42:46 +02:00
|
|
|
$cueout = Application_Common_DateHelper::secondsToPlaylistTime($cueOutSec);
|
2012-07-11 00:51:32 +02:00
|
|
|
|
2022-03-14 11:15:04 +01:00
|
|
|
// Set DbEnds - 1 second because otherwise there can be a timing issue
|
|
|
|
// when sending the new schedule to Pypo where Pypo thinks the track is still
|
|
|
|
// playing.
|
2012-03-29 19:20:02 +02:00
|
|
|
$removedItem->setDbCueOut($cueout)
|
|
|
|
->setDbClipLength($cliplength)
|
2012-08-31 18:18:37 +02:00
|
|
|
->setDbEnds($this->nowDT)
|
2022-01-23 19:15:55 +01:00
|
|
|
->save($this->con);
|
2012-07-16 03:17:13 +02:00
|
|
|
} else {
|
2012-03-27 12:44:48 +02:00
|
|
|
$removedItem->delete($this->con);
|
|
|
|
}
|
2012-02-15 18:27:59 +01:00
|
|
|
}
|
2014-11-19 20:10:53 +01:00
|
|
|
Application_Model_StoredFile::updatePastFilesIsScheduled();
|
2012-02-15 18:27:59 +01:00
|
|
|
|
2012-01-31 18:59:27 +01:00
|
|
|
if ($adjustSched === true) {
|
2014-11-19 20:10:53 +01:00
|
|
|
foreach ($effectedInstanceIds as $instance) {
|
2012-02-01 18:47:08 +01:00
|
|
|
$this->removeGaps($instance);
|
2013-05-02 22:15:21 +02:00
|
|
|
$this->calculateCrossfades($instance);
|
2012-01-31 18:59:27 +01:00
|
|
|
}
|
|
|
|
}
|
2012-01-31 21:39:34 +01:00
|
|
|
|
2022-03-14 11:15:04 +01:00
|
|
|
// update the status flag in cc_schedule.
|
2012-03-01 14:59:06 +01:00
|
|
|
$instances = CcShowInstancesQuery::create()
|
2014-11-19 20:10:53 +01:00
|
|
|
->filterByPrimaryKeys($effectedInstanceIds)
|
2022-01-23 19:15:55 +01:00
|
|
|
->find($this->con);
|
2012-03-01 14:59:06 +01:00
|
|
|
|
|
|
|
foreach ($instances as $instance) {
|
|
|
|
$instance->updateScheduleStatus($this->con);
|
2013-12-02 22:40:15 +01:00
|
|
|
$instance->correctSchedulePositions();
|
2012-03-01 14:59:06 +01:00
|
|
|
}
|
|
|
|
|
2022-03-14 11:15:04 +01:00
|
|
|
// update the last scheduled timestamp.
|
2012-02-16 19:46:14 +01:00
|
|
|
CcShowInstancesQuery::create()
|
|
|
|
->filterByPrimaryKeys($showInstances)
|
2022-01-23 19:15:55 +01:00
|
|
|
->update(['DbLastScheduled' => new DateTime('now', new DateTimeZone('UTC'))], $this->con);
|
2012-02-16 19:46:14 +01:00
|
|
|
|
2012-01-31 21:39:34 +01:00
|
|
|
$this->con->commit();
|
2012-02-09 21:19:21 +01:00
|
|
|
|
|
|
|
Application_Model_RabbitMq::PushSchedule();
|
2012-07-16 03:17:13 +02:00
|
|
|
} catch (Exception $e) {
|
2012-01-31 18:59:27 +01:00
|
|
|
$this->con->rollback();
|
2021-10-11 16:10:47 +02:00
|
|
|
|
2012-01-31 18:59:27 +01:00
|
|
|
throw $e;
|
|
|
|
}
|
|
|
|
}
|
2021-10-11 16:10:47 +02:00
|
|
|
|
|
|
|
// This is used to determine the duration of a files array
|
|
|
|
public function timeLengthOfFiles($files)
|
|
|
|
{
|
|
|
|
$timeLength = 0;
|
|
|
|
foreach ($files as $file) {
|
|
|
|
$timeLength += Application_Common_DateHelper::playlistTimeToSeconds($file['cliplength']);
|
|
|
|
$timeLength += $file['fadein'];
|
|
|
|
$timeLength += $file['fadeout'];
|
|
|
|
}
|
|
|
|
|
|
|
|
return $timeLength;
|
2019-04-22 21:26:09 +02:00
|
|
|
}
|
2012-07-11 00:51:32 +02:00
|
|
|
|
2012-02-02 18:38:56 +01:00
|
|
|
/*
|
2012-04-02 15:20:13 +02:00
|
|
|
* Used for cancelling the current show instance.
|
2012-07-11 00:51:32 +02:00
|
|
|
*
|
2012-04-02 15:20:13 +02:00
|
|
|
* @param $p_id id of the show instance to cancel.
|
2012-02-02 18:38:56 +01:00
|
|
|
*/
|
2012-07-16 03:17:13 +02:00
|
|
|
public function cancelShow($p_id)
|
|
|
|
{
|
2012-04-02 15:20:13 +02:00
|
|
|
$this->con->beginTransaction();
|
2012-07-11 00:51:32 +02:00
|
|
|
|
2012-04-02 15:20:13 +02:00
|
|
|
try {
|
|
|
|
$instance = CcShowInstancesQuery::create()->findPK($p_id);
|
2012-07-11 00:51:32 +02:00
|
|
|
|
2012-04-02 15:31:02 +02:00
|
|
|
if (!$instance->getDbRecord()) {
|
2012-07-16 03:17:13 +02:00
|
|
|
$items = CcScheduleQuery::create()
|
|
|
|
->filterByDbInstanceId($p_id)
|
|
|
|
->filterByDbEnds($this->nowDT, Criteria::GREATER_THAN)
|
2022-01-23 19:15:55 +01:00
|
|
|
->find($this->con);
|
2012-07-11 00:51:32 +02:00
|
|
|
|
2012-04-03 18:26:04 +02:00
|
|
|
if (count($items) > 0) {
|
2021-10-11 16:10:47 +02:00
|
|
|
$remove = [];
|
2012-07-16 03:17:13 +02:00
|
|
|
$ts = $this->nowDT->format('U');
|
|
|
|
|
2021-10-11 16:10:47 +02:00
|
|
|
for ($i = 0; $i < count($items); ++$i) {
|
|
|
|
$remove[$i]['instance'] = $p_id;
|
|
|
|
$remove[$i]['timestamp'] = $ts;
|
|
|
|
$remove[$i]['id'] = $items[$i]->getDbId();
|
2012-07-16 03:17:13 +02:00
|
|
|
}
|
|
|
|
|
2013-04-29 21:27:14 +02:00
|
|
|
$this->removeItems($remove, false, true);
|
2012-05-15 14:56:31 +02:00
|
|
|
}
|
2012-07-16 03:17:13 +02:00
|
|
|
} else {
|
2012-05-15 15:07:42 +02:00
|
|
|
$rebroadcasts = $instance->getCcShowInstancessRelatedByDbId(null, $this->con);
|
|
|
|
$rebroadcasts->delete($this->con);
|
2012-07-16 03:17:13 +02:00
|
|
|
}
|
2012-07-11 00:51:32 +02:00
|
|
|
|
2012-05-15 14:56:31 +02:00
|
|
|
$instance->setDbEnds($this->nowDT);
|
|
|
|
$instance->save($this->con);
|
2012-07-11 00:51:32 +02:00
|
|
|
|
2012-04-02 15:20:13 +02:00
|
|
|
$this->con->commit();
|
2012-07-11 00:51:32 +02:00
|
|
|
|
2012-04-03 18:43:13 +02:00
|
|
|
if ($instance->getDbRecord()) {
|
2021-10-11 16:10:47 +02:00
|
|
|
Application_Model_RabbitMq::SendMessageToShowRecorder('cancel_recording');
|
2012-04-03 18:43:13 +02:00
|
|
|
}
|
2012-07-16 03:17:13 +02:00
|
|
|
} catch (Exception $e) {
|
|
|
|
$this->con->rollback();
|
2021-10-11 16:10:47 +02:00
|
|
|
|
2012-07-16 03:17:13 +02:00
|
|
|
throw $e;
|
2012-07-11 00:51:32 +02:00
|
|
|
}
|
2012-01-27 21:06:04 +01:00
|
|
|
}
|
2012-02-16 16:29:11 +01:00
|
|
|
}
|
|
|
|
|
2023-09-08 15:45:24 +02:00
|
|
|
class OutDatedScheduleException extends Exception {}
|