ShowInstance.php 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732
  1. <?php
  2. require_once 'formatters/LengthFormatter.php';
  3. class Application_Model_ShowInstance
  4. {
  5. private $_instanceId;
  6. private $_showInstance;
  7. public function __construct($instanceId)
  8. {
  9. $this->_instanceId = $instanceId;
  10. $this->_showInstance = CcShowInstancesQuery::create()->findPK($instanceId);
  11. if (is_null($this->_showInstance)) {
  12. throw new Exception();
  13. }
  14. }
  15. public function getShowId()
  16. {
  17. return $this->_showInstance->getDbShowId();
  18. }
  19. /* TODO: A little inconsistent because other models have a getId() method
  20. to get PK --RG */
  21. public function getShowInstanceId()
  22. {
  23. return $this->_instanceId;
  24. }
  25. public function getShow()
  26. {
  27. return new Application_Model_Show($this->getShowId());
  28. }
  29. public function deleteRebroadcasts()
  30. {
  31. $timestamp = gmdate("Y-m-d H:i:s");
  32. $instance_id = $this->getShowInstanceId();
  33. $sql = <<<SQL
  34. DELETE FROM cc_show_instances
  35. WHERE starts > :timestamp::TIMESTAMP
  36. AND instance_id = :instanceId
  37. AND rebroadcast = 1;
  38. SQL;
  39. Application_Common_Database::prepareAndExecute( $sql, array(
  40. ':instanceId' => $instance_id,
  41. ':timestamp' => $timestamp), 'execute');
  42. }
  43. /* This function is weird. It should return a boolean, but instead returns
  44. * an integer if it is a rebroadcast, or returns null if it isn't. You can convert
  45. * it to boolean by using is_null(isRebroadcast), where true means isn't and false
  46. * means that it is. */
  47. public function isRebroadcast()
  48. {
  49. return $this->_showInstance->getDbOriginalShow();
  50. }
  51. public function isRecorded()
  52. {
  53. return $this->_showInstance->getDbRecord();
  54. }
  55. public function getName()
  56. {
  57. $show = CcShowQuery::create()->findPK($this->getShowId());
  58. return $show->getDbName();
  59. }
  60. public function getGenre()
  61. {
  62. $show = CcShowQuery::create()->findPK($this->getShowId());
  63. return $show->getDbGenre();
  64. }
  65. /**
  66. * Return the start time of the Show (UTC time)
  67. * @return string in format "Y-m-d H:i:s" (PHP time notation)
  68. */
  69. public function getShowInstanceStart($format="Y-m-d H:i:s")
  70. {
  71. return $this->_showInstance->getDbStarts($format);
  72. }
  73. /**
  74. * Return the end time of the Show (UTC time)
  75. * @return string in format "Y-m-d H:i:s" (PHP time notation)
  76. */
  77. public function getShowInstanceEnd($format="Y-m-d H:i:s")
  78. {
  79. return $this->_showInstance->getDbEnds($format);
  80. }
  81. public function getStartDate()
  82. {
  83. $showStart = $this->getShowInstanceStart();
  84. $showStartExplode = explode(" ", $showStart);
  85. return $showStartExplode[0];
  86. }
  87. public function getStartTime()
  88. {
  89. $showStart = $this->getShowInstanceStart();
  90. $showStartExplode = explode(" ", $showStart);
  91. return $showStartExplode[1];
  92. }
  93. public function setSoundCloudFileId($p_soundcloud_id)
  94. {
  95. $file = Application_Model_StoredFile::RecallById($this->_showInstance->getDbRecordedFile());
  96. $file->setSoundCloudFileId($p_soundcloud_id);
  97. }
  98. public function getSoundCloudFileId()
  99. {
  100. $file = Application_Model_StoredFile::RecallById($this->_showInstance->getDbRecordedFile());
  101. return $file->getSoundCloudId();
  102. }
  103. public function getRecordedFile()
  104. {
  105. $file_id = $this->_showInstance->getDbRecordedFile();
  106. if (isset($file_id)) {
  107. $file = Application_Model_StoredFile::RecallById($file_id);
  108. if (isset($file) && file_exists($file->getFilePath())) {
  109. return $file;
  110. }
  111. }
  112. return null;
  113. }
  114. public function setShowStart($start)
  115. {
  116. $this->_showInstance->setDbStarts($start)
  117. ->save();
  118. Application_Model_RabbitMq::PushSchedule();
  119. }
  120. public function setShowEnd($end)
  121. {
  122. $this->_showInstance->setDbEnds($end)
  123. ->save();
  124. Application_Model_RabbitMq::PushSchedule();
  125. }
  126. public function updateScheduledTime()
  127. {
  128. $con = Propel::getConnection(CcShowInstancesPeer::DATABASE_NAME);
  129. $this->_showInstance->updateDbTimeFilled($con);
  130. }
  131. public function isDeleted()
  132. {
  133. $this->_showInstance->getDbModifiedInstance();
  134. }
  135. /*
  136. * @param $dateTime
  137. * php Datetime object to add deltas to
  138. *
  139. * @param $deltaDay
  140. * php int, delta days show moved
  141. *
  142. * @param $deltaMin
  143. * php int, delta mins show moved
  144. *
  145. * @return $newDateTime
  146. * php DateTime, $dateTime with the added time deltas.
  147. */
  148. public static function addDeltas($dateTime, $deltaDay, $deltaMin)
  149. {
  150. $newDateTime = clone $dateTime;
  151. $days = abs($deltaDay);
  152. $mins = abs($deltaMin);
  153. $dayInterval = new DateInterval("P{$days}D");
  154. $minInterval = new DateInterval("PT{$mins}M");
  155. if ($deltaDay > 0) {
  156. $newDateTime->add($dayInterval);
  157. } elseif ($deltaDay < 0) {
  158. $newDateTime->sub($dayInterval);
  159. }
  160. if ($deltaMin > 0) {
  161. $newDateTime->add($minInterval);
  162. } elseif ($deltaMin < 0) {
  163. $newDateTime->sub($minInterval);
  164. }
  165. return $newDateTime;
  166. }
  167. /**
  168. * Add a playlist as the last item of the current show.
  169. *
  170. * @param int $plId
  171. * Playlist ID.
  172. */
  173. /*public function addPlaylistToShow($pl_id, $checkUserPerm = true)
  174. {
  175. $ts = intval($this->_showInstance->getDbLastScheduled("U")) ? : 0;
  176. $id = $this->_showInstance->getDbId();
  177. $scheduler = new Application_Model_Scheduler();
  178. $scheduler->scheduleAfter(
  179. array(array("id" => 0, "instance" => $id, "timestamp" => $ts)),
  180. array(array("id" => $pl_id, "type" => "playlist"))
  181. );
  182. }*/
  183. /**
  184. * Add a media file as the last item in the show.
  185. *
  186. * @param int $file_id
  187. */
  188. public function addFileToShow($file_id, $checkUserPerm = true)
  189. {
  190. $ts = intval($this->_showInstance->getDbLastScheduled("U")) ? : 0;
  191. $id = $this->_showInstance->getDbId();
  192. $scheduler = new Application_Model_Scheduler();
  193. $scheduler->setCheckUserPermissions($checkUserPerm);
  194. $scheduler->scheduleAfter(
  195. array(array("id" => 0, "instance" => $id, "timestamp" => $ts)),
  196. array(array("id" => $file_id, "type" => "audioclip"))
  197. );
  198. }
  199. /**
  200. * Add the given playlists to the show.
  201. *
  202. * @param array $plIds
  203. * An array of playlist IDs.
  204. */
  205. /*public function scheduleShow($plIds)
  206. {
  207. foreach ($plIds as $plId) {
  208. $this->addPlaylistToShow($plId);
  209. }
  210. }*/
  211. public function clearShow()
  212. {
  213. CcScheduleQuery::create()
  214. ->filterByDbInstanceId($this->_instanceId)
  215. ->delete();
  216. Application_Model_RabbitMq::PushSchedule();
  217. $this->updateScheduledTime();
  218. }
  219. private function checkToDeleteShow($showId)
  220. {
  221. //UTC DateTime object
  222. $showsPopUntil = Application_Model_Preference::GetShowsPopulatedUntil();
  223. $showDays = CcShowDaysQuery::create()
  224. ->filterByDbShowId($showId)
  225. ->findOne();
  226. $showEnd = $showDays->getDbLastShow();
  227. //there will always be more shows populated.
  228. if (is_null($showEnd)) {
  229. return false;
  230. }
  231. $lastShowStartDateTime = new DateTime("{$showEnd} {$showDays->getDbStartTime()}", new DateTimeZone($showDays->getDbTimezone()));
  232. //end dates were non inclusive.
  233. $lastShowStartDateTime = self::addDeltas($lastShowStartDateTime, -1, 0);
  234. //there's still some shows left to be populated.
  235. if ($lastShowStartDateTime->getTimestamp() > $showsPopUntil->getTimestamp()) {
  236. return false;
  237. }
  238. // check if there are any non deleted show instances remaining.
  239. $showInstances = CcShowInstancesQuery::create()
  240. ->filterByDbShowId($showId)
  241. ->filterByDbModifiedInstance(false)
  242. ->filterByDbRebroadcast(0)
  243. ->find();
  244. if (is_null($showInstances)) {
  245. return true;
  246. }
  247. //only 1 show instance left of the show, make it non repeating.
  248. else if (count($showInstances) === 1) {
  249. $showInstance = $showInstances[0];
  250. $showDaysOld = CcShowDaysQuery::create()
  251. ->filterByDbShowId($showId)
  252. ->find();
  253. $tz = $showDaysOld[0]->getDbTimezone();
  254. $startDate = new DateTime($showInstance->getDbStarts(), new DateTimeZone("UTC"));
  255. $startDate->setTimeZone(new DateTimeZone($tz));
  256. $endDate = self::addDeltas($startDate, 1, 0);
  257. //make a new rule for a non repeating show.
  258. $showDayNew = new CcShowDays();
  259. $showDayNew->setDbFirstShow($startDate->format("Y-m-d"));
  260. $showDayNew->setDbLastShow($endDate->format("Y-m-d"));
  261. $showDayNew->setDbStartTime($startDate->format("H:i:s"));
  262. $showDayNew->setDbTimezone($tz);
  263. $showDayNew->setDbDay($startDate->format('w'));
  264. $showDayNew->setDbDuration($showDaysOld[0]->getDbDuration());
  265. $showDayNew->setDbRepeatType(-1);
  266. $showDayNew->setDbShowId($showDaysOld[0]->getDbShowId());
  267. $showDayNew->setDbRecord($showDaysOld[0]->getDbRecord());
  268. $showDayNew->save();
  269. //delete the old rules for repeating shows
  270. $showDaysOld->delete();
  271. //remove the old repeating deleted instances.
  272. $showInstances = CcShowInstancesQuery::create()
  273. ->filterByDbShowId($showId)
  274. ->filterByDbModifiedInstance(true)
  275. ->delete();
  276. }
  277. return false;
  278. }
  279. public function delete($rabbitmqPush = true)
  280. {
  281. // see if it was recording show
  282. $recording = $this->isRecorded();
  283. // get show id
  284. $showId = $this->getShowId();
  285. $show = $this->getShow();
  286. $current_timestamp = gmdate("Y-m-d H:i:s");
  287. if ($current_timestamp <= $this->getShowInstanceEnd()) {
  288. if ($show->isRepeating()) {
  289. CcShowInstancesQuery::create()
  290. ->findPK($this->_instanceId)
  291. ->setDbModifiedInstance(true)
  292. ->save();
  293. if ($this->isRebroadcast()) {
  294. return;
  295. }
  296. //delete the rebroadcasts of the removed recorded show.
  297. if ($recording) {
  298. CcShowInstancesQuery::create()
  299. ->filterByDbOriginalShow($this->_instanceId)
  300. ->delete();
  301. }
  302. /* Automatically delete all files scheduled in cc_schedules table. */
  303. CcScheduleQuery::create()
  304. ->filterByDbInstanceId($this->_instanceId)
  305. ->delete();
  306. if ($this->checkToDeleteShow($showId)) {
  307. CcShowQuery::create()
  308. ->filterByDbId($showId)
  309. ->delete();
  310. }
  311. } else {
  312. if ($this->isRebroadcast()) {
  313. $this->_showInstance->delete();
  314. } else {
  315. $show->delete();
  316. }
  317. }
  318. }
  319. if ($rabbitmqPush) {
  320. Application_Model_RabbitMq::PushSchedule();
  321. }
  322. }
  323. public function setRecordedFile($file_id)
  324. {
  325. $showInstance = CcShowInstancesQuery::create()
  326. ->findPK($this->_instanceId);
  327. $showInstance->setDbRecordedFile($file_id)
  328. ->save();
  329. $rebroadcasts = CcShowInstancesQuery::create()
  330. ->filterByDbOriginalShow($this->_instanceId)
  331. ->find();
  332. foreach ($rebroadcasts as $rebroadcast) {
  333. try {
  334. $rebroad = new Application_Model_ShowInstance($rebroadcast->getDbId());
  335. $rebroad->addFileToShow($file_id, false);
  336. } catch (Exception $e) {
  337. Logging::info($e->getMessage());
  338. }
  339. }
  340. }
  341. public function getTimeScheduled()
  342. {
  343. $time = $this->_showInstance->getDbTimeFilled();
  344. if ($time != "00:00:00" && !empty($time)) {
  345. $time_arr = explode(".", $time);
  346. if (count($time_arr) > 1) {
  347. $time_arr[1] = "." . $time_arr[1];
  348. $milliseconds = number_format(round($time_arr[1], 2), 2);
  349. $time = $time_arr[0] . substr($milliseconds, 1);
  350. } else {
  351. $time = $time_arr[0] . ".00";
  352. }
  353. } else {
  354. $time = "00:00:00.00";
  355. }
  356. return $time;
  357. }
  358. public function getTimeScheduledSecs()
  359. {
  360. $time_filled = $this->getTimeScheduled();
  361. return Application_Common_DateHelper::playlistTimeToSeconds($time_filled);
  362. }
  363. public function getDurationSecs()
  364. {
  365. $ends = $this->getShowInstanceEnd(null);
  366. $starts = $this->getShowInstanceStart(null);
  367. return intval($ends->format('U')) - intval($starts->format('U'));
  368. }
  369. public function getPercentScheduled()
  370. {
  371. $durationSeconds = $this->getDurationSecs();
  372. $timeSeconds = $this->getTimeScheduledSecs();
  373. if ($durationSeconds != 0) { //Prevent division by zero if the show duration is somehow zero.
  374. $percent = ceil(($timeSeconds / $durationSeconds) * 100);
  375. } else {
  376. $percent = 0;
  377. }
  378. return $percent;
  379. }
  380. public function getShowLength()
  381. {
  382. $start = $this->getShowInstanceStart(null);
  383. $end = $this->getShowInstanceEnd(null);
  384. $interval = $start->diff($end);
  385. $days = $interval->format("%d");
  386. $hours = sprintf("%02d" ,$interval->format("%h"));
  387. if ($days > 0) {
  388. $totalHours = $days * 24 + $hours;
  389. //$interval object does not have milliseconds so hard code to .00
  390. $returnStr = $totalHours . ":" . $interval->format("%I:%S") . ".00";
  391. } else {
  392. $returnStr = $hours . ":" . $interval->format("%I:%S") . ".00";
  393. }
  394. return $returnStr;
  395. }
  396. public static function getContentCount($p_start, $p_end)
  397. {
  398. $sql = <<<SQL
  399. SELECT instance_id,
  400. count(*) AS instance_count
  401. FROM cc_schedule
  402. WHERE ends > :p_start::TIMESTAMP
  403. AND starts < :p_end::TIMESTAMP
  404. GROUP BY instance_id
  405. SQL;
  406. $counts = Application_Common_Database::prepareAndExecute($sql, array(
  407. ':p_start' => $p_start->format("Y-m-d G:i:s"),
  408. ':p_end' => $p_end->format("Y-m-d G:i:s"))
  409. , 'all');
  410. $real_counts = array();
  411. foreach ($counts as $c) {
  412. $real_counts[$c['instance_id']] = $c['instance_count'];
  413. }
  414. return $real_counts;
  415. }
  416. public static function getIsFull($p_start, $p_end)
  417. {
  418. $sql = <<<SQL
  419. SELECT id, ends-starts-'00:00:05' < time_filled as filled
  420. from cc_show_instances
  421. WHERE ends > :p_start::TIMESTAMP
  422. AND starts < :p_end::TIMESTAMP
  423. SQL;
  424. $res = Application_Common_Database::prepareAndExecute($sql, array(
  425. ':p_start' => $p_start->format("Y-m-d G:i:s"),
  426. ':p_end' => $p_end->format("Y-m-d G:i:s"))
  427. , 'all');
  428. $isFilled = array();
  429. foreach ($res as $r) {
  430. $isFilled[$r['id']] = $r['filled'];
  431. }
  432. return $isFilled;
  433. }
  434. public function showEmpty()
  435. {
  436. $sql = <<<SQL
  437. SELECT s.starts
  438. FROM cc_schedule AS s
  439. WHERE s.instance_id = :instance_id
  440. AND s.playout_status >= 0
  441. AND ((s.stream_id IS NOT NULL)
  442. OR (s.file_id IS NOT NULL)) LIMIT 1
  443. SQL;
  444. # TODO : use prepareAndExecute properly
  445. $res = Application_Common_Database::prepareAndExecute($sql,
  446. array( ':instance_id' => $this->_instanceId ), 'all' );
  447. # TODO : A bit retarded. fix this later
  448. foreach ($res as $r) {
  449. return false;
  450. }
  451. return true;
  452. }
  453. public function getShowListContent($timezone = null)
  454. {
  455. $con = Propel::getConnection();
  456. $sql = <<<SQL
  457. SELECT *
  458. FROM (
  459. (SELECT s.starts,
  460. 0::INTEGER as type ,
  461. f.id AS item_id,
  462. f.track_title,
  463. f.album_title AS album,
  464. f.genre AS genre,
  465. f.length AS length,
  466. f.artist_name AS creator,
  467. f.file_exists AS EXISTS,
  468. f.filepath AS filepath,
  469. f.mime AS mime
  470. FROM cc_schedule AS s
  471. LEFT JOIN cc_files AS f ON f.id = s.file_id
  472. WHERE s.instance_id = :instance_id1
  473. AND s.playout_status >= 0
  474. AND s.file_id IS NOT NULL
  475. AND f.hidden = 'false')
  476. UNION
  477. (SELECT s.starts,
  478. 1::INTEGER as type,
  479. ws.id AS item_id,
  480. (ws.name || ': ' || ws.url) AS title,
  481. null AS album,
  482. null AS genre,
  483. ws.length AS length,
  484. sub.login AS creator,
  485. 't'::boolean AS EXISTS,
  486. ws.url AS filepath,
  487. ws.mime as mime
  488. FROM cc_schedule AS s
  489. LEFT JOIN cc_webstream AS ws ON ws.id = s.stream_id
  490. LEFT JOIN cc_subjs AS sub ON ws.creator_id = sub.id
  491. WHERE s.instance_id = :instance_id2
  492. AND s.playout_status >= 0
  493. AND s.stream_id IS NOT NULL)) AS temp
  494. ORDER BY starts;
  495. SQL;
  496. $stmt = $con->prepare($sql);
  497. $stmt->execute(array(
  498. ':instance_id1' => $this->_instanceId,
  499. ':instance_id2' => $this->_instanceId
  500. ));
  501. $results = $stmt->fetchAll(PDO::FETCH_ASSOC);
  502. if (isset($timezone)) {
  503. $displayTimezone = new DateTimeZone($timezone);
  504. } else {
  505. $userTimezone = Application_Model_Preference::GetUserTimezone();
  506. $displayTimezone = new DateTimeZone($userTimezone);
  507. }
  508. $utcTimezone = new DateTimeZone("UTC");
  509. foreach ($results as &$row) {
  510. $dt = new DateTime($row["starts"], $utcTimezone);
  511. $dt->setTimezone($displayTimezone);
  512. $row["starts"] = $dt->format("Y-m-d H:i:s");
  513. if (isset($row['length'])) {
  514. $formatter = new LengthFormatter($row["length"]);
  515. $row["length"] = $formatter->format();
  516. }
  517. }
  518. return $results;
  519. }
  520. public function getLastAudioItemEnd()
  521. {
  522. $con = Propel::getConnection();
  523. $sql = "SELECT ends FROM cc_schedule "
  524. ."WHERE instance_id = :instanceId"
  525. ."ORDER BY ends DESC "
  526. ."LIMIT 1";
  527. $query = Application_Common_Database::prepareAndExecute( $sql,
  528. array(':instanceId' => $this->_instanceId), 'column');
  529. return ($query !== false) ? $query : null;
  530. }
  531. public static function GetLastShowInstance($p_timeNow)
  532. {
  533. $sql = <<<SQL
  534. SELECT si.id
  535. FROM cc_show_instances si
  536. WHERE si.ends < :timeNow::TIMESTAMP
  537. AND si.modified_instance = 'f'
  538. ORDER BY si.ends DESC LIMIT 1;
  539. SQL;
  540. $id = Application_Common_Database( $sql, array(
  541. ':timeNow' => $p_timeNow ), 'column' );
  542. return ($id ? new Application_Model_ShowInstance($id) : null );
  543. }
  544. public static function GetCurrentShowInstance($p_timeNow)
  545. {
  546. /* Orderby si.starts descending, because in some cases
  547. * we can have multiple shows overlapping each other. In
  548. * this case, the show that started later is the one that
  549. * is actually playing, and so this is the one we want.
  550. */
  551. $sql = <<<SQL
  552. SELECT si.id
  553. FROM cc_show_instances si
  554. WHERE si.starts <= :timeNow1::TIMESTAMP
  555. AND si.ends > :timeNow2::TIMESTAMP
  556. AND si.modified_instance = 'f'
  557. ORDER BY si.starts DESC LIMIT 1
  558. SQL;
  559. $id = Application_Common_Database( $sql, array(
  560. ':timeNow1' => $p_timeNow,
  561. ':timeNow2' => $p_timeNow ), 'column');
  562. return ( $id ? new Application_Model_ShowInstance($id) : null );
  563. }
  564. public static function GetNextShowInstance($p_timeNow)
  565. {
  566. $sql = <<<SQL
  567. SELECT si.id
  568. FROM cc_show_instances si
  569. WHERE si.starts > :timeNow::TIMESTAMP
  570. AND si.modified_instance = 'f'
  571. ORDER BY si.starts
  572. LIMIT 1
  573. SQL;
  574. $id = Application_Common_Database::prepareAndExecute( $sql,
  575. array( 'timeNow' => $p_timeNow ), 'column' );
  576. return ( $id ? new Application_Model_ShowInstance($id) : null );
  577. }
  578. // returns number of show instances that ends later than $day
  579. public static function GetShowInstanceCount($day)
  580. {
  581. $sql = <<<SQL
  582. SELECT count(*) AS cnt
  583. FROM cc_show_instances
  584. WHERE ends < :day
  585. SQL;
  586. return Application_Common_Database::prepareAndExecute( $sql,
  587. array( ':day' => $day ), 'column' );
  588. }
  589. // this returns end timestamp of all shows that are in the range and has live DJ set up
  590. public static function GetEndTimeOfNextShowWithLiveDJ($p_startTime, $p_endTime)
  591. {
  592. $sql = <<<SQL
  593. SELECT ends
  594. FROM cc_show_instances AS si
  595. JOIN cc_show AS sh ON si.show_id = sh.id
  596. WHERE si.ends > :startTime::TIMESTAMP
  597. AND si.ends < :endTime::TIMESTAMP
  598. AND (sh.live_stream_using_airtime_auth
  599. OR live_stream_using_custom_auth)
  600. ORDER BY si.ends
  601. SQL;
  602. return Application_Common_Database::prepareAndExecute( $sql, array(
  603. ':startTime' => $p_startTime,
  604. ':endTime' => $p_endTime), 'all');
  605. }
  606. public function isRepeating()
  607. {
  608. return $this->getShow()->isRepeating();
  609. }
  610. }