PageRenderTime 65ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 2ms

/zina/index.php

https://bitbucket.org/awgh/zina
PHP | 8314 lines | 7321 code | 756 blank | 237 comment | 1906 complexity | 2c50c0399391f1aad5e7e74d201f64dd MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  3. * ZINA (Zina is not Andromeda)
  4. *
  5. * Zina is a graphical interface to your MP3 collection, a personal
  6. * jukebox, an MP3 streamer. It can run on its own, embeded into an
  7. * existing website, or as a Drupal/Joomla/Wordpress/etc. module.
  8. *
  9. * http://www.pancake.org/zina
  10. * Author: Ryan Lathouwers <ryanlath@pacbell.net>
  11. * Support: http://sourceforge.net/projects/zina/
  12. * License: GNU GPL2 <http://www.gnu.org/copyleft/gpl.html>
  13. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  14. define('ZINA_VERSION', '2.0b22');
  15. #TODO:
  16. # - INSTRUCTIONS for cron for caches
  17. #todo
  18. # - uninstall? -> at least delete cache files created by webuser!
  19. # - check settings descriptions...
  20. # - normalize function names
  21. # - organize files
  22. # - comment functions?
  23. # - look and remove unused language crap?
  24. #TODO-EXTRA:
  25. # - if clean urls... drop l=8&m=1 for songs???
  26. # - See Also -> external links?
  27. # - multiple mp3 dirs
  28. # - Check output_buffering php.ini setting for video stuff?
  29. #TEST:
  30. # - pos
  31. function zina($conf) {
  32. global $zc;
  33. zina_init($conf);
  34. $path = isset($_GET['p']) ? zrawurldecode($_GET['p']) : null;
  35. $level = isset($_GET['l']) ? $_GET['l'] : null;
  36. $m = isset($_GET['m']) ? $_GET['m'] : null;
  37. $imgsrc = isset($_GET['img']) ? $_GET['img'] : null;
  38. $playlist = isset($_POST['playlist']) ? $_POST['playlist'] : (isset($_GET['pl']) ? $_GET['pl'] : null);
  39. $songs = isset($_POST['mp3s']) ? $_POST['mp3s'] : (isset($_GET['mp3s']) ? $_GET['mp3s'] : array());
  40. $path = preg_replace("|(/){2,}|",'$1',trim($path,'/'));
  41. $badpath = false;
  42. if (strstr($path,'..') && !zfile_check_location($zc['mp3_dir'].'/'.$path, $zc['mp3_dir'])) {
  43. $badpath = true;
  44. }
  45. if (!$badpath && strstr($imgsrc,'..')) {
  46. $badpath = true;
  47. if ($level == 11) {
  48. $badpath = (!zfile_check_location($zc['mp3_dir'].'/'.$path, $zc['mp3_dir']));
  49. } elseif ($level == 7) {
  50. if (isset($_GET['it'])) {
  51. if ($_GET['it'] == 'genre') {
  52. } elseif (in_array($_GET['it'], array('sub','dir','full','search'))) {
  53. $badpath = (!zfile_check_location($zc['mp3_dir'].'/'.$path, $zc['mp3_dir']));
  54. }
  55. }
  56. }
  57. }
  58. if (!$badpath && strstr($playlist,'..')) $badpath = true;
  59. if (!$badpath && !empty($songs) && is_array($songs)) {
  60. foreach ($songs as $song) {
  61. if (strstr($song,'..') && !zfile_check_location($zc['mp3_dir'].'/'.$path, $zc['mp3_dir'])) {
  62. $badpath = true;
  63. break;
  64. }
  65. }
  66. }
  67. if ($badpath) {
  68. zina_debug(zt('Bad path: @path', array('@path'=>$path)));
  69. return zina_not_found();
  70. }
  71. $zc['cur_dir'] = $zc['mp3_dir']. (!empty($path) ? '/'.$path : '');
  72. if (!empty($path) && !file_exists($zc['cur_dir'])) {
  73. $file_not_found = true;
  74. if (substr($path,-3) == '.lp') {
  75. $tmp_path = substr($path, 0, strlen($path) -3);
  76. if (file_exists($zc['mp3_dir'].'/'.$tmp_path)) {
  77. $file_not_found = false;
  78. $zc['cur_dir'] = $zc['mp3_dir'].'/'.$tmp_path;
  79. }
  80. } elseif ($zc['sitemap'] && $path == $zc['sitemap_file']) {
  81. $level = 51;
  82. $path = '';
  83. $zc['cur_dir'] = $zc['mp3_dir'];
  84. $file_not_found = false;
  85. } elseif ($zc['rss'] && basename($path) == $zc['rss_file']) {
  86. $level = 50;
  87. $path = substr($path,0,-(strlen($zc['rss_file'])+1));
  88. $zc['cur_dir'] = $zc['mp3_dir'].'/'.$path;
  89. if (file_exists($zc['cur_dir'])) $file_not_found = false;
  90. } elseif ($zc['stats_rss'] && $zc['database'] && basename($path) == 'stats.xml') {
  91. zina_stats_feed($path);
  92. } elseif ($zc['playlists'] && $zc['database'] && basename($path) == 'pls.xml') {
  93. $pls_id = dirname($path);
  94. if (zina_validate('int',$pls_id)) {
  95. zina_playlist_feed($pls_id);
  96. }
  97. } elseif ($level == 46 && basename($path) == 'zina_id3_zina.jpg') {
  98. $file_not_found = false;
  99. $tmp_path = dirname($path);
  100. $tmp_path = $zc['mp3_dir'].(!empty($tmp_path) ? '/'.$tmp_path : '');
  101. if (file_exists($tmp_path) && is_dir($tmp_path)) $file_not_found = false;
  102. }
  103. if ($file_not_found) {
  104. $tmp_path = utf8_decode($path);
  105. $tmp_cur_dir = $zc['mp3_dir']. (!empty($tmp_path) ? '/'.$tmp_path : '');
  106. if (file_exists($tmp_cur_dir)) {
  107. $path = $tmp_path;
  108. $zc['cur_dir'] = $tmp_cur_dir;
  109. } else {
  110. if (substr($path,-11) != 'favicon.ico') zina_debug(zt('Path does not exist: @path', array('@path'=>$path)));
  111. return zina_not_found();
  112. }
  113. }
  114. }
  115. #todo: validate?
  116. if ($zc['settings_override']) {
  117. $override_file = $zc['cur_dir'].'/'.$zc['settings_override_file'];
  118. if (file_exists($override_file)) {
  119. $override = false;
  120. if (($dir_xml = file_get_contents($override_file)) !== false) {
  121. $dir_settings = xml_to_array($dir_xml, 'settings');
  122. if (!empty($dir_settings[0])) {
  123. foreach($dir_settings[0] as $key => $val) {
  124. if (isset($zc[$key])) $zc[$key] = $val;
  125. }
  126. $override = true;
  127. }
  128. }
  129. if (!$override) {
  130. zina_set_message(zt('Cannot read override file.'), 'error');
  131. return zina_access_denied();
  132. }
  133. }
  134. }
  135. /*
  136. * MAIN
  137. *
  138. * Determines what zina does.
  139. */
  140. if (in_array($level, array(18,19,20,21,26,27,28,30,31,32,33,34,35,42,45,47,48,49,52,58,59,60,61,62,63,64,67,71,72,73,75,76,78))) {
  141. # ADMIN FUNCTIONS
  142. if (!$zc['is_admin']) return zina_access_denied();
  143. #todo: needed?
  144. #header('Expires: Wed, 11 Jan 1984 05:00:00 GMT');
  145. #header('Last-Modified: ' . gmdate( 'D, d M Y H:i:s' ) . ' GMT');
  146. #header('Cache-Control: no-cache, must-revalidate, max-age=0');
  147. #header('Pragma: no-cache');
  148. switch($level) {
  149. Case 18 : # INSTALL OR UPDATE DB
  150. if ($zc['database'] && ($m == 'update' || $m == 'install')) {
  151. $file = $zc['zina_dir_abs'].'/'.$m.'.php';
  152. if ($zc['database'] && file_exists($file)) {
  153. require_once($file);
  154. if ($m == 'install') {
  155. $result = zina_install_database();
  156. } else {
  157. $result = zina_updates_execute();
  158. }
  159. if ($result) {
  160. if ($m == 'install') zvar_set('version', ZINA_VERSION);
  161. zina_set_message(zt('Database @m succeeded!',array('@m'=>$m)));
  162. } else {
  163. zina_set_message(zt('Database @m failed!', array('@m'=>$m)),'error');
  164. }
  165. } else {
  166. zina_set_message(zt('Cannot @m the database...either no database connection or the file does not exist.',array('@m'=>$m)), 'error');
  167. }
  168. zina_goto('', 'l=20');
  169. }
  170. return zina_not_found();
  171. break;
  172. Case 19 : # try to manually submit last.fm queue
  173. if ($zc['lastfm']) {
  174. require_once($zc['zina_dir_abs'].'/extras/scrobbler.class.php');
  175. @set_time_limit($zc['timeout']);
  176. $scrobbler = new scrobbler($zc['lastfm_username'],$zc['lastfm_password']);
  177. $scrobbler->handshake_socket_timeout = 2;
  178. $scrobbler->submit_socket_timeout = 30;
  179. $scrobbler->queued_tracks = zina_set_scrobbler_queue();
  180. if ($scrobbler->submit_tracks()) {
  181. zina_set_message(zt('Queued Last.fm tracks submitted successfully.'));
  182. zina_set_scrobbler_queue(array(), true);
  183. } else {
  184. zina_set_message(zt('Queued Last.fm tracks failed:').$scrobbler->error_msg,'warn');
  185. }
  186. zina_goto('', 'l=20');
  187. }
  188. break;
  189. Case 20 : # CFG
  190. return zina_page_main($path, 'config');
  191. break;
  192. Case 21 : # CFG POST
  193. if (zina_write_settings()) {
  194. zina_set_message(zt('Settings updated.'));
  195. } else {
  196. zina_set_message(zt('Your settings were not saved!'),'error');
  197. }
  198. zina_goto('', 'l=20');
  199. break;
  200. Case 26 : # regen
  201. require_once($zc['zina_dir_abs'].'/batch.php');
  202. @trigger_error('');
  203. $error = false;
  204. if ($m == 1) { # dir/files caches
  205. if ($zc['database']) {
  206. foreach(array('dirs','files_assoc') as $type) {
  207. $operations[] = array('zina_core_cache_batch', array($type, '', array('force'=>true)));
  208. }
  209. if ($zc['low']) {
  210. foreach(array('files_assoc') as $type) {
  211. $operations[] = array('zina_core_cache_batch', array($type, '', array('force'=>true, 'low'=>true)));
  212. }
  213. }
  214. $batch = array(
  215. 'title' => zt('Regenerating directory and file caches.'),
  216. 'finished_message' => zt('Caches generated successfully.'),
  217. 'operations' => $operations,
  218. );
  219. zbatch_set($batch);
  220. zbatch_process();
  221. } else {
  222. foreach(array('dirs','files_assoc') as $type) zina_core_cache($type, '', array('force'=>true));
  223. if ($zc['low']) {
  224. foreach(array('files_assoc') as $type) zina_core_cache($type, '', array('force'=>true,'low'=>true));
  225. }
  226. $message = zt('Cache generated successfully.');
  227. }
  228. } elseif ($m == 2) { # genre cache
  229. #todo: use db or cache but not both? for genres? for dirs/files?
  230. if ($zc['database']) {
  231. $operations = array();
  232. $operations[] = array('zina_core_cache_batch', array('genre', '', array('force'=>true)));
  233. $operations[] = array('zdb_genre_populate', array(time()));
  234. $batch = array(
  235. 'title' => zt('Regenerating genre caches.'),
  236. 'finished_message' => zt('Genre cache generated successfully.'),
  237. 'operations' => $operations,
  238. );
  239. zbatch_set($batch);
  240. zbatch_process();
  241. } else {
  242. $message = zt('Genre cache generated successfully.');
  243. zina_core_cache('genre', '', array('force'=>true));
  244. }
  245. } elseif ($m == 3 || $m == 4) { # populate missing
  246. #TODO: combine 3 & 4... combine 1,3&4?
  247. if ($zc['database']) {
  248. $runtime = time();
  249. $operations = array();
  250. foreach(array('dirs','files_assoc') as $type) {
  251. $operations[] = array('zina_core_cache_batch', array($type, '', array('force'=>true)));
  252. }
  253. if ($m == 3) {
  254. $regen = false;
  255. $title = zt('Populating database with missing entries.');
  256. $finished = zt('Database populated.');
  257. } else { # 4
  258. $regen = true;
  259. $title = zt('Synchronising database');
  260. $finished = zt('Synchronized database.');
  261. }
  262. $operations[] = array('zdb_populate_batch', array($regen));
  263. $operations[] = array('zdb_search_playlist_populate', array($runtime));
  264. $operations[] = array('zdb_genre_populate', array($runtime));
  265. $batch = array(
  266. 'title' => $title,
  267. 'finished_message' => $finished,
  268. 'finished' => 'zdb_populate_finished',
  269. 'operations' => $operations,
  270. );
  271. zbatch_set($batch);
  272. zbatch_process();
  273. }
  274. } elseif ($m == 5) { # image from id3 tags
  275. $operations[] = array('zbatch_extract_images', array());
  276. $batch = array(
  277. 'title' => zt('Extracting images from id3 tags.'),
  278. 'finished_message' => zt('Images extracted successfully.'),
  279. 'operations' => $operations,
  280. 'finished' => 'zbatch_extract_images_finished',
  281. );
  282. zbatch_set($batch);
  283. zbatch_process();
  284. } else {
  285. $error = true;
  286. zina_set_message(zt('Invalid option'), 'error');
  287. }
  288. $e = error_get_last();
  289. if ($error || ($e['type'] < 2048 && !empty($e['message']))) {
  290. #todo: ? zunserialize throws error on older custom_files...
  291. if (!empty($e['message'])) zina_set_message(zt('PHP returned an error[@type]: @message', array('@type'=>$e['type'], '@message'=>$e['message'])), 'error');
  292. } else {
  293. zina_set_message($message);
  294. }
  295. zina_goto('','l=20');
  296. break;
  297. Case 27 : # Find and Clean
  298. if ($zc['database']) {
  299. if ($_POST && !zina_token_sess_check()) return zina_page_main($path);
  300. if (!empty($_POST['zfileids'])) zdb_clean('file',$_POST['zfileids']);
  301. if (!empty($_POST['zdirids'])) zdb_clean('dir',$_POST['zdirids']);
  302. if ($_POST) {
  303. zina_set_message(zt('Database cleaned.'));
  304. zina_goto('', 'l=20');
  305. } else {
  306. return zina_page_main($path, 'clean');
  307. }
  308. }
  309. break;
  310. Case 33 : # DELETE SITEMAP
  311. $file = $zc['cache_dir_public_abs'].'/'.$zc['sitemap_file'];
  312. if (file_exists($file) && @unlink($file)) {
  313. zina_set_message(zt('Sitemap cached file deleted successfully'));
  314. } else {
  315. zina_set_message(zt('Sitemap cached file could not be deleted'),'warn');
  316. }
  317. zina_goto('', 'l=20');
  318. break;
  319. Case 30 :# DELETE TMPL CACHE
  320. Case 31 :# DELETE IMGS CACHE
  321. Case 34 :# DELETE ZIP CACHE
  322. $func = array(
  323. '30'=> array(
  324. 'dir' => $zc['cache_tmpl_dir'],
  325. 'text' => zt('Template cache files deleted.'),
  326. ),
  327. '31'=> array(
  328. 'dir' => $zc['cache_imgs_dir'],
  329. 'text' => zt('Images cache files deleted.'),
  330. ),
  331. '34'=> array(
  332. 'dir' => $zc['cache_zip_dir'],
  333. 'text' => zt('Compressed cache files deleted.'),
  334. ),
  335. );
  336. if (zina_delete_files($func[$level]['dir'])) {
  337. zina_set_message($func[$level]['text']);
  338. }
  339. zina_goto('', 'l=20');
  340. break;
  341. Case 32 : #get language phrases for translation
  342. $files = array('index.php', 'theme.php', 'database.php', 'lang-cfg.php');
  343. $source = '';
  344. foreach($files as $file) {
  345. $source .= file_get_contents($zc['zina_dir_abs'].'/'.$file);
  346. }
  347. if (preg_match_all("/zt\('(.*?)'(\)|,)/is", $source, $matches)) {
  348. $reduced = array_unique($matches[1]);
  349. $instr = array(
  350. zt('These are most of the translation strings currently in Zina.'),
  351. zt('Save this file to LANGCODE.php and modify it.'),
  352. zt('Format: \'english words\' => \'your translation\'')."\n *",
  353. zt('You do not have to do them all (just delete the lines you do not do).'),
  354. zt('If you are making a new translation or completing an older one, move the file to the "lang" directory.'),
  355. zt('If languages.txt file exists in your cache directory, delete it.'),
  356. zt('Or a copy in your theme folder will override the default language file.'),
  357. zt('English users can change wording/phrasings this way.')."\n *",
  358. zt('Test it out.')."\n *",
  359. zt('If you would like it to be included in Zina, please email it: to: <@email>', array('@email'=>'ryanlath@pacbell.net')),
  360. );
  361. $text = '<?php'."\n".
  362. "/*\n * ".zt('Zina Translation Instructions')."\n *\n";
  363. foreach($instr as $i) {
  364. $text .= ' * '.$i."\n";
  365. }
  366. $lang = zina_get_languages();
  367. $language = (isset($lang[$zc['lang']])) ? $lang[$zc['lang']] : zt('Language');
  368. $text .= " */\n\n".'$language = "'.$language.'";'."\n\n";
  369. $text .= '$lang[\''.$zc['lang'].'\'] = array('."\n";
  370. foreach ($reduced as $en) {
  371. $text .= "\t'".$en."' => '";
  372. if ($zc['lang'] != 'en') {
  373. $trans = zt($en);
  374. if ($trans != $en) {
  375. $text .= $trans;
  376. }
  377. }
  378. $text .= "',\n";
  379. }
  380. $text .= ");\n?>";
  381. while(@ob_end_clean());
  382. header('Content-type: text/plain');
  383. if (!$zc['debug']) header('Content-Disposition: attachment; filename="'.$zc['lang'].'.php"');
  384. echo $text;
  385. exit;
  386. } else {
  387. zina_set_message(zt('Nothing Found'),'error');
  388. zina_goto('', 'l=20');
  389. }
  390. break;
  391. Case 42 : # Add Custom Playlist Title
  392. if (!zina_token_sess_check()) return zina_page_main($path);
  393. zina_write_playlist($songs, str_replace('/',' - ',$path).'.m3u', 't');
  394. if ($zc['cache_tmpl']) {
  395. if (!zina_delete_tmpl_file(zina_get_tmpl_cache_file($path)))
  396. zina_debug(zt('Could not delete cache file'));
  397. }
  398. zina_goto($_SERVER['HTTP_REFERER']);
  399. break;
  400. Case 45 : # sync database to mp3 files...
  401. $files_assoc = zina_core_cache('files_assoc', $path);
  402. if (isset($files_assoc[$path])) {
  403. $files = $files_assoc[$path];
  404. foreach($files as $file) {
  405. zdb_log_stat('insertonly', $path, $file, null, true, true);
  406. }
  407. } else {
  408. zdb_log_stat('insertonly', $path, null, null, true, true);
  409. }
  410. zina_goto($path);
  411. break;
  412. Case 47 : # regen statistics
  413. if ($zc['database']) {
  414. zdb_stats_generate(time());
  415. zina_goto('', 'l=20');
  416. }
  417. break;
  418. Case 48 :
  419. if ($zc['genres'] && $zc['database']) {
  420. return zina_page_main($path, 'genre_hierarchy');
  421. }
  422. break;
  423. Case 49 :
  424. if ($zc['genres'] && $zc['database']) {
  425. if (!zina_token_sess_check()) return zina_page_main($path);
  426. zdb_genres_save($_POST);
  427. #todo: check for errors?
  428. zina_set_message(zt('Genre hierarchy saved.'));
  429. zina_goto('', 'l=48');
  430. }
  431. break;
  432. Case 52 :
  433. if ($zc['genres'] && $zc['database']) {
  434. if (zina_validate('int',$m)) {
  435. if (zdb_genre_delete($m)) zina_set_message(zt('Genre deleted.'));
  436. }
  437. zina_goto('', 'l=48');
  438. }
  439. break;
  440. Case 58 :
  441. return zina_page_main($path, 'edit_images');
  442. break;
  443. Case 59 : # ajax return images
  444. @session_write_close();
  445. if (!$zc['debug']) while(@ob_end_clean());
  446. echo zina_content_3rd_images($path, $m);
  447. exit;
  448. break;
  449. Case 60 : # Delete Image
  450. $file = $zc['mp3_dir'] .'/'.$path;
  451. $result = zt('Could not delete file.');
  452. if (preg_match('/\.('.$zc['ext_graphic'].')$/i', $path) && file_exists($file)) {
  453. if (@unlink($file)) {
  454. $result = zt('Deleted: @file', array('@file'=>$file));
  455. $other = zdb_get_others($path);
  456. if (isset($other['image']) && $other['image'] == basename($path)) {
  457. $image = zina_get_dir_item(dirname($path),'/\.('.$zc['ext_graphic'].')$/i');
  458. zdb_update_others(array('image'=>$image), dirname($path));
  459. }
  460. }
  461. }
  462. echo $result;
  463. exit;
  464. break;
  465. Case 61 : # Save Image
  466. $result = zt('Failed');
  467. if (is_writeable($zc['cur_dir'])) {
  468. if (($image = file_get_contents($imgsrc)) !== false) {
  469. $filename = $zc['cur_dir'].'/'.basename($imgsrc);
  470. $i=1;
  471. while (file_exists($filename)) {
  472. $filename = $zc['cur_dir'].'/copy'.$i.'_'.basename($imgsrc);
  473. }
  474. if (file_put_contents($filename, $image)) {
  475. $result = zt('Image Saved: @src -> @dest', array('@src'=> $imgsrc, '@dest' => $filename));
  476. if (isset($_SESSION['zina_missing'][$path])) unset($_SESSION['zina_missing'][$path]);
  477. }
  478. }
  479. }
  480. if (!$zc['debug']) while(@ob_end_clean());
  481. echo $result;
  482. exit;
  483. break;
  484. Case 62 : # Find album art
  485. $missing = zina_search_dirs_for_missing_images();
  486. if (!empty($missing)) {
  487. $_SESSION['zina_missing'] = $missing;
  488. zina_goto(current($missing),'l=58');
  489. } else {
  490. zina_set_message(zt('No missing artist/album artwork.'));
  491. unset($_SESSION['zina_missing']);
  492. zina_goto('', 'l=20');
  493. }
  494. exit;
  495. break;
  496. Case 63 : # Close Album Art
  497. unset($_SESSION['zina_missing']);
  498. zina_goto($path);
  499. break;
  500. Case 64 :
  501. return zina_page_main('', 'help');
  502. break;
  503. Case 67 : # import textfile playlists into database...
  504. #remove in 3.0 / make part of upgrade
  505. if ($zc['database']) {
  506. $playlists = zina_get_playlists_custom();
  507. if (empty($playlists)) {
  508. zina_set_message(zt('No playlists to convert'));
  509. zina_goto('', 'l=20');
  510. }
  511. foreach($playlists as $playlist) {
  512. $filename = $zc['cache_pls_dir'].'/_zina_'.$playlist.'.m3u';
  513. if (file_exists($filename)) {
  514. $pls_id = zdbq_single("SELECT id FROM {playlists} WHERE title = '%s' AND user_id = %d", array($playlist, $zc['user_id']));
  515. if (!empty($pls_id)) {
  516. zina_set_message(zt('Playlist already exists: @pls', array('@pls'=>$playlist)));
  517. continue;
  518. }
  519. $genre_id = null;
  520. $dir_id = zdbq_single("SELECT id FROM {dirs} WHERE path = '%s' AND level = 1", array($playlist));
  521. if ($dir_id) {
  522. $image_type = 1;
  523. } else {
  524. $dir_id = null;
  525. $image_type = 0;
  526. }
  527. $mtime = filemtime($filename);
  528. if (zdbq("INSERT {playlists} (title, user_id, dir_id, genre_id, image_type, date_created, mtime) VALUES ('%s', %d, %d, '%s', '%s', %d, %d)",
  529. array($playlist, $zc['user_id'], $dir_id, $genre_id, $image_type, $mtime, $mtime))) {
  530. $pls_id = zdbq_single("SELECT id FROM {playlists} WHERE title = '%s' AND user_id = %d", array($playlist, $zc['user_id']));
  531. if (!empty($pls_id)) {
  532. $songs = zunserialize_alt(file_get_contents($filename));
  533. zina_playlist_insert($pls_id, $songs, 1);
  534. }
  535. }
  536. } else {
  537. zina_set_message(zt('Cannot open playlist: @pls', array('@pls'=>$playlist)));
  538. }
  539. }
  540. zina_goto('', 'l=20');
  541. }
  542. break;
  543. Case 71 : # edit tags
  544. require_once($zc['zina_dir_abs'].'/extras/tag_editor.php');
  545. return zina_page_main($path, 'edittags');
  546. break;
  547. Case 72 : # tag search
  548. Case 73 : # tag search
  549. require_once($zc['zina_dir_abs'].'/extras/tag_editor.php');
  550. if ($level == 72) {
  551. if (($result = zina_extras_tags_freedb_matches(rawurldecode($playlist))) !== false) {
  552. echo $result;
  553. }
  554. } else {
  555. if (($result = zina_extras_tags_freedb_match($_GET['cat'], $_GET['discid'])) !== false) {
  556. echo $result;
  557. }
  558. }
  559. exit;
  560. break;
  561. Case 75 : # delete file
  562. if (($path = zina_delete_file($zc['cur_dir'])) !== false) {
  563. zina_set_message(zt('Deleted file: @file', array('@file'=>$zc['cur_dir'])));
  564. }
  565. zina_goto($path);
  566. break;
  567. Case 76 : # delete dir
  568. if (!zfile_check_location($zc['cur_dir'], $zc['mp3_dir']) || !is_dir($zc['cur_dir'])) {
  569. zina_set_message(zt('Directory does not exist: @dir', array('@dir'=>$zc['cur_dir'])));
  570. zina_goto('');
  571. }
  572. $dir = zina_get_directory($path);
  573. if (!empty($dir['subdirs'])) {
  574. zina_set_message(zt('Cannot delete directory. Directory has subdirectories.'));
  575. zina_goto($path);
  576. }
  577. if (!empty($dir['files'])) {
  578. foreach($dir['files'] as $file => $xxx) {
  579. if (zina_delete_file($zc['mp3_dir'].'/'.$file)) zina_set_message(zt('Deleted file: @file', array('@file'=>$file)));
  580. }
  581. }
  582. if (zina_delete_directory($zc['cur_dir'])) {
  583. if ($zc['database']) {
  584. $id = zdbq_single("SELECT id FROM {dirs} WHERE path = '%s'", array($path));
  585. if (!empty($id)) zdb_remove('dir', $id);
  586. }
  587. } else {
  588. zina_set_message(zt('Cannot delete directory: @dir', array('@dir'=>$path)), 'error');
  589. }
  590. if (($pos = strrpos($path, '/')) == 0) {
  591. $path = '';
  592. } else {
  593. $path = substr($path, 0, $pos);
  594. }
  595. zina_goto($path);
  596. break;
  597. Case 78 :
  598. if ($path != '') return zina_page_main($path, 'rename_directory');
  599. break;
  600. } # end admin switch
  601. return zina_not_found();
  602. } elseif (in_array($level, array(3,5,6,7,8,10,11,12,16,17,25,53,54,56,57,66,68,70,74))) {
  603. # STREAM FUNCTIONS
  604. switch ($level) {
  605. Case 3 :
  606. if ($zc['cmp_sel']) {
  607. zina_send_zip_selected($songs, (isset($_GET['lf'])));
  608. }
  609. break;
  610. Case 5 :
  611. if ($zc['cmp_sel']) {
  612. zina_send_zip_selected_dir($path, (isset($_GET['c'])), (isset($_GET['lf'])));
  613. }
  614. break;
  615. Case 6 : # Return resampled MP3
  616. if ($zc['resample']) {
  617. if ($zc['database'] && $zc['stats']) zdb_log_stat('play', dirname($path), basename($path));
  618. zina_send_file_music($path, true);
  619. }
  620. break;
  621. Case 7 : # return resized image
  622. $type = isset($_GET['it']) ? $_GET['it'] : null;
  623. if (in_array($type, array('sub','dir','full','search','genre','genresearch','pls','plssearch'))) {
  624. $cache_file = $string = false;
  625. $text = null;
  626. if (empty($imgsrc)) {
  627. if ($type == 'genresearch' || $type == 'plssearch') $type = 'search';
  628. $tmp = $zc['theme_path_abs'].'/images';
  629. $imgsrc = ztheme('missing_image',$type);
  630. $text = ztheme('title',basename($path));
  631. } else {
  632. $res_out_type = ($zc['res_out_type'] == 'jpeg') ? 'jpg' : $zc['res_out_type'];
  633. if ($type == 'genre' || $type == 'genresearch') {
  634. if ($type == 'genresearch') $type = 'search';
  635. $tmp = $zc['theme_path_abs'].'/images';
  636. $genre_file = ztheme('image_genre', $imgsrc);
  637. if (file_exists($tmp.'/'.$genre_file)) {
  638. $imgsrc = $genre_file;
  639. } else {
  640. $text = strtoupper($imgsrc);
  641. $imgsrc = ztheme('missing_image','genre');
  642. }
  643. $cache_file = $zc['cache_imgs_dir'].'/'.$type.md5($tmp.'/'.$genre_file).'.'.$res_out_type;
  644. } elseif ($type == 'pls' || $type == 'plssearch') {
  645. $tmp = $zc['theme_path_abs'].'/images';
  646. $text = strtoupper($imgsrc);
  647. $imgsrc = ztheme('missing_image','playlist');
  648. $type = ($type == 'pls') ? 'sub' : 'search';
  649. #$cache_file = $zc['cache_imgs_dir'].'/'.$type.md5($tmp.'/'.$genre_file).'.'.$res_out_type;
  650. } elseif ($imgsrc == 'zina_id3_zina.jpg') {
  651. $subdir_file = zina_get_dir_item($zc['mp3_dir'].'/'.$path,'/\.('.$zc['ext_mus'].')$/i');
  652. $tmp = $zc['mp3_dir'].'/'.$path;
  653. if (!empty($subdir_file)) {
  654. $info = zina_get_file_info($zc['mp3_dir'].'/'.$path.'/'.$subdir_file, false, true, false, true);
  655. if (isset($info->image)) {
  656. $string = $info->image;
  657. $cache_file = $zc['cache_imgs_dir'].'/'.$type.md5($zc['mp3_dir'].'/'.$path.'/'.$imgsrc).'.'.$res_out_type;
  658. }
  659. }
  660. } else {
  661. $tmp = $zc['mp3_dir'].'/'.$path;
  662. $cache_file = $zc['cache_imgs_dir'].'/'.$type.md5($zc['mp3_dir'].'/'.$path.'/'.$imgsrc).'.'.$res_out_type;
  663. }
  664. if ($zc['cache_imgs'] && $cache_file) {
  665. if (file_exists($cache_file)) {
  666. while(@ob_end_clean());
  667. Header('Content-type: image/'.$zc['res_out_type']);
  668. readfile($cache_file);
  669. exit;
  670. }
  671. }
  672. }
  673. $image_source = $tmp.'/'.$imgsrc;
  674. if (!file_exists($image_source) && !$string) {
  675. $image_source = $zc['theme_path_abs'].'/images/'.ztheme('missing_image',$type);
  676. $text = zt('Error');
  677. $cache_file = $string = false;
  678. }
  679. zina_send_image_resized($image_source, $type, $text, $cache_file, $string);
  680. }
  681. break;
  682. Case 11 : # return img
  683. if ($zc['stream_int'] && preg_match('/\.('.$zc['ext_graphic'].')$/i', $imgsrc)) {
  684. $file = $zc['mp3_dir'].'/'.((!empty($path)) ? $path.'/' : '').$imgsrc;
  685. if (file_exists($file)) {
  686. @ob_end_clean();
  687. readfile($file);
  688. }
  689. }
  690. break;
  691. Case 8 : # RETURN PLAYLISTS
  692. if ($zc['play']) {
  693. if (!isset($m)) $m = isset($_POST['m']) ? $_POST['m'] : null;
  694. $lofi = (isset($_GET['lf']));
  695. $cus = (isset($_GET['c']));
  696. $num = isset($_POST['n']) ? $_POST['n'] : (isset($_GET['n']) ? $_GET['n'] : null);
  697. if (!in_array($num, $zc['ran_opts'])) $num = $zc['ran_opts_def'];
  698. if ($playlist == null && isset($_GET['playlist'])) $playlist = $_GET['playlist'];
  699. $random = (isset($_GET['rand']));
  700. $store = (isset($_GET['store']));
  701. switch($m) {
  702. Case 0 :
  703. zina_send_playlist_title($path, $cus, $lofi);
  704. break;
  705. Case 1 :
  706. zina_send_playlist_song($path, $lofi);
  707. break;
  708. Case 3 :
  709. zina_send_playlist_custom($playlist, $lofi, $random);
  710. break;
  711. Case 4 : # Random Albums
  712. zina_send_playlist_random($num,'t',$lofi, true, null, $playlist);
  713. break;
  714. Case 5 : # Random Songs
  715. zina_send_playlist_random($num,'s',$lofi, true, null, $playlist);
  716. break;
  717. Case 6 : # Random Songs By Year
  718. zina_send_playlist_random($num,'s',$lofi, true, null, null, $playlist);
  719. break;
  720. Case 7 :
  721. zina_send_playlist_selected($songs, $lofi, $store);
  722. break;
  723. Case 8 :
  724. zina_send_playlist_selected_random($songs, $lofi, $store);
  725. break;
  726. Case 10 : # Play Recursively & Recursively Random ($cus = random)
  727. zina_send_playlist_random(0,'s',$lofi,$cus,$path);
  728. break;
  729. Case 11 : # Random Songs via Rated Songs
  730. zina_send_playlist_random($num,'tt',$lofi, true, null, $playlist);
  731. break;
  732. Case 12 : # Random Songs via Rated Artists
  733. zina_send_playlist_random($num,'artist',$lofi, true, null, $playlist);
  734. break;
  735. }
  736. }
  737. break;
  738. Case 10 : # internal streaming
  739. if ($zc['play']) {
  740. if ($zc['remote'] && preg_match('/\.('.$zc['remote_ext'].')$/i', $path)) {
  741. $rem = new remoteFile($zc['mp3_dir'].'/'.$path, false, true);
  742. if (isset($rem->url)) {
  743. if ($zc['database'] && $zc['stats']) zdb_log_stat('play', dirname($path), basename($path));
  744. while(@ob_end_clean());
  745. header('Location: '.$rem->url);
  746. exit;
  747. }
  748. } elseif ($zc['play'] && $zc['stream_int']) {
  749. if ($zc['database'] && $zc['stats']) zdb_log_stat('play', dirname($path), basename($path));
  750. zina_send_file_music($path);
  751. }
  752. }
  753. break;
  754. Case 12 : # download mp3
  755. if ($zc['download'] && preg_match('/\.('.$zc['ext_mus'].')$/i', $path, $exts)) {
  756. $file = $zc['mp3_dir'].'/'.$path;
  757. if (file_exists($file)) {
  758. if ($zc['database'] && $zc['stats']) zdb_log_stat('down', dirname($path), basename($path));
  759. if ($zc['stream_int']) {
  760. $filename = html_entity_decode(zina_get_file_artist_title($file, $zc['mp3_id3'])).'.'.$exts[1];
  761. zina_set_header('Content-Type: application/force-download');
  762. zina_set_header('Content-Disposition: inline; filename="'.$filename.'"');
  763. zina_set_header('Content-Length: '.filesize($file));
  764. zina_set_header('Cache-control: private'); #IE seems to need this.
  765. zina_send_file($file);
  766. } else {
  767. zina_goto($path,NULL,NULL,TRUE,TRUE);
  768. }
  769. }
  770. }
  771. break;
  772. Case 16 : # VOTE
  773. if ($zc['database']) {
  774. $num = isset($_POST['n']) ? $_POST['n'] : (isset($_GET['n']) ? $_GET['n'] : null);
  775. if (zina_validate('int',$num) && $num <= 5 && ($num >= 1 || ($zc['user_id'] > 0 && $num == 0))) {
  776. if (preg_match('/\.('.$zc['ext_mus'].')$/i', $path) || ($zc['remote'] && preg_match('/\.('.$zc['remote_ext'].')$/i', $path))) {
  777. if ($zc['rating_files']) zdb_log_stat('vote',dirname($path), basename($path), $num);
  778. $path = dirname($path);
  779. } else {
  780. if ($zc['rating_dirs']) zdb_log_stat('vote',$path, null, $num);
  781. }
  782. if ($zc['cache_tmpl']) {
  783. if (!zina_delete_tmpl_file(zina_get_tmpl_cache_file($path))) zina_debug(zt('Cannot delete cache file'));
  784. }
  785. #todo: return 'error' on bad result
  786. echo ($num == 0) ? zt('Deleted') : zt('Thank you');
  787. }
  788. }
  789. break;
  790. Case 68 : # Vote Playlists
  791. if ($zc['database'] && $zc['pls_ratings']) {
  792. $num = isset($_POST['n']) ? $_POST['n'] : (isset($_GET['n']) ? $_GET['n'] : null);
  793. if (zina_validate('int',$num) && $num <= 5 && ($num >= 1 || ($zc['user_id'] > 0 && $num == 0))) {
  794. zdb_log_stat_playlist((int)$playlist, 'votes', $num);
  795. #todo: return 'error' on bad result
  796. echo ($num == 0) ? zt('Deleted') : zt('Thank you');
  797. }
  798. }
  799. break;
  800. Case 25 : # download MM
  801. if ($zc['mm'] && $zc['mm_down'] && preg_match('/\.('.$zc['mm_ext'].')$/i', $path, $exts)) {
  802. $file = $zc['mp3_dir'].'/'.$path;
  803. if (file_exists($file)) {
  804. if ($zc['stream_int']) {
  805. $ext = strtolower($exts[1]);
  806. zina_set_header('Content-Type: '.$zc['mm_types'][$ext]['mime']);
  807. $disposition = (isset($zc['mm_types'][$ext]['disposition'])) ? $zc['mm_types'][$ext]['disposition'] : 'attachment';
  808. zina_set_header('Content-Disposition: '.$disposition.'; filename="'.basename($path).'"');
  809. zina_set_header('Content-Length: '.filesize($file));
  810. zina_set_header('Cache-control: private'); #IE seems to need this.
  811. zina_send_file($file);
  812. } else {
  813. zina_goto($path,NULL,NULL,TRUE,TRUE);
  814. }
  815. }
  816. }
  817. break;
  818. Case 53 : # LIVE SEARCH RETURN
  819. $search_term = (isset($_GET['zinaq'])) ? $_GET['zinaq'] : '';
  820. if (strlen($search_term) >= $zc['search_min_chars']) {
  821. $num = isset($_GET['limit']) ? $_GET['limit'] : $zc['search_live_limit'];
  822. $num = (zina_validate('int', $num) && $num > 0 && $num < $zc['search_live_limit']) ? $num : $zc['search_live_limit'];
  823. if ($zc['db_search']) {
  824. $results = zdbq_array("SELECT i.title, i.type, i.context, i.id, i.path, i.genre ".
  825. ",if(i.type='playlist', p.image_type, FALSE) as image_type ".
  826. ",if(i.type='playlist', pd.path, FALSE) as image_path ".
  827. "FROM {search_index} AS i ".
  828. "LEFT OUTER JOIN {playlists} AS p ON (i.type = 'playlist' AND i.type_id = p.id) ".
  829. "LEFT OUTER JOIN {dirs} AS pd ON (i.type = 'playlist' AND i.type_id = p.id AND p.dir_id = pd.id) ".
  830. "WHERE i.title LIKE '%%%s%%' ".
  831. "ORDER BY i.title LIMIT %d",
  832. array($search_term, $num));
  833. } else {
  834. $results = zina_search_cache($search_term, $num);
  835. }
  836. if (!empty($results)) {
  837. if ($zc['search_images']) {
  838. foreach ($results as $key => $item) {
  839. $results[$key]['image'] = zina_content_search_image($item, 'search');
  840. }
  841. }
  842. foreach ($results as $item) {
  843. unset($item['image_type']);
  844. unset($item['image_path']);
  845. $item['type'] = zt(ucfirst($item['type']));
  846. echo implode('|', $item)."\n";
  847. }
  848. }
  849. }
  850. exit;
  851. break;
  852. Case 54 : # XML file info for flash app
  853. if ($zc['zinamp']) {
  854. $output = zina_get_file_xml($path);
  855. while(@ob_end_clean());
  856. header('Content-type: application/xml');
  857. echo $output;
  858. }
  859. break;
  860. Case 56 :
  861. if ($zc['zinamp'] && $zc['lastfm'] && isset($_GET['n'])) {
  862. zina_play_complete($path, intval($_GET['n']));
  863. }
  864. break;
  865. Case 57 : # 3rd party lyrics
  866. if ($zc['song_extras'] && in_array($m, $zc['song_es_exts'])) {
  867. @session_write_close();
  868. if ($zc['zinamp'] && $playlist == 'zinamp') {
  869. $content = zina_content_blurb($zina, $path, array('type'=>$m, 'return'=>true));
  870. if (isset($content['output']) && !empty($content['output'])) {
  871. if (!$zc['debug']) @ob_end_clean();
  872. echo nl2br($content['output']);
  873. exit;
  874. }
  875. }
  876. if (isset($zc['third_'.$m]) && $zc['third_'.$m]) {
  877. $info = array();
  878. zina_get_file_artist_title($zc['mp3_dir'].'/'.$path, true, $info);
  879. $lyr_opts = zina_get_extras_opts($m);
  880. $opts = explode(',', $zc['third_lyr_order']);
  881. $output = '';
  882. if (!empty($info['artist']) && !empty($info['title'])) {
  883. foreach($opts as $source) {
  884. if (!in_array($source, $lyr_opts)) continue;
  885. require_once($zc['zina_dir_abs'].'/extras/extras_'.$m.'_'.$source.'.php');
  886. $result = array();
  887. if (($result = call_user_func('zina_extras_'.$m.'_'.$source, $info['artist'], $info['title'])) !== false) {
  888. $output .= $result['output'];
  889. if ($zc['third_'.$m.'_save']) {
  890. zina_save_blurb($path, $m, $output, null, false);
  891. }
  892. $output = nl2br($output);
  893. if (isset($result['source'])) $output .= ztheme('extras_source', $result['source']);
  894. break;
  895. }
  896. }
  897. }
  898. if (empty($output)) $output .= zt('No @type found.', array('@type'=>$zc['song_es'][$m]['name']));
  899. if (!$zc['debug']) while(@ob_end_clean());
  900. echo $output;
  901. }
  902. }
  903. break;
  904. Case 66 :
  905. if ($zc['zinamp'] && $zc['lastfm']) {
  906. zina_zinamp_start($path);
  907. }
  908. break;
  909. Case 70 :
  910. if ($zc['playlists'] && $zc['database'] && zina_validate('int',$playlist)) {
  911. zina_playlist_feed($playlist);
  912. }
  913. break;
  914. Case 74:
  915. if (isset($_SESSION['zina_store'])) {
  916. $store = $_SESSION['zina_store'];
  917. unset($_SESSION['zina_store']);
  918. if (!empty($store)) {
  919. zina_send_playlist_content($store['type'], $store['content']);
  920. }
  921. }
  922. break;
  923. }
  924. exit;
  925. } else {
  926. # PAGE DISPLAYS (2,4,9,13,14,15,22,23,24,29,40,41,43,44,50,51,55,69,77,99)
  927. switch ($level) {
  928. Case 2 :
  929. if ($zc['playlists']) return zina_page_main($path, 'playlists', array('pl'=>$playlist, 'id'=>$m));
  930. break;
  931. Case 4 : # SEARCH
  932. if ($zc['search']) return zina_page_main($path, 'search', array('m'=>$m));
  933. break;
  934. Case 9 : # LOGIN
  935. if ($zc['login']) {
  936. if (isset($_POST['un']) && isset($_POST['up'])) {
  937. if (zina_check_password($_POST['un'], $_POST['up'])) {
  938. $_SESSION['za-'.ZINA_VERSION] = true;
  939. if ($zc['session']) { // standalone only
  940. $sess_id = zina_token_sess('1');
  941. setcookie('ZINA_SESSION', $sess_id, time() + (60*60*$zc['session_lifetime']), '/');
  942. $sess_file = $zc['cache_dir_private_abs'].'/sess_'.$sess_id;
  943. @touch($sess_file);
  944. }
  945. zina_goto($path);
  946. } else {
  947. sleep(3);
  948. $_SESSION['za-'.ZINA_VERSION] = false;
  949. zina_set_message(zt('Username and/or password are incorrect.'),'warn');
  950. }
  951. }
  952. return zina_page_main($path, 'login');
  953. }
  954. break;
  955. Case 13 : # Genre Listing
  956. if ($zc['genres']) return zina_page_main($path, 'searchgenre');
  957. break;
  958. Case 14 : # Genres
  959. if ($zc['genres']) return zina_page_main($path, 'genres');
  960. break;
  961. Case 15 : # STATS
  962. if ($zc['database'] && $zc['stats'] && ($zc['stats_public'] || $zc['is_admin'])) {
  963. $period = isset($_POST['period']) ? $_POST['period'] : null;
  964. $type = isset($_POST['type']) ? $_POST['type'] : null;
  965. return zina_page_main($path, 'stats', array('stat'=>$playlist, 'period'=>$period, 'type'=>$type));
  966. }
  967. break;
  968. Case 22 : # VARIOUS EDIT WINDOWS
  969. if ($zc['is_admin'] || (zina_cms_access('editor') && (in_array($m, array(1,2,3,4,6)) || in_array($m, $zc['song_es_exts'])))) {
  970. return zina_page_main($path, 'blurb', array('type'=>$m, 'item'=>$playlist));
  971. } else {
  972. return zina_access_denied();
  973. }
  974. break;
  975. Case 23 : # VARIOUS EDIT WINDOWS SAVE
  976. if (!zina_token_sess_check()) return zina_page_main($path);
  977. if ($zc['is_admin'] || (zina_cms_access('editor') && (in_array($m, array(1,2,3,4,6)) || in_array($m, $zc['song_es_exts'])))) {
  978. zina_save_blurb($path, $m, $songs, $playlist);
  979. } else {
  980. return zina_access_denied();
  981. }
  982. break;
  983. Case 77 :
  984. if ($zc['is_admin'] || (zina_cms_access('editor'))) {
  985. if (isset($_POST) && !empty($_POST) && !zina_token_sess_check()) return zina_access_denied();
  986. return zina_page_main($path, 'dir_opts');
  987. } else {
  988. return zina_access_denied();
  989. }
  990. break;
  991. Case 24 : # PLAY MM
  992. if ($zc['mm']) return zina_page_main($path, 'mm');
  993. break;
  994. Case 29 :# Song Extras
  995. if ($zc['song_extras'] && in_array($m, $zc['song_es_exts'])) {
  996. return zina_page_main($path, 'songextras', array('type'=>$m, 'item'=>null));
  997. }
  998. break;
  999. Case 40 : # Add New Playlist && Add To Playlist
  1000. if (!zina_token_sess_check()) return zina_page_main($path);
  1001. if ($zc['database']) {
  1002. $access = zina_cms_access('edit_playlists', $zc['user_id']);
  1003. if (!($access || ($zc['session_pls'] && $playlist == 'zina_session_playlist'))) {
  1004. zina_set_message(zt('Not authorized'));
  1005. return zina_page_main($path);
  1006. }
  1007. if ($access && $playlist == 'new_zina_list') {
  1008. if (!$zc['is_admin']) {
  1009. $count = zdbq_single("SELECT COUNT(*) FROM {playlists} WHERE user_id = %d", array($zc['user_id']));
  1010. if ($count > $zc['pls_limit']) {
  1011. zina_set_message(zt('Cannot create playlist.').' '.zt('Maximum number of playlists reached.'));
  1012. return zina_page_main($path);
  1013. }
  1014. }
  1015. return zina_page_main($path, 'newplaylist',array('songs'=>$songs));
  1016. } else {
  1017. if (isset($_POST['fromnew'])) {
  1018. if (($pls_id = zina_playlist_form_submit('insert')) !== false) {
  1019. $playlist = $pls_id;
  1020. $start = 1;
  1021. } else {
  1022. $start = false;
  1023. }
  1024. } else {
  1025. if ($playlist == 'zina_session_playlist') {
  1026. $existing = (isset($_SESSION['z_sp'])) ? unserialize_utf8($_SESSION['z_sp']) : array();
  1027. $start = count($existing);
  1028. } else {
  1029. $start = zdbq_single("SELECT MAX(weight) FROM {playlists_map} WHERE playlist_id = %d", array($playlist, $zc['user_id']));
  1030. }
  1031. }
  1032. if ($start !== false) {
  1033. if (zina_playlist_insert($playlist, $songs, $start+1)) {
  1034. zina_set_message(zt('Added to playlist'));
  1035. } else {
  1036. zina_set_message(zt('Could not add to playlist'), 'warn');
  1037. }
  1038. }
  1039. if (isset($_POST['fromnew'])) {
  1040. if (empty($path)) {
  1041. zina_goto('','l=2&pl='.rawurlencode($playlist));
  1042. } else {
  1043. return zina_page_main($path);
  1044. }
  1045. } else {
  1046. echo ztheme('messages');
  1047. exit;
  1048. }
  1049. }
  1050. } elseif ($zc['is_admin'] || $zc['session_pls']) {
  1051. if (!$zc['is_admin']) $playlist = 'zina_session_playlist';
  1052. if ($playlist == 'new_zina_list') {
  1053. return zina_page_main($path, 'newplaylist',array('songs'=>$songs));
  1054. } else {
  1055. zina_write_playlist($songs, '_zina_'.$playlist.'.m3u', 'a');
  1056. zina_set_message(zt('Added to playlist'));
  1057. if (isset($_POST['fromnew'])) {
  1058. if (empty($path)) {
  1059. zina_goto('','l=2&pl='.rawurlencode($playlist));
  1060. } else {
  1061. return zina_page_main($path);
  1062. }
  1063. } else {
  1064. echo ztheme('messages');
  1065. exit;
  1066. }
  1067. }
  1068. }
  1069. break;
  1070. Case 41 : # Update Playlist
  1071. if (!zina_token_sess_check()) return zina_page_main($path);
  1072. $order = isset($_POST['order']) ? $_POST['order'] : null;
  1073. if ($zc['database']) {
  1074. $pls_user_id = zdbq_single("SELECT user_id FROM {playlists} WHERE id = %d", array($playlist));
  1075. $access = zina_cms_access('edit_playlists', $pls_user_id);
  1076. if (!($access || ($zc['session_pls'] && $playlist == 'zina_session_playlist'))) {
  1077. zina_set_message(zt('Not authorized'));
  1078. return zina_page_main($path);
  1079. }
  1080. $songs = zina_reorder_playlist($songs, $order);
  1081. if ($playlist == 'zina_session_playlist') {
  1082. $_SESSION['z_sp'] = utf8_encode(serialize($songs));
  1083. } else {
  1084. zdbq("DELETE FROM {playlists_map} WHERE playlist_id = %d", array($playlist));
  1085. foreach($songs as $weight => $type_id) {
  1086. if (preg_match('/\.lp$/i', $type_id)) {
  1087. $type = 'album';
  1088. $type_id = preg_replace('/\/\.lp$/i','',$type_id);
  1089. } elseif (preg_match('/\.pls$/i', $type_id)) {
  1090. $type = 'playlist';
  1091. $type_id = preg_replace('/\.pls/i','',$type_id);
  1092. } else {
  1093. $type = 'song';
  1094. }
  1095. if (!zdbq("INSERT {playlists_map} (playlist_id, type, type_id, weight) VALUES (%d, '%s', %d, %d)",
  1096. array($playlist, $type, $type_id, $weight+1))) {
  1097. zina_set_message(zt('Could not insert into playlist: @file', array('@file'=>$type_id)));
  1098. }
  1099. }
  1100. if (($sum_items = zdbq_single("SELECT COUNT(*) FROM {playlists_map} WHERE playlist_id = %d", array($playlist))) !== false) {
  1101. zdbq("UPDATE {playlists} SET sum_items = %d WHERE id = $playlist", array($sum_items, $playlist));
  1102. }
  1103. }
  1104. return zina_page_main($path, 'playlists',array('pl'=>$playlist));
  1105. } elseif ($zc['is_admin'] || $zc['session_pls']) {
  1106. if (!$zc['is_admin']) $playlist = 'zina_session_playlist';
  1107. zina_write_playlist(zina_reorder_playlist($songs, $order), '_zina_'.$playlist.'.m3u');
  1108. return zina_page_main($path, 'playlists',array('pl'=>$playlist));
  1109. }
  1110. break;
  1111. Case 43 : # DELETE CUSTOM PLAYLIST
  1112. if ($zc['database'] && $playlist != 'zina_session_playlist') {
  1113. if ($zc['is_admin'] || $zc['pls_user']) {
  1114. if ($zc['is_admin']) {
  1115. $access = true;
  1116. } else {
  1117. $access = zdbq_single("SELECT 1 FROM {playlists} WHERE id = %d AND user_id = %d", array($playlist, $zc['user_id']));
  1118. }
  1119. if ($access) {
  1120. zdbq("DELETE FROM {playlists_map} WHERE playlist_id = %d", array($playlist));
  1121. zdbq("DELETE FROM {playlists} WHERE id = %d", array($playlist));
  1122. zina_set_message(zt('Playlist deleted'));
  1123. zina_goto('','l=2');
  1124. }
  1125. }
  1126. } else {
  1127. if ($zc['is_admin'] || $zc['session_pls']) {
  1128. if (!$zc['is_admin']) $playlist = 'zina_session_playlist';
  1129. zina_delete_playlist_custom($playlist);
  1130. zina_goto('','l=2');
  1131. }
  1132. }
  1133. break;
  1134. Case 44 : # EDIT PLAYLIST
  1135. if ($_POST && !zina_token_sess_check()) return zina_page_main($path);
  1136. if (!($zc['playlists'] && ($zc['is_admin'] || ($zc['pls_user'] && $zc['user_id'] > 0)))) return zina_access_denied();
  1137. $playlist_new = isset($_POST['playlist_new']) ? $_POST['playlist_new'] : '';
  1138. return zina_page_main($path, 'renameplaylist', array('playlist'=>$playlist, 'new'=>$playlist_new));
  1139. break;
  1140. case 46 :
  1141. if ($zc['res_full_img'] && preg_match('/\.('.$zc['ext_graphic'].')$/i', $path)) {
  1142. return zina_page_main($path, 'image');
  1143. }
  1144. break;
  1145. Case 50 : #podcast
  1146. if ($zc['rss']) {
  1147. #TODO: make common output function...
  1148. while(@ob_end_clean());
  1149. header('Content-type: application/xml');
  1150. echo zina_content_rss($path);
  1151. exit;
  1152. }
  1153. break;
  1154. Case 51 : # SITEMAP
  1155. if ($zc['sitemap']) {
  1156. $output = zina_cache('sitemap', 'zina_content_sitemap', null, ($zc['sitemap'] == 2));
  1157. while(@ob_end_clean());
  1158. header('Content-type: text/xml');
  1159. echo $output;
  1160. exit;
  1161. }
  1162. break;
  1163. Case 99 : # logout
  1164. session_unregister('za-'.ZINA_VERSION);
  1165. if ($zc['session']) {
  1166. if (isset($_COOKIE['ZINA_SESSION'])) {
  1167. $sess_file = $zc['cache_dir_private_abs'].'/sess_'.zcheck_plain($_COOKIE['ZINA_SESSION']);
  1168. setcookie('ZINA_SESSION', $_COOKIE['ZINA_SESSION'], time() - 42000, '/');
  1169. if (file_exists($sess_file)) @unlink($sess_file);
  1170. }
  1171. # remove expired sessions
  1172. $old_sessions = glob($zc['cache_dir_private_abs']."/sess_*");
  1173. if (is_array($old_sessions)) {
  1174. foreach ($old_sessions as $filename) {
  1175. if (filemtime($filename) + (60*60*$zc['session_lifetime']) < time()) {
  1176. @unlink($filename);
  1177. }
  1178. }
  1179. }
  1180. }
  1181. zina_set_message(zt('Logged out succesfully.'));
  1182. zina_goto($path);
  1183. break;
  1184. case 55 :
  1185. #todo: move to stream?
  1186. if ($zc['zinamp'] == 2) {
  1187. $content = ztheme('zinamp');
  1188. zina_set_js('inline',
  1189. 'window.onunload = function() {'.
  1190. 'zina_cookie("zinamp_window", "screenX="+window.screenX+",screenY="+window.screenY, {expires:7});'.
  1191. '};');
  1192. $zina = zina_page_simple('zinamp', $content);
  1193. echo ztheme('page_zinamp', $zina);
  1194. exit;
  1195. }
  1196. break;
  1197. Case 65 :
  1198. require_once($zc['zina_dir_abs'].'/batch.php');
  1199. $output = _zbatch_page();
  1200. if ($output === FALSE) {
  1201. return zina_access_denied();
  1202. } elseif (isset($output)) {
  1203. zina_set_css('file', 'extras/progress.css');
  1204. return zina_page_simple(zbatch_set_title(), $output);
  1205. }
  1206. return;
  1207. Case 69 : # Year Listing
  1208. if ($zc['db_search']) return zina_page_main($path, 'searchyear');
  1209. break;
  1210. default : # MAIN PAGE
  1211. # Allows files to stream without l=8 (for RSS and prettiness)
  1212. if (is_file($zc['cur_dir']) && $zc['play'] && (($zc['stream_int'] && preg_match('/\.('.$zc['ext_mus'].')$/i', $path)) ||
  1213. ($zc['remote'] && preg_match('/\.('.$zc['remote_ext'].')$/i', $path, $matches)))) {
  1214. if ($zc['database'] && $zc['stats']) zdb_log_stat('play', dirname($path), basename($path));
  1215. zina_send_file_music($path);
  1216. }
  1217. if (is_file($zc['cur_dir']) && $zc['rss'] && basename($path) == $zc['rss_file']) {
  1218. $output = file_get_contents($zc['cur_dir']);
  1219. $output = utf8_decode($output);
  1220. header('Content-type: application/xml');
  1221. echo $output;
  1222. exit;
  1223. }
  1224. if (!is_dir($zc['cur_dir'])) return zina_not_found();
  1225. if ($zc['database']) zdb_log_stat('view', $path);
  1226. return zina_page_main($path);
  1227. }
  1228. return zina_not_found();
  1229. }
  1230. } #END MAIN
  1231. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  1232. * PAGES
  1233. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  1234. function zina_page_main($path, $type='main', $opts=null) {
  1235. global $zc;
  1236. $page = zina_get_page_opt($path);
  1237. $cat_sort = zina_get_catsort_opt($path);
  1238. if ($zc['cache_tmpl']) {
  1239. $cache_file = $zc['cache_tmpl_dir'].'/'.zina_get_tmpl_cache_file($path);
  1240. if (!$zc['is_admin'] && $_SERVER['REQUEST_METHOD'] == 'GET' && file_exists($cache_file)) {
  1241. $mtime = filemtime($cache_file);
  1242. if ($mtime > filemtime($zc['cur_dir'].'/.') && $mtime + ($zc['cache_tmpl_expire'] * 86400) > time()) {
  1243. $zina = unserialize(implode('', gzfile($cache_file)));
  1244. $zina['cached'] = true;
  1245. return $zina;
  1246. }
  1247. }
  1248. }
  1249. $zina = array();
  1250. $zina['lang']['main_dir_title'] = zt($zc['main_dir_title']);
  1251. $zina['embed'] = $zc['embed'];
  1252. $zina['site_name'] = isset($zc['conf']['site_name']) ? $zc['conf']['site_name'] : '';
  1253. $zina['amg'] = $zc['amg'];
  1254. $zina['theme_path'] = zpath_to_theme();
  1255. $zina['searchform'] = $zina['stats'] = $zina['genres'] = $random = '';
  1256. $zina['charset'] = $zc['charset'];
  1257. $zina['addthis'] = $zc['third_addthis'];
  1258. $zina['addthis_id'] = $zc['third_addthis_id'];
  1259. $zina['addthis_options'] = $zc['third_addthis_options'];
  1260. $zina['addthis_path'] = $path;
  1261. $zina['addthis_query'] = null;
  1262. if ($zc['search']) {
  1263. $search_term = isset($_POST['searchterm']) ? $_POST['searchterm'] : (isset($_GET['pl']) ? $_GET['pl'] : (isset($_GET['searchterm']) ? $_GET['searchterm'] : ''));
  1264. $zina['searchform…

Large files files are truncated, but you can click here to view the full file