PreferenceController.php 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513
  1. <?php
  2. class PreferenceController extends Zend_Controller_Action
  3. {
  4. public function init()
  5. {
  6. /* Initialize action controller here */
  7. $ajaxContext = $this->_helper->getHelper('AjaxContext');
  8. $ajaxContext->addActionContext('server-browse', 'json')
  9. ->addActionContext('change-stor-directory', 'json')
  10. ->addActionContext('reload-watch-directory', 'json')
  11. ->addActionContext('remove-watch-directory', 'json')
  12. ->addActionContext('is-import-in-progress', 'json')
  13. ->addActionContext('change-stream-setting', 'json')
  14. ->addActionContext('get-liquidsoap-status', 'json')
  15. ->addActionContext('set-source-connection-url', 'json')
  16. ->addActionContext('get-admin-password-status', 'json')
  17. ->initContext();
  18. }
  19. public function indexAction()
  20. {
  21. $CC_CONFIG = Config::getConfig();
  22. $request = $this->getRequest();
  23. $isSaas = Application_Model_Preference::GetPlanLevel() == 'disabled'?false:true;
  24. $baseUrl = Application_Common_OsPath::getBaseDir();
  25. $this->view->headScript()->appendFile($baseUrl.'js/airtime/preferences/preferences.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
  26. $this->view->statusMsg = "";
  27. $form = new Application_Form_Preferences();
  28. $values = array();
  29. if ($request->isPost()) {
  30. $values = $request->getPost();
  31. if ($form->isValid($values))
  32. {
  33. Application_Model_Preference::SetHeadTitle($values["stationName"], $this->view);
  34. Application_Model_Preference::SetStationDescription($values["stationDescription"]);
  35. Application_Model_Preference::SetDefaultCrossfadeDuration($values["stationDefaultCrossfadeDuration"]);
  36. Application_Model_Preference::SetDefaultFadeIn($values["stationDefaultFadeIn"]);
  37. Application_Model_Preference::SetDefaultFadeOut($values["stationDefaultFadeOut"]);
  38. Application_Model_Preference::SetAllow3rdPartyApi($values["thirdPartyApi"]);
  39. Application_Model_Preference::SetDefaultLocale($values["locale"]);
  40. Application_Model_Preference::SetDefaultTimezone($values["timezone"]);
  41. Application_Model_Preference::SetWeekStartDay($values["weekStartDay"]);
  42. $logoUploadElement = $form->getSubForm('preferences_general')->getElement('stationLogo');
  43. $logoUploadElement->receive();
  44. $imagePath = $logoUploadElement->getFileName();
  45. // Only update the image logo if the new logo is non-empty
  46. if (!is_null($imagePath) && $imagePath != "") {
  47. Application_Model_Preference::SetStationLogo($imagePath);
  48. }
  49. Application_Model_Preference::SetEnableSystemEmail($values["enableSystemEmail"]);
  50. Application_Model_Preference::SetSystemEmail($values["systemEmail"]);
  51. Application_Model_Preference::SetMailServerConfigured($values["configureMailServer"]);
  52. Application_Model_Preference::SetMailServer($values["mailServer"]);
  53. Application_Model_Preference::SetMailServerEmailAddress($values["email"]);
  54. Application_Model_Preference::SetMailServerPassword($values["ms_password"]);
  55. Application_Model_Preference::SetMailServerPort($values["port"]);
  56. Application_Model_Preference::SetMailServerRequiresAuth($values["msRequiresAuth"]);
  57. Application_Model_Preference::SetAutoUploadRecordedShowToSoundcloud($values["UseSoundCloud"]);
  58. Application_Model_Preference::SetUploadToSoundcloudOption($values["UploadToSoundcloudOption"]);
  59. Application_Model_Preference::SetSoundCloudDownloadbleOption($values["SoundCloudDownloadbleOption"]);
  60. Application_Model_Preference::SetSoundCloudUser($values["SoundCloudUser"]);
  61. Application_Model_Preference::SetSoundCloudPassword($values["SoundCloudPassword"]);
  62. Application_Model_Preference::SetSoundCloudTags($values["SoundCloudTags"]);
  63. Application_Model_Preference::SetSoundCloudGenre($values["SoundCloudGenre"]);
  64. Application_Model_Preference::SetSoundCloudTrackType($values["SoundCloudTrackType"]);
  65. Application_Model_Preference::SetSoundCloudLicense($values["SoundCloudLicense"]);
  66. $this->view->statusMsg = "<div class='success'>". _("Preferences updated.")."</div>";
  67. $this->view->form = $form;
  68. //$this->_helper->json->sendJson(array("valid"=>"true", "html"=>$this->view->render('preference/index.phtml')));
  69. } else {
  70. $this->view->form = $form;
  71. //$this->_helper->json->sendJson(array("valid"=>"false", "html"=>$this->view->render('preference/index.phtml')));
  72. }
  73. }
  74. $this->view->logoImg = Application_Model_Preference::GetStationLogo();
  75. $this->view->form = $form;
  76. }
  77. public function supportSettingAction()
  78. {
  79. $CC_CONFIG = Config::getConfig();
  80. $request = $this->getRequest();
  81. $baseUrl = Application_Common_OsPath::getBaseDir();
  82. $this->view->headScript()->appendFile($baseUrl.'js/airtime/preferences/support-setting.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
  83. $this->view->statusMsg = "";
  84. $form = new Application_Form_SupportSettings();
  85. if ($request->isPost()) {
  86. $values = $request->getPost();
  87. if ($values["Publicise"] != 1) {
  88. Application_Model_Preference::SetSupportFeedback($values["SupportFeedback"]);
  89. Application_Model_Preference::SetPublicise($values["Publicise"]);
  90. if (isset($values["Privacy"])) {
  91. Application_Model_Preference::SetPrivacyPolicyCheck($values["Privacy"]);
  92. }
  93. } else if ($form->isValid($values)) {
  94. Application_Model_Preference::SetHeadTitle($values["stationName"], $this->view);
  95. Application_Model_Preference::SetPhone($values["Phone"]);
  96. Application_Model_Preference::SetEmail($values["Email"]);
  97. Application_Model_Preference::SetStationWebSite($values["StationWebSite"]);
  98. Application_Model_Preference::SetSupportFeedback($values["SupportFeedback"]);
  99. Application_Model_Preference::SetPublicise($values["Publicise"]);
  100. Application_Model_Preference::SetStationCountry($values["Country"]);
  101. Application_Model_Preference::SetStationCity($values["City"]);
  102. Application_Model_Preference::SetStationDescription($values["Description"]);
  103. if (isset($values["Privacy"])) {
  104. Application_Model_Preference::SetPrivacyPolicyCheck($values["Privacy"]);
  105. }
  106. }
  107. $this->view->statusMsg = "<div class='success'>"._("Support setting updated.")."</div>";
  108. }
  109. $privacyChecked = false;
  110. if (Application_Model_Preference::GetPrivacyPolicyCheck() == 1) {
  111. $privacyChecked = true;
  112. }
  113. $this->view->privacyChecked = $privacyChecked;
  114. $this->view->section_title = _('Support Feedback');
  115. $this->view->form = $form;
  116. }
  117. public function directoryConfigAction()
  118. {
  119. $CC_CONFIG = Config::getConfig();
  120. $baseUrl = Application_Common_OsPath::getBaseDir();
  121. $this->view->headScript()->appendFile($baseUrl.'js/serverbrowse/serverbrowser.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
  122. $this->view->headScript()->appendFile($baseUrl.'js/airtime/preferences/musicdirs.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
  123. $watched_dirs_pref = new Application_Form_WatchedDirPreferences();
  124. $this->view->form = $watched_dirs_pref;
  125. }
  126. public function removeLogoAction()
  127. {
  128. $this->view->layout()->disableLayout();
  129. // Remove reliance on .phtml files to render requests
  130. $this->_helper->viewRenderer->setNoRender(true);
  131. Application_Model_Preference::SetStationLogo("");
  132. }
  133. public function streamSettingAction()
  134. {
  135. $CC_CONFIG = Config::getConfig();
  136. $request = $this->getRequest();
  137. $baseUrl = Application_Common_OsPath::getBaseDir();
  138. $this->view->headScript()->appendFile($baseUrl.'js/airtime/preferences/streamsetting.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
  139. // get current settings
  140. $temp = Application_Model_StreamSetting::getStreamSetting();
  141. $setting = array();
  142. foreach ($temp as $t) {
  143. $setting[$t['keyname']] = $t['value'];
  144. }
  145. $name_map = array(
  146. 'ogg' => 'Ogg Vorbis',
  147. 'fdkaac' => 'AAC+',
  148. 'aac' => 'AAC',
  149. 'opus' => 'Opus',
  150. 'mp3' => 'MP3',
  151. );
  152. // get predefined type and bitrate from pref table
  153. $temp_types = Application_Model_Preference::GetStreamType();
  154. $stream_types = array();
  155. foreach ($temp_types as $type) {
  156. $type = strtolower(trim($type));
  157. if (isset($name_map[$type])) {
  158. $name = $name_map[$type];
  159. } else {
  160. $name = $type;
  161. }
  162. $stream_types[$type] = $name;
  163. }
  164. $temp_bitrate = Application_Model_Preference::GetStreamBitrate();
  165. $max_bitrate = intval(Application_Model_Preference::GetMaxBitrate());
  166. $stream_bitrates = array();
  167. foreach ($temp_bitrate as $type) {
  168. if (intval($type) <= $max_bitrate) {
  169. $stream_bitrates[trim($type)] = strtoupper(trim($type))." kbit/s";
  170. }
  171. }
  172. $num_of_stream = intval(Application_Model_Preference::GetNumOfStreams());
  173. $form = new Application_Form_StreamSetting();
  174. $form->addElement('hash', 'csrf', array(
  175. 'salt' => 'unique'
  176. ));
  177. $form->setSetting($setting);
  178. $form->startFrom();
  179. $live_stream_subform = new Application_Form_LiveStreamingPreferences();
  180. $form->addSubForm($live_stream_subform, "live_stream_subform");
  181. for ($i=1; $i<=$num_of_stream; $i++) {
  182. $subform = new Application_Form_StreamSettingSubForm();
  183. $subform->setPrefix($i);
  184. $subform->setSetting($setting);
  185. $subform->setStreamTypes($stream_types);
  186. $subform->setStreamBitrates($stream_bitrates);
  187. $subform->startForm();
  188. $form->addSubForm($subform, "s".$i."_subform");
  189. }
  190. if ($request->isPost()) {
  191. $params = $request->getPost();
  192. /* Parse through post data and put in format
  193. * $form->isValid() is expecting it in
  194. */
  195. $postData = explode('&', $params['data']);
  196. $s1_data = array();
  197. $s2_data = array();
  198. $s3_data = array();
  199. $values = array();
  200. foreach($postData as $k=>$v) {
  201. $v = explode('=', urldecode($v));
  202. if (strpos($v[0], "s1_data") !== false) {
  203. /* In this case $v[0] may be 's1_data[enable]' , for example.
  204. * We only want the 'enable' part
  205. */
  206. preg_match('/\[(.*)\]/', $v[0], $matches);
  207. $s1_data[$matches[1]] = $v[1];
  208. } elseif (strpos($v[0], "s2_data") !== false) {
  209. preg_match('/\[(.*)\]/', $v[0], $matches);
  210. $s2_data[$matches[1]] = $v[1];
  211. } elseif (strpos($v[0], "s3_data") !== false) {
  212. preg_match('/\[(.*)\]/', $v[0], $matches);
  213. $s3_data[$matches[1]] = $v[1];
  214. } else {
  215. $values[$v[0]] = $v[1];
  216. }
  217. }
  218. $values["s1_data"] = $s1_data;
  219. $values["s2_data"] = $s2_data;
  220. $values["s3_data"] = $s3_data;
  221. $error = false;
  222. if ($form->isValid($values)) {
  223. $values['output_sound_device'] = $form->getValue('output_sound_device');
  224. $values['output_sound_device_type'] = $form->getValue('output_sound_device_type');
  225. $values['icecast_vorbis_metadata'] = $form->getValue('icecast_vorbis_metadata');
  226. $values['streamFormat'] = $form->getValue('streamFormat');
  227. Application_Model_StreamSetting::setStreamSetting($values);
  228. /* If the admin password values are empty then we should not
  229. * set the pseudo password ('xxxxxx') on the front-end
  230. */
  231. $s1_set_admin_pass = !empty($values["s1_data"]["admin_pass"]);
  232. $s2_set_admin_pass = !empty($values["s2_data"]["admin_pass"]);
  233. $s3_set_admin_pass = !empty($values["s3_data"]["admin_pass"]);
  234. // this goes into cc_pref table
  235. Application_Model_Preference::SetStreamLabelFormat($values['streamFormat']);
  236. Application_Model_Preference::SetLiveStreamMasterUsername($values["master_username"]);
  237. Application_Model_Preference::SetLiveStreamMasterPassword($values["master_password"]);
  238. Application_Model_Preference::SetDefaultTransitionFade($values["transition_fade"]);
  239. Application_Model_Preference::SetAutoTransition($values["auto_transition"]);
  240. Application_Model_Preference::SetAutoSwitch($values["auto_switch"]);
  241. // compare new values with current value
  242. $changeRGenabled = Application_Model_Preference::GetEnableReplayGain() != $values["enableReplayGain"];
  243. $changeRGmodifier = Application_Model_Preference::getReplayGainModifier() != $values["replayGainModifier"];
  244. if ($changeRGenabled || $changeRGmodifier) {
  245. Application_Model_Preference::SetEnableReplayGain($values["enableReplayGain"]);
  246. Application_Model_Preference::setReplayGainModifier($values["replayGainModifier"]);
  247. $md = array('schedule' => Application_Model_Schedule::getSchedule());
  248. Application_Model_RabbitMq::SendMessageToPypo("update_schedule", $md);
  249. //Application_Model_RabbitMq::PushSchedule();
  250. }
  251. if (!Application_Model_Preference::GetMasterDjConnectionUrlOverride()) {
  252. $master_connection_url = "http://".$_SERVER['SERVER_NAME'].":".$values["master_harbor_input_port"]."/".$values["master_harbor_input_mount_point"];
  253. if (empty($values["master_harbor_input_port"]) || empty($values["master_harbor_input_mount_point"])) {
  254. Application_Model_Preference::SetMasterDJSourceConnectionURL('N/A');
  255. } else {
  256. Application_Model_Preference::SetMasterDJSourceConnectionURL($master_connection_url);
  257. }
  258. } else {
  259. Application_Model_Preference::SetMasterDJSourceConnectionURL($values["master_dj_connection_url"]);
  260. }
  261. if (!Application_Model_Preference::GetLiveDjConnectionUrlOverride()) {
  262. $live_connection_url = "http://".$_SERVER['SERVER_NAME'].":".$values["dj_harbor_input_port"]."/".$values["dj_harbor_input_mount_point"];
  263. if (empty($values["dj_harbor_input_port"]) || empty($values["dj_harbor_input_mount_point"])) {
  264. Application_Model_Preference::SetLiveDJSourceConnectionURL('N/A');
  265. } else {
  266. Application_Model_Preference::SetLiveDJSourceConnectionURL($live_connection_url);
  267. }
  268. } else {
  269. Application_Model_Preference::SetLiveDJSourceConnectionURL($values["live_dj_connection_url"]);
  270. }
  271. // extra info that goes into cc_stream_setting
  272. Application_Model_StreamSetting::setMasterLiveStreamPort($values["master_harbor_input_port"]);
  273. Application_Model_StreamSetting::setMasterLiveStreamMountPoint($values["master_harbor_input_mount_point"]);
  274. Application_Model_StreamSetting::setDjLiveStreamPort($values["dj_harbor_input_port"]);
  275. Application_Model_StreamSetting::setDjLiveStreamMountPoint($values["dj_harbor_input_mount_point"]);
  276. Application_Model_StreamSetting::setOffAirMeta($values['offAirMeta']);
  277. // store stream update timestamp
  278. Application_Model_Preference::SetStreamUpdateTimestamp();
  279. $data = array();
  280. $info = Application_Model_StreamSetting::getStreamSetting();
  281. $data['setting'] = $info;
  282. for ($i=1; $i<=$num_of_stream; $i++) {
  283. Application_Model_StreamSetting::setLiquidsoapError($i, "waiting");
  284. }
  285. Application_Model_RabbitMq::SendMessageToPypo("update_stream_setting", $data);
  286. $live_stream_subform->updateVariables();
  287. $this->view->enable_stream_conf = Application_Model_Preference::GetEnableStreamConf();
  288. $this->view->form = $form;
  289. $this->view->num_stream = $num_of_stream;
  290. $this->view->statusMsg = "<div class='success'>"._("Stream Setting Updated.")."</div>";
  291. $this->_helper->json->sendJson(array(
  292. "valid"=>"true",
  293. "html"=>$this->view->render('preference/stream-setting.phtml'),
  294. "s1_set_admin_pass"=>$s1_set_admin_pass,
  295. "s2_set_admin_pass"=>$s2_set_admin_pass,
  296. "s3_set_admin_pass"=>$s3_set_admin_pass,
  297. ));
  298. } else {
  299. $live_stream_subform->updateVariables();
  300. $this->view->enable_stream_conf = Application_Model_Preference::GetEnableStreamConf();
  301. $this->view->form = $form;
  302. $this->view->num_stream = $num_of_stream;
  303. $this->_helper->json->sendJson(array("valid"=>"false", "html"=>$this->view->render('preference/stream-setting.phtml')));
  304. }
  305. }
  306. $live_stream_subform->updateVariables();
  307. $this->view->num_stream = $num_of_stream;
  308. $this->view->enable_stream_conf = Application_Model_Preference::GetEnableStreamConf();
  309. $this->view->form = $form;
  310. }
  311. public function serverBrowseAction()
  312. {
  313. $request = $this->getRequest();
  314. $path = $request->getParam("path", null);
  315. $result = array();
  316. if (is_null($path)) {
  317. $element = array();
  318. $element["name"] = _("path should be specified");
  319. $element["isFolder"] = false;
  320. $element["isError"] = true;
  321. $result[$path] = $element;
  322. } else {
  323. $path = $path.'/';
  324. $handle = opendir($path);
  325. if ($handle !== false) {
  326. while (false !== ($file = readdir($handle))) {
  327. if ($file != "." && $file != "..") {
  328. //only show directories that aren't private.
  329. if (is_dir($path.$file) && substr($file, 0, 1) != ".") {
  330. $element = array();
  331. $element["name"] = $file;
  332. $element["isFolder"] = true;
  333. $element["isError"] = false;
  334. $result[$file] = $element;
  335. }
  336. }
  337. }
  338. }
  339. }
  340. ksort($result);
  341. //returns format serverBrowse is looking for.
  342. $this->_helper->json->sendJson($result);
  343. }
  344. public function changeStorDirectoryAction()
  345. {
  346. $chosen = $this->getRequest()->getParam("dir");
  347. $element = $this->getRequest()->getParam("element");
  348. $watched_dirs_form = new Application_Form_WatchedDirPreferences();
  349. $res = Application_Model_MusicDir::setStorDir($chosen);
  350. if ($res['code'] != 0) {
  351. $watched_dirs_form->populate(array('storageFolder' => $chosen));
  352. $watched_dirs_form->getElement($element)->setErrors(array($res['error']));
  353. }
  354. $this->view->subform = $watched_dirs_form->render();
  355. }
  356. public function reloadWatchDirectoryAction()
  357. {
  358. $chosen = $this->getRequest()->getParam("dir");
  359. $element = $this->getRequest()->getParam("element");
  360. $watched_dirs_form = new Application_Form_WatchedDirPreferences();
  361. $res = Application_Model_MusicDir::addWatchedDir($chosen);
  362. if ($res['code'] != 0) {
  363. $watched_dirs_form->populate(array('watchedFolder' => $chosen));
  364. $watched_dirs_form->getElement($element)->setErrors(array($res['error']));
  365. }
  366. $this->view->subform = $watched_dirs_form->render();
  367. }
  368. public function rescanWatchDirectoryAction()
  369. {
  370. $dir_path = $this->getRequest()->getParam('dir');
  371. $dir = Application_Model_MusicDir::getDirByPath($dir_path);
  372. $data = array( 'directory' => $dir->getDirectory(),
  373. 'id' => $dir->getId());
  374. Application_Model_RabbitMq::SendMessageToMediaMonitor('rescan_watch', $data);
  375. Logging::info("Unhiding all files belonging to:: $dir_path");
  376. $dir->unhideFiles();
  377. $this->_helper->json->sendJson(null);
  378. }
  379. public function removeWatchDirectoryAction()
  380. {
  381. $chosen = $this->getRequest()->getParam("dir");
  382. $dir = Application_Model_MusicDir::removeWatchedDir($chosen);
  383. $watched_dirs_form = new Application_Form_WatchedDirPreferences();
  384. $this->view->subform = $watched_dirs_form->render();
  385. }
  386. public function isImportInProgressAction()
  387. {
  388. $now = time();
  389. $res = false;
  390. if (Application_Model_Preference::GetImportTimestamp()+10 > $now) {
  391. $res = true;
  392. }
  393. $this->_helper->json->sendJson($res);
  394. }
  395. public function getLiquidsoapStatusAction()
  396. {
  397. $out = array();
  398. $num_of_stream = intval(Application_Model_Preference::GetNumOfStreams());
  399. for ($i=1; $i<=$num_of_stream; $i++) {
  400. $status = Application_Model_StreamSetting::getLiquidsoapError($i);
  401. $status = $status == NULL?_("Problem with Liquidsoap..."):$status;
  402. if (!Application_Model_StreamSetting::getStreamEnabled($i)) {
  403. $status = "N/A";
  404. }
  405. $out[] = array("id"=>$i, "status"=>$status);
  406. }
  407. $this->_helper->json->sendJson($out);
  408. }
  409. public function setSourceConnectionUrlAction()
  410. {
  411. $request = $this->getRequest();
  412. $type = $request->getParam("type", null);
  413. $url = urldecode($request->getParam("url", null));
  414. $override = $request->getParam("override", false);
  415. if ($type == 'masterdj') {
  416. Application_Model_Preference::SetMasterDJSourceConnectionURL($url);
  417. Application_Model_Preference::SetMasterDjConnectionUrlOverride($override);
  418. } elseif ($type == 'livedj') {
  419. Application_Model_Preference::SetLiveDJSourceConnectionURL($url);
  420. Application_Model_Preference::SetLiveDjConnectionUrlOverride($override);
  421. }
  422. $this->_helper->json->sendJson(null);
  423. }
  424. public function getAdminPasswordStatusAction()
  425. {
  426. $out = array();
  427. for ($i=1; $i<=3; $i++) {
  428. if (Application_Model_StreamSetting::getAdminPass('s'.$i)=='') {
  429. $out["s".$i] = false;
  430. } else {
  431. $out["s".$i] = true;
  432. }
  433. }
  434. $this->_helper->json->sendJson($out);
  435. }
  436. }