ShowFormService.php 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525
  1. <?php
  2. class Application_Service_ShowFormService
  3. {
  4. private $ccShow;
  5. private $instanceId;
  6. public function __construct($showId = null, $instanceId = null)
  7. {
  8. if (!is_null($showId)) {
  9. $this->ccShow = CcShowQuery::create()->findPk($showId);
  10. }
  11. $this->instanceId = $instanceId;
  12. }
  13. /**
  14. *
  15. * @return array of show forms
  16. */
  17. public function createShowForms()
  18. {
  19. $formWhat = new Application_Form_AddShowWhat();
  20. $formWho = new Application_Form_AddShowWho();
  21. $formWhen = new Application_Form_AddShowWhen();
  22. $formRepeats = new Application_Form_AddShowRepeats();
  23. $formStyle = new Application_Form_AddShowStyle();
  24. $formLive = new Application_Form_AddShowLiveStream();
  25. $formRecord = new Application_Form_AddShowRR();
  26. $formAbsoluteRebroadcast = new Application_Form_AddShowAbsoluteRebroadcastDates();
  27. $formRebroadcast = new Application_Form_AddShowRebroadcastDates();
  28. $formWhat->removeDecorator('DtDdWrapper');
  29. $formWho->removeDecorator('DtDdWrapper');
  30. $formWhen->removeDecorator('DtDdWrapper');
  31. $formRepeats->removeDecorator('DtDdWrapper');
  32. $formStyle->removeDecorator('DtDdWrapper');
  33. $formLive->removeDecorator('DtDdWrapper');
  34. $formRecord->removeDecorator('DtDdWrapper');
  35. $formAbsoluteRebroadcast->removeDecorator('DtDdWrapper');
  36. $formRebroadcast->removeDecorator('DtDdWrapper');
  37. $forms = array();
  38. $forms["what"] = $formWhat;
  39. $forms["who"] = $formWho;
  40. $forms["when"] = $formWhen;
  41. $forms["repeats"] = $formRepeats;
  42. $forms["style"] = $formStyle;
  43. $forms["live"] = $formLive;
  44. $forms["record"] = $formRecord;
  45. $forms["abs_rebroadcast"] = $formAbsoluteRebroadcast;
  46. $forms["rebroadcast"] = $formRebroadcast;
  47. return $forms;
  48. }
  49. /**
  50. *
  51. * Popluates the what, when, and repeat forms
  52. * with default values
  53. */
  54. public function populateNewShowForms($formWhat, $formWhen, $formRepeats)
  55. {
  56. $formWhat->populate(
  57. array('add_show_id' => '-1',
  58. 'add_show_instance_id' => '-1'));
  59. $formWhen->populate(
  60. array('add_show_start_date' => date("Y-m-d"),
  61. 'add_show_start_time' => '00:00',
  62. 'add_show_end_date_no_repeate' => date("Y-m-d"),
  63. 'add_show_end_time' => '01:00',
  64. 'add_show_duration' => '01h 00m'));
  65. $formRepeats->populate(array('add_show_end_date' => date("Y-m-d")));
  66. }
  67. public function delegateShowInstanceFormPopulation($forms)
  68. {
  69. $this->populateFormWhat($forms["what"]);
  70. $this->populateInstanceFormWhen($forms["when"]);
  71. $this->populateFormWho($forms["who"]);
  72. $this->populateFormLive($forms["live"]);
  73. $this->populateFormStyle($forms["style"]);
  74. /* Only the field on the 'when' form will get updated so we should
  75. * make all other forms disabled or readonly
  76. *
  77. * 'what' needs to be readonly because zendform will not validate
  78. * if they are disabled
  79. *
  80. * All other forms can be disabled because we do not update those values
  81. * when the user edits a repeating instance
  82. */
  83. $forms["what"]->makeReadonly();
  84. $forms["repeats"]->disable();
  85. $forms["who"]->disable();
  86. $forms["style"]->disable();
  87. $forms["live"]->disable();
  88. $forms["record"]->disable();
  89. $forms["rebroadcast"]->disable();
  90. $forms["abs_rebroadcast"]->disable();
  91. }
  92. /**
  93. *
  94. * Delegates populating each show form with the appropriate
  95. * data of the current show being edited
  96. *
  97. * @param $forms
  98. */
  99. public function delegateShowFormPopulation($forms)
  100. {
  101. $this->populateFormWhat($forms["what"]);
  102. //local show start DT
  103. $showStart = $this->populateFormWhen($forms["when"]);
  104. $this->populateFormRepeats($forms["repeats"], $showStart);
  105. $this->populateFormWho($forms["who"]);
  106. $this->populateFormStyle($forms["style"]);
  107. $this->populateFormLive($forms["live"]);
  108. $this->populateFormRecord($forms["record"]);
  109. $this->populateFormRebroadcastRelative($forms["rebroadcast"]);
  110. $this->populateFormRebroadcastAbsolute($forms["abs_rebroadcast"]);
  111. }
  112. private function populateFormWhat($form)
  113. {
  114. $form->populate(
  115. array(
  116. 'add_show_instance_id' => $this->instanceId,
  117. 'add_show_id' => $this->ccShow->getDbId(),
  118. 'add_show_name' => $this->ccShow->getDbName(),
  119. 'add_show_url' => $this->ccShow->getDbUrl(),
  120. 'add_show_genre' => $this->ccShow->getDbGenre(),
  121. 'add_show_description' => $this->ccShow->getDbDescription()));
  122. }
  123. private function populateFormWhen($form)
  124. {
  125. if ($this->ccShow->isRepeating()) {
  126. $ccShowDay = $this->ccShow->getFirstRepeatingCcShowDay();
  127. } else {
  128. $ccShowDay = $this->ccShow->getFirstCcShowDay();
  129. }
  130. $showStart = $ccShowDay->getLocalStartDateAndTime();
  131. $showEnd = $ccShowDay->getLocalEndDateAndTime();
  132. //check if the first show is in the past
  133. if ($ccShowDay->isShowStartInPast()) {
  134. //for a non-repeating show, we should never allow user to change the start time.
  135. //for a repeating show, we should allow because the form works as repeating template form
  136. if (!$ccShowDay->isRepeating()) {
  137. $form->disableStartDateAndTime();
  138. } else {
  139. list($showStart, $showEnd) = $this->getNextFutureRepeatShowTime();
  140. if ($this->hasShowStarted($showStart)) {
  141. $form->disableStartDateAndTime();
  142. }
  143. }
  144. }
  145. $form->populate(
  146. array(
  147. 'add_show_start_date' => $showStart->format("Y-m-d"),
  148. 'add_show_start_time' => $showStart->format("H:i"),
  149. 'add_show_end_date_no_repeat' => $showEnd->format("Y-m-d"),
  150. 'add_show_end_time' => $showEnd->format("H:i"),
  151. 'add_show_duration' => $ccShowDay->formatDuration(true),
  152. 'add_show_timezone' => $ccShowDay->getDbTimezone(),
  153. 'add_show_repeats' => $ccShowDay->isRepeating() ? 1 : 0));
  154. return $showStart;
  155. }
  156. private function populateInstanceFormWhen($form)
  157. {
  158. $ccShowInstance = CcShowInstancesQuery::create()->findPk($this->instanceId);
  159. //get timezone the show is created in
  160. $timezone = $ccShowInstance->getCcShow()->getFirstCcShowDay()->getDbTimezone();
  161. //$timezone = new DateTimeZone(Application_Model_Preference::GetDefaultTimezone());
  162. //DateTime object in UTC
  163. $showStart = $ccShowInstance->getDbStarts(null);
  164. $showStart->setTimezone(new DateTimeZone($timezone));
  165. $showEnd = $ccShowInstance->getDbEnds(null);
  166. $showEnd->setTimezone(new DateTimeZone($timezone));
  167. //if the show has started, do not allow editing on the start time
  168. if ($showStart->getTimestamp() <= time()) {
  169. $form->disableStartDateAndTime();
  170. }
  171. $form->populate(
  172. array(
  173. 'add_show_start_date' => $showStart->format("Y-m-d"),
  174. 'add_show_start_time' => $showStart->format("H:i"),
  175. 'add_show_end_date_no_repeat' => $showEnd->format("Y-m-d"),
  176. 'add_show_end_time' => $showEnd->format("H:i"),
  177. 'add_show_duration' => $this->calculateDuration(
  178. $showStart->format("Y-m-d H:i:s"), $showEnd->format("Y-m-d H:i:s"), $timezone),
  179. 'add_show_timezone' => $timezone,
  180. 'add_show_repeats' => 0));
  181. $form->getElement('add_show_repeats')->setOptions(array("disabled" => true));
  182. }
  183. /**
  184. *
  185. * Enter description here ...
  186. * @param $form
  187. * @param DateTime $nextFutureShowStart user's local timezone
  188. */
  189. private function populateFormRepeats($form, $nextFutureShowStart)
  190. {
  191. if ($this->ccShow->isRepeating()) {
  192. $ccShowDays = $this->ccShow->getRepeatingCcShowDays();
  193. } else {
  194. $ccShowDays = $this->ccShow->getCcShowDayss();
  195. }
  196. $days = array();
  197. foreach ($ccShowDays as $ccShowDay) {
  198. $showStart = $ccShowDay->getLocalStartDateAndTime();
  199. array_push($days, $showStart->format("w"));
  200. }
  201. $service_show = new Application_Service_ShowService($this->ccShow->getDbId());
  202. $repeatEndDate = $service_show->getRepeatingEndDate();
  203. //end dates are stored non-inclusively so we need to
  204. //subtract one day
  205. if (!is_null($repeatEndDate)) {
  206. $repeatEndDate->sub(new DateInterval("P1D"));
  207. }
  208. //default monthly repeat type
  209. $monthlyRepeatType = 2;
  210. $repeatType = $ccShowDays[0]->getDbRepeatType();
  211. if ($repeatType == REPEAT_MONTHLY_WEEKLY) {
  212. $monthlyRepeatType = $repeatType;
  213. //a repeat type of 2 means the show is repeating monthly
  214. $repeatType = 2;
  215. } elseif ($repeatType == REPEAT_MONTHLY_MONTHLY) {
  216. $monthlyRepeatType = $repeatType;
  217. }
  218. $form->populate(
  219. array(
  220. 'add_show_linked' => $this->ccShow->getDbLinked(),
  221. 'add_show_repeat_type' => $repeatType,
  222. 'add_show_day_check' => $days,
  223. 'add_show_end_date' => (!is_null($repeatEndDate)) ? $repeatEndDate->format("Y-m-d"):null,
  224. 'add_show_no_end' => (is_null($repeatEndDate)),
  225. 'add_show_monthly_repeat_type' => $monthlyRepeatType));
  226. if (!$this->ccShow->isLinkable() || $this->ccShow->isRecorded()) {
  227. $form->getElement('add_show_linked')->setOptions(array('disabled' => true));
  228. }
  229. /* Because live editing of a linked show is disabled, we will make
  230. * the linking option readonly if the current show is being edited. We
  231. * dont' want the user to suddenly not be able to edit the current show
  232. *
  233. * Readonly does not work with checkboxes but we can't disable it
  234. * because the value won't get posted. In add-show.js we stop the
  235. * onclick event from firing by returning false
  236. */
  237. if ($this->hasShowStarted($nextFutureShowStart)) {
  238. $form->getElement('add_show_linked')->setAttrib('readonly', 'readonly');
  239. }
  240. }
  241. private function populateFormWho($form)
  242. {
  243. $ccShowHosts = $this->ccShow->getCcShowHostss();
  244. $hosts = array();
  245. foreach ($ccShowHosts as $ccShowHost) {
  246. array_push($hosts, $ccShowHost->getDbHost());
  247. }
  248. $form->populate(array('add_show_hosts' => $hosts));
  249. }
  250. private function populateFormStyle($form)
  251. {
  252. $form->populate(
  253. array(
  254. 'add_show_background_color' => $this->ccShow->getDbBackgroundColor(),
  255. 'add_show_color' => $this->ccShow->getDbColor()));
  256. }
  257. private function populateFormLive($form)
  258. {
  259. $form->populate(
  260. array(
  261. "cb_airtime_auth" => $this->ccShow->getDbLiveStreamUsingAirtimeAuth(),
  262. "cb_custom_auth" => $this->ccShow->getDbLiveStreamUsingCustomAuth(),
  263. "custom_username" => $this->ccShow->getDbLiveStreamUser(),
  264. "custom_password" => $this->ccShow->getDbLiveStreamPass()));
  265. }
  266. private function populateFormRecord($form)
  267. {
  268. $form->populate(
  269. array(
  270. 'add_show_record' => $this->ccShow->isRecorded(),
  271. 'add_show_rebroadcast' => $this->ccShow->isRebroadcast()));
  272. $form->getElement('add_show_record')->setOptions(array('disabled' => true));
  273. }
  274. private function populateFormRebroadcastRelative($form)
  275. {
  276. $relativeRebroadcasts = $this->ccShow->getRebroadcastsRelative();
  277. $formValues = array();
  278. $i = 1;
  279. foreach ($relativeRebroadcasts as $rr) {
  280. $formValues["add_show_rebroadcast_date_$i"] = $rr->getDbDayOffset();
  281. $formValues["add_show_rebroadcast_time_$i"] = Application_Common_DateHelper::removeSecondsFromTime(
  282. $rr->getDbStartTime());
  283. $i++;
  284. }
  285. $form->populate($formValues);
  286. }
  287. private function populateFormRebroadcastAbsolute($form)
  288. {
  289. $absolutRebroadcasts = $this->ccShow->getRebroadcastsAbsolute();
  290. $timezone = $this->ccShow->getFirstCcShowDay()->getDbTimezone();
  291. $formValues = array();
  292. $i = 1;
  293. foreach ($absolutRebroadcasts as $ar) {
  294. //convert dates to user's local time
  295. $start = new DateTime($ar->getDbStarts(), new DateTimeZone("UTC"));
  296. $start->setTimezone(new DateTimeZone($timezone));
  297. $formValues["add_show_rebroadcast_date_absolute_$i"] = $start->format("Y-m-d");
  298. $formValues["add_show_rebroadcast_time_absolute_$i"] = $start->format("H:i");
  299. $i++;
  300. }
  301. $form->populate($formValues);
  302. }
  303. /**
  304. *
  305. * Enter description here ...
  306. * @param DateTime $showStart user's local time
  307. */
  308. private function hasShowStarted($p_showStart) {
  309. $showStart = clone $p_showStart;
  310. $showStart->setTimeZone(new DateTimeZone("UTC"));
  311. if ($showStart->format("Y-m-d H:i:s") < gmdate("Y-m-d H:i:s")) {
  312. return true;
  313. } else {
  314. return false;
  315. }
  316. }
  317. /**
  318. * Before we send the form data in for validation, there
  319. * are a few fields we may need to adjust first
  320. *
  321. * @param $formData
  322. */
  323. public function preEditShowValidationCheck($formData)
  324. {
  325. // If the start date or time were disabled, don't validate them
  326. $validateStartDate = $formData['start_date_disabled'] === "false";
  327. $validateStartTime = $formData['start_time_disabled'] === "false";
  328. //CcShowDays object of the show currently being edited
  329. $currentShowDay = $this->ccShow->getFirstCcShowDay();
  330. //DateTime object
  331. $dt = $currentShowDay->getLocalStartDateAndTime();
  332. $formData['add_show_record'] = $currentShowDay->getDbRecord();
  333. //if the show is repeating, set the start date to the next
  334. //repeating instance in the future
  335. if ($this->ccShow->isRepeating()) {
  336. list($originalShowStartDateTime,) = $this->getNextFutureRepeatShowTime();
  337. } else {
  338. $originalShowStartDateTime = $dt;
  339. }
  340. return array($formData, $validateStartDate, $validateStartTime, $originalShowStartDateTime);
  341. }
  342. /**
  343. *
  344. * Returns 2 DateTime objects, in the user's local time,
  345. * of the next future repeat show instance start and end time
  346. */
  347. public function getNextFutureRepeatShowTime()
  348. {
  349. $ccShowInstance = CcShowInstancesQuery::create()
  350. ->filterByDbShowId($this->ccShow->getDbId())
  351. ->filterByDbModifiedInstance(false)
  352. ->filterByDbStarts(gmdate("Y-m-d H:i:s"), Criteria::GREATER_THAN)
  353. ->orderByDbStarts()
  354. ->findOne();
  355. $starts = new DateTime($ccShowInstance->getDbStarts(), new DateTimeZone("UTC"));
  356. $ends = new DateTime($ccShowInstance->getDbEnds(), new DateTimeZone("UTC"));
  357. $showTimezone = $this->ccShow->getFirstCcShowDay()->getDbTimezone();
  358. $starts->setTimezone(new DateTimeZone($showTimezone));
  359. $ends->setTimezone(new DateTimeZone($showTimezone));
  360. return array($starts, $ends);
  361. }
  362. /**
  363. *
  364. * Validates show forms
  365. *
  366. * @return boolean
  367. */
  368. public function validateShowForms($forms, $formData, $validateStartDate = true,
  369. $originalStartDate=null, $editShow=false, $instanceId=null)
  370. {
  371. $what = $forms["what"]->isValid($formData);
  372. $live = $forms["live"]->isValid($formData);
  373. $record = $forms["record"]->isValid($formData);
  374. $who = $forms["who"]->isValid($formData);
  375. $style = $forms["style"]->isValid($formData);
  376. $when = $forms["when"]->isWhenFormValid($formData, $validateStartDate,
  377. $originalStartDate, $editShow, $instanceId);
  378. $repeats = true;
  379. if ($formData["add_show_repeats"]) {
  380. $repeats = $forms["repeats"]->isValid($formData);
  381. /*
  382. * Make the absolute rebroadcast form valid since
  383. * it does not get used if the show is repeating
  384. */
  385. $forms["abs_rebroadcast"]->reset();
  386. $absRebroadcast = true;
  387. $rebroadcast = true;
  388. if (isset($formData["add_show_rebroadcast"]) && $formData["add_show_rebroadcast"]) {
  389. $formData["add_show_duration"] = Application_Service_ShowService::formatShowDuration(
  390. $formData["add_show_duration"]);
  391. $rebroadcast = $forms["rebroadcast"]->isValid($formData);
  392. }
  393. } else {
  394. /*
  395. * Make the rebroadcast form valid since it does
  396. * not get used if the show is not repeating.
  397. * Instead, we use the absolute rebroadcast form
  398. */
  399. $forms["rebroadcast"]->reset();
  400. $rebroadcast = true;
  401. $absRebroadcast = true;
  402. if (isset($formData["add_show_rebroadcast"]) && $formData["add_show_rebroadcast"]) {
  403. $formData["add_show_duration"] = Application_Service_ShowService::formatShowDuration(
  404. $formData["add_show_duration"]);
  405. $absRebroadcast = $forms["abs_rebroadcast"]->isValid($formData);
  406. }
  407. }
  408. if ($what && $live && $record && $who && $style && $when &&
  409. $repeats && $absRebroadcast && $rebroadcast) {
  410. return true;
  411. } else {
  412. return false;
  413. }
  414. }
  415. public function calculateDuration($start, $end, $timezone)
  416. {
  417. try {
  418. $tz = new DateTimeZone($timezone);
  419. $startDateTime = new DateTime($start, $tz);
  420. $endDateTime = new DateTime($end, $tz);
  421. $duration = $startDateTime->diff($endDateTime);
  422. $day = intval($duration->format('%d'));
  423. if ($day > 0) {
  424. $hour = intval($duration->format('%h'));
  425. $min = intval($duration->format('%i'));
  426. $hour += $day * 24;
  427. $hour = min($hour, 99);
  428. $sign = $duration->format('%r');
  429. return sprintf('%s%02dh %02dm', $sign, $hour, $min);
  430. } else {
  431. return $duration->format('%r%Hh %Im');
  432. }
  433. } catch (Exception $e) {
  434. Logging::info($e->getMessage());
  435. return "Invalid Date";
  436. }
  437. }
  438. /**
  439. * When the timezone is changed in add-show form this function
  440. * applies the new timezone to the start and end time
  441. *
  442. * @param $date String
  443. * @param $time String
  444. * @param $timezone String
  445. */
  446. public static function localizeDateTime($date, $time, $newTimezone, $oldTimezone)
  447. {
  448. $dt = new DateTime($date." ".$time, new DateTimeZone($oldTimezone));
  449. $dt->setTimeZone(new DateTimeZone($newTimezone));
  450. return array(
  451. "date" => $dt->format("Y-m-d"),
  452. "time" => $dt->format("H:i")
  453. );
  454. }
  455. }