PlaylistController.php 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641
  1. <?php
  2. class PlaylistController extends Zend_Controller_Action
  3. {
  4. public function init()
  5. {
  6. $ajaxContext = $this->_helper->getHelper('AjaxContext');
  7. $ajaxContext->addActionContext('add-items', 'json')
  8. ->addActionContext('move-items', 'json')
  9. ->addActionContext('delete-items', 'json')
  10. ->addActionContext('set-fade', 'json')
  11. ->addActionContext('set-crossfade', 'json')
  12. ->addActionContext('set-cue', 'json')
  13. ->addActionContext('new', 'json')
  14. ->addActionContext('edit', 'json')
  15. ->addActionContext('delete', 'json')
  16. ->addActionContext('close-playlist', 'json')
  17. ->addActionContext('play', 'json')
  18. ->addActionContext('set-playlist-fades', 'json')
  19. ->addActionContext('get-playlist-fades', 'json')
  20. ->addActionContext('set-playlist-name', 'json')
  21. ->addActionContext('set-playlist-description', 'json')
  22. ->addActionContext('playlist-preview', 'json')
  23. ->addActionContext('get-playlist', 'json')
  24. ->addActionContext('save', 'json')
  25. ->addActionContext('smart-block-generate', 'json')
  26. ->addActionContext('smart-block-shuffle', 'json')
  27. ->addActionContext('get-block-info', 'json')
  28. ->addActionContext('shuffle', 'json')
  29. ->addActionContext('empty-content', 'json')
  30. ->initContext();
  31. }
  32. private function getPlaylist($p_type)
  33. {
  34. $obj = null;
  35. $objInfo = Application_Model_Library::getObjInfo($p_type);
  36. $obj_sess = new Zend_Session_Namespace(UI_PLAYLISTCONTROLLER_OBJ_SESSNAME);
  37. if (isset($obj_sess->id)) {
  38. $obj = new $objInfo['className']($obj_sess->id);
  39. $modified = $this->_getParam('modified', null);
  40. if ($obj->getLastModified("U") !== $modified) {
  41. $this->createFullResponse($obj);
  42. throw new PlaylistOutDatedException(sprintf(_("You are viewing an older version of %s"), $obj->getName()));
  43. }
  44. }
  45. return $obj;
  46. }
  47. private function createUpdateResponse($obj)
  48. {
  49. $formatter = new LengthFormatter($obj->getLength());
  50. $this->view->length = $formatter->format();
  51. $this->view->obj = $obj;
  52. $this->view->contents = $obj->getContents();
  53. $this->view->html = $this->view->render('playlist/update.phtml');
  54. $this->view->name = $obj->getName();
  55. $this->view->description = $obj->getDescription();
  56. $this->view->modified = $obj->getLastModified("U");
  57. unset($this->view->obj);
  58. }
  59. private function createFullResponse($obj = null, $isJson = false,
  60. $formIsValid = false)
  61. {
  62. $isBlock = false;
  63. $viewPath = 'playlist/playlist.phtml';
  64. if ($obj instanceof Application_Model_Block) {
  65. $isBlock = true;
  66. $viewPath = 'playlist/smart-block.phtml';
  67. }
  68. if (isset($obj)) {
  69. $formatter = new LengthFormatter($obj->getLength());
  70. $this->view->length = $formatter->format();
  71. if ($isBlock) {
  72. $form = new Application_Form_SmartBlockCriteria();
  73. $form->removeDecorator('DtDdWrapper');
  74. $form->startForm($obj->getId(), $formIsValid);
  75. $this->view->form = $form;
  76. $this->view->obj = $obj;
  77. $this->view->id = $obj->getId();
  78. if ($isJson) {
  79. return $this->view->render($viewPath);
  80. } else {
  81. $this->view->html = $this->view->render($viewPath);
  82. }
  83. } else {
  84. $this->view->obj = $obj;
  85. $this->view->id = $obj->getId();
  86. if ($isJson) {
  87. return $this->view->html = $this->view->render($viewPath);
  88. } else {
  89. $this->view->html = $this->view->render($viewPath);
  90. }
  91. unset($this->view->obj);
  92. }
  93. } else {
  94. if ($isJson) {
  95. return $this->view->render($viewPath);
  96. } else {
  97. $this->view->html = $this->view->render($viewPath);
  98. }
  99. }
  100. }
  101. private function playlistOutdated($e)
  102. {
  103. $this->view->error = $e->getMessage();
  104. }
  105. private function blockDynamic($obj)
  106. {
  107. $this->view->error = _("You cannot add tracks to dynamic blocks.");
  108. $this->createFullResponse($obj);
  109. }
  110. private function playlistNotFound($p_type, $p_isJson = false)
  111. {
  112. $p_type = ucfirst($p_type);
  113. $this->view->error = sprintf(_("%s not found"), $p_type);
  114. Logging::info("{$p_type} not found");
  115. Application_Model_Library::changePlaylist(null, $p_type);
  116. if (!$p_isJson) {
  117. $this->createFullResponse(null);
  118. } else {
  119. $this->_helper->json->sendJson(array("error"=>$this->view->error, "result"=>1, "html"=>$this->createFullResponse(null, $p_isJson)));
  120. }
  121. }
  122. private function playlistNoPermission($p_type)
  123. {
  124. $this->view->error = sprintf(_("You don't have permission to delete selected %s(s)."), $p_type);
  125. $this->changePlaylist(null, $p_type);
  126. $this->createFullResponse(null);
  127. }
  128. private function playlistUnknownError($e)
  129. {
  130. $this->view->error = _("Something went wrong.");
  131. Logging::info($e->getMessage());
  132. }
  133. private function wrongTypeToBlock($obj)
  134. {
  135. $this->view->error = _("You can only add tracks to smart block.");
  136. $this->createFullResponse($obj);
  137. }
  138. private function wrongTypeToPlaylist($obj)
  139. {
  140. $this->view->error = _("You can only add tracks, smart blocks, and webstreams to playlists.");
  141. $this->createFullResponse($obj);
  142. }
  143. public function newAction()
  144. {
  145. //$pl_sess = $this->pl_sess;
  146. $userInfo = Zend_Auth::getInstance()->getStorage()->read();
  147. $type = $this->_getParam('type');
  148. $objInfo = Application_Model_Library::getObjInfo($type);
  149. $name = _('Untitled Playlist');
  150. if ($type == 'block') {
  151. $name = _('Untitled Smart Block');
  152. }
  153. $obj = new $objInfo['className']();
  154. $obj->setName($name);
  155. $obj->setMetadata('dc:creator', $userInfo->id);
  156. Application_Model_Library::changePlaylist($obj->getId(), $type);
  157. $this->createFullResponse($obj);
  158. }
  159. public function editAction()
  160. {
  161. $id = $this->_getParam('id', null);
  162. $type = $this->_getParam('type');
  163. $objInfo = Application_Model_Library::getObjInfo($type);
  164. Logging::info("editing {$type} {$id}");
  165. if (!is_null($id)) {
  166. Application_Model_Library::changePlaylist($id, $type);
  167. }
  168. try {
  169. $obj = new $objInfo['className']($id);
  170. $this->createFullResponse($obj);
  171. } catch (PlaylistNotFoundException $e) {
  172. $this->playlistNotFound($type);
  173. } catch (Exception $e) {
  174. $this->playlistUnknownError($e);
  175. }
  176. }
  177. public function deleteAction()
  178. {
  179. $ids = $this->_getParam('ids');
  180. $ids = (!is_array($ids)) ? array($ids) : $ids;
  181. $type = $this->_getParam('type');
  182. $obj = null;
  183. $objInfo = Application_Model_Library::getObjInfo($type);
  184. $userInfo = Zend_Auth::getInstance()->getStorage()->read();
  185. $obj_sess = new Zend_Session_Namespace(
  186. UI_PLAYLISTCONTROLLER_OBJ_SESSNAME);
  187. try {
  188. Logging::info("Currently active {$type} {$obj_sess->id}");
  189. if (in_array($obj_sess->id, $ids)) {
  190. Logging::info("Deleting currently active {$type}");
  191. Application_Model_Library::changePlaylist(null, $type);
  192. } else {
  193. Logging::info("Not deleting currently active {$type}");
  194. $obj = new $objInfo['className']($obj_sess->id);
  195. }
  196. if (strcmp($objInfo['className'], 'Application_Model_Playlist')==0) {
  197. Application_Model_Playlist::deletePlaylists($ids, $userInfo->id);
  198. } else {
  199. Application_Model_Block::deleteBlocks($ids, $userInfo->id);
  200. }
  201. $this->createFullResponse($obj);
  202. } catch (PlaylistNoPermissionException $e) {
  203. $this->playlistNoPermission($type);
  204. } catch (BlockNoPermissionException $e) {
  205. $this->playlistNoPermission($type);
  206. } catch (PlaylistNotFoundException $e) {
  207. $this->playlistNotFound($type);
  208. } catch (Exception $e) {
  209. $this->playlistUnknownError($e);
  210. }
  211. }
  212. public function closePlaylistAction() {
  213. $type = $this->_getParam('type');
  214. $obj = null;
  215. Application_Model_Library::changePlaylist($obj, $type);
  216. $this->createFullResponse($obj);
  217. }
  218. public function addItemsAction()
  219. {
  220. $ids = $this->_getParam('aItems', array());
  221. $ids = (!is_array($ids)) ? array($ids) : $ids;
  222. $afterItem = $this->_getParam('afterItem', null);
  223. $addType = $this->_getParam('type', 'after');
  224. // this is the obj type of destination
  225. $obj_type = $this->_getParam('obj_type');
  226. try {
  227. $obj = $this->getPlaylist($obj_type);
  228. if ($obj_type == 'playlist') {
  229. foreach ($ids as $id) {
  230. if (is_array($id) && isset($id[1])) {
  231. if ($id[1] == 'playlist') {
  232. throw new WrongTypeToPlaylistException;
  233. }
  234. }
  235. }
  236. $obj->addAudioClips($ids, $afterItem, $addType);
  237. } elseif ($obj->isStatic()) {
  238. // if the dest is a block object
  239. //check if any items are playlists
  240. foreach ($ids as $id) {
  241. if (is_array($id) && isset($id[1])) {
  242. if ($id[1] != 'audioclip') {
  243. throw new WrongTypeToBlockException;
  244. }
  245. }
  246. }
  247. $obj->addAudioClips($ids, $afterItem, $addType);
  248. } else {
  249. throw new BlockDynamicException;
  250. }
  251. $this->createUpdateResponse($obj);
  252. } catch (PlaylistOutDatedException $e) {
  253. $this->playlistOutdated($e);
  254. } catch (PlaylistNotFoundException $e) {
  255. $this->playlistNotFound($obj_type);
  256. } catch (WrongTypeToBlockException $e) {
  257. $this->wrongTypeToBlock($obj);
  258. } catch (WrongTypeToPlaylistException $e) {
  259. $this->wrongTypeToPlaylist($obj);
  260. } catch (BlockDynamicException $e) {
  261. $this->blockDynamic($obj);
  262. } catch (BlockNotFoundException $e) {
  263. $this->playlistNotFound($obj_type);
  264. } catch (Exception $e) {
  265. $this->playlistUnknownError($e);
  266. }
  267. }
  268. public function moveItemsAction()
  269. {
  270. $ids = $this->_getParam('ids');
  271. $ids = (!is_array($ids)) ? array($ids) : $ids;
  272. $afterItem = $this->_getParam('afterItem', null);
  273. $type = $this->_getParam('obj_type');
  274. try {
  275. $obj = $this->getPlaylist($type);
  276. $obj->moveAudioClips($ids, $afterItem);
  277. $this->createUpdateResponse($obj);
  278. } catch (PlaylistOutDatedException $e) {
  279. $this->playlistOutdated($e);
  280. } catch (PlaylistNotFoundException $e) {
  281. $this->playlistNotFound($type);
  282. } catch (Exception $e) {
  283. $this->playlistUnknownError($e);
  284. }
  285. }
  286. public function deleteItemsAction()
  287. {
  288. $ids = $this->_getParam('ids');
  289. $ids = (!is_array($ids)) ? array($ids) : $ids;
  290. $modified = $this->_getParam('modified');
  291. $type = $this->_getParam('obj_type');
  292. try {
  293. $obj = $this->getPlaylist($type);
  294. $obj->delAudioClips($ids);
  295. $this->createUpdateResponse($obj);
  296. } catch (PlaylistOutDatedException $e) {
  297. $this->playlistOutdated($e);
  298. } catch (PlaylistNotFoundException $e) {
  299. $this->playlistNotFound($type);
  300. } catch (Exception $e) {
  301. $this->playlistUnknownError($e);
  302. }
  303. }
  304. public function emptyContentAction()
  305. {
  306. $type = $this->_getParam('obj_type');
  307. try {
  308. $obj = $this->getPlaylist($type);
  309. if ($type == 'playlist') {
  310. $obj->deleteAllFilesFromPlaylist();
  311. } else {
  312. $obj->deleteAllFilesFromBlock();
  313. }
  314. $this->createUpdateResponse($obj);
  315. } catch (PlaylistOutDatedException $e) {
  316. $this->playlistOutdated($e);
  317. } catch (PlaylistNotFoundException $e) {
  318. $this->playlistNotFound($type);
  319. } catch (Exception $e) {
  320. $this->playlistUnknownError($e);
  321. }
  322. }
  323. public function setCueAction()
  324. {
  325. $id = $this->_getParam('id');
  326. $cueIn = $this->_getParam('cueIn', null);
  327. $cueOut = $this->_getParam('cueOut', null);
  328. $type = $this->_getParam('type');
  329. try {
  330. $obj = $this->getPlaylist($type);
  331. $response = $obj->changeClipLength($id, $cueIn, $cueOut);
  332. if (!isset($response["error"])) {
  333. $this->view->response = $response;
  334. $this->createUpdateResponse($obj);
  335. } else {
  336. $this->view->cue_error = $response["error"];
  337. $this->view->code = $response["type"];
  338. }
  339. } catch (PlaylistOutDatedException $e) {
  340. $this->playlistOutdated($e);
  341. } catch (PlaylistNotFoundException $e) {
  342. $this->playlistNotFound($type);
  343. } catch (Exception $e) {
  344. $this->playlistUnknownError($e);
  345. }
  346. }
  347. public function setFadeAction()
  348. {
  349. $id = $this->_getParam('id');
  350. $fadeIn = $this->_getParam('fadeIn', null);
  351. $fadeOut = $this->_getParam('fadeOut', null);
  352. $type = $this->_getParam('type');
  353. try {
  354. $obj = $this->getPlaylist($type);
  355. $response = $obj->changeFadeInfo($id, $fadeIn, $fadeOut);
  356. if (!isset($response["error"])) {
  357. $this->createUpdateResponse($obj);
  358. $this->view->response = $response;
  359. } else {
  360. $this->view->fade_error = $response["error"];
  361. }
  362. } catch (PlaylistOutDatedException $e) {
  363. $this->playlistOutdated($e);
  364. } catch (PlaylistNotFoundException $e) {
  365. $this->playlistNotFound($type);
  366. } catch (Exception $e) {
  367. $this->playlistUnknownError($e);
  368. }
  369. }
  370. public function setCrossfadeAction()
  371. {
  372. $id1 = $this->_getParam('id1', null);
  373. $id2 = $this->_getParam('id2', null);
  374. $type = $this->_getParam('type');
  375. $fadeIn = $this->_getParam('fadeIn', 0);
  376. $fadeOut = $this->_getParam('fadeOut', 0);
  377. $offset = $this->_getParam('offset', 0);
  378. try {
  379. $obj = $this->getPlaylist($type);
  380. $response = $obj->createCrossfade($id1, $fadeOut, $id2, $fadeIn, $offset);
  381. if (!isset($response["error"])) {
  382. $this->createUpdateResponse($obj);
  383. } else {
  384. $this->view->error = $response["error"];
  385. }
  386. } catch (PlaylistOutDatedException $e) {
  387. $this->playlistOutdated($e);
  388. } catch (PlaylistNotFoundException $e) {
  389. $this->playlistNotFound($type);
  390. } catch (Exception $e) {
  391. $this->playlistUnknownError($e);
  392. }
  393. }
  394. public function getPlaylistFadesAction()
  395. {
  396. $type = $this->_getParam('type');
  397. try {
  398. $obj = $this->getPlaylist($type);
  399. $fades = $obj->getFadeInfo(0);
  400. $this->view->fadeIn = $fades[0];
  401. $fades = $obj->getFadeInfo($obj->getSize()-1);
  402. $this->view->fadeOut = $fades[1];
  403. } catch (PlaylistOutDatedException $e) {
  404. $this->playlistOutdated($e);
  405. } catch (PlaylistNotFoundException $e) {
  406. $this->playlistNotFound($type);
  407. } catch (Exception $e) {
  408. $this->playlistUnknownError($e);
  409. }
  410. }
  411. /**
  412. * The playlist fades are stored in the elements themselves.
  413. * The fade in is set to the first elements fade in and
  414. * the fade out is set to the last elements fade out.
  415. **/
  416. public function setPlaylistFadesAction()
  417. {
  418. $fadeIn = $this->_getParam('fadeIn', null);
  419. $fadeOut = $this->_getParam('fadeOut', null);
  420. $type = $this->_getParam('type');
  421. try {
  422. $obj = $this->getPlaylist($type);
  423. $obj->setfades($fadeIn, $fadeOut);
  424. $this->view->modified = $obj->getLastModified("U");
  425. } catch (PlaylistOutDatedException $e) {
  426. $this->playlistOutdated($e);
  427. } catch (PlaylistNotFoundException $e) {
  428. $this->playlistNotFound($type);
  429. } catch (Exception $e) {
  430. $this->playlistUnknownError($e);
  431. }
  432. }
  433. public function setPlaylistNameDescAction()
  434. {
  435. $name = $this->_getParam('name', _('Unknown Playlist'));
  436. $description = $this->_getParam('description', "");
  437. $type = $this->_getParam('type');
  438. try {
  439. $obj = $this->getPlaylist($type);
  440. $obj->setName(trim($name));
  441. $obj->setDescription($description);
  442. $this->view->description = $description;
  443. $this->view->playlistName = $name;
  444. $this->view->modified = $obj->getLastModified("U");
  445. } catch (PlaylistOutDatedException $e) {
  446. $this->playlistOutdated($e);
  447. } catch (PlaylistNotFoundException $e) {
  448. $this->playlistNotFound($type, true);
  449. } catch (Exception $e) {
  450. $this->playlistUnknownError($e);
  451. }
  452. }
  453. public function saveAction()
  454. {
  455. $request = $this->getRequest();
  456. $params = $request->getPost();
  457. $result = array();
  458. if ($params['type'] == 'block') {
  459. try {
  460. $bl = new Application_Model_Block($params['obj_id']);
  461. } catch (BlockNotFoundException $e) {
  462. $this->playlistNotFound('block', true);
  463. }
  464. $form = new Application_Form_SmartBlockCriteria();
  465. $form->startForm($params['obj_id']);
  466. if ($form->isValid($params)) {
  467. $this->setPlaylistNameDescAction();
  468. $bl->saveSmartBlockCriteria($params['data']);
  469. $result['html'] = $this->createFullResponse($bl, true, true);
  470. $result['result'] = 0;
  471. } else {
  472. $this->view->obj = $bl;
  473. $this->view->id = $bl->getId();
  474. $this->view->form = $form;
  475. $this->view->unsavedName = $params['name'];
  476. $this->view->unsavedDesc = $params['description'];
  477. $viewPath = 'playlist/smart-block.phtml';
  478. $result['html'] = $this->view->render($viewPath);
  479. $result['result'] = 1;
  480. }
  481. } else if ($params['type'] == 'playlist') {
  482. $this->setPlaylistNameDescAction();
  483. }
  484. $result["modified"] = $this->view->modified;
  485. $this->_helper->json->sendJson($result);
  486. }
  487. public function smartBlockGenerateAction()
  488. {
  489. $request = $this->getRequest();
  490. $params = $request->getPost();
  491. //make sure block exists
  492. try {
  493. $bl = new Application_Model_Block($params['obj_id']);
  494. $form = new Application_Form_SmartBlockCriteria();
  495. $form->startForm($params['obj_id']);
  496. if ($form->isValid($params)) {
  497. $result = $bl->generateSmartBlock($params['data']);
  498. $this->_helper->json->sendJson(array("result"=>0, "html"=>$this->createFullResponse($bl, true, true)));
  499. } else {
  500. $this->view->obj = $bl;
  501. $this->view->id = $bl->getId();
  502. $this->view->form = $form;
  503. $viewPath = 'playlist/smart-block.phtml';
  504. $result['html'] = $this->view->render($viewPath);
  505. $result['result'] = 1;
  506. $this->_helper->json->sendJson($result);
  507. }
  508. } catch (BlockNotFoundException $e) {
  509. $this->playlistNotFound('block', true);
  510. } catch (Exception $e) {
  511. Logging::info($e);
  512. $this->playlistUnknownError($e);
  513. }
  514. }
  515. public function smartBlockShuffleAction()
  516. {
  517. $request = $this->getRequest();
  518. $params = $request->getPost();
  519. try {
  520. $bl = new Application_Model_Block($params['obj_id']);
  521. $result = $bl->shuffleSmartBlock();
  522. if ($result['result'] == 0) {
  523. $this->_helper->json->sendJson(array("result"=>0, "html"=>$this->createFullResponse($bl, true)));
  524. } else {
  525. $this->_helper->json->sendJson($result);
  526. }
  527. } catch (BlockNotFoundException $e) {
  528. $this->playlistNotFound('block', true);
  529. } catch (Exception $e) {
  530. $this->playlistUnknownError($e);
  531. }
  532. }
  533. public function shuffleAction()
  534. {
  535. $request = $this->getRequest();
  536. $params = $request->getPost();
  537. try {
  538. $pl = new Application_Model_Playlist($params['obj_id']);
  539. $result = $pl->shuffle();
  540. if ($result['result'] == 0) {
  541. $this->_helper->json->sendJson(array("result"=>0, "html"=>$this->createFullResponse($pl, true)));
  542. } else {
  543. $this->_helper->json->sendJson($result);
  544. }
  545. } catch (PlaylistNotFoundException $e) {
  546. $this->playlistNotFound('block', true);
  547. } catch (Exception $e) {
  548. $this->playlistUnknownError($e);
  549. }
  550. }
  551. public function getBlockInfoAction()
  552. {
  553. $request = $this->getRequest();
  554. $params = $request->getPost();
  555. $bl = new Application_Model_Block($params['id']);
  556. if ($bl->isStatic()) {
  557. $out = $bl->getContents();
  558. $out['isStatic'] = true;
  559. } else {
  560. $out = $bl->getCriteria();
  561. $out['isStatic'] = false;
  562. }
  563. $this->_helper->json->sendJson($out);
  564. }
  565. }
  566. class WrongTypeToBlockException extends Exception {}
  567. class WrongTypeToPlaylistException extends Exception {}
  568. class BlockDynamicException extends Exception {}