PageRenderTime 112ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 1ms

/zina/index.php

https://bitbucket.org/helmespc/zina2
PHP | 8728 lines | 7679 code | 784 blank | 265 comment | 1937 complexity | 4dc2c0ccfb281ef63c4d9f19b3b2d65f MD5 | raw file
  1. <?php
  2. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  3. * ZINA2 (Zina2 is not Zina)
  4. *
  5. * Zina2 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. * https://bitbucket.org/helmespc/zina2
  10. * Author: Patrick Helmes <helmespc@gmail.com>
  11. * Support: https://bitbucket.org/helmespc/zina2/wiki/Home
  12. * License: GNU GPL2 <http://www.gnu.org/copyleft/gpl.html>
  13. *
  14. * This Software is a fork of Zina (is not Andromeda):
  15. * http://www.pancake.org/zina
  16. * Author: Ryan Lathouwers <ryanlath@pacbell.net>
  17. * Support: http://sourceforge.net/projects/zina/
  18. * License: GNU GPL2 <http://www.gnu.org/copyleft/gpl.html>
  19. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  20. define('ZINA_VERSION', '1.0b1');
  21. #TODO:
  22. # - INSTRUCTIONS for cron for caches
  23. #todo
  24. # - uninstall? -> at least delete cache files created by webuser!
  25. # - check settings descriptions...
  26. # - normalize function names
  27. # - organize files
  28. # - comment functions?
  29. # - look and remove unused language crap?
  30. #TODO-EXTRA:
  31. # - if clean urls... drop l=8&m=1 for songs???
  32. # - See Also -> external links?
  33. # - multiple mp3 dirs
  34. # - Check output_buffering php.ini setting for video stuff?
  35. #TEST:
  36. # - pos
  37. function zina($conf) {
  38. global $zc;
  39. zina_init($conf);
  40. $path = isset($_GET['p']) ? zrawurldecode($_GET['p']) : null;
  41. $level = isset($_GET['l']) ? $_GET['l'] : null;
  42. $m = isset($_GET['m']) ? $_GET['m'] : null;
  43. $imgsrc = isset($_GET['img']) ? $_GET['img'] : null;
  44. $playlist = isset($_POST['playlist']) ? $_POST['playlist'] : (isset($_GET['pl']) ? $_GET['pl'] : null);
  45. $songs = isset($_POST['mp3s']) ? $_POST['mp3s'] : (isset($_GET['mp3s']) ? $_GET['mp3s'] : array());
  46. $path = preg_replace("|(/){2,}|",'$1',trim($path,'/'));
  47. // Validate path doesn't contain '..' and is a valid location under mp3_dir
  48. $badpath = false;
  49. if (strstr($path,'..') && !zfile_check_location($zc['mp3_dir'].'/'.$path, $zc['mp3_dir'])) {
  50. $badpath = true;
  51. }
  52. // Validate that the imgsrc doesn't contain a '..', unless level is 11 or 7
  53. if (!$badpath && strstr($imgsrc,'..')) {
  54. $badpath = true;
  55. if ($level == 11) {
  56. $badpath = (!zfile_check_location($zc['mp3_dir'].'/'.$path, $zc['mp3_dir']));
  57. }
  58. elseif ($level == 7) {
  59. if (isset($_GET['it'])) {
  60. if ($_GET['it'] == 'genre') {
  61. }
  62. elseif (in_array($_GET['it'], array('sub','dir','full','search'))) {
  63. $badpath = (!zfile_check_location($zc['mp3_dir'].'/'.$path, $zc['mp3_dir']));
  64. }
  65. }
  66. }
  67. }
  68. // Validate that the playlist doesn't contain a '..'
  69. if (!$badpath && strstr($playlist,'..')) {
  70. $badpath = true;
  71. }
  72. // Validate song paths
  73. if (!$badpath && !empty($songs) && is_array($songs)) {
  74. foreach ($songs as $song) {
  75. if (strstr($song,'..') && !zfile_check_location($zc['mp3_dir'].'/'.$path, $zc['mp3_dir'])) {
  76. $badpath = true;
  77. break;
  78. }
  79. }
  80. }
  81. // If the path is bad, fail
  82. if ($badpath) {
  83. zina_debug(zt('Bad path: @path', array('@path'=>$path)));
  84. return zina_not_found();
  85. }
  86. // Set the current directory based on the URL
  87. $zc['cur_dir'] = $zc['mp3_dir']. (!empty($path) ? '/'.$path : '');
  88. if (!empty($path) && !file_exists($zc['cur_dir'])) {
  89. $file_not_found = true;
  90. if (substr($path,-3) == '.lp') {
  91. $tmp_path = substr($path, 0, strlen($path) -3);
  92. if (file_exists($zc['mp3_dir'].'/'.$tmp_path)) {
  93. $file_not_found = false;
  94. $zc['cur_dir'] = $zc['mp3_dir'].'/'.$tmp_path;
  95. }
  96. }
  97. elseif ($zc['sitemap'] && $path == $zc['sitemap_file']) {
  98. $level = 51;
  99. $path = '';
  100. $zc['cur_dir'] = $zc['mp3_dir'];
  101. $file_not_found = false;
  102. }
  103. elseif ($zc['rss'] && basename($path) == $zc['rss_file']) {
  104. $level = 50;
  105. $path = substr($path,0,-(strlen($zc['rss_file'])+1));
  106. $zc['cur_dir'] = $zc['mp3_dir'].'/'.$path;
  107. if (file_exists($zc['cur_dir'])) {
  108. $file_not_found = false;
  109. }
  110. }
  111. elseif ($zc['stats_rss'] && $zc['database'] && basename($path) == 'stats.xml') {
  112. zina_stats_feed($path);
  113. }
  114. elseif ($zc['playlists'] && $zc['database'] && basename($path) == 'pls.xml') {
  115. $pls_id = dirname($path);
  116. if (zina_validate('int',$pls_id)) {
  117. zina_playlist_feed($pls_id);
  118. }
  119. }
  120. elseif ($level == 46 && basename($path) == 'zina_id3_zina.jpg') {
  121. $file_not_found = false;
  122. $tmp_path = dirname($path);
  123. $tmp_path = $zc['mp3_dir'].(!empty($tmp_path) ? '/'.$tmp_path : '');
  124. if (file_exists($tmp_path) && is_dir($tmp_path)) {
  125. $file_not_found = false;
  126. }
  127. }
  128. // Handle file not found
  129. if ($file_not_found) {
  130. $tmp_path = utf8_decode($path);
  131. $tmp_cur_dir = $zc['mp3_dir']. (!empty($tmp_path) ? '/'.$tmp_path : '');
  132. if (file_exists($tmp_cur_dir)) {
  133. $path = $tmp_path;
  134. $zc['cur_dir'] = $tmp_cur_dir;
  135. }
  136. else {
  137. if (substr($path,-11) != 'favicon.ico') {
  138. zina_debug(zt('Path does not exist: @path', array('@path'=>$path)));
  139. }
  140. return zina_not_found();
  141. }
  142. }
  143. }
  144. #todo: validate?
  145. if ($zc['settings_override']) {
  146. $override_file = $zc['cur_dir'].'/'.$zc['settings_override_file'];
  147. if (file_exists($override_file)) {
  148. $override = false;
  149. if (($dir_xml = file_get_contents($override_file)) !== false) {
  150. $dir_settings = xml_to_array($dir_xml, 'settings');
  151. if (!empty($dir_settings[0])) {
  152. foreach($dir_settings[0] as $key => $val) {
  153. if (isset($zc[$key])) {
  154. $zc[$key] = $val;
  155. }
  156. }
  157. $override = true;
  158. }
  159. }
  160. if (!$override) {
  161. zina_set_message(zt('Cannot read override file.'), 'error');
  162. return zina_access_denied();
  163. }
  164. }
  165. }
  166. /*
  167. * MAIN
  168. *
  169. * Determines what zina does.
  170. */
  171. 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))) {
  172. # ADMIN FUNCTIONS
  173. if (!$zc['is_admin']) return zina_access_denied();
  174. #todo: needed?
  175. #header('Expires: Wed, 11 Jan 1984 05:00:00 GMT');
  176. #header('Last-Modified: ' . gmdate( 'D, d M Y H:i:s' ) . ' GMT');
  177. #header('Cache-Control: no-cache, must-revalidate, max-age=0');
  178. #header('Pragma: no-cache');
  179. switch($level) {
  180. Case 18 : # INSTALL OR UPDATE DB
  181. if ($zc['database'] && ($m == 'update' || $m == 'install')) {
  182. $file = $zc['zina_dir_abs'].'/'.$m.'.php';
  183. if ($zc['database'] && file_exists($file)) {
  184. require_once($file);
  185. if ($m == 'install') {
  186. $result = zina_install_database();
  187. } else {
  188. $result = zina_updates_execute();
  189. }
  190. if ($result) {
  191. if ($m == 'install') zvar_set('version', ZINA_VERSION);
  192. zina_set_message(zt('Database @m succeeded!',array('@m'=>$m)));
  193. } else {
  194. zina_set_message(zt('Database @m failed!', array('@m'=>$m)),'error');
  195. }
  196. } else {
  197. zina_set_message(zt('Cannot @m the database...either no database connection or the file does not exist.',array('@m'=>$m)), 'error');
  198. }
  199. zina_goto('', 'l=20');
  200. }
  201. return zina_not_found();
  202. break;
  203. Case 19 : # try to manually submit last.fm queue
  204. if ($zc['lastfm']) {
  205. require_once($zc['zina_dir_abs'].'/extras/scrobbler.class.php');
  206. @set_time_limit($zc['timeout']);
  207. $scrobbler = new scrobbler($zc['lastfm_username'],$zc['lastfm_password']);
  208. $scrobbler->handshake_socket_timeout = 2;
  209. $scrobbler->submit_socket_timeout = 30;
  210. $scrobbler->queued_tracks = zina_set_scrobbler_queue();
  211. if ($scrobbler->submit_tracks()) {
  212. zina_set_message(zt('Queued Last.fm tracks submitted successfully.'));
  213. zina_set_scrobbler_queue(array(), true);
  214. } else {
  215. zina_set_message(zt('Queued Last.fm tracks failed:').$scrobbler->error_msg,'warn');
  216. }
  217. zina_goto('', 'l=20');
  218. }
  219. break;
  220. Case 20 : # CFG
  221. return zina_page_main($path, 'config');
  222. break;
  223. Case 21 : # CFG POST
  224. if (zina_write_settings()) {
  225. zina_set_message(zt('Settings updated.'));
  226. } else {
  227. zina_set_message(zt('Your settings were not saved!'),'error');
  228. }
  229. zina_goto('', 'l=20');
  230. break;
  231. Case 26 : # regen
  232. require_once($zc['zina_dir_abs'].'/batch.php');
  233. @trigger_error('');
  234. $error = false;
  235. if ($m == 1) { # dir/files caches
  236. if ($zc['database']) {
  237. foreach(array('dirs','files_assoc') as $type) {
  238. $operations[] = array('zina_core_cache_batch', array($type, '', array('force'=>true)));
  239. }
  240. if ($zc['low']) {
  241. foreach(array('files_assoc') as $type) {
  242. $operations[] = array('zina_core_cache_batch', array($type, '', array('force'=>true, 'low'=>true)));
  243. }
  244. }
  245. $batch = array(
  246. 'title' => zt('Regenerating directory and file caches.'),
  247. 'finished_message' => zt('Caches generated successfully.'),
  248. 'operations' => $operations,
  249. );
  250. zbatch_set($batch);
  251. zbatch_process();
  252. } else {
  253. foreach(array('dirs','files_assoc') as $type) zina_core_cache($type, '', array('force'=>true));
  254. if ($zc['low']) {
  255. foreach(array('files_assoc') as $type) zina_core_cache($type, '', array('force'=>true,'low'=>true));
  256. }
  257. $message = zt('Cache generated successfully.');
  258. }
  259. } elseif ($m == 2) { # genre cache
  260. #todo: use db or cache but not both? for genres? for dirs/files?
  261. if ($zc['database']) {
  262. $operations = array();
  263. $operations[] = array('zina_core_cache_batch', array('genre', '', array('force'=>true)));
  264. $operations[] = array('zdb_genre_populate', array(time()));
  265. $batch = array(
  266. 'title' => zt('Regenerating genre caches.'),
  267. 'finished_message' => zt('Genre cache generated successfully.'),
  268. 'operations' => $operations,
  269. );
  270. zbatch_set($batch);
  271. zbatch_process();
  272. } else {
  273. $message = zt('Genre cache generated successfully.');
  274. zina_core_cache('genre', '', array('force'=>true));
  275. }
  276. } elseif ($m == 3 || $m == 4) { # populate missing
  277. #TODO: combine 3 & 4... combine 1,3&4?
  278. if ($zc['database']) {
  279. $runtime = time();
  280. $operations = array();
  281. foreach(array('dirs','files_assoc') as $type) {
  282. $operations[] = array('zina_core_cache_batch', array($type, '', array('force'=>true)));
  283. }
  284. if ($m == 3) {
  285. $regen = false;
  286. $title = zt('Populating database with missing entries.');
  287. $finished = zt('Database populated.');
  288. } else { # 4
  289. $regen = true;
  290. $title = zt('Synchronising database');
  291. $finished = zt('Synchronized database.');
  292. }
  293. $operations[] = array('zdb_populate_batch', array($regen));
  294. $operations[] = array('zdb_search_playlist_populate', array($runtime));
  295. $operations[] = array('zdb_genre_populate', array($runtime));
  296. $batch = array(
  297. 'title' => $title,
  298. 'finished_message' => $finished,
  299. 'finished' => 'zdb_populate_finished',
  300. 'operations' => $operations,
  301. );
  302. zbatch_set($batch);
  303. zbatch_process();
  304. }
  305. } elseif ($m == 5) { # image from id3 tags
  306. $operations[] = array('zbatch_extract_images', array());
  307. $batch = array(
  308. 'title' => zt('Extracting images from id3 tags.'),
  309. 'finished_message' => zt('Images extracted successfully.'),
  310. 'operations' => $operations,
  311. 'finished' => 'zbatch_extract_images_finished',
  312. );
  313. zbatch_set($batch);
  314. zbatch_process();
  315. } else {
  316. $error = true;
  317. zina_set_message(zt('Invalid option'), 'error');
  318. }
  319. $e = error_get_last();
  320. if ($error || ($e['type'] < 2048 && !empty($e['message']))) {
  321. #todo: ? zunserialize throws error on older custom_files...
  322. if (!empty($e['message'])) zina_set_message(zt('PHP returned an error[@type]: @message', array('@type'=>$e['type'], '@message'=>$e['message'])), 'error');
  323. } else {
  324. zina_set_message($message);
  325. }
  326. zina_goto('','l=20');
  327. break;
  328. Case 27 : # Find and Clean
  329. if ($zc['database']) {
  330. if ($_POST && !zina_token_sess_check()) return zina_page_main($path);
  331. if (!empty($_POST['zfileids'])) zdb_clean('file',$_POST['zfileids']);
  332. if (!empty($_POST['zdirids'])) zdb_clean('dir',$_POST['zdirids']);
  333. if ($_POST) {
  334. zina_set_message(zt('Database cleaned.'));
  335. zina_goto('', 'l=20');
  336. } else {
  337. return zina_page_main($path, 'clean');
  338. }
  339. }
  340. break;
  341. Case 33 : # DELETE SITEMAP
  342. $file = $zc['cache_dir_public_abs'].'/'.$zc['sitemap_file'];
  343. if (file_exists($file) && @unlink($file)) {
  344. zina_set_message(zt('Sitemap cached file deleted successfully'));
  345. } else {
  346. zina_set_message(zt('Sitemap cached file could not be deleted'),'warn');
  347. }
  348. zina_goto('', 'l=20');
  349. break;
  350. Case 30 :# DELETE TMPL CACHE
  351. Case 31 :# DELETE IMGS CACHE
  352. Case 34 :# DELETE ZIP CACHE
  353. $func = array(
  354. '30'=> array(
  355. 'dir' => $zc['cache_tmpl_dir'],
  356. 'text' => zt('Template cache files deleted.'),
  357. ),
  358. '31'=> array(
  359. 'dir' => $zc['cache_imgs_dir'],
  360. 'text' => zt('Images cache files deleted.'),
  361. ),
  362. '34'=> array(
  363. 'dir' => $zc['cache_zip_dir'],
  364. 'text' => zt('Compressed cache files deleted.'),
  365. ),
  366. );
  367. if (zina_delete_files($func[$level]['dir'])) {
  368. zina_set_message($func[$level]['text']);
  369. }
  370. zina_goto('', 'l=20');
  371. break;
  372. Case 32 : #get language phrases for translation
  373. $files = array('index.php', 'theme.php', 'database.php', 'lang-cfg.php');
  374. $source = '';
  375. foreach($files as $file) {
  376. $source .= file_get_contents($zc['zina_dir_abs'].'/'.$file);
  377. }
  378. if (preg_match_all("/zt\('(.*?)'(\)|,)/is", $source, $matches)) {
  379. $reduced = array_unique($matches[1]);
  380. $instr = array(
  381. zt('These are most of the translation strings currently in Zina.'),
  382. zt('Save this file to LANGCODE.php and modify it.'),
  383. zt('Format: \'english words\' => \'your translation\'')."\n *",
  384. zt('You do not have to do them all (just delete the lines you do not do).'),
  385. zt('If you are making a new translation or completing an older one, move the file to the "lang" directory.'),
  386. zt('If languages.txt file exists in your cache directory, delete it.'),
  387. zt('Or a copy in your theme folder will override the default language file.'),
  388. zt('English users can change wording/phrasings this way.')."\n *",
  389. zt('Test it out.')."\n *",
  390. zt('If you would like it to be included in Zina, please email it to: <@email>', array('@email'=>'ryanlath@pacbell.net')),
  391. );
  392. $text = '<?php'."\n".
  393. "/*\n * ".zt('Zina Translation Instructions')."\n *\n";
  394. foreach($instr as $i) {
  395. $text .= ' * '.$i."\n";
  396. }
  397. $lang = zina_get_languages();
  398. $language = (isset($lang[$zc['lang']])) ? $lang[$zc['lang']] : zt('Language');
  399. $text .= " */\n\n".'$language = "'.$language.'";'."\n\n";
  400. $text .= '$lang[\''.$zc['lang'].'\'] = array('."\n";
  401. foreach ($reduced as $en) {
  402. $text .= "\t'".$en."' => '";
  403. if ($zc['lang'] != 'en') {
  404. $trans = zt($en);
  405. if ($trans != $en) {
  406. $text .= $trans;
  407. }
  408. }
  409. $text .= "',\n";
  410. }
  411. $text .= ");\n?".">";
  412. while(@ob_end_clean());
  413. header('Content-type: text/plain');
  414. if (!$zc['debug']) header('Content-Disposition: attachment; filename="'.$zc['lang'].'.php"');
  415. echo $text;
  416. exit;
  417. } else {
  418. zina_set_message(zt('Nothing Found'),'error');
  419. zina_goto('', 'l=20');
  420. }
  421. break;
  422. Case 42 : # Add Custom Playlist Title
  423. if (!zina_token_sess_check()) return zina_page_main($path);
  424. zina_write_playlist($songs, str_replace('/',' - ',$path).'.m3u', 't');
  425. if ($zc['cache_tmpl']) {
  426. if (!zina_delete_tmpl_file(zina_get_tmpl_cache_file($path)))
  427. zina_debug(zt('Could not delete cache file'));
  428. }
  429. zina_goto($_SERVER['HTTP_REFERER']);
  430. break;
  431. Case 45 : # sync database to mp3 files...
  432. $files_assoc = zina_core_cache('files_assoc', $path);
  433. if (isset($files_assoc[$path])) {
  434. $files = $files_assoc[$path];
  435. foreach($files as $file) {
  436. zdb_log_stat('insertonly', $path, $file, null, true, true);
  437. }
  438. } else {
  439. zdb_log_stat('insertonly', $path, null, null, true, true);
  440. }
  441. zina_goto($path);
  442. break;
  443. Case 47 : # regen statistics
  444. if ($zc['database']) {
  445. zdb_stats_generate(time());
  446. zina_goto('', 'l=20');
  447. }
  448. break;
  449. Case 48 :
  450. if ($zc['genres'] && $zc['database']) {
  451. return zina_page_main($path, 'genre_hierarchy');
  452. }
  453. break;
  454. Case 49 :
  455. if ($zc['genres'] && $zc['database']) {
  456. if (!zina_token_sess_check()) return zina_page_main($path);
  457. zdb_genres_save($_POST);
  458. #todo: check for errors?
  459. zina_set_message(zt('Genre hierarchy saved.'));
  460. zina_goto('', 'l=48');
  461. }
  462. break;
  463. Case 52 :
  464. if ($zc['genres'] && $zc['database']) {
  465. if (zina_validate('int',$m)) {
  466. if (zdb_genre_delete($m)) zina_set_message(zt('Genre deleted.'));
  467. }
  468. zina_goto('', 'l=48');
  469. }
  470. break;
  471. Case 58 :
  472. return zina_page_main($path, 'edit_images');
  473. break;
  474. Case 59 : # ajax return images
  475. @session_write_close();
  476. if (!$zc['debug']) while(@ob_end_clean());
  477. echo zina_content_3rd_images($path, $m);
  478. exit;
  479. break;
  480. Case 60 : # Delete Image
  481. $file = $zc['mp3_dir'] .'/'.$path;
  482. $result = zt('Could not delete file.');
  483. if (preg_match('/\.('.$zc['ext_graphic'].')$/i', $path) && file_exists($file)) {
  484. if (@unlink($file)) {
  485. $result = zt('Deleted: @file', array('@file'=>$file));
  486. $other = zdb_get_others($path);
  487. if (isset($other['image']) && $other['image'] == basename($path)) {
  488. $image = zina_get_dir_item(dirname($path),'/\.('.$zc['ext_graphic'].')$/i');
  489. zdb_update_others(array('image'=>$image), dirname($path));
  490. }
  491. }
  492. }
  493. echo $result;
  494. exit;
  495. break;
  496. Case 61 : # Save Image
  497. $result = zt('Failed');
  498. if (is_writeable($zc['cur_dir'])) {
  499. if (($image = file_get_contents($imgsrc)) !== false) {
  500. $filename = $zc['cur_dir'].'/'.basename($imgsrc);
  501. $i=1;
  502. while (file_exists($filename)) {
  503. $filename = $zc['cur_dir'].'/copy'.$i.'_'.basename($imgsrc);
  504. }
  505. if (file_put_contents($filename, $image)) {
  506. $result = zt('Image Saved: @src -> @dest', array('@src'=> $imgsrc, '@dest' => $filename));
  507. if (isset($_SESSION['zina_missing'][$path])) unset($_SESSION['zina_missing'][$path]);
  508. }
  509. }
  510. }
  511. if (!$zc['debug']) while(@ob_end_clean());
  512. echo $result;
  513. exit;
  514. break;
  515. Case 62 : # Find album art
  516. $missing = zina_search_dirs_for_missing_images();
  517. if (!empty($missing)) {
  518. $_SESSION['zina_missing'] = $missing;
  519. zina_goto(current($missing),'l=58');
  520. } else {
  521. zina_set_message(zt('No missing artist/album artwork.'));
  522. unset($_SESSION['zina_missing']);
  523. zina_goto('', 'l=20');
  524. }
  525. exit;
  526. break;
  527. Case 63 : # Close Album Art
  528. unset($_SESSION['zina_missing']);
  529. zina_goto($path);
  530. break;
  531. Case 64 :
  532. return zina_page_main('', 'help');
  533. break;
  534. Case 67 : # import textfile playlists into database...
  535. #remove in 3.0 / make part of upgrade
  536. if ($zc['database']) {
  537. $playlists = zina_get_playlists_custom();
  538. if (empty($playlists)) {
  539. zina_set_message(zt('No playlists to convert'));
  540. zina_goto('', 'l=20');
  541. }
  542. foreach($playlists as $playlist) {
  543. $filename = $zc['cache_pls_dir'].'/_zina_'.$playlist.'.m3u';
  544. if (file_exists($filename)) {
  545. $pls_id = zdbq_single("SELECT id FROM {playlists} WHERE title = '%s' AND user_id = %d", array($playlist, $zc['user_id']));
  546. if (!empty($pls_id)) {
  547. zina_set_message(zt('Playlist already exists: @pls', array('@pls'=>$playlist)));
  548. continue;
  549. }
  550. $genre_id = null;
  551. $dir_id = zdbq_single("SELECT id FROM {dirs} WHERE path = '%s' AND level = 1", array($playlist));
  552. if ($dir_id) {
  553. $image_type = 1;
  554. } else {
  555. $dir_id = null;
  556. $image_type = 0;
  557. }
  558. $mtime = filemtime($filename);
  559. if (zdbq("INSERT {playlists} (title, user_id, dir_id, genre_id, image_type, date_created, mtime) VALUES ('%s', %d, %d, '%s', '%s', %d, %d)",
  560. array($playlist, $zc['user_id'], $dir_id, $genre_id, $image_type, $mtime, $mtime))) {
  561. $pls_id = zdbq_single("SELECT id FROM {playlists} WHERE title = '%s' AND user_id = %d", array($playlist, $zc['user_id']));
  562. if (!empty($pls_id)) {
  563. $songs = zunserialize_alt(file_get_contents($filename));
  564. zina_playlist_insert($pls_id, $songs, 1);
  565. }
  566. }
  567. } else {
  568. zina_set_message(zt('Cannot open playlist: @pls', array('@pls'=>$playlist)));
  569. }
  570. }
  571. zina_goto('', 'l=20');
  572. }
  573. break;
  574. Case 71 : # edit tags
  575. require_once($zc['zina_dir_abs'].'/extras/tag_editor.php');
  576. return zina_page_main($path, 'edittags');
  577. break;
  578. Case 72 : # tag search
  579. Case 73 : # tag search
  580. require_once($zc['zina_dir_abs'].'/extras/tag_editor.php');
  581. if ($level == 72) {
  582. if (($result = zina_extras_tags_freedb_matches(rawurldecode($playlist))) !== false) {
  583. echo $result;
  584. }
  585. } else {
  586. if (($result = zina_extras_tags_freedb_match($_GET['cat'], $_GET['discid'])) !== false) {
  587. echo $result;
  588. }
  589. }
  590. exit;
  591. break;
  592. Case 75 : # delete file
  593. if (($path = zina_delete_file($zc['cur_dir'])) !== false) {
  594. zina_set_message(zt('Deleted file: @file', array('@file'=>$zc['cur_dir'])));
  595. }
  596. zina_goto($path);
  597. break;
  598. Case 76 : # delete dir
  599. if (!zfile_check_location($zc['cur_dir'], $zc['mp3_dir']) || !is_dir($zc['cur_dir'])) {
  600. zina_set_message(zt('Directory does not exist: @dir', array('@dir'=>$zc['cur_dir'])));
  601. zina_goto('');
  602. }
  603. $dir = zina_get_directory($path);
  604. if (!empty($dir['subdirs'])) {
  605. zina_set_message(zt('Cannot delete directory. Directory has subdirectories.'));
  606. zina_goto($path);
  607. }
  608. if (!empty($dir['files'])) {
  609. foreach($dir['files'] as $file => $xxx) {
  610. if (zina_delete_file($zc['mp3_dir'].'/'.$file)) zina_set_message(zt('Deleted file: @file', array('@file'=>$file)));
  611. }
  612. }
  613. if (zina_delete_directory($zc['cur_dir'])) {
  614. if ($zc['database']) {
  615. $id = zdbq_single("SELECT id FROM {dirs} WHERE path = '%s'", array($path));
  616. if (!empty($id)) zdb_remove('dir', $id);
  617. }
  618. } else {
  619. zina_set_message(zt('Cannot delete directory: @dir', array('@dir'=>$path)), 'error');
  620. }
  621. if (($pos = strrpos($path, '/')) == 0) {
  622. $path = '';
  623. } else {
  624. $path = substr($path, 0, $pos);
  625. }
  626. zina_goto($path);
  627. break;
  628. Case 78 :
  629. if ($path != '') return zina_page_main($path, 'rename_directory');
  630. break;
  631. } # end admin switch
  632. return zina_not_found();
  633. }
  634. elseif (in_array($level, array(3,5,6,7,8,10,11,12,16,17,25,53,54,56,57,66,68,70,74))) {
  635. # STREAM FUNCTIONS
  636. switch ($level) {
  637. Case 3 :
  638. if ($zc['cmp_sel']) {
  639. zina_send_zip_selected($songs, (isset($_GET['lf'])));
  640. }
  641. break;
  642. Case 5 :
  643. if ($zc['cmp_sel']) {
  644. zina_send_zip_selected_dir($path, (isset($_GET['c'])), (isset($_GET['lf'])));
  645. }
  646. break;
  647. Case 6 : # Return resampled MP3
  648. if ($zc['resample']) {
  649. if ($zc['database'] && $zc['stats']) zdb_log_stat('play', dirname($path), basename($path));
  650. zina_send_file_music($path, true);
  651. }
  652. break;
  653. Case 7 : # return resized image
  654. $type = isset($_GET['it']) ? $_GET['it'] : null;
  655. if (in_array($type, array('sub','dir','full','search','genre','genresearch','pls','plssearch'))) {
  656. $cache_file = $string = false;
  657. $text = null;
  658. if (empty($imgsrc)) {
  659. if ($type == 'genresearch' || $type == 'plssearch') $type = 'search';
  660. $tmp = $zc['theme_path_abs'].'/images';
  661. $imgsrc = ztheme('missing_image',$type);
  662. $text = ztheme('title',basename($path));
  663. } else {
  664. $res_out_type = ($zc['res_out_type'] == 'jpeg') ? 'jpg' : $zc['res_out_type'];
  665. if ($type == 'genre' || $type == 'genresearch') {
  666. if ($type == 'genresearch') $type = 'search';
  667. $tmp = $zc['theme_path_abs'].'/images';
  668. $genre_file = ztheme('image_genre', $imgsrc);
  669. if (file_exists($tmp.'/'.$genre_file)) {
  670. $imgsrc = $genre_file;
  671. } else {
  672. $text = strtoupper($imgsrc);
  673. $imgsrc = ztheme('missing_image','genre');
  674. }
  675. $cache_file = $zc['cache_imgs_dir'].'/'.$type.md5($tmp.'/'.$genre_file).'.'.$res_out_type;
  676. } elseif ($type == 'pls' || $type == 'plssearch') {
  677. $tmp = $zc['theme_path_abs'].'/images';
  678. $text = strtoupper($imgsrc);
  679. $imgsrc = ztheme('missing_image','playlist');
  680. $type = ($type == 'pls') ? 'sub' : 'search';
  681. #$cache_file = $zc['cache_imgs_dir'].'/'.$type.md5($tmp.'/'.$genre_file).'.'.$res_out_type;
  682. } elseif ($imgsrc == 'zina_id3_zina.jpg') {
  683. $subdir_file = zina_get_dir_item($zc['mp3_dir'].'/'.$path,'/\.('.$zc['ext_mus'].')$/i');
  684. $tmp = $zc['mp3_dir'].'/'.$path;
  685. if (!empty($subdir_file)) {
  686. $info = zina_get_file_info($zc['mp3_dir'].'/'.$path.'/'.$subdir_file, false, true, false, true);
  687. if (isset($info->image)) {
  688. $string = $info->image;
  689. $cache_file = $zc['cache_imgs_dir'].'/'.$type.md5($zc['mp3_dir'].'/'.$path.'/'.$imgsrc).'.'.$res_out_type;
  690. }
  691. }
  692. }
  693. else {
  694. $tmp = $zc['mp3_dir'].'/'.$path;
  695. $cache_file = $zc['cache_imgs_dir'].'/'.$type.md5($zc['mp3_dir'].'/'.$path.'/'.$imgsrc).'.'.$res_out_type;
  696. }
  697. if ($zc['cache_imgs'] && $cache_file) {
  698. if (file_exists($cache_file)) {
  699. while(@ob_end_clean());
  700. Header('Content-type: image/'.$zc['res_out_type']);
  701. readfile($cache_file);
  702. exit;
  703. }
  704. }
  705. }
  706. $image_source = $tmp.'/'.$imgsrc;
  707. if (!file_exists($image_source) && !$string) {
  708. $image_source = $zc['theme_path_abs'].'/images/'.ztheme('missing_image',$type);
  709. $text = zt('Error');
  710. $cache_file = $string = false;
  711. }
  712. zina_send_image_resized($image_source, $type, $text, $cache_file, $string);
  713. }
  714. break;
  715. Case 11 : # return img
  716. if ($zc['stream_int'] && preg_match('/\.('.$zc['ext_graphic'].')$/i', $imgsrc)) {
  717. $file = $zc['mp3_dir'].'/'.((!empty($path)) ? $path.'/' : '').$imgsrc;
  718. if (file_exists($file)) {
  719. @ob_end_clean();
  720. readfile($file);
  721. }
  722. }
  723. break;
  724. Case 8 : # RETURN PLAYLISTS
  725. if ($zc['play']) {
  726. if (!isset($m)) $m = isset($_POST['m']) ? $_POST['m'] : null;
  727. $lofi = (isset($_GET['lf']));
  728. $cus = (isset($_GET['c']));
  729. $num = isset($_POST['n']) ? $_POST['n'] : (isset($_GET['n']) ? $_GET['n'] : null);
  730. if (!in_array($num, $zc['ran_opts'])) $num = $zc['ran_opts_def'];
  731. if ($playlist == null && isset($_GET['playlist'])) $playlist = $_GET['playlist'];
  732. $random = (isset($_GET['rand']));
  733. $store = (isset($_GET['store']));
  734. switch($m) {
  735. Case 0 :
  736. zina_send_playlist_title($path, $cus, $lofi);
  737. break;
  738. Case 1 :
  739. zina_send_playlist_song($path, $lofi);
  740. break;
  741. Case 3 :
  742. zina_send_playlist_custom($playlist, $lofi, $random);
  743. break;
  744. Case 4 : # Random Albums
  745. zina_send_playlist_random($num,'t',$lofi, true, null, $playlist);
  746. break;
  747. Case 5 : # Random Songs
  748. zina_send_playlist_random($num,'s',$lofi, true, null, $playlist);
  749. break;
  750. Case 6 : # Random Songs By Year
  751. zina_send_playlist_random($num,'s',$lofi, true, null, null, $playlist);
  752. break;
  753. Case 7 :
  754. zina_send_playlist_selected($songs, $lofi, $store);
  755. break;
  756. Case 8 :
  757. zina_send_playlist_selected_random($songs, $lofi, $store);
  758. break;
  759. Case 10 : # Play Recursively & Recursively Random ($cus = random)
  760. zina_send_playlist_random(0,'s',$lofi,$cus,$path);
  761. break;
  762. Case 11 : # Random Songs via Rated Songs
  763. zina_send_playlist_random($num,'tt',$lofi, true, null, $playlist);
  764. break;
  765. Case 12 : # Random Songs via Rated Artists
  766. zina_send_playlist_random($num,'artist',$lofi, true, null, $playlist);
  767. break;
  768. }
  769. }
  770. break;
  771. Case 10 : # internal streaming
  772. if ($zc['play']) {
  773. if ($zc['remote'] && preg_match('/\.('.$zc['remote_ext'].')$/i', $path)) {
  774. $rem = new remoteFile($zc['mp3_dir'].'/'.$path, false, true);
  775. if (isset($rem->url)) {
  776. if ($zc['database'] && $zc['stats']) zdb_log_stat('play', dirname($path), basename($path));
  777. while(@ob_end_clean());
  778. header('Location: '.$rem->url);
  779. exit;
  780. }
  781. }
  782. elseif ($zc['play'] && $zc['stream_int']) {
  783. if ($zc['database'] && $zc['stats']) zdb_log_stat('play', dirname($path), basename($path));
  784. zina_send_file_music($path);
  785. }
  786. }
  787. break;
  788. Case 12 : # download mp3
  789. if ($zc['download'] && preg_match('/\.('.$zc['ext_mus'].')$/i', $path, $exts)) {
  790. $file = $zc['mp3_dir'].'/'.$path;
  791. if (file_exists($file)) {
  792. if ($zc['database'] && $zc['stats']) zdb_log_stat('down', dirname($path), basename($path));
  793. if ($zc['stream_int']) {
  794. $filename = html_entity_decode(zina_get_file_artist_title($file, $zc['mp3_id3'])).'.'.$exts[1];
  795. zina_set_header('Content-Type: application/force-download');
  796. zina_set_header('Content-Disposition: inline; filename="'.$filename.'"');
  797. zina_set_header('Content-Length: '.filesize($file));
  798. zina_set_header('Cache-control: private'); #IE seems to need this.
  799. zina_send_file($file);
  800. }
  801. else {
  802. zina_goto($path,NULL,NULL,TRUE,TRUE);
  803. }
  804. }
  805. }
  806. break;
  807. Case 16 : # VOTE
  808. if ($zc['database']) {
  809. $num = isset($_POST['n']) ? $_POST['n'] : (isset($_GET['n']) ? $_GET['n'] : null);
  810. if (zina_validate('int',$num) && $num <= 5 && ($num >= 1 || ($zc['user_id'] > 0 && $num == 0))) {
  811. if (preg_match('/\.('.$zc['ext_mus'].')$/i', $path) || ($zc['remote'] && preg_match('/\.('.$zc['remote_ext'].')$/i', $path))) {
  812. if ($zc['rating_files']) zdb_log_stat('vote',dirname($path), basename($path), $num);
  813. $path = dirname($path);
  814. }
  815. else {
  816. if ($zc['rating_dirs']) zdb_log_stat('vote',$path, null, $num);
  817. }
  818. if ($zc['cache_tmpl']) {
  819. if (!zina_delete_tmpl_file(zina_get_tmpl_cache_file($path))) zina_debug(zt('Cannot delete cache file'));
  820. }
  821. #todo: return 'error' on bad result
  822. echo ($num == 0) ? zt('Deleted') : zt('Thank you');
  823. }
  824. }
  825. break;
  826. Case 68 : # Vote Playlists
  827. if ($zc['database'] && $zc['pls_ratings']) {
  828. $num = isset($_POST['n']) ? $_POST['n'] : (isset($_GET['n']) ? $_GET['n'] : null);
  829. if (zina_validate('int',$num) && $num <= 5 && ($num >= 1 || ($zc['user_id'] > 0 && $num == 0))) {
  830. zdb_log_stat_playlist((int)$playlist, 'votes', $num);
  831. #todo: return 'error' on bad result
  832. echo ($num == 0) ? zt('Deleted') : zt('Thank you');
  833. }
  834. }
  835. break;
  836. Case 25 : # download MM
  837. if ($zc['mm'] && $zc['mm_down'] && preg_match('/\.('.$zc['mm_ext'].')$/i', $path, $exts)) {
  838. $file = $zc['mp3_dir'].'/'.$path;
  839. if (file_exists($file)) {
  840. if ($zc['stream_int']) {
  841. $ext = strtolower($exts[1]);
  842. zina_set_header('Content-Type: '.$zc['mm_types'][$ext]['mime']);
  843. $disposition = (isset($zc['mm_types'][$ext]['disposition'])) ? $zc['mm_types'][$ext]['disposition'] : 'attachment';
  844. zina_set_header('Content-Disposition: '.$disposition.'; filename="'.basename($path).'"');
  845. zina_set_header('Content-Length: '.filesize($file));
  846. zina_set_header('Cache-control: private'); #IE seems to need this.
  847. zina_send_file($file);
  848. }
  849. else {
  850. zina_goto($path,NULL,NULL,TRUE,TRUE);
  851. }
  852. }
  853. }
  854. break;
  855. Case 53 : # LIVE SEARCH RETURN
  856. $search_term = (isset($_GET['zinaq'])) ? $_GET['zinaq'] : '';
  857. if (strlen($search_term) >= $zc['search_min_chars']) {
  858. $num = isset($_GET['limit']) ? $_GET['limit'] : $zc['search_live_limit'];
  859. $num = (zina_validate('int', $num) && $num > 0 && $num < $zc['search_live_limit']) ? $num : $zc['search_live_limit'];
  860. if ($zc['db_search']) {
  861. $results = zdbq_array("SELECT i.title, i.type, i.context, i.id, i.path, i.genre ".
  862. ",if(i.type='playlist', p.image_type, FALSE) as image_type ".
  863. ",if(i.type='playlist', pd.path, FALSE) as image_path ".
  864. "FROM {search_index} AS i ".
  865. "LEFT OUTER JOIN {playlists} AS p ON (i.type = 'playlist' AND i.type_id = p.id) ".
  866. "LEFT OUTER JOIN {dirs} AS pd ON (i.type = 'playlist' AND i.type_id = p.id AND p.dir_id = pd.id) ".
  867. "WHERE i.title LIKE '%%%s%%' ".
  868. "ORDER BY i.title LIMIT %d",
  869. array($search_term, $num));
  870. }
  871. else {
  872. $results = zina_search_cache($search_term, $num);
  873. }
  874. if (!empty($results)) {
  875. if ($zc['search_images']) {
  876. foreach ($results as $key => $item) {
  877. $results[$key]['image'] = zina_content_search_image($item, 'search');
  878. }
  879. }
  880. foreach ($results as $item) {
  881. unset($item['image_type']);
  882. unset($item['image_path']);
  883. $item['type'] = zt(ucfirst($item['type']));
  884. echo implode('|', $item)."\n";
  885. }
  886. }
  887. }
  888. exit;
  889. break;
  890. Case 54 : # XML file info for flash app
  891. if ($zc['zinamp']) {
  892. $output = zina_get_file_xml($path);
  893. while(@ob_end_clean());
  894. header('Content-type: application/xml');
  895. echo $output;
  896. }
  897. break;
  898. Case 56 :
  899. if ($zc['zinamp'] && $zc['lastfm'] && isset($_GET['n'])) {
  900. zina_play_complete($path, intval($_GET['n']));
  901. }
  902. break;
  903. Case 57 : # 3rd party lyrics
  904. if ($zc['song_extras'] && in_array($m, $zc['song_es_exts'])) {
  905. @session_write_close();
  906. if ($zc['zinamp'] && $playlist == 'zinamp') {
  907. $content = zina_content_blurb($zina, $path, array('type'=>$m, 'return'=>true));
  908. if (isset($content['output']) && !empty($content['output'])) {
  909. if (!$zc['debug']) @ob_end_clean();
  910. echo nl2br($content['output']);
  911. exit;
  912. }
  913. }
  914. if (isset($zc['third_'.$m]) && $zc['third_'.$m]) {
  915. $info = array();
  916. zina_get_file_artist_title($zc['mp3_dir'].'/'.$path, true, $info);
  917. $lyr_opts = zina_get_extras_opts($m);
  918. $opts = explode(',', $zc['third_lyr_order']);
  919. $output = '';
  920. if (!empty($info['artist']) && !empty($info['title'])) {
  921. foreach($opts as $source) {
  922. if (!in_array($source, $lyr_opts)) continue;
  923. require_once($zc['zina_dir_abs'].'/extras/extras_'.$m.'_'.$source.'.php');
  924. $result = array();
  925. if (($result = call_user_func('zina_extras_'.$m.'_'.$source, $info['artist'], $info['title'])) !== false) {
  926. $output .= $result['output'];
  927. if ($zc['third_'.$m.'_save']) {
  928. zina_save_blurb($path, $m, $output, null, false);
  929. }
  930. $output = nl2br($output);
  931. if (isset($result['source'])) {
  932. $output .= ztheme('extras_source', $result['source']);
  933. }
  934. break;
  935. }
  936. }
  937. }
  938. if (empty($output)) {
  939. $output .= zt('No @type found.', array('@type'=>$zc['song_es'][$m]['name']));
  940. }
  941. if (!$zc['debug']) {
  942. while(@ob_end_clean());
  943. }
  944. echo $output;
  945. }
  946. }
  947. break;
  948. Case 66 :
  949. if ($zc['zinamp'] && $zc['lastfm']) {
  950. zina_zinamp_start($path);
  951. }
  952. break;
  953. Case 70 :
  954. if ($zc['playlists'] && $zc['database'] && zina_validate('int',$playlist)) {
  955. zina_playlist_feed($playlist);
  956. }
  957. break;
  958. Case 74:
  959. if (isset($_SESSION['zina_store'])) {
  960. $store = $_SESSION['zina_store'];
  961. unset($_SESSION['zina_store']);
  962. if (!empty($store)) {
  963. zina_send_playlist_content($store['type'], $store['content']);
  964. }
  965. }
  966. break;
  967. }
  968. exit;
  969. }
  970. else {
  971. # PAGE DISPLAYS (2,4,9,13,14,15,22,23,24,29,40,41,43,44,50,51,55,69,77,99,100,101,102)
  972. switch ($level) {
  973. Case 2 :
  974. if ($zc['playlists']) {
  975. return zina_page_main($path, 'playlists', array('pl'=>$playlist, 'id'=>$m));
  976. }
  977. break;
  978. Case 4 : # SEARCH
  979. if ($zc['search']) {
  980. return zina_page_main($path, 'search', array('m'=>$m));
  981. }
  982. break;
  983. Case 9 : # LOGIN
  984. if ($zc['login']) {
  985. if (isset($_POST['un']) && isset($_POST['up'])) {
  986. if (zina_check_password($_POST['un'], $_POST['up'])) {
  987. $_SESSION['za-'.ZINA_VERSION] = true;
  988. if ($zc['session']) { // standalone only
  989. $sess_id = zina_token_sess('1');
  990. setcookie('ZINA_SESSION', $sess_id, time() + (60*60*$zc['session_lifetime']), '/');
  991. $sess_file = $zc['cache_dir_private_abs'].'/sess_'.$sess_id;
  992. @touch($sess_file);
  993. }
  994. zina_goto($path);
  995. }
  996. else {
  997. sleep(3);
  998. $_SESSION['za-'.ZINA_VERSION] = false;
  999. zina_set_message(zt('Username and/or password are incorrect.'),'warn');
  1000. }
  1001. }
  1002. return zina_page_main($path, 'login');
  1003. }
  1004. break;
  1005. Case 13 : # Genre Listing
  1006. if ($zc['genres']) {
  1007. return zina_page_main($path, 'searchgenre');
  1008. }
  1009. break;
  1010. Case 14 : # Genres
  1011. if ($zc['genres']) {
  1012. return zina_page_main($path, 'genres');
  1013. }
  1014. break;
  1015. Case 15 : # STATS
  1016. if ($zc['database'] && $zc['stats'] && ($zc['stats_public'] || $zc['is_admin'])) {
  1017. $period = isset($_POST['period']) ? $_POST['period'] : null;
  1018. $type = isset($_POST['type']) ? $_POST['type'] : null;
  1019. return zina_page_main($path, 'stats', array('stat'=>$playlist, 'period'=>$period, 'type'=>$type));
  1020. }
  1021. break;
  1022. Case 22 : # VARIOUS EDIT WINDOWS
  1023. if ($zc['is_admin'] || (zina_cms_access('editor') && (in_array($m, array(1,2,3,4,6)) || in_array($m, $zc['song_es_exts'])))) {
  1024. return zina_page_main($path, 'blurb', array('type'=>$m, 'item'=>$playlist));
  1025. }
  1026. else {
  1027. return zina_access_denied();
  1028. }
  1029. break;
  1030. Case 23 : # VARIOUS EDIT WINDOWS SAVE
  1031. if (!zina_token_sess_check()) {
  1032. return zina_page_main($path);
  1033. }
  1034. if ($zc['is_admin'] || (zina_cms_access('editor') && (in_array($m, array(1,2,3,4,6)) || in_array($m, $zc['song_es_exts'])))) {
  1035. zina_save_blurb($path, $m, $songs, $playlist);
  1036. }
  1037. else {
  1038. return zina_access_denied();
  1039. }
  1040. break;
  1041. Case 77 :
  1042. if ($zc['is_admin'] || (zina_cms_access('editor'))) {
  1043. if (isset($_POST) && !empty($_POST) && !zina_token_sess_check()) {
  1044. return zina_access_denied();
  1045. }
  1046. return zina_page_main($path, 'dir_opts');
  1047. }
  1048. else {
  1049. return zina_access_denied();
  1050. }
  1051. break;
  1052. Case 24 : # PLAY MM
  1053. if ($zc['mm']) {
  1054. return zina_page_main($path, 'mm');
  1055. }
  1056. break;
  1057. Case 29 :# Song Extras
  1058. if ($zc['song_extras'] && in_array($m, $zc['song_es_exts'])) {
  1059. return zina_page_main($path, 'songextras', array('type'=>$m, 'item'=>null));
  1060. }
  1061. break;
  1062. Case 40 : # Add New Playlist && Add To Playlist
  1063. if (!zina_token_sess_check()) {
  1064. return zina_page_main($path);
  1065. }
  1066. if ($zc['database']) {
  1067. $access = zina_cms_access('edit_playlists', $zc['user_id']);
  1068. if (!($access || ($zc['session_pls'] && $playlist == 'zina_session_playlist'))) {
  1069. zina_set_message(zt('Not authorized'));
  1070. return zina_page_main($path);
  1071. }
  1072. if ($access && $playlist == 'new_zina_list') {
  1073. if (!$zc['is_admin']) {
  1074. $count = zdbq_single("SELECT COUNT(*) FROM {playlists} WHERE user_id = %d", array($zc['user_id']));
  1075. if ($count > $zc['pls_limit']) {
  1076. zina_set_message(zt('Cannot create playlist.').' '.zt('Maximum number of playlists reached.'));
  1077. return zina_page_main($path);
  1078. }
  1079. }
  1080. return zina_page_main($path, 'newplaylist',array('songs'=>$songs));
  1081. }
  1082. else {
  1083. if (isset($_POST['fromnew'])) {
  1084. if (($pls_id = zina_playlist_form_submit('insert')) !== false) {
  1085. $playlist = $pls_id;
  1086. $start = 1;
  1087. }
  1088. else {
  1089. $start = false;
  1090. }
  1091. }
  1092. else {
  1093. if ($playlist == 'zina_session_playlist') {
  1094. $existing = (isset($_SESSION['z_sp'])) ? unserialize_utf8($_SESSION['z_sp']) : array();
  1095. $start = count($existing);
  1096. }
  1097. else {
  1098. $start = zdbq_single("SELECT MAX(weight) FROM {playlists_map} WHERE playlist_id = %d", array($playlist, $zc['user_id']));
  1099. }
  1100. }
  1101. if ($start !== false) {
  1102. if (zina_playlist_insert($playlist, $songs, $start+1)) {
  1103. zina_set_message(zt('Added to playlist'));
  1104. }
  1105. else {
  1106. zina_set_message(zt('Could not add to playlist'), 'warn');
  1107. }
  1108. }
  1109. if (isset($_POST['fromnew'])) {
  1110. if (empty($path)) {
  1111. zina_goto('','l=2&pl='.rawurlencode($playlist));
  1112. }
  1113. else {
  1114. return zina_page_main($path);
  1115. }
  1116. }
  1117. else {
  1118. echo ztheme('messages');
  1119. exit;
  1120. }
  1121. }
  1122. }
  1123. elseif ($zc['is_admin'] || $zc['session_pls']) {
  1124. if (!$zc['is_admin']) {
  1125. $playlist = 'zina_session_playlist';
  1126. }
  1127. if ($playlist == 'new_zina_list') {
  1128. return zina_page_main($path, 'newplaylist',array('songs'=>$songs));
  1129. }
  1130. else {
  1131. zina_write_playlist($songs, '_zina_'.$playlist.'.m3u', 'a');
  1132. zina_set_message(zt('Added to playlist'));
  1133. if (isset($_POST['fromnew'])) {
  1134. if (empty($path)) {
  1135. zina_goto('','l=2&pl='.rawurlencode($playlist));
  1136. }
  1137. else {
  1138. return zina_page_main($path);
  1139. }
  1140. }
  1141. else {
  1142. echo ztheme('messages');
  1143. exit;
  1144. }
  1145. }
  1146. }
  1147. break;
  1148. Case 41 : # Update Playlist
  1149. if (!zina_token_sess_check()) {
  1150. return zina_page_main($path);
  1151. }
  1152. $order = isset($_POST['order']) ? $_POST['order'] : null;
  1153. if ($zc['database']) {
  1154. $pls_user_id = zdbq_single("SELECT user_id FROM {playlists} WHERE id = %d", array($playlist));
  1155. $access = zina_cms_access('edit_playlists', $pls_user_id);
  1156. if (!($access || ($zc['session_pls'] && $playlist == 'zina_session_playlist'))) {
  1157. zina_set_message(zt('Not authorized'));
  1158. return zina_page_main($path);
  1159. }
  1160. $songs = zina_reorder_playlist($songs, $order);
  1161. if ($playlist == 'zina_session_playlist') {
  1162. $_SESSION['z_sp'] = utf8_encode(serialize($songs));
  1163. }
  1164. else {
  1165. zdbq("DELETE FROM {playlists_map} WHERE playlist_id = %d", array($playlist));
  1166. foreach($songs as $weight => $type_id) {
  1167. if (preg_match('/\.lp$/i', $type_id)) {
  1168. $type = 'album';
  1169. $type_id = preg_replace('/\/\.lp$/i','',$type_id);
  1170. }
  1171. elseif (preg_match('/\.pls$/i', $type_id)) {
  1172. $type = 'playlist';
  1173. $type_id = preg_replace('/\.pls/i','',$type_id);
  1174. }
  1175. else {
  1176. $type = 'song';
  1177. }
  1178. if (!zdbq("INSERT {playlists_map} (playlist_id, type, type_id, weight) VALUES (%d, '%s', %d, %d)",
  1179. array($playlist, $type, $type_id, $weight+1))) {
  1180. zina_set_message(zt('Could not insert into playlist: @file', array('@file'=>$type_id)));
  1181. }
  1182. }
  1183. if (($sum_items = zdbq_single("SELECT COUNT(*) FROM {playlists_map} WHERE playlist_id = %d", array($playlist))) !== false) {
  1184. zdbq("UPDATE {playlists} SET sum_items = %d WHERE id = $playlist", array($sum_items, $playlist));
  1185. }
  1186. }
  1187. return zina_page_main($path, 'playlists',array('pl'=>$playlist));
  1188. }
  1189. elseif ($zc['is_admin'] || $zc['session_pls']) {
  1190. if (!$zc['is_admin']) {
  1191. $playlist = 'zina_session_playlist';
  1192. }
  1193. zina_write_playlist(zina_reorder_playlist($songs, $order), '_zina_'.$playlist.'.m3u');
  1194. return zina_page_main($path, 'playlists',array('pl'=>$playlist));
  1195. }
  1196. break;
  1197. Case 43 : # DELETE CUSTOM PLAYLIST
  1198. if ($zc['database'] && $playlist != 'zina_session_playlist') {
  1199. if ($zc['is_admin'] || $zc['pls_user']) {
  1200. if ($zc['is_admin']) {
  1201. $access = true;
  1202. }
  1203. else {
  1204. $access = zdbq_single("SELECT 1 FROM {playlists} WHERE id = %d AND user_id = %d", array($playlist, $zc['user_id']));
  1205. }
  1206. if ($access) {
  1207. zdbq("DELETE FROM {playlists_map} WHERE playlist_id = %d", array($playlist));
  1208. zdbq("DELETE FROM {playlists} WHERE id = %d", array($playlist));
  1209. zina_set_message(zt('Playlist deleted'));
  1210. zina_goto('','l=2');
  1211. }
  1212. }
  1213. }
  1214. else {
  1215. if ($zc['is_admin'] || $zc['session_pls']) {
  1216. if (!$zc['is_admin']) $playlist = 'zina_session_playlist';
  1217. zina_delete_playlist_custom($playlist);
  1218. zina_goto('','l=2');
  1219. }
  1220. }
  1221. break;
  1222. Case 44 : # EDIT PLAYLIST
  1223. if ($_POST && !zina_token_sess_check()) {
  1224. return zina_page_main($path);
  1225. }
  1226. if (!($zc['playlists'] && ($zc['is_admin'] || ($zc['pls_user'] && $zc['user_id'] > 0)))) {
  1227. return zina_access_denied();
  1228. }
  1229. $playlist_new = isset($_POST['playlist_new']) ? $_POST['playlist_new'] : '';
  1230. return zina_page_main($path, 'renameplaylist', array('playlist'=>$playlist, 'new'=>$playlist_new));
  1231. break;
  1232. case 46 :
  1233. if ($zc['res_full_img'] && preg_match('/\.('.$zc['ext_graphic'].')$/i', $path)) {
  1234. return zina_page_main($path, 'image');
  1235. }
  1236. break;
  1237. Case 50 : #podcast
  1238. if ($zc['rss']) {
  1239. #TODO: make common output function...
  1240. while(@ob_end_clean());
  1241. header('Content-type: application/xml');
  1242. echo zina_content_rss($path);
  1243. exit;
  1244. }
  1245. break;
  1246. Case 51 : # SITEMAP
  1247. if ($zc['sitemap']) {
  1248. $output = zina_cache('sitemap', 'zina_content_sitemap', null, ($zc['sitemap'] == 2));
  1249. while(@ob_end_clean());
  1250. header('Content-type: text/xml');
  1251. echo $output;
  1252. exit;
  1253. }
  1254. break;
  1255. Case 99 : # logout
  1256. session_unregister('za-'.ZINA_VERSION);
  1257. if ($zc['session']) {
  1258. if (isset($_COOKIE['ZINA_SESSION'])) {
  1259. $sess_file = $zc['cache_dir_private_abs'].'/sess_'.zcheck_plain($_COOKIE['ZINA_SESSION']);
  1260. setcookie('ZINA_SESSION', $_COOKIE['ZINA_SESSION'], time() - 42000, '/');
  1261. if (file_exists($sess_file)) {
  1262. @unlink($sess_file);
  1263. }
  1264. }
  1265. # remove expired sessions
  1266. $old_sessions = glob($zc['cache_dir_private_abs']."/sess_*");
  1267. if (is_array($old_sessions)) {
  1268. foreach ($old_sessions as $filename) {
  1269. if (filemtime($filename) + (60*60*$zc['session_lifetime']) < time()) {
  1270. @unlink($filename);
  1271. }
  1272. }
  1273. }
  1274. }
  1275. zina_set_message(zt('Logged out succesfully.'));
  1276. zina_goto($path);
  1277. break;
  1278. case 55 :
  1279. #todo: move to stream?
  1280. if ($zc['zinamp'] == 2) {
  1281. $content = ztheme('zinamp');
  1282. zina_set_js('inline',
  1283. 'window.onunload = function() {'.
  1284. 'zina_cookie("zinamp_window", "screenX="+window.screenX+",screenY="+window.screenY, {expires:7});'.
  1285. '};');
  1286. $zina = zina_page_simple('zinamp', $content);
  1287. echo ztheme('page_zinamp', $zina);
  1288. exit;
  1289. }
  1290. break;
  1291. case 100 :
  1292. if ($zc['zinamp']==3) {
  1293. $content = ztheme('jplayer');
  1294. zina_set_js('inline',
  1295. 'window.onunload = function() {'.
  1296. 'zina_cookie("jplayer_window", "screenX="+window.screenX+",screenY="+window.screenY, {expires:7});'.
  1297. '};');
  1298. $zina = zina_page_simple('jplayer', $content);
  1299. echo ztheme('page_jplayer', $zina);
  1300. exit;
  1301. }
  1302. break;
  1303. case 101 : # Start Scrobble
  1304. if ($zc['zinamp']==3) {
  1305. zina_add_now_playing($path);
  1306. }
  1307. break;
  1308. case 102 : # Complete Scrobble
  1309. if ($zc['zinamp']==3) {
  1310. zina_complete_scrobble($path);
  1311. }
  1312. break;
  1313. Case 65 :
  1314. require_once($zc['zina_dir_abs'].'/batch.php');
  1315. $output = _zbatch_page();
  1316. if ($output === FALSE) {
  1317. return zina_access_denied();
  1318. }
  1319. elseif (isset($output)) {
  1320. zina_set_css('file', 'extras/progress.css');
  1321. return zina_page_simple(zbatch_set_title(), $output);
  1322. }
  1323. return;
  1324. Case 69 : # Year Listing
  1325. if ($zc['db_search']) {
  1326. return zina_page_main($path, 'searchyear');
  1327. }
  1328. break;
  1329. default : # MAIN PAGE
  1330. # Allows files to stream without l=8 (for RSS and prettiness)
  1331. if (is_file($zc['cur_dir']) && $zc['play'] && (($zc['stream_int'] && preg_match('/\.('.$zc['ext_mus'].')$/i', $path)) ||
  1332. ($zc['remote'] && preg_match('/\.('.$zc['remote_ext'].')$/i', $path, $matches)))) {
  1333. if ($zc['database'] && $zc['stats']) zdb_log_stat('play', dirname($path), basename($path));
  1334. zina_send_file_music($path);
  1335. }
  1336. if (is_file($zc['cur_dir']) && $zc['rss'] && basename($path) == $zc['rss_file']) {
  1337. $output = file_get_contents($zc['cur_dir']);
  1338. $output = utf8_decode($output);
  1339. header('Content-type: application/xml');
  1340. echo $output;
  1341. exit;
  1342. }
  1343. if (!is_dir($zc['cur_dir'])) {
  1344. return zina_not_found();
  1345. }
  1346. if ($zc['database']) {
  1347. zdb_log_stat('view', $path);
  1348. }
  1349. return zina_page_main($path);
  1350. }
  1351. return zina_not_found();
  1352. }
  1353. } #END MAIN
  1354. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  1355. * PAGES
  1356. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  1357. function zina_page_main($path, $type='main', $opts=null) {
  1358. global $zc;
  1359. $page = zina_get_page_opt($path);
  1360. $cat_sort = zina_get_catsort_opt($path);
  1361. if ($zc['cache_tmpl']) {
  1362. $cache_file = $zc['cache_tmpl_dir'].'/'.zina_get_tmpl_cache_file($path);
  1363. if (!$zc['is_admin'] && $_SERVER['REQUEST_METHOD'] == 'GET' && file_exists($cache_file)) {
  1364. $mtime = filemtime($cache_file);
  1365. if ($mtime > filemtime($zc['cur_dir'].'/.') && $mtime + ($zc['cache_tmpl_expire'] * 86400) > time()) {
  1366. $zina = unserialize(implode('', gzfile($cache_file)));
  1367. $zina['cached'] = true;
  1368. return $zina;
  1369. }
  1370. }
  1371. }
  1372. $zina = array();
  1373. $zina['lang']['main_dir_title'] = zt($zc['main_dir_title']);
  1374. $zina['embed'] = $zc['embed'];
  1375. $zina['site_name'] = isset($zc['conf']['site_name']) ? $zc['conf']['site_name'] : '';
  1376. $zina['amg'] = $zc['amg'];
  1377. $zina['theme_path'] = zpath_to_theme();
  1378. $zina['searchform'] = $zina['stats'] = $zina['genres'] = $random = '';
  1379. $zina['charset'] = $zc['charset'];
  1380. $zina['addthis'] = $zc['third_addthis'];
  1381. $zina['addthis_id'] = $zc['third_addthis_id'];
  1382. $zina['addthis_options'] = $zc['third_addthis_options'];
  1383. $zina['addthis_path'] = $path;
  1384. $zina['addthis_query'] = null;
  1385. if ($zc['search']) {
  1386. $search_term = isset($_POST['searchterm']) ? $_POST['searchterm'] : (isset($_GET['pl']) ? $_GET['pl'] : (isset($_GET['searchterm']) ? $_GET['searchterm'] : ''));
  1387. $zina['searchform'] = ztheme('searchform', array(
  1388. 'action' => zurl('','l=4'),
  1389. 'search_min_chars' => $zc['search_min_chars'],
  1390. 'search_live_limit' => $zc['search_live_limit'],
  1391. 'live_url' => zurl('', 'l=53'),
  1392. 'images' => $zc['search_images'],
  1393. ),
  1394. (($type == 'search') ? htmlentities($search_term) : '')
  1395. );
  1396. }
  1397. if ($zc['genres']) {
  1398. if ($type == 'genres' && $path = 'genre') {
  1399. $path = '';
  1400. }
  1401. # not used
  1402. $zina['genres'] = array('path'=>null, 'query'=>'l=14');
  1403. }
  1404. if ($zc['is_admin'] && $type != 'config') {
  1405. $zina['admin_config'] = array('path'=>$path, 'query'=>'l=20');
  1406. }
  1407. if ($zc['login']) {
  1408. if ($zc['is_admin']) {
  1409. $zina['login'] = array('type'=>'logout', 'path'=>$path,'query'=>'l=99');
  1410. }
  1411. else {
  1412. $zina['login'] = array('type'=>'login', 'path'=>$path,'query'=>'l=9');
  1413. }
  1414. }
  1415. # not used
  1416. if ($zc['database'] && ($zc['is_admin'] || ($zc['stats'] && $zc['stats_public']))) {
  1417. $zina['stats'] = array('path'=>$path, 'query'=>'l=15');
  1418. }
  1419. $zina['zinamp'] = ($zc['zinamp']==1 || $zc['zinamp']==2) ? ztheme('zinamp_embed') : '';
  1420. $zina['jplayer'] = ($zc['zinamp']==3) ? ztheme('jplayer_embed') : '';
  1421. switch($type) {
  1422. case 'main':
  1423. default:
  1424. $zina['page_type'] = 'main';
  1425. //zina_content_breadcrumb($zina, $path, $zc['main_dir_title']);
  1426. zina_content_main($zina, $path, $page, $cat_sort);
  1427. break;
  1428. case 'playlists';
  1429. zina_content_breadcrumb($zina, $path);
  1430. if ($zc['database']) {
  1431. $id = (isset($opts['id'])) ? $opts['id'] : null;
  1432. zina_content_playlist_db($zina, $path, $opts['pl'], $id);
  1433. }
  1434. else {
  1435. zina_content_playlists($zina, $path, $opts['pl']);
  1436. }
  1437. break;
  1438. case 'genres':
  1439. zina_content_breadcrumb($zina, '', zt('Genres'));
  1440. $genres = zina_get_genres_list();
  1441. $genre_num = sizeof($genres);
  1442. $full_page_split = $genres_navigation = false;
  1443. $page = isset($_GET['page']) ? $_GET['page'] : 1;
  1444. #todo: combine with cat_split
  1445. if ($zc['genres_split'] == 2 || $zc['genres_split'] == 3) {
  1446. $splits = ztheme('category_alphabet_split', $genres, $zc['dir_si_str']);
  1447. $splits_sum = array_keys($splits);
  1448. if ($zc['genres_split'] == 2) {
  1449. if (!in_array($page, $splits_sum)) {
  1450. $page = $splits_sum[0];
  1451. }
  1452. $genres_navigation = ztheme('category_alphabet',null, $page, $splits_sum, 'l=14&amp;');
  1453. $genres = $splits[$page];
  1454. }
  1455. else { # $genres_split == 3
  1456. $full_page_split = 0;
  1457. foreach ($splits as $i) {
  1458. foreach($i as $item) {
  1459. $full_page_split++;
  1460. }
  1461. }
  1462. $genres_navigation = ztheme('category_alphabet',null, $page, $splits_sum, 'l=14&amp;', true);
  1463. $genres = &$splits;
  1464. }
  1465. }
  1466. elseif ($zc['genres_split'] && $genre_num > $zc['genres_pp']) {
  1467. $pages_total = ceil($genre_num/$zc['genres_pp']);
  1468. if (!zina_validate('int', $page) || $page < 1 || $page > $pages_total) {
  1469. $page = 1;
  1470. }
  1471. $genres_navigation = ztheme('category_pages',null, $page, $pages_total,'l=14&amp;');
  1472. $cstart = ($page - 1) * $zc['genres_pp'];
  1473. if ($cstart > $genre_num) {
  1474. $cstart = 0;
  1475. }
  1476. $genres = array_slice($genres, $cstart, $zc['genres_pp']);
  1477. }
  1478. $zina['messages'] = ztheme('messages');
  1479. $zina['content'] = ztheme('genres', $genres, $zc['genres_cols'], $zc['genres_images'], $zc['genres_truncate'], $zina, $genres_navigation, $full_page_split);
  1480. break;
  1481. case 'search':
  1482. #todo: move this whole thing somewhere...
  1483. zina_content_breadcrumb($zina, '', zt('Search Results'));
  1484. $mode_opts = array_keys(zina_get_opt_search());
  1485. $mode = (in_array($opts['m'], $mode_opts)) ? $opts['m'] : $zc['search_default'];
  1486. if ($mode == 'play' && !$zc['play']) {
  1487. $mode = 'browse';
  1488. }
  1489. $result = array();
  1490. $search_id = (isset($_POST['searchid'])) ? $_POST['searchid'] : (isset($_GET['searchid']) ? $_GET['searchid'] : false);
  1491. if ($zc['db_search']) {
  1492. if ($search_id && zina_validate('int', $search_id)) {
  1493. $result = zdbq_array_single("SELECT path, type FROM {search_index} WHERE id = %d && title = '%s'", array($search_id, $search_term));
  1494. }
  1495. }
  1496. else {
  1497. if ($search_id) {
  1498. if ((!strstr($search_id,'..') || zfile_check_location($zc['mp3_dir'].'/'.$search_id, $zc['mp3_dir'])) && file_exists($zc['mp3_dir'].'/'.$search_id)) {
  1499. $result['path'] = $search_id;
  1500. if (preg_match('/\.('.$zc['ext_mus'].')$/i', $search_id)) {
  1501. $result['type'] = 'song';
  1502. }
  1503. else {
  1504. $result['type'] = 'directory';
  1505. if ($zc['search_structure']) {
  1506. $count = substr_count($path, '/');
  1507. if ($count == 0) {
  1508. $result['type'] = 'artist';
  1509. }
  1510. elseif ($count == 1) {
  1511. $result['type'] = 'album';
  1512. }
  1513. }
  1514. }
  1515. }
  1516. }
  1517. }
  1518. if (!empty($result)) {
  1519. $search_type = $result['type'];
  1520. $search_path = $result['path'];
  1521. if ($search_type == 'song') {
  1522. if ($mode == 'play') {
  1523. if (file_exists($zc['mp3_dir'].'/'.$search_path)) {
  1524. zina_send_playlist_song($search_path);
  1525. }
  1526. }
  1527. else {
  1528. $search_dir = dirname($search_path);
  1529. if (file_exists($zc['mp3_dir'].'/'.$search_dir)) {
  1530. zina_goto($search_dir);
  1531. }
  1532. }
  1533. }
  1534. elseif ($search_type == 'genre') {
  1535. if ($mode == 'play') {
  1536. zina_send_playlist_random($zc['ran_opts_def'], 's', false, true, null, $search_path);
  1537. }
  1538. else {
  1539. zina_goto('', 'l=13&pl='.rawurlencode($search_path));
  1540. }
  1541. }
  1542. elseif (in_array($search_type, array('directory', 'artist', 'album'))) {
  1543. if (is_dir($zc['mp3_dir'].'/'.$search_path)) {
  1544. if ($mode == 'play') {
  1545. if ($search_type == 'album') {
  1546. zina_send_playlist_title($search_path, false, false);
  1547. }
  1548. else {
  1549. zina_send_playlist_random(0,'s',false,true,$search_path);
  1550. }
  1551. }
  1552. else {
  1553. zina_goto($search_path);
  1554. }
  1555. }
  1556. }
  1557. elseif ($search_type == 'playlist') {
  1558. if ($mode == 'play') {
  1559. zina_send_playlist_custom($search_path, false);
  1560. }
  1561. else {
  1562. zina_goto('', 'l=2&pl='.rawurlencode($search_path));
  1563. }
  1564. }
  1565. else {
  1566. zina_debug(zt('Search type not found in index.'));
  1567. }
  1568. }
  1569. $results = array();
  1570. $count = 0;
  1571. $action = $selected = $search_navigation = false;
  1572. if (strlen($search_term) < $zc['search_min_chars']) {
  1573. zina_set_message(zt('Search term must be longer than @num characters',@array('@num'=>$zc['search_min_chars'])),'warn');
  1574. }
  1575. else {
  1576. $page = (isset($_GET['page'])) ? '&amp;page='.$_GET['page'] : '';
  1577. $action = zurl('','l=4'.$page);
  1578. $sql = ($zc['db_search']) ? array('where'=>"i.title LIKE '%%%s%%'") : array();
  1579. $results = zina_search_pager_query($search_term, 'l=4', $count, $search_navigation, $sql, false, $selected);
  1580. }
  1581. $checkbox = (($zc['is_admin'] && $zc['cache']) || $zc['session_pls']);
  1582. zina_content_search_list($results, $checkbox, array('highlight'=>$search_term));
  1583. $list = ztheme('search_list', $results, $zc['search_images']);
  1584. $form_id = 'zinasearchresultsform';
  1585. #todo: why m=1?
  1586. $form_attr = 'id="'.$form_id.'" action="'.zurl('','m=1').'"';
  1587. $list_opts = ($zc['playlists']) ? ztheme('search_list_opts', zina_content_song_list_opts(false, false, $checkbox, $form_id, true), $form_id) : null;
  1588. $zina['content'] = ztheme('search_page', $search_term, $results, $count, $search_navigation, $form_attr, $list, $list_opts, $action, $selected, $zina);
  1589. break;
  1590. case 'searchgenre':
  1591. zina_content_search('genres', $zina);
  1592. break;
  1593. case 'searchyear':
  1594. zina_content_search('year', $zina);
  1595. break;
  1596. case 'blurb':
  1597. zina_content_blurb($zina, $path, $opts);
  1598. break;
  1599. case 'dir_opts':
  1600. zina_content_directory_opts($zina, $path);
  1601. break;
  1602. case 'edittags':
  1603. zina_content_edit_tags($zina, $path, $opts);
  1604. break;
  1605. case 'songextras':
  1606. $opts['return'] = true;
  1607. $content = zina_content_blurb($zina, $path, $opts);
  1608. $ajax_url = false;
  1609. if (empty($content['output']) && isset($zc['third_'.$opts['type']]) && $zc['third_'.$opts['type']]) {
  1610. $ajax_url = zurl($path, 'l=57&m='.$opts['type']);
  1611. zina_set_js('file', 'extras/jquery.js');
  1612. }
  1613. $zina['content'] = ztheme('song_extra', $opts['type'], $content['title'], nl2br($content['output']), $ajax_url);
  1614. break;
  1615. case 'image':
  1616. $img_path = dirname($path);
  1617. $dir = zina_get_directory($img_path);
  1618. zina_content_breadcrumb($zina, $img_path, $dir['title'], true);
  1619. $zina['content'] = ztheme('page_image', $zina, $img_path, $dir['images'], basename($path), $dir['captions']);
  1620. break;
  1621. case 'login':
  1622. zina_content_breadcrumb($zina, '', zt('Login'));
  1623. $rows[] = array('label'=>zt('Username'),'item'=>'<input type="text" name="un"/>');
  1624. $rows[] = array('label'=>zt('Password'),'item'=>'<input type="password" name="up"/>');
  1625. $rows[] = array('label'=>null,'item'=>'<input type="submit" value="'.zt('Login').'"/>');
  1626. $form = array(
  1627. 'title'=>zt('Login'),
  1628. 'attr'=>'action="'.zurl($path, 'l=9').'"',
  1629. 'rows'=>$rows
  1630. );
  1631. $zina['content'] = ztheme('login', $form);
  1632. break;
  1633. case 'newplaylist':
  1634. zina_content_breadcrumb($zina, '', zt('New Playlist'));
  1635. if ($zc['database']) {
  1636. $item = array('title'=>'', 'description'=>'', 'genre_id'=> '', 'dir_id'=>'', 'image_type'=>'', 'visible'=>true);
  1637. $rows = zina_content_playlist_form($item);
  1638. }
  1639. else {
  1640. $rows[] = array('label'=>zt('Playlist Name'),'item'=>'<input name="playlist" type="text" size="25" maxlength="30"/>');
  1641. }
  1642. $rows[] = array('label'=>null,'item'=>'<input type="submit" value="'.zt('Submit').'"/>');
  1643. $hidden = '';
  1644. if (sizeof($opts['songs']) != 0) {
  1645. sort($opts['songs']);
  1646. foreach($opts['songs'] as $song) {
  1647. $hidden .= '<input type="hidden" name="mp3s[]" value="'.$song.'"/>';
  1648. }
  1649. }
  1650. $form = array(
  1651. 'attr' =>'action="'.zurl($path,'l=40').'"',
  1652. 'hidden'=>$hidden.ztheme('form_hidden','fromnew',1),
  1653. 'rows' =>$rows
  1654. );
  1655. $zina['content'] = ztheme('newplaylist',$form);
  1656. break;
  1657. case 'renameplaylist':
  1658. if (!empty($opts['new']) || ($zc['database'] && $_POST)) {
  1659. if ($zc['database']) {
  1660. if (zina_playlist_form_submit('update', $opts['playlist'])) {
  1661. zina_goto('', 'l=2&pl='.$opts['playlist']);
  1662. }
  1663. }
  1664. else {
  1665. if (zina_rename_playlist($opts['playlist'], $opts['new'])) {
  1666. zina_goto('', 'l=2');
  1667. }
  1668. }
  1669. zina_set_message(zt('Cannot edit playlist.'), 'warn');
  1670. }
  1671. if ($zc['database']) {
  1672. $title = zt('Edit Playlist');
  1673. $item = zdbq_array_single("SELECT title, description, dir_id, user_id, genre_id, image_type, visible FROM {playlists} WHERE id = %d", array($opts['playlist']));
  1674. if (empty($item)) {
  1675. zina_set_message(zt('Cannot edit playlist.'), 'warn');
  1676. zina_goto('', 'l=2');
  1677. }
  1678. $rows = zina_content_playlist_form($item);
  1679. }
  1680. else {
  1681. $title = zt('Rename');
  1682. $rows[] = array('label'=>zt('Rename').' "'.htmlentities($opts['playlist']).'" '.zt('Playlist'),
  1683. 'item'=>'<input name="playlist_new" type="text" size="25" maxlength="30" value="'.htmlentities($opts['new']).'"/>');
  1684. }
  1685. zina_content_breadcrumb($zina, '', $title);
  1686. $rows[] = array('label'=>null,'item'=>
  1687. '<input type="submit" value="'.zt('Submit').'"/> '.
  1688. '<input type="button" value="'.zt('Cancel').'" onClick="location.href=\''.zurl('', 'l=2&pl='.$opts['playlist']).'\'"/>'
  1689. );
  1690. $form = array(
  1691. 'attr' => 'action="'.zurl('','l=44').'"',
  1692. 'hidden'=> '<input type="hidden" name="playlist" value="'.htmlentities($opts['playlist']).'"/>',
  1693. 'rows' => $rows
  1694. );
  1695. $zina['content'] = ztheme('renameplaylist',$form);
  1696. break;
  1697. case 'stats':
  1698. zina_content_stats($zina, $opts);
  1699. break;
  1700. case 'config':
  1701. zina_content_breadcrumb($zina, '', zt('Settings'));
  1702. $zina['content'] = zina_content_settings($path);
  1703. break;
  1704. case 'genre_hierarchy':
  1705. zina_content_breadcrumb($zina, '', zt('Genres and Hierarchy'));
  1706. $zina['content'] = zina_content_genre_hierarchy();
  1707. break;
  1708. case 'edit_images':
  1709. $zina['content'] = zina_content_edit_images($zina, $path);
  1710. break;
  1711. case 'rename_directory':
  1712. $dir = zina_get_directory($path, false, array('get_files'=>false));
  1713. if ($dir['dir_write']) {
  1714. if (isset($_POST) && !empty($_POST) && zina_token_sess_check() && !empty($_POST['new_directory'])) {
  1715. $new_dir = $_POST['new_directory'];
  1716. $base = dirname($path);
  1717. $new_path = ($base == '.') ? $new_dir : $base.'/'.$new_dir;
  1718. $new_full = $zc['mp3_dir'].'/'.$new_path;
  1719. if (zfile_check_location($new_full, $zc['mp3_dir']) && $zc['cur_dir'] != $new_full) {
  1720. if (rename($zc['cur_dir'], $new_full)) {
  1721. zina_set_message(zt('Directory renamed'));
  1722. if ($zc['database']) {
  1723. if (isset($dir['id']) && !empty($dir['id'])) {
  1724. $dir_id = $dir['id'];
  1725. }
  1726. else {
  1727. $dir_id = zdbq_single("SELECT id FROM {dirs} WHERE path = '%s'", array($new_path));
  1728. }
  1729. if (!empty($dir_id)) {
  1730. $sql = "SET path = REPLACE(path, '%s', '%s') WHERE path LIKE '%s%%'";
  1731. $vars = array($path, $new_path, $path);
  1732. zdbq("UPDATE {dirs} $sql", $vars);
  1733. zdbq("UPDATE {dirs} SET title = '%s' WHERE id = %d AND title = '%s'", array(basename($new_path), $dir_id, basename($path)));
  1734. zdbq("UPDATE {files} $sql", $vars);
  1735. zdbq("UPDATE {search_index} $sql", $vars);
  1736. zdbq("UPDATE {search_index} SET context = REPLACE(path, '%s', '%s') WHERE context LIKE '%s%%'", $vars);
  1737. zdbq("UPDATE {search_index} SET title = '%s' WHERE type_id = %d AND title = '%s' AND type IN ('artist', 'album', 'directory')", array(basename($new_path), $dir_id, basename($path)));
  1738. $alts = array();
  1739. if (isset($dir['alt_items'])) {
  1740. $alts = $dir['alt_items'];
  1741. }
  1742. else {
  1743. $alt_file = $new_full.'/'.$zc['alt_file'];
  1744. if (file_exists($alt_file)) {
  1745. $alts = zunserialize_alt(file_get_contents($alt_file));
  1746. }
  1747. }
  1748. if (!empty($alts)) {
  1749. foreach($alts as $alt) {
  1750. # backwards compatibility...strip /
  1751. $alt_path = rtrim($alt, '/');
  1752. $others = zdb_get_others($alt_path);
  1753. $items = array();
  1754. if (!empty($others) && isset($others['alt_items'])) {
  1755. $items = $others['alt_items'];
  1756. }
  1757. else {
  1758. $alt_file = $zc['mp3_dir'].(!empty($alt_path) ? '/'.$alt_path : '') . '/'.$zc['alt_file'];
  1759. if (file_exists($alt_file)) {
  1760. $items = zunserialize_alt(file_get_contents($alt_file));
  1761. }
  1762. }
  1763. if (!empty($items)) {
  1764. $change = false;
  1765. foreach($items as $key => $item) {
  1766. $item = rtrim($item, '/');
  1767. if ($item == $path) {
  1768. $items[$key] = $new_path;
  1769. $change = true;
  1770. }
  1771. else {
  1772. $items[$key] = $item;
  1773. }
  1774. }
  1775. if ($change) {
  1776. zdb_update_others(array('alt_items'=>$items), $alt_path);
  1777. }
  1778. }
  1779. }
  1780. }
  1781. zina_set_message(zt('Database updated'));
  1782. }
  1783. else {
  1784. zina_set_message(zt('Database not updated'), 'warn');
  1785. }
  1786. }
  1787. zina_goto($new_path);
  1788. }
  1789. else {
  1790. zina_set_message(zt('Could not rename directory: @old to @new', array('@old'=>$path, '@new'=>$new_path)), 'error');
  1791. }
  1792. }
  1793. else {
  1794. zina_set_message(zt('Cannot rename directory.'), 'error');
  1795. }
  1796. }
  1797. zina_content_breadcrumb($zina, $path, $dir['title'], true);
  1798. $rows[] = array('label'=>zt('New Directory Name'), 'item'=>zina_content_form_helper('new_directory', array('type'=>'textfield', 'def'=>'', 'size'=>30, 'v'=>array('req')), ''));
  1799. $rows[] = array('label'=>0,'item'=>'<input type="Submit" value="'.zt('Submit').'"/>');
  1800. $form = array(
  1801. 'attr'=>'action="'.zurl($path, 'l=78').'"',
  1802. 'rows'=>$rows,
  1803. 'title' => zt('Rename Directory'),
  1804. );
  1805. $zina['content'] = ztheme('form_table', $form);
  1806. }
  1807. else {
  1808. zina_set_message(zt('Cannot rename directory.').' '.zt('Directory is not writeable.'), 'error');
  1809. zina_goto($path);
  1810. }
  1811. break;
  1812. case 'help':
  1813. require_once($zc['zina_dir_abs'].'/extras/help.php');
  1814. zina_content_breadcrumb($zina, '', zt('Help and Support Information'));
  1815. $zina['content'] = zina_content_help();
  1816. break;
  1817. case 'mm':
  1818. zina_content_breadcrumb($zina, $path);
  1819. if (preg_match('/\.('.$zc['mm_ext'].')$/i', $path, $exts)) {
  1820. $ext = strtolower($exts[1]);
  1821. if (isset($zc['mm_types'][$ext]['player'])) {
  1822. $ext = strtolower($exts[1]);
  1823. if (preg_match('#^'.$_SERVER['DOCUMENT_ROOT'].'#i',$zc['mp3_dir'])) {
  1824. $file = zurl($path, null, null, true, true);
  1825. }
  1826. else {
  1827. #todo: doesnt work
  1828. $file = zurl($path, 'l=25', NULL, TRUE);
  1829. }
  1830. $zina['content'] = ztheme('mm', strtolower($zc['mm_types'][$ext]['player']), $file);
  1831. }
  1832. }
  1833. break;
  1834. case 'clean':
  1835. zina_content_breadcrumb($zina, '', zt('Clean up database'));
  1836. #todo: THEME?
  1837. $form_id = 'zinacleanform';
  1838. zina_set_js('inline', 'function selAll(x){for(var i=0;i<document.forms.'.$form_id.'.elements.length;i++){var e=document.forms.'.$form_id.'.elements[i];if(e.type==\'select-one\'){e.selectedIndex=x;}}}');
  1839. $rows[] = array('label'=>zt('All'),'item'=>zl(zt('Remove'),'javascript: void 0;',NULL,NULL,FALSE,' onclick="selAll(0);"').' | '.
  1840. zl(zt('Ignore'),'javascript: void 0;',NULL,NULL,FALSE,' onclick="selAll(1);"') );
  1841. $rows[] = array('label'=>-1,'item'=>'<h3>'.zt('Database entries with missing directories').'</h3>');
  1842. $hidden = zina_content_dbclean_select($rows,'zdirids', zdb_clean_find('dir'));
  1843. $rows[] = array('label'=>-1,'item'=>'<h3>'.zt('Database entries with missing files').'</h3>');
  1844. $hidden .= zina_content_dbclean_select($rows,'zfileids', zdb_clean_find('file'));
  1845. $rows[] = array('label'=>-1,'item'=>'<input type="Submit" value="'.zt('Submit').'"/>');
  1846. $form = array(
  1847. 'attr'=>'action="'.zurl($path, 'l=27').'" id="'.$form_id.'"',
  1848. 'rows'=>$rows,
  1849. 'hidden'=>$hidden,
  1850. );
  1851. $zina['content'] = '<p><strong>'.zt('This feature is experimental. It should not hurt anything, but it might not do everything it is supposed to.').'</strong></p>'.ztheme('clean',$form);
  1852. break;
  1853. }
  1854. if ($zc['play'] && $zc['random']) {
  1855. $genres = ($zc['genres']) ? zina_core_cache('genres') : array();
  1856. $random = ztheme('random', $zc, $zc['database'], $genres, zurl('','l=8'), zurl('','l=8&amp;lf'), zurl('','l=8'));
  1857. }
  1858. $zina['randomplayform'] = $random;
  1859. $zina['time'] = $zc['conf']['time'];
  1860. $zina['messages'] = ztheme('messages');
  1861. $zina['head_js'] = zina_get_js();
  1862. $zina['head_css'] = zina_set_css();
  1863. $zina['head_html'] = zina_get_html_head();
  1864. if ($zc['cache_tmpl'] && !$zc['is_admin'] && empty($zina['messages']) && is_writeable($zc['cache_tmpl_dir'])) {
  1865. $fp = gzopen ($cache_file, 'w1');
  1866. gzwrite($fp,serialize($zina));
  1867. gzclose($fp);
  1868. }
  1869. return $zina;
  1870. }
  1871. function zina_page_simple($title, $content) {
  1872. global $zc;
  1873. $zina['charset'] = $zc['charset'];
  1874. $zina['embed'] = $zc['embed'];
  1875. $zina['theme_path'] = zpath_to_theme();
  1876. $zina['head_js'] = zina_get_js();
  1877. $zina['head_css'] = zina_set_css();
  1878. $zina['head_html'] = zina_get_html_head();
  1879. zina_content_breadcrumb($zina, '', $title);
  1880. $zina['searchform'] = false;
  1881. $zina['randomplayform'] = null;
  1882. $zina['content'] = $content;
  1883. $zina['messages'] = ztheme('messages');
  1884. $zina['time'] = $zc['conf']['time'];
  1885. return $zina;
  1886. }
  1887. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  1888. * CONTENT
  1889. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  1890. function zina_content_main(&$zina, $path, $page, $category_sort) {
  1891. global $zc;
  1892. if ($cat = zina_is_category($zc['cur_dir'])) {
  1893. $category = true;
  1894. }
  1895. else {
  1896. $category = $cat['images'] = false;
  1897. }
  1898. $dir = zina_get_directory($path, $category, array('cat_images'=>$cat['images']));
  1899. if (empty($path) || $path == '.') $dir['title'] = $zina['lang']['main_dir_title'];
  1900. zina_content_breadcrumb($zina, $path, $dir['title']);
  1901. if ($dir['dir_edit']) {
  1902. $zina['dir_edit_opts']['dir_opts'] = array('path'=>$path, 'query'=>'l=77');
  1903. $zina['dir_edit_opts']['dir'] = array('path'=>$path, 'query'=>'l=22&amp;m=1');
  1904. }
  1905. $zina['description'] = (isset($dir['description'])) ? $dir['description'] : false;
  1906. $zina['subdir_num'] = $subdir_num = sizeof($dir['subdirs']);
  1907. $zina['alt_num'] = 0;
  1908. $zina['pls_included'] = false;
  1909. $files_found = (!empty($dir['files']));
  1910. $subdirs = &$dir['subdirs'];
  1911. $dirinfo = &$dir['info'];
  1912. if ($category) {
  1913. if ($subdir_num > 0) {
  1914. $full_page_split = false;
  1915. # 0 = none, 1 = pages, 2 = alphabet, 3 = full_page_split
  1916. if ($cat['split'] == 2 || $cat['split'] == 3) {
  1917. zina_directory_sort($subdirs);
  1918. $sort_ignore_str = ($zc['dir_sort_ignore']) ? $zc['dir_si_str'] : false;
  1919. $splits = ztheme('category_alphabet_split', $subdirs, $sort_ignore_str);
  1920. if ($zc['cat_various_lookahead'] || $cat['split'] == 3) {
  1921. $count = 0;
  1922. foreach ($splits as $subkey => $i) {
  1923. foreach($i as $itemkey => $item) {
  1924. if (isset($item['category']) && !empty($item['category'])) {
  1925. $cat_dir_tags = (isset($item['category']['override']['dir_tags'])) ? $item['category']['override']['dir_tags'] : $zc['dir_tags'];
  1926. $v = zina_get_directory($item['path'], true, array('get_files'=>false, 'dir_tags'=>$cat_dir_tags));
  1927. $letter = ($subkey == 'zzz') ? $item['title']: $item['path'];
  1928. if (!empty($v['subdirs'])) {
  1929. zina_directory_sort($v['subdirs']);
  1930. foreach($v['subdirs'] as $various_subkey => $vdir) {
  1931. $splits[$letter][$various_subkey] = $vdir;
  1932. $count++;
  1933. }
  1934. if ($subkey == 'zzz') unset($splits[$subkey][$itemkey]);
  1935. }
  1936. else {
  1937. $count++;
  1938. }
  1939. }
  1940. else {
  1941. $count++;
  1942. }
  1943. }
  1944. }
  1945. }
  1946. $splits_sum = array_keys($splits);
  1947. if ($cat['split'] == 2) {
  1948. if (!in_array($page, $splits_sum)) $page = $splits_sum[0];
  1949. $zina['category']['navigation'] = ztheme('category_alphabet',$path, $page, $splits_sum);
  1950. $subdirs = $splits[$page];
  1951. }
  1952. else { # $cat['split'] == 3
  1953. $zina['category']['navigation'] = ztheme('category_alphabet',$path, null, $splits_sum, null, true);
  1954. $full_page_split = $count;
  1955. $subdirs = &$splits;
  1956. }
  1957. }
  1958. else {
  1959. #todo: won't always be cat sort? or what if catsort == 0
  1960. if ($cat['sort'] && $subdir_num > 1) {
  1961. if ($category_sort == 'ad') { # alpha desc
  1962. zina_directory_sort($subdirs);
  1963. $subdirs = array_reverse($subdirs, true);
  1964. $cat['alpha'] = array('sort'=>'asc','query'=>'zs=a');
  1965. }
  1966. elseif ($category_sort == 'd') { #date asc
  1967. uasort($subdirs, 'zsort_date');
  1968. $cat['date'] = array('sort'=>'desc','query'=>'zs=dd');
  1969. }
  1970. elseif ($category_sort == 'dd') { #date desc
  1971. uasort($subdirs, 'zsort_date_desc');
  1972. $cat['date'] = array('sort'=>'asc','query'=>'zs=d');
  1973. }
  1974. else { # alpha asc
  1975. $category_sort = 'a';
  1976. zina_directory_sort($subdirs);
  1977. $cat['alpha']=array('sort'=>'desc','query'=>'zs=ad');
  1978. }
  1979. if (!empty($cat['alpha'])) {
  1980. $cat['date']=array('sort'=>'desc','query'=>'zs=dd');
  1981. }
  1982. elseif (!empty($cat['date'])) {
  1983. $cat['alpha']=array('sort'=>'asc','query'=>'zs=a');
  1984. }
  1985. $zina['category']['sort'] = $t_sort = ztheme('category_sort',$path, $cat);
  1986. }
  1987. else {
  1988. zina_directory_sort($subdirs);
  1989. $zina['category']['sort'] = '';
  1990. }
  1991. if ($cat['split'] && $subdir_num > $cat['pp']) {
  1992. $pages_total = ceil($subdir_num/$cat['pp']);
  1993. if (!zina_validate('int', $page) || $page < 1 || $page > $pages_total) {
  1994. $page = 1;
  1995. }
  1996. $zina['category']['navigation'] = ztheme('category_pages',$path, $page, $pages_total);
  1997. $cstart = ($page - 1) * $cat['pp'];
  1998. if ($cstart > $subdir_num) {
  1999. $cstart = 0;
  2000. }
  2001. $subdirs = array_slice($subdirs, $cstart, $cat['pp']);
  2002. }
  2003. }
  2004. if ($cat['images']) {
  2005. if ($cat['split'] == 3) {
  2006. foreach($subdirs as $key => $val) zina_get_dir_list($subdirs[$key], false);
  2007. }
  2008. else {
  2009. zina_get_dir_list($subdirs, false);
  2010. }
  2011. }
  2012. $zina['category']['content'] = ztheme('category', $subdirs, $cat['cols'], $cat['images'], $cat['truncate'], $full_page_split);
  2013. }
  2014. }
  2015. else { # Not Category
  2016. $zina['dir_list'] = $zc['dir_list'];
  2017. $zina['subdir_images'] = $zc['subdir_images'];
  2018. $list = false;
  2019. if ($subdir_num > 0 && ($zc['dir_list'] || $zc['subdir_images'])) {
  2020. $list = true;
  2021. if (!$zc['dir_list_sort']) {
  2022. ($zc['dir_sort_ignore']) ? uksort($subdirs, 'zsort_ignore') : uksort($subdirs, 'strnatcasecmp');
  2023. }
  2024. zina_get_dir_list($subdirs);
  2025. $zina['subdirs'] = $subdirs;
  2026. }
  2027. else {
  2028. if ($dir['dir_write']) {
  2029. $zina['dir_opts']['delete'] = array('path'=>$path, 'query'=>'l=76');
  2030. }
  2031. }
  2032. $zina['dir_image'] = ztheme('images', 'dir', $zina, $path, $dir['images'], 'l=46', $dir['image'], $dir['captions']);
  2033. $zina['dir_image_sub'] = ztheme('image',zina_get_image_url($path, (isset($dir['images'][0])?$dir['images'][0]:$dir['images']), 'sub'), $zina['title'], $zina['title']);
  2034. $alt_num = 0;
  2035. if ($zc['alt_dirs']) {
  2036. $zina['alt_items'] = array();
  2037. if (isset($dir['alt_items'])) {
  2038. $alts = $dir['alt_items'];
  2039. $list = true;
  2040. }
  2041. else {
  2042. $alt_file = $zc['cur_dir'].'/'.$zc['alt_file'];
  2043. if (file_exists($alt_file)) {
  2044. $alts = zunserialize_alt(file_get_contents($alt_file));
  2045. $list = true;
  2046. }
  2047. }
  2048. if (!empty($alts)) {
  2049. $alt_num = count($alts);
  2050. $alts_db = array();
  2051. if ($zc['database']) {
  2052. $alts_db = zdbq_assoc_list("SELECT path, other FROM {dirs} WHERE path IN (".substr(str_repeat(",'%s'", $alt_num),1).")", $alts);
  2053. }
  2054. foreach($alts as $alt) {
  2055. # backwards compatibility...strip /
  2056. $alt = rtrim($alt, '/');
  2057. $alt_dirs[$alt] = array('path'=>$alt,'new'=>false, 'lofi'=>1);
  2058. $alt_img = false;
  2059. if (isset($alts_db[$alt])) {
  2060. $temp = unserialize_utf8($alts_db[$alt]);
  2061. if (isset($temp['image']) && $temp['image']) {
  2062. $alt_img = $temp['image'];
  2063. }
  2064. }
  2065. if (!$alt_img) {
  2066. $alt_img = zina_get_dir_item($zc['mp3_dir'].'/'.$alt,'/\.('.$zc['ext_graphic'].')$/i');
  2067. }
  2068. $alt_dirs[$alt]['image'] = $alt_img;
  2069. if ($zc['low_lookahead']) {
  2070. $alt_dirs[$alt]['lofi'] = zina_get_dir_item($zc['mp3_dir'].'/'.$alt,'/('.$zc['low_suf'].')\.('.$zc['ext_mus'].')$/i');
  2071. }
  2072. if (empty($alt)) {
  2073. $alt_dirs[$alt]['title'] = $zc['main_dir_title'];
  2074. }
  2075. }
  2076. zina_get_dir_list($alt_dirs);
  2077. $zina['alt_items'] = $alt_dirs;
  2078. }
  2079. if ($dir['dir_edit']) {
  2080. $zina['alt_list_edit']['query'] = 'l=22&amp;m=2';
  2081. }
  2082. }
  2083. $zina['alt_num'] = $alt_num;
  2084. $zina['pls_included'] = false;
  2085. if ($zc['playlists'] && $zc['database'] && $zc['pls_included'] && isset($dir['id'])) {
  2086. $where = (!$zc['is_admin']) ? (($zc['pls_public']) ? 'AND (p.user_id = %d OR p.visible = 1)' : 'AND p.user_id = %d') : '';
  2087. $dir_playlists = zdbq_array("SELECT p.id, p.title, NULL as path, CONCAT('l=2&amp;pl=',p.id) as query, FALSE as new ".
  2088. "FROM {playlists_map} as pm ".
  2089. "INNER JOIN {playlists} as p ON (pm.playlist_id = p.id) ".
  2090. "LEFT OUTER JOIN {files} AS f ON pm.type = 'song' AND pm.type_id = f.id ".
  2091. "LEFT OUTER JOIN {dirs} AS d ON pm.type = 'album' AND pm.type_id = d.id ".
  2092. "WHERE (d.id = %d OR f.dir_id = %d) $where ".
  2093. "GROUP BY p.id ".
  2094. "ORDER BY p.sum_rating DESC, p.title LIMIT ".$zc['pls_included_limit'], array($dir['id'], $dir['id'], $zc['user_id']));
  2095. if (!empty($dir_playlists)) {
  2096. foreach ($dir_playlists as $key => $pls) {
  2097. $item = &$dir_playlists[$key];
  2098. $item['opts']['play'] = array('path'=>null, 'query'=>'l=8&amp;m=3&amp;pl='.$item['id']);
  2099. }
  2100. $zina['pls_included']['items'] = $dir_playlists;
  2101. if (sizeof($dir_playlists) >= $zc['pls_included_limit']) {
  2102. $zina['pls_included']['more'] = array('path'=>null, 'query'=>'l=2&m='.$dir['id']);
  2103. }
  2104. }
  2105. }
  2106. if ($list && $zc['playlists']) {
  2107. $form_id = 'zinadirsform';
  2108. $type = ($subdir_num + $alt_num > 0) ? 'l a x p r q v' : 'l x p r q v';
  2109. $zina['list_form'] = zina_content_playlist_form_opts($form_id, $zina['title'], $type);
  2110. $zina['list_form_opts'] = 'id="'.$form_id.'" action="'.zurl($path).'"';
  2111. } else {
  2112. $zina['list_form'] = $zina['list_form_opts'] = '';
  2113. }
  2114. if ($zc['database']) {
  2115. if ($zc['rating_dirs']) {
  2116. $user_rating = ($zc['user_id'] > 0) ? zdb_get_dir_user_rating($path, $zc['user_id']) : 0;
  2117. $zina['dir_rate'] = ztheme('vote', zina_get_vote_url($path), $user_rating);
  2118. }
  2119. if ($zc['rating_dirs_public'] || $zc['is_admin']) {
  2120. $zina['dir_rating']['sum_views'] = $dir['sum_views'];
  2121. $zina['dir_rating']['sum_votes'] = $dir['sum_votes'];
  2122. $zina['dir_rating']['sum_rating'] = $dir['sum_rating'];
  2123. }
  2124. }
  2125. } #NOT CAT
  2126. if ($files_found) {
  2127. $lofi = ($zc['low'] && ($zc['resample'] || $dir['lofi']));
  2128. $custom_pls = ($zc['cache'] && file_exists($zc['cache_pls_dir'].'/'.str_replace('/',' - ',$path).'.m3u'));
  2129. # Dir Play
  2130. if ($zc['play']) {
  2131. $zina['dir_opts']['play'] = array('path'=>$path, 'query'=>'l=8&amp;m=0', 'class'=>'zinamp');
  2132. if ($custom_pls) {
  2133. $zina['dir_opts']['play_custom'] = array('path'=>$path, 'query'=>'l=8&amp;m=0&amp;c');
  2134. }
  2135. # Recursive Play & Random
  2136. if ($zc['play_rec'] && $subdir_num > 1) {
  2137. $zina['dir_opts']['play_rec'] = array('path'=>$path, 'query'=>'l=8&amp;m=10');
  2138. }
  2139. if ($zc['play_rec_rand'] && $subdir_num > 0) {
  2140. $zina['dir_opts']['play_rec_rand'] = array('path'=>$path, 'query'=>'l=8&amp;m=10&amp;c');
  2141. }
  2142. }
  2143. if ($lofi) {
  2144. $zina['dir_opts']['play_lofi'] = array('path'=>$path, 'query'=>'l=8&amp;m=0&amp;lf');
  2145. if ($custom_pls) {
  2146. $zina['dir_opts']['play_lofi_custom'] = array('path'=>$path, 'query'=>'l=8&amp;m=0&amp;c&amp;lf');
  2147. }
  2148. }
  2149. if ($zc['cmp_sel']) {
  2150. $zina['dir_opts']['download'] = array('path'=>$path.'/.lp', 'query'=>'l=5');
  2151. if ($custom_pls) {
  2152. $zina['dir_opts']['download_custom'] = array('path'=>$path.'/.lp', 'query'=>'l=5&amp;c');
  2153. }
  2154. }
  2155. #todo: this is done twice
  2156. $key = key($dir['files']);
  2157. $dir_year = (isset($dir['year'])) ? $dir['year'] : ((isset($subdirs[$key]['info']->year)) ? $subdirs[$key]['info']->year : false);
  2158. $zina['dir_year'] = ($dir_year && $zc['db_search']) ? zl($dir_year,$path,'l=69&amp;pl='.rawurlencode($dir_year)) : $dir_year;
  2159. $dir_genre = ($zc['genres'] && isset($dir['genre'])) ? $dir['genre'] : ((isset($subdirs[$key]['info']->genre)) ? $subdirs[$key]['info']->genre : false);
  2160. $zina['dir_genre'] = ($dir_genre) ? zl($dir_genre,$path,'l=13&amp;pl='.rawurlencode($dir_genre)) : $dir_genre;
  2161. if ($zc['files_sort'] == 1) {
  2162. krsort($dir['files']);
  2163. } elseif ($zc['files_sort'] == 2) {
  2164. usort($dir['files'],'zsort_date');
  2165. } elseif ($zc['files_sort'] == 3) {
  2166. usort($dir['files'],'zsort_date_desc');
  2167. } elseif ($zc['files_sort'] == 4) {
  2168. usort($dir['files'],'zsort_trackno');
  2169. }
  2170. $songrow = ztheme('song_list', $dir['files'], $dir['various']);
  2171. $check_boxes = (($zc['is_admin'] && $zc['cache']) || ($zc['playlists'] && $zc['session_pls']) || $zc['play_sel'] || $zc['cmp_sel']);
  2172. $form_id = 'zinasongsform';
  2173. $form_attr = 'id="'.$form_id.'" action="'.zurl($path).'"';
  2174. $songopts = ztheme('song_list_opts', zina_content_song_list_opts($custom_pls, $lofi, $check_boxes,$form_id),$form_id);
  2175. $zina['songs'] = ztheme('song_section',$form_attr, $songrow, $songopts);
  2176. if ($zc['rss']) {
  2177. if ($zc['clean_urls']) {
  2178. $zina['podcast']['url'] = (empty($path)) ? $zc['rss_file'] : $path.'/'.$zc['rss_file'];
  2179. $zina['podcast']['query'] = null;;
  2180. } else {
  2181. $zina['podcast']['url'] = $path;
  2182. $zina['podcast']['query'] = 'l=50';
  2183. }
  2184. $zina['podcast']['type'] = ($zc['rss_podcast']) ? 'podcast' : 'rss';
  2185. zina_set_html_head('<link rel="alternate" type="application/rss+xml" title="'.zt('!title Podcast', array('!title'=>$zina['title'])).'" href="'.zurl($zina['podcast']['url'], $zina['podcast']['query']).'"/>');
  2186. if ($dir['dir_edit'] && $zc['is_admin']) {
  2187. $zina['dir_edit_opts']['podcast'] = array('path'=>$path, 'query'=>'l=22&amp;m=5');
  2188. }
  2189. }
  2190. } else { #NO FILES FOUND
  2191. if($zc['dir_genre_look'] && $subdir_num > 0) {
  2192. if (isset($dir['genre'])) {
  2193. $dir_genre = $dir['genre'];
  2194. } else {
  2195. $keys = array_keys($subdirs);
  2196. $key = $keys[0];
  2197. $dir_genre = (isset($subdirs[$key]['info']->genre)) ? $subdirs[$key]['info']->genre : false;
  2198. }
  2199. $zina['dir_genre'] = ($dir_genre) ? zl($dir_genre,$path,'l=13&amp;pl='.rawurlencode($dir_genre)) : $dir_genre;
  2200. }
  2201. # Recursive Play & Random
  2202. if ($zc['play'] && $zc['play_rec'] && $subdir_num > 1) {
  2203. $zina['dir_opts']['play_rec'] = array('path'=>$path, 'query'=>'l=8&amp;m=10');
  2204. }
  2205. if ($zc['play'] && $zc['play_rec_rand'] && $subdir_num > 0) {
  2206. $zina['dir_opts']['play_rec_rand'] = array('path'=>$path, 'query'=>'l=8&amp;m=10&amp;c');
  2207. }
  2208. }
  2209. if ($zc['is_admin']) {
  2210. $zina['dir_edit_opts']['images'] = array('path'=>$path, 'query'=>'l=58');
  2211. if ($dir['dir_edit'] && $files_found) $zina['dir_edit_opts']['tags'] = array('path'=>$path, 'query'=>'l=71');
  2212. }
  2213. if ($zc['mm'] && !empty($dir['mm'])) $zina['multimedia'] = $dir['mm'];
  2214. $zina['subdir_truncate'] = $zc['subdir_truncate'];
  2215. $zina['subdir_cols'] = $zc['subdir_cols'];
  2216. $zina['page_main'] = true;
  2217. $zina['content'] = ztheme('page_main', $zina);
  2218. }
  2219. function zina_content_breadcrumb(&$zina, $path, $alt_title = null, $full = false) {
  2220. $zina['path'] = $path;
  2221. if (!empty($path)) {
  2222. $zina['breadcrumb'] = zina_get_breadcrumb($path, $alt_title, $full);
  2223. $dir_current = zina_get_current_dir();
  2224. $title = ztheme('page_title',zina_get_page_title());
  2225. } else {
  2226. $title = $dir_current = $alt_title;
  2227. $zina['breadcrumb'] = zina_get_breadcrumb($alt_title, null, $full);
  2228. }
  2229. $zina['html_title'] = zcheck_utf8($dir_current);
  2230. $zina['title_raw'] = zdecode_entities($dir_current);
  2231. $zina['title'] = $title;
  2232. }
  2233. function zina_content_search_list(&$results, $checkbox, $opts = array(), $extras = array()) {
  2234. global $zc;
  2235. if (!empty($results)) {
  2236. $ratings = (isset($opts['rating'])) ? $opts['rating'] : ($zc['rating_files'] && $zc['db_search']);
  2237. $images = (isset($opts['images'])) ? $opts['images'] : $zc['search_images'];
  2238. $types = (isset($opts['types'])) ? $opts['types'] : true;
  2239. $genres = (isset($opts['genres'])) ? $opts['genres'] : $zc['genres'];
  2240. $years = (isset($opts['years'])) ? $opts['years'] : true;
  2241. foreach($results as $key=>$item) {
  2242. $play = $zc['play'];
  2243. $download = $zc['download'];
  2244. $rem_title = false;
  2245. $result = &$results[$key];
  2246. $result['new'] = false;
  2247. $result['image'] = (isset($item['image'])) ? $item['image'] : false;
  2248. $result['ratings'] = $ratings;
  2249. if (isset($result['title']) && isset($opts['highlight'])) {
  2250. $result['alt'] = $result['title'];
  2251. $result['title'] = preg_replace("|(".preg_quote($opts['highlight']).")|i",'<span class="ac_match_results">$1</span>',$result['title']);
  2252. }
  2253. #TODO: test ratings w/o DB
  2254. if ($item['type'] == 'song') {
  2255. if ($checkbox) {
  2256. $result['checkbox'] = array('name'=>'mp3s[]', 'value'=>zrawurlencode($item['path']), 'checked'=>false);
  2257. } else {
  2258. $result['checkbox'] = false;
  2259. }
  2260. if (!isset($result['title'])) {
  2261. if (isset($item['id3_info'])) {
  2262. $mp3 = unserialize_utf8($item['id3_info']);
  2263. if (isset($mp3->title)) $result['title'] = ztheme('song_title', $mp3->title, true);
  2264. }
  2265. if (!isset($result['title'])) {
  2266. $result['title'] = zina_content_song_title($item['path']);
  2267. }
  2268. }
  2269. $desc_opts = array();
  2270. if ($types && !empty($item['type'])) $desc_opts['type'] = zt(ucfirst($result['type']));
  2271. if ($years && isset($item['year']) && !empty($item['year'])) $desc_opts['year'] = zl($item['year'],'','l=69&amp;pl='.rawurlencode($item['year']));
  2272. if ($genres && isset($item['genre'])) $desc_opts['genre'] = zl($item['genre'],'','l=13&amp;pl='.rawurlencode($item['genre']));
  2273. #todo: put in "description" if exists?
  2274. $result['description'] = ztheme('search_description', zina_content_pathlinks(dirname($item['path']), 't', false, $rem_title), $desc_opts);
  2275. $dir_path = dirname($item['path']);
  2276. $title_link = (zvalidate_utf8($dir_path)) ? utf8_decode($dir_path) : $dir_path;
  2277. $result['image_link'] = array('path'=>$title_link, 'query'=>null);
  2278. if ($play) {
  2279. $title_link = (zvalidate_utf8($item['path'])) ? utf8_decode($item['path']) : $item['path'];
  2280. $result['title_link'] = $result['opts']['play'] = array('path'=>$title_link, 'query'=>'l=8&amp;m=1', 'attr'=>' class="zinamp"');
  2281. } else {
  2282. $result['title_link'] = array('path'=>$title_link, 'query'=>null);
  2283. }
  2284. if ($download) $result['opts']['download'] = array('path'=>$item['path'], 'query'=>'l=12');
  2285. if (isset($item['id3_info'])) $result['info'] = unserialize_utf8($item['id3_info']);
  2286. } elseif ($item['type'] == 'genre') {
  2287. $result['description'] = ($types) ? ucfirst($item['type']) : '';
  2288. $result['checkbox'] = false;
  2289. if ($play) {
  2290. $result['opts']['play'] = array('path'=>null, 'query'=>'l=8&amp;m=5&amp;pl='.rawurlencode($item['path']));
  2291. }
  2292. $result['image_link'] = $result['title_link'] = array('path'=>null, 'query'=>'l=13&pl='.rawurlencode($item['path']));
  2293. } elseif (in_array($item['type'], array('artist','album','directory'))) {
  2294. zina_content_subdir_opts($result, $item['path'], $checkbox, NULL);
  2295. if (!isset($result['title'])) {
  2296. if ($zc['dir_tags'] && isset($item['id3_info']) && !empty($item['id3_info'])) {
  2297. $title_path = $item['id3_info'];
  2298. } else {
  2299. $title_path = (substr_count($item['path'], '/') > 0) ? substr($item['path'], strrpos($item['path'],'/')+1) : $item['path'];
  2300. if (zvalidate_utf8($title_path)) $title_path = utf8_decode($title_path);
  2301. }
  2302. $result['title'] = ztheme('title', $title_path);
  2303. }
  2304. #todo: redudant with songs
  2305. $desc_opts = array();
  2306. if ($types && !empty($item['type'])) $desc_opts['type'] = zt(ucfirst($result['type']));
  2307. if ($years && isset($item['year']) && !empty($item['year'])) $desc_opts['year'] = zl($item['year'],'','l=69&amp;pl='.rawurlencode($item['year']));
  2308. if ($genres && isset($item['genre'])) $desc_opts['genre'] = zl($item['genre'],'','l=13&amp;pl='.rawurlencode($item['genre']));
  2309. $title_link = (zvalidate_utf8($item['path'])) ? utf8_decode($item['path']) : $item['path'];
  2310. $result['image_link'] = $result['title_link'] = array('path'=>$title_link, 'query'=>null);
  2311. if ($item['type'] == 'album') {
  2312. $result['description'] = ztheme('search_description', zina_content_pathlinks(dirname($item['path']), 't', false, $rem_title), $desc_opts);
  2313. } else {
  2314. if ($item['type'] == 'artist') unset($desc_opts['year']);
  2315. $result['description'] = ztheme('search_description', '', $desc_opts);
  2316. #todo: have '/.art' so artists can be added to playlists...?
  2317. $result['checkbox'] = false;
  2318. }
  2319. } elseif ($item['type'] == 'playlist') {
  2320. if (isset($item['description'])) {
  2321. $result['description'] = zina_url_filter($item['description']);
  2322. } else {
  2323. $result['description'] = ($types) ? ucfirst($item['type']) : '';
  2324. }
  2325. # SEARCH RESULTS
  2326. if ($images && !$result['image']) {
  2327. if (isset($item['image_type']) || !empty($item['image_type'])) {
  2328. if ($item['image_type'] == 1 && isset($item['image_path'])) {
  2329. $tmp = $item['id'];
  2330. $item['id'] = $item['path'];
  2331. $item['path'] = $item['image_path'];
  2332. $item['type'] = 'artist';
  2333. $result['image'] = zina_content_search_image($item, 'search');
  2334. $item['type'] = 'playlist';
  2335. $item['path'] = $item['id'];
  2336. $item['id'] = $tmp;
  2337. }
  2338. }
  2339. }
  2340. $pls = ($zc['database'] && isset($item['id'])) ? $item['id'] : $item['path'];
  2341. if ($zc['database'] && $item['id'] != 'zina_session_playlist') {
  2342. $result['checkbox'] = array('name'=>'mp3s[]', 'value'=>zrawurlencode($item['id']).'.pls', 'checked'=>false);
  2343. } else {
  2344. $result['checkbox'] = false;
  2345. }
  2346. if ($play) {
  2347. $result['opts']['play'] = array('path'=>null, 'query'=>'l=8&amp;m=3&amp;pl='.rawurlencode($pls));
  2348. }
  2349. $result['image_link'] = $result['title_link'] = array('path'=>null, 'query'=>'l=2&pl='.rawurlencode($pls));
  2350. } else {
  2351. $result['description'] = null;
  2352. $result['checkbox'] = false;
  2353. }
  2354. if ($images && !$result['image']) {
  2355. $result['image'] = zina_content_search_image($result, 'search');
  2356. }
  2357. foreach($extras as $key=>$extra) { $result[$key] = $extra; }
  2358. }
  2359. }
  2360. }
  2361. # genre & year search
  2362. function zina_content_search($type, &$zina) {
  2363. global $zc;
  2364. $search_opts = false;
  2365. $count = 0;
  2366. $results = array();
  2367. $selected = false;
  2368. $term = isset($_POST['pl']) ? $_POST['pl'] : (isset($_GET['pl']) ? $_GET['pl'] : null);
  2369. $checkbox = ($zc['playlists'] && (($zc['is_admin'] && $zc['cache']) || $zc['session_pls'] || $zc['pls_public'] || ($zc['pls_user'] && $zc['user_id'] > 0)));
  2370. if ($type == 'year') {
  2371. $query = 'l=69';
  2372. $qp = '6';
  2373. $sql = array('where'=>"i.year = %d", 'orderby'=>"i.title");
  2374. $items = zdbq_array_list("SELECT DISTINCT year, year FROM {dirs} WHERE year IS NOT NULL ORDER BY year DESC");
  2375. $label = zt('Year');
  2376. } else {
  2377. $type = 'genres';
  2378. $query = 'l=13';
  2379. $qp = '5';
  2380. $sql = array('where'=>"i.genre = '%s'", 'orderby'=>"i.title");
  2381. $items = zina_core_cache('genres');
  2382. $label = false;
  2383. if (!$zc['db_search']) $sql = array();
  2384. }
  2385. if (!in_array($term, $items)) {
  2386. zina_set_message(zt('Unknown term: @term', array('@term'=>$term)));
  2387. $bad_query = ($type == 'year') ? '' : 'l=14';
  2388. zina_goto('', $bad_query);
  2389. }
  2390. $navigation = ztheme($type.'_form', $zc['genres'], zurl('',$query), $items, $term, $label);
  2391. $zina['html_title'] = $zina['title'] = htmlentities($term);
  2392. $results = zina_search_pager_query($term, $query, $count, $search_opts, $sql, ($type == 'genres'), $selected);
  2393. if (!empty($results)) {
  2394. zina_content_breadcrumb($zina, '', $term);
  2395. if ($zc['genres_images']) {
  2396. $genre_image = ztheme('image', zina_get_genre_image_path($term), $term, null, 'class="genre-image"');
  2397. } else {
  2398. $genre_image = false;
  2399. }
  2400. } else {
  2401. zina_content_breadcrumb($zina, '', zt('Search Results'));
  2402. }
  2403. zina_content_search_list($results, $checkbox, array('highlight'=>$term, 'genres'=>($zc['genres'] && $type != 'genres'), 'years'=>($zc['db_search'] && $type != 'year')));
  2404. $list = ztheme('search_list', $results, $zc['search_images']);
  2405. $form_id = 'zinasearchresultsform';
  2406. $form_attr = 'id="'.$form_id.'" action="'.zurl('','m=1').'"';
  2407. $list_opts = ($zc['playlists']) ? ztheme('search_list_opts', zina_content_song_list_opts(false, false, $checkbox, $form_id, true), $form_id) : null;
  2408. $opts['image'] = $zc['genres_images'];
  2409. $opts['play_query'] = 'l=8&amp;m='.$qp.'&amp;pl='.rawurlencode($term);
  2410. $opts['genre_edit'] = $opts['description'] = false;
  2411. if ($type == 'genres' && $zc['database']) {
  2412. $page = zdbq_array_single("SELECT * FROM {genres} as g INNER JOIN {genre_tree} as gt ON g.id=gt.id ".
  2413. "WHERE g.genre = '%s'", array($term));
  2414. if ($page['pid'] != 0) {
  2415. $crumbs = explode('/', $page['path']);
  2416. array_pop($crumbs);
  2417. $gs = zdbq_assoc_list("SELECT id, genre FROM {genres} WHERE id IN (".implode(',', $crumbs).")");
  2418. foreach($crumbs as $crumb) {
  2419. $links[] = zl($gs[$crumb],null, 'l=13&pl='.zrawurlencode($gs[$crumb]));
  2420. }
  2421. $zina['breadcrumb'] = zina_get_breadcrumb(null, null, false, $links);
  2422. }
  2423. $children = zdbq_array_list("SELECT genre FROM {genres} AS g INNER JOIN {genre_tree} AS gt ON g.id=gt.id ".
  2424. "WHERE g.pid = %d ORDER BY weight", array($page['id']));
  2425. if (!empty($children)) {
  2426. $children = zina_get_genres_list($children, 'genresearch');
  2427. $zina['subgenres'] = ztheme('genres', $children, $zc['genres_cols']*2, $zc['genres_images'], $zc['genres_truncate'], $zina, false, false);
  2428. }
  2429. if ($zc['is_admin'] && $zc['database']) {
  2430. if (!empty($page['description'])) $opts['description'] = zina_url_filter(nl2br($page['description']));
  2431. $opts['genre_edit'] = array('path'=>'', 'query'=>'l=22&amp;m=6&amp;pl='.rawurlencode($term));
  2432. }
  2433. }
  2434. $zina['search_page_type'] = $type;
  2435. $zina['content'] = ztheme($type.'_page', $term, $results, $count, $search_opts, $navigation, $form_attr, $list, $list_opts, $opts, zurl('', $query.'&amp;pl='.zrawurlencode($term)), $selected, $zina);
  2436. }
  2437. function zina_content_search_image($item, $size = 'sub', $class="search-image", $absolute = false) {
  2438. global $zc;
  2439. # some of these utf8s can be removed in 3.0 when db is installed as utf-8
  2440. if (isset($item['path']) && zvalidate_utf8($item['path'])) $item['path'] = utf8_decode($item['path']);
  2441. $image = $img_url = null;
  2442. if ($item['type'] == 'song') {
  2443. $img_path = dirname($item['path']);
  2444. $img = zina_get_dir_item($zc['mp3_dir'].'/'.$img_path,'/\.('.$zc['ext_graphic'].')$/i');
  2445. $img_url = zina_get_image_url($img_path, $img, $size, $absolute);
  2446. } elseif (in_array($item['type'], array('artist','album','directory'))) {
  2447. $img_path = $item['path'];
  2448. $img = zina_get_dir_item($zc['mp3_dir'].'/'.$img_path,'/\.('.$zc['ext_graphic'].')$/i');
  2449. $img_url = zina_get_image_url($img_path, $img, $size, $absolute);
  2450. } elseif (($item['type'] == 'genre' || $item['type'] == 'genresearch') && $zc['genres_images']) {
  2451. #todo: absolute
  2452. #$img_url = zina_get_genre_image_path($item['path'], 'genresearch');
  2453. if ($size != 'genre') $size = 'genresearch';
  2454. $img_url = zina_get_genre_image_path($item['path'], $size);
  2455. } elseif ($item['type'] == 'playlist') {
  2456. # SEARCH BOX
  2457. if (isset($item['image_type'])) {
  2458. if ($item['image_type'] == 1) {
  2459. $item['type'] = 'artist';
  2460. $item['path'] = $item['image_path'];
  2461. return zina_content_search_image($item, $size, $class, $absolute);
  2462. } elseif ($item['image_type'] == 2) {
  2463. $item['type'] = ($size == 'search') ? 'genresearch' : 'genre';
  2464. $item['path'] = $item['genre'];
  2465. $item['title'] = $item['genre'];
  2466. return zina_content_search_image($item, $item['type'], $class, $absolute);
  2467. } else {
  2468. $size = ($size == 'search') ? 'plssearch' : 'pls';
  2469. if ($zc['res_genre_img']) {
  2470. $img_url = zurl(null,'l=7&amp;it='.$size.'&amp;img='.rawurlencode($item['title']), null, $absolute);
  2471. }
  2472. }
  2473. } else {
  2474. zina_debug(zt('No playlist image info'));
  2475. }
  2476. }
  2477. if (!empty($img_url)) {
  2478. $alt = (isset($item['alt'])) ? $item['alt'] : $item['title'];
  2479. $image = ztheme('image', $img_url, $alt, null, 'class="'.$class.'"');
  2480. }
  2481. return $image;
  2482. }
  2483. function zina_directory_sort(&$subdirs) {
  2484. global $zc;
  2485. if ($zc['dir_tags']) {
  2486. ($zc['dir_sort_ignore']) ? usort($subdirs, 'zsort_title_ignore') : usort($subdirs, 'zsort_title');
  2487. } else {
  2488. ($zc['dir_sort_ignore']) ? uksort($subdirs, 'zsort_ignore') : uksort($subdirs, 'strnatcasecmp');
  2489. }
  2490. }
  2491. function zina_playlist_insert($pls_id, $items, $start) {
  2492. global $zc;
  2493. $weight = $start;
  2494. $error = false;
  2495. foreach($items as $item) {
  2496. if ($weight > $zc['pls_length_limit']) {
  2497. zina_set_message(zt('You cannot have more than @num items per playlist.', array('@num'=>$zc['pls_length_limit'])));
  2498. $error = true;
  2499. break;
  2500. }
  2501. $item = zrawurldecode($item);
  2502. if (preg_match('/\.('.$zc['ext_mus'].')$/i', $item) || ($zc['remote'] && preg_match('/\.('.$zc['remote_ext'].')$/i', $item))) {
  2503. $type = 'song';
  2504. if (substr_count($item, '/') > 0) {
  2505. $pos = strrpos($item,'/');
  2506. $file_name = substr($item, $pos+1);
  2507. $file_path = substr($item, 0, $pos);
  2508. } else {
  2509. $file_name = $item;
  2510. $file_path = '';
  2511. }
  2512. if ($file_path == '.') $file_path = '';
  2513. $type_id = zdbq_single("SELECT id FROM {files} WHERE path = '%s' AND file = '%s'", array($file_path, $file_name));
  2514. if (empty($type_id)) {
  2515. if (zfile_check_location($zc['mp3_dir'].'/'.$file_path.'/'.$file_name, $zc['mp3_dir'])) {
  2516. zdb_log_stat('insertonly', $file_path, $file_name);
  2517. $type_id = zdbq_single("SELECT id FROM {files} WHERE path = '%s' AND file = '%s'", array($file_path, $file_name));
  2518. }
  2519. }
  2520. } elseif (preg_match('/\.lp$/i', $item)) {
  2521. $type = 'album';
  2522. $file_path = preg_replace('/\/\.lp$/i','',$item);
  2523. $type_id = zdbq_single("SELECT id FROM {dirs} WHERE path = '%s'", array($file_path));
  2524. if (empty($type_id)) {
  2525. if (zfile_check_location($zc['mp3_dir'].'/'.$file_path, $zc['mp3_dir'])) {
  2526. zdb_log_stat('insertonly', $file_path);
  2527. $type_id = zdbq_single("SELECT id FROM {dirs} WHERE path = '%s'", array($file_path));
  2528. }
  2529. }
  2530. } elseif (preg_match('/\.pls$/i', $item)) {
  2531. $type = 'playlist';
  2532. $pls_id_add = preg_replace('/\.pls/i','',$item);
  2533. $type_id = zdbq_single("SELECT id FROM {playlists} WHERE id = %d", array($pls_id_add));
  2534. } else {
  2535. $type_id = null;
  2536. }
  2537. if (!empty($type_id)) {
  2538. if ($pls_id == 'zina_session_playlist') {
  2539. #$item[] = array('type'=> $type, 'type_id' => $type_id, 'weight'=>$weight);
  2540. $pls_items = array();
  2541. if ($type == 'album') {
  2542. $type_id .= '/.lp';
  2543. } elseif ($type == 'playlist') {
  2544. $type_id .= '.pls';
  2545. }
  2546. $pls_items[] = $type_id;
  2547. $existing = (isset($_SESSION['z_sp'])) ? unserialize_utf8($_SESSION['z_sp']) : array();
  2548. $_SESSION['z_sp'] = utf8_encode(serialize(array_merge($existing, $pls_items)));
  2549. } else {
  2550. if (!zdbq("INSERT {playlists_map} (playlist_id, type, type_id, weight) VALUES (%d, '%s', %d, %d)",
  2551. array($pls_id, $type, $type_id, $weight))) {
  2552. zina_set_message(zt('Could not insert into playlist: @file', array('@file'=>$item)));
  2553. $error = true;
  2554. }
  2555. }
  2556. } else {
  2557. zina_set_message(zt('Could not find item[@pls]: @item', array('@pls'=>$pls_id, '@item'=>$item)));
  2558. $error = true;
  2559. }
  2560. $weight++;
  2561. }
  2562. if (($sum_items = zdbq_single("SELECT COUNT(*) FROM {playlists_map} WHERE playlist_id = %d", array($pls_id))) !== false) {
  2563. zdbq("UPDATE {playlists} SET sum_items = %d WHERE id = %d", array($sum_items, $pls_id));
  2564. }
  2565. return (!$error);
  2566. }
  2567. function zina_playlists_list_helper(&$playlists, $editable = true, $checkbox = false) {
  2568. global $zc;
  2569. foreach($playlists as $key => $playlist) {
  2570. $item = &$playlists[$key];
  2571. $pl = $playlist['id'];
  2572. $edit = ($editable && ($pl == 'zina_session_playlist' || zina_cms_access('edit_playlists', $playlist['user_id'])));
  2573. if ($zc['play']) {
  2574. $item['opts']['play'] = array('path'=>null, 'query'=>'l=8&amp;m=3&amp;pl='.$pl);
  2575. if ($zc['play_rec_rand'])
  2576. $item['opts']['play_rec_rand'] = array('path'=>null, 'query'=>'l=8&amp;m=3&amp;pl='.$pl.'&amp;rand');
  2577. }
  2578. if ($edit && $pl != 'zina_session_playlist') {
  2579. $item['options'][] = zl(zt("Edit"), null, 'l=44&amp;pl='.$pl);
  2580. $item['options'][] = zl(zt("Delete"), null, 'l=43&amp;pl='.$pl);
  2581. }
  2582. $item['image_link'] = $item['title_link'] = array('path' => null, 'query'=>'l=2&amp;pl='.$pl);
  2583. $item['title'] = htmlentities($playlist['playlist']);
  2584. $item['image'] = false;
  2585. $desc_opts = array();
  2586. if (!empty($item['date_created'])) $desc_opts['date_created'] = $item['date_created'];
  2587. $user = zina_cms_user($item['user_id']);
  2588. if ($user) {
  2589. if ($user['profile_url']) $desc_opts['profile_url'] = $user['profile_url'];
  2590. $desc_opts['username'] = $user['name'];
  2591. }
  2592. if ($zc['genres'] && !empty($item['genre'])) $desc_opts['genre'] = zl($item['genre'],'','l=13&amp;pl='.rawurlencode($item['genre']));
  2593. $stats = array();
  2594. if (isset($item['sum_items']) && !empty($item['sum_items'])) $stats['sum_items'] = $item['sum_items'];
  2595. if (isset($item['sum_views']) && !empty($item['sum_views'])) $stats['sum_views'] = $item['sum_views'];
  2596. if (isset($item['sum_plays']) && !empty($item['sum_plays'])) $stats['sum_plays'] = $item['sum_plays'];
  2597. $item['description'] = ztheme('playlist_description', $item['description'], $desc_opts, $stats, $item);
  2598. $item['new'] = $item['ratings'] = $item['checkbox'] = false;
  2599. # PLAYLIST LIST PAGE
  2600. $item['type'] = 'playlist';
  2601. $item['image'] = zina_content_search_image($item, 'search');
  2602. $item['ratings'] = $zc['pls_ratings'];
  2603. if ($checkbox && $pl != 'zina_session_playlist') {
  2604. $item['checkbox'] = array('name'=>'mp3s[]', 'value'=>$pl.'.pls', 'checked'=>false);
  2605. }
  2606. }
  2607. }
  2608. function zina_content_playlists_db(&$zina, $id = null) {
  2609. global $zc;
  2610. #TODO: need to verify pls access crap throughout
  2611. if (!($zc['playlists'] && ($zc['is_admin'] || $zc['pls_public'] || ($zc['pls_user'] && $zc['user_id'] > 0)))) return zina_access_denied();
  2612. $zina['title'] = zt('Playlists');
  2613. $count = 0;
  2614. $navigation = false;
  2615. $selected = array();
  2616. $page = (isset($_GET['page'])) ? '&amp;page='.$_GET['page'] : '';
  2617. $query = 'l=2'.$page;
  2618. if (!empty($id)) {
  2619. $query.='&amp;m='.$id;
  2620. $path = zdbq_single("SELECT path FROM {dirs} WHERE id = %d", array($id));
  2621. if (empty($path)) {
  2622. zina_set_message(zt('Sorry, there are no playlists'));
  2623. $zina['content'] = '';
  2624. return;
  2625. }
  2626. $title = ztheme('title',$path);
  2627. $title = zt('@album Tracks Appear on These Playlists', array('@album'=>$title));
  2628. #TEST
  2629. zina_content_breadcrumb($zina, '', $title, true);
  2630. }
  2631. $playlists = zina_playlist_pager_query($query, $count, $navigation, $selected, $id);
  2632. if ($zc['session_pls']) {
  2633. if (!isset($_GET['page']) || $_GET['page'] == 1) {
  2634. $results = (isset($_SESSION['z_sp'])) ? unserialize_utf8($_SESSION['z_sp']) : array();
  2635. $zsp = array('id'=>'zina_session_playlist','image_type'=>0,'playlist'=>zt('Session Playlist'),'description'=>'',
  2636. 'user_id' => 0, 'date_created'=>null, 'sum_items'=>sizeof($results), 'sum_votes'=>0,'sum_rating'=>0);
  2637. if (empty($playlists)) {
  2638. $playlists['zina_session_playlist'] = $zsp;
  2639. } else {
  2640. array_unshift($playlists, $zsp);
  2641. }
  2642. }
  2643. $count++;
  2644. }
  2645. if (!empty($playlists)) {
  2646. $checkbox = true;
  2647. zina_playlists_list_helper($playlists, true, $checkbox);
  2648. $form_id = 'pls-form';
  2649. $list_opts = ztheme('search_list_opts', zina_content_song_list_opts(false, false, $checkbox, $form_id, true), $form_id);
  2650. $form_attr = 'id="'.$form_id.'" action="'.zurl('', 'l=2').'"';
  2651. $zina['content'] = ztheme('playlists_list_db', $playlists, $count, $navigation, zurl('', $query), $form_attr, $list_opts, $selected, $checkbox);
  2652. } else {
  2653. zina_set_message(zt('Sorry, there are no playlists'));
  2654. $zina['content'] = '';
  2655. }
  2656. }
  2657. function zina_get_session_playlist() {
  2658. $songs = $dirs = $playlists = array();
  2659. $results = (isset($_SESSION['z_sp'])) ? unserialize_utf8($_SESSION['z_sp']) : array();
  2660. #todo: change .lp & .pls stuff to substr
  2661. foreach($results as $result) {
  2662. if (preg_match('/\.lp$/i', $result)) {
  2663. $dirs[] = preg_replace('/\/\.lp$/i','',$result);
  2664. } elseif (preg_match('/\.pls/i', $result)) {
  2665. $playlists[] = preg_replace('/\.pls/i','',$result);
  2666. } else {
  2667. $songs[] = $result;
  2668. }
  2669. }
  2670. if (!empty($songs)) {
  2671. $sql = "SELECT f.id as type_id, 'song' as type, IF(f.path!='.',CONCAT(f.path,IF(ISNULL(f.path), '','/'),f.file),f.file) AS path, ".
  2672. "f.id3_info, f.year, f.genre, f.sum_votes, f.sum_rating ".
  2673. "FROM {files} AS f ".
  2674. "WHERE f.id IN (".implode(',', $songs).")";
  2675. $result_songs = zdbq_assoc('type_id', $sql);
  2676. }
  2677. if (!empty($dirs)) {
  2678. $sql = "SELECT d.id as type_id, 'album' as type, d.path, ".
  2679. "d.title as id3_info, d.year, d.genre, d.sum_votes, d.sum_rating ".
  2680. "FROM {dirs} AS d ".
  2681. "WHERE d.id IN (".implode(',', $dirs).")";
  2682. $result_dirs = zdbq_assoc('type_id', $sql);
  2683. }
  2684. if (!empty($playlists)) {
  2685. $sql = "SELECT p.id as type_id, 'playlist' as type, p.id as path, p.title as id3_info, p.title, ".
  2686. "d.path as image_path, g.genre, p.image_type, p.id, p.sum_votes, p.sum_rating ".
  2687. "FROM {playlists} AS p ".
  2688. "LEFT OUTER JOIN {dirs} AS d ON (p.dir_id = d.id) ".
  2689. "LEFT OUTER JOIN {genres} AS g ON (p.genre_id = g.id) ".
  2690. "WHERE p.id IN (".implode(',', $playlists).")";
  2691. $result_playlists = zdbq_assoc('type_id', $sql);
  2692. }
  2693. foreach($results as $key => $val) {
  2694. $item = &$results[$key];
  2695. if (preg_match('/\.lp$/i', $val)) {
  2696. $dir_id = preg_replace('/\/\.lp$/i','',$val);
  2697. if (isset($result_dirs[$dir_id])) $item = $result_dirs[$dir_id];
  2698. } elseif (preg_match('/\.pls/i', $val)) {
  2699. $pls_id2 = preg_replace('/\.pls/i','',$val);
  2700. if (isset($result_playlists[$pls_id2])) $item = $result_playlists[$pls_id2];
  2701. } else {
  2702. if (isset($result_songs[$val])) $item = $result_songs[$val];
  2703. }
  2704. }
  2705. return $results;
  2706. }
  2707. function zina_content_playlist_db(&$zina, $path, $pls_id, $id = null) {
  2708. global $zc;
  2709. if (empty($pls_id)) return zina_content_playlists_db($zina, $id);
  2710. if ($pls_id == 'zina_session_playlist') {
  2711. if (!$zc['session_pls']) {
  2712. zina_set_message(zt('Access denied'), 'warn');
  2713. return zina_content_playlists_db($zina);
  2714. }
  2715. $reorder_access = true;
  2716. $edit_access = false;
  2717. $delete_access = true;
  2718. $results = zina_get_session_playlist();
  2719. $page['title'] = zt('Session');
  2720. $page['user_id'] = $zc['user_id'];
  2721. $page['type'] = 'playlist';
  2722. $page['image_type'] = 0;
  2723. $page['date_created'] = time();
  2724. $page['title'] = $title = zt('Session Playlist');
  2725. $page['image'] = zina_content_search_image($page, 'sub', 'genre-image');
  2726. $page['addthis'] = false;
  2727. } else {
  2728. $page = zina_playlist_get_info($pls_id);
  2729. if (!$page) {
  2730. zina_set_message(zt('Playlist not found'), 'warn');
  2731. return zina_content_playlists_db($zina);
  2732. }
  2733. zdb_log_stat_playlist($pls_id, 'views');
  2734. $user_rating = 0;
  2735. if ($zc['pls_ratings']) {
  2736. $page['pls_ratings'] = true;
  2737. $user_ratings = zdbq_assoc('playlist_id',"SELECT playlist_id, stat ".
  2738. "FROM {playlists_stats} ".
  2739. "WHERE playlist_id = %d AND user_id = %d AND stat_type = 3", array($pls_id, $zc['user_id']));
  2740. if (isset($user_ratings[$pls_id])) $user_rating = $user_ratings[$pls_id]['stat'];
  2741. }
  2742. $page['pls_rate_output'] = ztheme('vote', zurl('','l=68&pl='.$pls_id).'&n=', $user_rating);
  2743. # PLAYLIST VIEW PAGE
  2744. $page['type'] = 'playlist';
  2745. if (!empty($page['path'])) $page['image_path'] = $page['path'];
  2746. $page['description'] = zina_url_filter(nl2br($page['description']));
  2747. $page['addthis'] = $zina['addthis'];
  2748. $page['addthis_id'] = $zina['addthis_id'];
  2749. $page['addthis_options'] = $zina['addthis_options'];
  2750. $page['addthis_path'] = null;
  2751. $page['addthis_query'] = 'l=2&amp;pl='.$pls_id;
  2752. $page['site_name'] = $zina['site_name'];
  2753. #TODO:XXX playlist image size???
  2754. $page['image'] = zina_content_search_image($page, 'sub', 'genre-image');
  2755. if ($zc['genres'] && !empty($page['genre'])) {
  2756. $zina['dir_genre'] = zl($page['genre'],$path,'l=13&amp;pl='.rawurlencode($page['genre']));
  2757. }
  2758. $reorder_access = $edit_access = $delete_access = zina_cms_access('edit_playlists', $page['user_id']);
  2759. $results = zina_playlist_get_items($pls_id);
  2760. $title = zt('@title Playlist', array('@title'=>$page['title']));
  2761. }
  2762. $zina['title'] = $title;
  2763. $page['count'] = sizeof($results);
  2764. if ($page['count'] > 0) {
  2765. zina_set_js('file', 'extras/jquery.js');
  2766. zina_set_js('file', 'extras/drupal.js');
  2767. $opts['checkbox'] = $opts['submit'] = ($edit_access || $reorder_access);
  2768. zina_content_search_list($results, $opts['checkbox']);
  2769. if ($opts['checkbox']) {
  2770. foreach($results as $key => $val) {
  2771. $item = &$results[$key];
  2772. if ($val['type'] == 'song') {
  2773. $item['checkbox'] = array('name'=>'mp3s[]', 'value'=>zrawurlencode($val['type_id']), 'checked'=>true);
  2774. } elseif ($val['type'] == 'playlist') {
  2775. $item['checkbox'] = array('name'=>'mp3s[]', 'value'=>zrawurlencode($val['type_id']).'.pls', 'checked'=>true);
  2776. } else {
  2777. $item['checkbox'] = array('name'=>'mp3s[]', 'value'=>zrawurlencode($val['type_id']).'/.lp', 'checked'=>true);
  2778. }
  2779. }
  2780. }
  2781. if ($zc['rss'] && $zc['database'] && $pls_id != 'zina_session_playlist') {
  2782. if ($zc['clean_urls']) {
  2783. $page['podcast']['url'] = $pls_id.'/pls.xml';
  2784. $page['podcast']['query'] = null;;
  2785. } else {
  2786. $page['podcast']['url'] = null;
  2787. $page['podcast']['query'] = 'l=70&amp;pl='.$pls_id;
  2788. }
  2789. $page['podcast']['type'] = ($zc['rss_podcast']) ? 'podcast' : 'rss';
  2790. zina_set_html_head('<link rel="alternate" type="application/rss+xml" title="'.zt('!title Podcast', array('!title'=>$zina['title'])).'" href="'.zurl($page['podcast']['url'], $page['podcast']['query']).'"/>');
  2791. }
  2792. $list = ztheme('playlist_list', $results, $zc['search_images'], $opts['checkbox']);
  2793. } else {
  2794. $list = zt('This playlist is empty.');
  2795. $opts['submit'] = $opts['checkbox'] = false;
  2796. }
  2797. $plopts['user']['play'] = ($zc['play']) ? array('path'=>null, 'query'=>'l=8&amp;m=3&amp;pl='.$pls_id, 'attr'=>'class="zinamp"') : false;
  2798. if ($zc['play'] && $zc['play_rec_rand'])
  2799. $plopts['user']['play_rec_rand'] = ($zc['play']) ? array('path'=>null, 'query'=>'l=8&amp;m=3&amp;pl='.$pls_id.'&amp;rand', 'attr'=>'class="zinamp"') : false;
  2800. $plopts['admin']['edit'] = $plopts['admin']['delete'] = false;
  2801. $user = zina_cms_user($page['user_id']);
  2802. if ($user) {
  2803. if ($user['profile_url']) $page['profile_url'] = $user['profile_url'];
  2804. $page['username'] = $user['name'];
  2805. }
  2806. if ($edit_access) $plopts['admin']['edit'] = array('path'=>null, 'query'=>'l=44&amp;pl='.$pls_id);
  2807. if ($delete_access) $plopts['admin']['delete'] = array('path'=>null, 'query'=>'l=43&amp;pl='.$pls_id);
  2808. $form_id = 'zinaplaylistform';
  2809. $form_attr = 'id="'.$form_id.'" action="'.zurl($path, 'l=41').'"';
  2810. $list .= '<input type="hidden" name="playlist" value="'.$pls_id.'"/>';
  2811. $list_opts = ztheme('playlist_list_opts', $opts, $form_id);
  2812. $zina['content'] = ztheme('playlists_section', $page, $form_attr, $list, $list_opts, $plopts);
  2813. }
  2814. # NON DB
  2815. function zina_content_playlists_view(&$zina) {
  2816. global $zc;
  2817. $zina['title'] = zt('Playlists');
  2818. $playlists = zina_get_playlists_custom();
  2819. if ($zc['session_pls']) {
  2820. if (empty($playlists)) {
  2821. $playlists[] = 'zina_session_playlist';
  2822. } else {
  2823. array_unshift($playlists, 'zina_session_playlist');
  2824. }
  2825. }
  2826. if (!empty($playlists)) {
  2827. foreach($playlists as $playlist) {
  2828. $item = null;
  2829. $pl = rawurlencode($playlist);
  2830. if ($zc['play']) {
  2831. $item['opts']['play'] = array('path'=>null, 'query'=>'l=8&amp;m=3&amp;pl='.$pl);
  2832. }
  2833. $item['opts']['more'] = array('path'=>null, 'query'=>'l=2&amp;pl='.$pl);
  2834. if ($zc['is_admin'] && $zc['cache'] && $playlist != 'zina_session_playlist') {
  2835. $item['opts']['rename'] = array('path'=>null, 'query'=>'l=44&amp;pl='.$pl);
  2836. }
  2837. if ($zc['is_admin'] || ($zc['session_pls'] && $playlist == 'zina_session_playlist')) {
  2838. $item['opts']['delete'] = array('path'=>null, 'query'=>'l=43&amp;pl='.$pl);
  2839. }
  2840. $item['image_link'] = $item['title_link'] = array('path' => null, 'query' => 'l=2&amp;pl='.$pl);
  2841. $item['title'] = ($zc['session_pls'] && $playlist == 'zina_session_playlist') ? zt('Session Playlist') : htmlentities($playlist);
  2842. $items[] = $item;
  2843. }
  2844. $zina['content'] = ztheme('playlists_list',$items, $zina);
  2845. } else {
  2846. zina_set_message(zt('Sorry, there are no playlists'));
  2847. $zina['content'] = '';
  2848. }
  2849. }
  2850. function zina_content_playlists(&$zina, $path, $playlist) {
  2851. global $zc;
  2852. if ($zc['session_pls'] && $playlist == 'zina_session_playlist') {
  2853. $sp = true;
  2854. } else {
  2855. $sp = false;
  2856. $filename = $zc['cache_pls_dir'].'/_zina_'.$playlist.'.m3u';
  2857. $edit = (!empty($playlist) && file_exists($filename));
  2858. }
  2859. if ($sp || $edit) { # Edit Playlist
  2860. if ($sp) {
  2861. $songs = (isset($_SESSION['z_sp'])) ? unserialize_utf8($_SESSION['z_sp']) : array();
  2862. $title = zt('Session Playlist');
  2863. } else {
  2864. $title = zt('@title Playlist', array('@title'=>$playlist));
  2865. $songs = zunserialize_alt(file_get_contents($filename));
  2866. }
  2867. $zina['title'] = $title;
  2868. $count = sizeof($songs);
  2869. if ($count > 0) {
  2870. $download = $zc['download'];
  2871. #todo: similar loop with search...combine?
  2872. foreach($songs as $song) {
  2873. $play = $zc['play'];
  2874. $rem_title = false;
  2875. $item = array();
  2876. $arr = explode('/', $song);
  2877. $num = sizeof($arr);
  2878. $item['checkbox'] = array('name'=>'mp3s[]', 'value'=>zrawurlencode($song), 'checked'=>true);
  2879. $type = (preg_match('/\.('.$zc['ext_mus'].')$/i', $song) || ($zc['remote'] && preg_match('/\.('.$zc['remote_ext'].')$/i', $song))) ? 's' : 'a';
  2880. if ($type == 's') {
  2881. if ($zc['remote'] && preg_match('/\.('.$zc['remote_ext'].')$/i', $song, $matches)) {
  2882. $rem = new remoteFile($zc['mp3_dir'].'/'.$song, false, true);
  2883. if ($play && isset($rem->url)) {
  2884. $item['opts']['play'] = array('path'=>$song, 'query'=>'l=8&amp;m=1');
  2885. if (isset($rem->title)) $rem_title = $rem->title;
  2886. } else {
  2887. $play = false;
  2888. }
  2889. if ($zc['download'] && isset($rem->download)) {
  2890. $item['opts']['download'] = array('path'=>$song, 'query'=>'l=12');
  2891. }
  2892. } else {
  2893. if ($play) {
  2894. $item['opts']['play'] = array('path'=>$song, 'query'=>'l=8&amp;m=1');
  2895. }
  2896. if ($download) {
  2897. $item['opts']['download'] = array('path'=>$song, 'query'=>'l=12');
  2898. }
  2899. }
  2900. } else {
  2901. zina_content_subdir_opts($item, preg_replace('/\/\.lp$/i','',$song), false, NULL);
  2902. }
  2903. $item['title'] = zina_content_pathlinks($song, $type, $play, $rem_title);
  2904. $items[] = $item;
  2905. }
  2906. zina_set_js('file', 'extras/jquery.js');
  2907. zina_set_js('file', 'extras/drupal.js');
  2908. $list = ztheme('playlists_list',$items, $zina, true);
  2909. $opts['checkbox'] = $opts['submit'] = (($zc['is_admin'] && $zc['cache']) || ($zc['session_pls'] && $playlist == 'zina_session_playlist'));
  2910. } else {
  2911. $list = zt('This playlist is empty.');
  2912. $opts['submit'] = $opts['checkbox'] = false;
  2913. }
  2914. $pl = rawurlencode($playlist);
  2915. $plopts['edit'] = $plopts['delete'] = false;
  2916. $plopts['play'] = ($zc['play']) ? array('path'=>null, 'query'=>'l=8&amp;m=3&amp;pl='.$pl) : false;
  2917. if ($zc['is_admin'] && $zc['cache'] && $playlist != 'zina_session_playlist') {
  2918. $plopts['rename'] = array('path'=>null, 'query'=>'l=44&amp;pl='.$pl);
  2919. }
  2920. if ($zc['is_admin'] || ($zc['session_pls'] && $playlist == 'zina_session_playlist')) {
  2921. $plopts['delete'] = array('path'=>null, 'query'=>'l=43&amp;pl='.$pl);
  2922. }
  2923. $form_id = 'zinaplaylistform';
  2924. $form_attr = 'id="'.$form_id.'" action="'.zurl($path, 'l=41').'"';
  2925. $list .= '<input type="hidden" name="playlist" value="'.$playlist.'"/>';
  2926. $list_opts = ztheme('playlist_list_opts', $opts, $form_id);
  2927. $zina['content'] = ztheme('playlists_section',array('title'=>$title, 'count'=>$count),$form_attr,$list,$list_opts, $plopts);
  2928. } else { # View Playlists
  2929. zina_content_playlists_view($zina);
  2930. }
  2931. }
  2932. function zina_content_blurb(&$zina, $path, $opts) {
  2933. global $zc;
  2934. $alt_title = $hidden = $text = '';
  2935. $set_title = $seed = false;
  2936. $rows = array();
  2937. $type = $opts['type'];
  2938. $return = (isset($opts['return']));
  2939. $label = -1;
  2940. $url = (isset($_SERVER['HTTP_REFERER'])) ? parse_url($_SERVER['HTTP_REFERER']) : false;
  2941. $help = true;
  2942. switch($type) {
  2943. Case 1 : #DIR
  2944. $dir = zina_get_directory($path);
  2945. $title = $dir['title'];
  2946. $file = $zc['dir_file'];
  2947. if (empty($path)) {
  2948. $display_path = $zc['main_dir_title'];
  2949. } else {
  2950. $display_path = $path;
  2951. $alt_title = $title;
  2952. $seed = true;
  2953. }
  2954. if ($zc['database']) {
  2955. #TODO: make empty path be treated like a normal dir...
  2956. if (empty($path)) {
  2957. $text = utf8_decode(zdbq_single("SELECT description FROM {dirs} WHERE path = '.'"));
  2958. } else {
  2959. $text = utf8_decode(zdbq_single("SELECT description FROM {dirs} WHERE path = '%s'", $path));
  2960. }
  2961. }
  2962. $text_file = $zc['cur_dir'].'/'.$file;
  2963. break;
  2964. Case 2 : #ALT
  2965. $seed = true;
  2966. $dir = zina_get_directory($path);
  2967. $alt_title = $title = $dir['title'];
  2968. $lang = zina_get_settings('lang');
  2969. $titles = &$lang['titles'];
  2970. $subs = &$lang['subs'];
  2971. if ($zc['database']) {
  2972. $other = zdb_get_others($path);
  2973. if (isset($other['alt_items']) && !empty($other['alt_items'])) $text = $other['alt_items'];
  2974. }
  2975. if (empty($text)) {
  2976. $file = $zc['alt_file'];
  2977. $text_file = $zc['cur_dir'].'/'.$file;
  2978. $text = (file_exists($text_file)) ? zunserialize_alt(file_get_contents($text_file)) : array();
  2979. }
  2980. $rows[] = array('label'=>-1,'item'=>$subs['alt_dirs']);
  2981. $label = $title = $titles['alt_dirs'];
  2982. $dirs = zina_core_cache('dirs');
  2983. if (!empty($dirs)) {
  2984. $row = '<select size="10" multiple name="mp3s[]">';
  2985. foreach($dirs as $d) {
  2986. $selected = (in_array($d, $text)) ? ' selected="selected"' : '';
  2987. $val = (empty($d)) ? $zc['main_dir_title'] : htmlentities($d);
  2988. $row .= '<option value="'.zrawurlencode($d).'"'.$selected.'>'.$val.'</option>';
  2989. }
  2990. $row .= '</select>';
  2991. $rows[] = array('label'=>$label,'item'=>$row);
  2992. }
  2993. break;
  2994. Case 4 : #MM
  2995. $title = preg_replace('/\.('.$zc['mm_ext'].')$/i', '', basename($path));
  2996. $file = $path.'.txt';
  2997. $text_file = $zc['mp3_dir'].'/'.$file;
  2998. $dir = zina_get_directory(dirname($path));
  2999. $display_path = dirname($path);
  3000. $alt_title = $dir['title'];
  3001. $seed = true;
  3002. $set_title = true;
  3003. break;
  3004. Case 5 : #PODCAST
  3005. $label = zt('Podcast');
  3006. $dir = zina_get_directory($path);
  3007. $alt_title = $title = $dir['title'];
  3008. $seed = true;
  3009. $help = false;
  3010. if ($zc['database']) {
  3011. $other = zdb_get_others($path);
  3012. if (isset($other['rss']) && !empty($other['rss'])) $text = utf8_decode($other['rss']);
  3013. }
  3014. if (empty($text)) {
  3015. $file = $zc['rss_file'];
  3016. $text_file = $zc['cur_dir'].'/'.$file;
  3017. if (!file_exists($text_file)) {
  3018. $text = zina_content_rss($path);
  3019. $text = utf8_decode($text);
  3020. }
  3021. }
  3022. break;
  3023. Case 6 : # GENRE DESC
  3024. $term = $_GET['pl'];
  3025. $text_file = $zc['cache_dir_private_abs'].'/genre_desc_'.rawurlencode($term).'.txt';
  3026. if (!zfile_check_location($zc['cache_dir_private_abs'], $text_file)) $text_file = false;
  3027. $display_path = $title = htmlentities($term);
  3028. $text = zdbq_single("SELECT description FROM {genres} WHERE genre = '%s'", array($term));
  3029. $hidden = ztheme('form_hidden','playlist',$term);
  3030. break;
  3031. Case 3: # songs
  3032. Default: # SONG EXTRAS
  3033. if ($type == 3 || ($zc['song_extras'] && in_array($type, $zc['song_es_exts']))) {
  3034. if ($type != 3) {
  3035. $label = $zc['song_es'][$type]['name'];
  3036. $url['path'] = $path;
  3037. }
  3038. if ($zc['database']) {
  3039. $result = zdbq_array_single("SELECT description, other, id3_info FROM {files} WHERE path = '%s' AND file = '%s'", dirname($path), basename($path));
  3040. if (!empty($result)) {
  3041. if ($type == 3) {
  3042. $text = utf8_decode($result['description']);
  3043. } else {
  3044. $other = unserialize_utf8($result['other']);
  3045. if (isset($other[$type])) $text = $other[$type];
  3046. }
  3047. $mp3 = unserialize_utf8($result['id3_info']);
  3048. if (isset($mp3->title)) $title = ztheme('song_title', $mp3->title, true);
  3049. if ($type == 'lyr' && empty($text) && isset($mp3->lyrics) && !empty($mp3->lyrics)) {
  3050. $text = $mp3->lyrics;
  3051. }
  3052. }
  3053. } elseif ($type == 'lyr') {
  3054. $mp3 = zina_get_file_info($zc['mp3_dir'].'/'.$path);
  3055. if (isset($mp3->lyrics) && !empty($mp3->lyrics)) $text = $mp3->lyrics;
  3056. }
  3057. $id3 = $zc['mp3_id3'];
  3058. if (empty($text)) {
  3059. if ($zc['remote'] && preg_match('/\.('.$zc['remote_ext'].')$/i', $path)) {
  3060. $ext = $zc['remote_ext'];
  3061. $id3 = true;
  3062. } elseif ($zc['fake'] && preg_match('/\.('.$zc['fake_ext'].')$/i', $path)) {
  3063. $ext = $zc['fake_ext'];
  3064. } else {
  3065. $ext = $zc['ext_mus'];
  3066. }
  3067. $file_ext = ($type == 3) ? 'txt' : $type;
  3068. $file = preg_replace('/\.('.$ext.')$/i', '.'.$file_ext, $path);
  3069. $text_file = $zc['mp3_dir'].'/'.$file;
  3070. }
  3071. if (empty($title)) {
  3072. $title = zina_content_song_title($zc['mp3_dir'].'/'.$path, $id3);
  3073. }
  3074. $dir = zina_get_directory(dirname($path));
  3075. $display_path = dirname($path);
  3076. $alt_title = $dir['title'];
  3077. $seed = true;
  3078. $set_title = true;
  3079. } else {
  3080. return zina_not_found();
  3081. }
  3082. break;
  3083. }
  3084. if (!isset($display_path)) $display_path = preg_replace('/\.('.$zc['ext_mus'].')$/i', '', $path);
  3085. zina_content_breadcrumb($zina, $display_path, $alt_title, $seed);
  3086. if ($set_title) {
  3087. $zina['title'] = ztheme('page_title', array($zina['title'], $title));
  3088. }
  3089. $ajax_url = false;
  3090. if ($type == 2) {
  3091. } else {
  3092. if (empty($text)) $text = (file_exists($text_file)) ? utf8_decode(file_get_contents($text_file)) : '';
  3093. if ($return) return array('output'=>$text, 'title'=>$title);
  3094. $id = '';
  3095. if (empty($text) && isset($zc['third_'.$type]) && $zc['third_'.$type]) {
  3096. $ajax_url = zurl($path, 'l=57&m='.$type);
  3097. zina_set_js('file', 'extras/jquery.js');
  3098. $id = ' id="zina-'.$type.'"';
  3099. if (!$zc['third_'.$type.'_save']) {
  3100. zina_set_message(zt('If lyrics are present, they have not been saved.'));
  3101. }
  3102. }
  3103. $rows[] = array(
  3104. 'label'=>$label,
  3105. 'item'=>'<textarea name="mp3s" cols="70" rows="20" wrap="virtual"'.$id.'>'.htmlentities($text).'</textarea>',
  3106. 'help'=> ($help) ? zt('HTML tags allowed: @tags', array('@tags' => $zc['cms_tags'])) : false,
  3107. );
  3108. }
  3109. $space = ($label == -1) ? -1 : null;
  3110. $rows[] = array('label'=>$space,'item'=>'<input type="submit" value="'.zt('Submit').'"/>');
  3111. $form = array(
  3112. 'title'=>$title,
  3113. 'attr'=>'action="'.zurl($path, 'l=23&amp;m='.$type).'"',
  3114. 'hidden'=>$hidden,
  3115. 'rows'=>$rows
  3116. );
  3117. $zina['content'] = ztheme('blurb',$form, $type, $ajax_url);
  3118. }
  3119. function zina_save_blurb($path, $m, $songs, $playlist = null, $goto = true) {
  3120. global $zc;
  3121. $success = false;
  3122. $cache_path = $path;
  3123. $query = null;
  3124. $check_loc = $zc['mp3_dir'];
  3125. if ($m == 1) { # DIR
  3126. $cd = $zc['cur_dir'];
  3127. $file = $zc['dir_file'];
  3128. $songs = zina_filter_html($songs, $zc['cms_tags']);
  3129. if ($zc['database']) {
  3130. zdb_log_stat('insertonly', $path);
  3131. if (empty($path)) {
  3132. $success = zdbq("UPDATE {dirs} SET description = '%s' WHERE path = '.' AND parent_id = 0", array($songs));
  3133. } else {
  3134. $success = zdbq("UPDATE {dirs} SET description = '%s' WHERE path = '%s'", array($songs, $path));
  3135. }
  3136. }
  3137. } elseif ($m == 2) { # ALT
  3138. $cd = $zc['cur_dir'];
  3139. $file = $zc['alt_file'];
  3140. $mp3s = array();
  3141. foreach($songs as $song) {
  3142. $fp = $zc['mp3_dir'].'/'.zrawurldecode($song);
  3143. if (file_exists($fp) && is_dir($fp)) {
  3144. $mp3s[] = zrawurldecode($song);
  3145. } else {
  3146. zina_debug(zt('@file does not exist.',array('@file'=>$fp)),'warn');
  3147. }
  3148. }
  3149. $songs = (!empty($mp3s)) ? serialize($mp3s) : '';
  3150. if ($zc['database']) {
  3151. $result = zdb_update_others(array('alt_items'=>$mp3s), $path);
  3152. }
  3153. } elseif ($m == 3 || $m == 4) { # Song or MM
  3154. $cd = dirname($zc['cur_dir']);
  3155. $filename = basename($path);
  3156. $path = dirname($path);
  3157. if ($path == '.') $path = '';
  3158. $songs = zina_filter_html($songs, $zc['cms_tags']);
  3159. if ($m == 3) {
  3160. if ($zc['remote'] && preg_match('/\.('.$zc['remote_ext'].')$/i', $filename)) {
  3161. $file = preg_replace('/\.('.$zc['remote_ext'].')$/i', '.txt', $filename);
  3162. } elseif ($zc['fake'] && preg_match('/\.('.$zc['fake_ext'].')$/i', $filename)) {
  3163. $file = preg_replace('/\.('.$zc['fake_ext'].')$/i', '.txt', $filename);
  3164. } else {
  3165. $file = preg_replace('/\.('.$zc['ext_mus'].')$/i', '.txt', $filename);
  3166. }
  3167. } else {
  3168. $file = $filename.'.txt';
  3169. }
  3170. if ($zc['database']) {
  3171. zdb_log_stat('insertonly', $path, $filename);
  3172. #$success = zdbq("UPDATE {files} SET description = '%s', mtime = %d WHERE path = '%s' AND file = '%s'", array($songs, time(), $path, $filename));
  3173. $success = zdbq("UPDATE {files} SET description = '%s' WHERE path = '%s' AND file = '%s'", array($songs, $path, $filename));
  3174. }
  3175. } elseif ($m == 5) { # PODCAST
  3176. $cd = $zc['cur_dir'];
  3177. $file = $zc['rss_file'];
  3178. if ($zc['database']) $result = zdb_update_others(array('rss'=>$songs), $path);
  3179. $songs = utf8_encode($songs);
  3180. } elseif ($m == 6) { # GENRE DESC
  3181. $check_loc = $cd = $zc['cache_dir_private_abs'];
  3182. $file = 'genre_desc_'.rawurlencode($playlist).'.txt';
  3183. $songs = zina_filter_html($songs, $zc['cms_tags']);
  3184. if ($zc['database']) {
  3185. zdbq("UPDATE {genres} SET description = '%s' WHERE genre = '%s'", array($songs, $playlist));
  3186. }
  3187. $query = 'l=13&pl='.rawurlencode($playlist);
  3188. } elseif ($zc['song_extras'] && in_array($m, $zc['song_es_exts'])) {
  3189. #TODO: similar to 3 & 4 (see "entry")
  3190. $cd = dirname($zc['cur_dir']);
  3191. $filename = basename($path);
  3192. $path = dirname($path);
  3193. if ($path == '.') $path = '';
  3194. $songs = zina_filter_html($songs, $zc['cms_tags']);
  3195. if ($zc['remote'] && preg_match('/\.('.$zc['remote_ext'].')$/i', $filename)) {
  3196. $file = preg_replace('/\.('.$zc['remote_ext'].')$/i', '.'.$m, $filename);
  3197. } elseif ($zc['fake'] && preg_match('/\.('.$zc['fake_ext'].')$/i', $filename)) {
  3198. $file = preg_replace('/\.('.$zc['fake_ext'].')$/i', '.'.$m, $filename);
  3199. } else {
  3200. $file = preg_replace('/\.('.$zc['ext_mus'].')$/i', '.'.$m, $filename);
  3201. }
  3202. if ($zc['database']) $result = zdb_update_others(array($m=>$songs), $path, $filename);
  3203. } else {
  3204. return zina_not_found();
  3205. }
  3206. $text_file = $cd.'/'.$file;
  3207. if (is_writeable($cd) && zfile_check_location($text_file, $check_loc)) {
  3208. $emptytest = trim($songs);
  3209. if (!empty($emptytest)) {
  3210. if (file_put_contents($text_file, $songs)) {
  3211. if ($goto) zina_set_message(zt('Updated.'));
  3212. $success = true;
  3213. } else {
  3214. zina_set_message(zt('Could not write file.'), 'error');
  3215. }
  3216. } else {
  3217. if (file_exists($text_file)) unlink($text_file);
  3218. }
  3219. } else {
  3220. if (!$zc['database']) {
  3221. zina_set_message(zt('Cannot save. Directory is not writeable.'),'error');
  3222. }
  3223. }
  3224. if ($success && $zc['cache_tmpl']) {
  3225. if (!zina_delete_tmpl_file(zina_get_tmpl_cache_file($cache_path))) {
  3226. zina_set_message(zt('Cannot delete cache file'),'error');
  3227. }
  3228. if ($cache_path != $path) zina_delete_tmpl_file(zina_get_tmpl_cache_file($path));
  3229. }
  3230. if ($goto) {
  3231. zina_goto($path, $query);
  3232. } else {
  3233. return $success;
  3234. }
  3235. }
  3236. function zina_content_directory_opts(&$zina, $path) {
  3237. global $zc;
  3238. $query = 'l=77';
  3239. $lang = zina_get_settings('lang');
  3240. $titles = &$lang['titles'];
  3241. $cats = &$lang['cats'];
  3242. $subs = &$lang['subs'];
  3243. $titles += array(
  3244. 'person' => zt('Person'),
  3245. 'image' => zt('Default Image'),
  3246. 'category' => $cats['categories']['t'],
  3247. 'images' => $titles['cat_images'],
  3248. 'cols' => $titles['cat_cols'],
  3249. 'truncate' => $titles['cat_truncate'],
  3250. 'split' => $titles['cat_split'],
  3251. 'sort' => $titles['cat_sort'],
  3252. 'sort_default' => $titles['cat_sort_default'],
  3253. 'pp' => $titles['cat_pp'],
  3254. );
  3255. $subs['person'] = zt('Assume last name first for sorting');
  3256. $fields = zina_get_settings('directory');
  3257. $dir = zina_get_directory($path);
  3258. $over = true;
  3259. if (empty($path) || $path == '.') {
  3260. $dir['title'] = $zina['lang']['main_dir_title'];
  3261. $over = false;
  3262. }
  3263. $zina['title'] = $dir['title'];
  3264. zina_content_breadcrumb($zina, $path, $zina['title'], $over);
  3265. if (isset($_POST) && !empty($_POST)) { # SAVE SETTINGS
  3266. $settings = array();
  3267. $errors = false;
  3268. $fields['directory_opts']['image'] = array('type'=>'select');
  3269. foreach($fields as $cat => $x) {
  3270. foreach($x as $name => $field) {
  3271. $input = (isset($_POST[$name])) ? $_POST[$name] : null;
  3272. if (isset($field['v'])) {
  3273. foreach($field['v'] as $key => $type) {
  3274. $opts = null;
  3275. if (is_array($type)) {
  3276. $opts = $type;
  3277. $type = $key;
  3278. }
  3279. if (!zina_validate($type, $input, $opts)) {
  3280. $errors = true;
  3281. $title = $titles[$name];
  3282. if ($opts) $type = current($opts);
  3283. zina_validate_error_message($type, $title, $input);
  3284. continue 2;
  3285. }
  3286. }
  3287. } elseif ($name == 'image') {
  3288. if (empty($dir['images'])) {
  3289. continue;
  3290. } else {
  3291. if (!in_array($input, $dir['images'])) {
  3292. $errors = true;
  3293. zina_set_message(zt('Unknown image: @image', array('@image'=>$input)), 'error');
  3294. }
  3295. }
  3296. }
  3297. if (is_array($input)) $input = serialize($input);
  3298. $settings[$name] = $input;
  3299. }
  3300. }
  3301. #dir_tags?
  3302. if ($settings['category']) {
  3303. unset($settings['category']);
  3304. $cat_out = '<category>'."\n";
  3305. foreach(array('images', 'cols', 'truncate', 'split', 'sort', 'sort_default', 'pp') as $cat_item) {
  3306. $settings['category'][$cat_item] = $settings[$cat_item];
  3307. $cat_out .= '<'.$cat_item.'>'.$settings[$cat_item].'</'.$cat_item.'>'."\n";
  3308. unset($settings[$cat_item]);
  3309. }
  3310. $cat_out .= '</category>'."\n";
  3311. } else {
  3312. foreach(array('images', 'cols', 'truncate', 'split', 'sort', 'sort_default', 'pp') as $cat_item) {
  3313. unset($settings[$cat_item]);
  3314. }
  3315. }
  3316. if (!$errors && zdb_update_others($settings, $path)) {
  3317. zina_set_message(zt('Directory Options Updated'));
  3318. if ($dir['dir_write']) {
  3319. $var_file = $zc['cur_dir'].'/'.$zc['various_file'];
  3320. if ($settings['various']) {
  3321. touch($var_file);
  3322. } else {
  3323. if (file_exists($var_file)) unlink($var_file);
  3324. }
  3325. $cat_file = $zc['cur_dir'].'/'.$zc['cat_file'];
  3326. if ($settings['category']) {
  3327. file_put_contents($cat_file, $cat_out);
  3328. } else {
  3329. if (file_exists($cat_file)) unlink($cat_file);
  3330. }
  3331. }
  3332. } else {
  3333. zina_set_message(zt('Directory Options Not Updated'), 'error');
  3334. }
  3335. }
  3336. $category = false;
  3337. $other = zdb_get_others($path);
  3338. $other['various'] = ($dir['various'] || (isset($other['various']) && $other['various']));
  3339. if (isset($other['category']) && $other['category']) {
  3340. $category = $other['category'];
  3341. } else {
  3342. $category = zina_is_category($zc['cur_dir']);
  3343. }
  3344. if ($category) {
  3345. $other['category'] = 1;
  3346. foreach($category as $key => $val) {
  3347. $other[$key] = $val;
  3348. }
  3349. }
  3350. if (!empty($dir['images'])) {
  3351. $images = $dir['images'];
  3352. foreach($images as $key => $item) {
  3353. $images[$item] = $item;
  3354. unset($images[$key]);
  3355. }
  3356. $image = (isset($other['image'])) ? $other['image'] : zina_get_dir_item($zc['mp3_dir'].'/'.$path,'/\.('.$zc['ext_graphic'].')$/i');
  3357. $img = ztheme('image', zina_get_image_url($path, $image,'sub'), $image, null, 'class="dir-image"');
  3358. } else {
  3359. $images = array(''=>zt('None'));
  3360. $image = $img = '';
  3361. }
  3362. $fields['directory_opts']['image'] = array('type'=>'select', 'opts'=>$images, 'def'=>$image);
  3363. $subs['image'] = '<div id="directory-image" class="directory-image">'.$img.'</div>';
  3364. $cats['directory_opts']['t'] = zt('Directory Options');
  3365. $cats['directory_opts']['d'] = '';
  3366. $rows = array();
  3367. foreach($fields as $cat => $x) {
  3368. $items = null;
  3369. foreach($x as $name => $field) {
  3370. $value = isset($other[$name]) ? $other[$name] : null;
  3371. $item = zina_content_form_helper($name, $field, $value);
  3372. $row = array('label'=>$titles[$name], 'item'=>$item);
  3373. if (isset($subs[$name])) $row['desc'] = $subs[$name];
  3374. $items[] = $row;
  3375. if (isset($field['break'])) $items[] = array('label'=>-1,'item'=>'<hr/>');
  3376. }
  3377. $item = ztheme('admin_section_header', $cats[$cat]['t'], $cat, $query);
  3378. /*
  3379. $desc = $cats[$cat]['d'];
  3380. if (!empty($desc)) {
  3381. if (is_array($desc)) {
  3382. $output = '';
  3383. foreach ($desc as $d) $output .= '<p>'.$d.'</p>';
  3384. $item .= $output;
  3385. } else {
  3386. $item .= '<em>'.$desc.'</em>';
  3387. }
  3388. }
  3389. */
  3390. $rows[] = array('label'=>-1, 'item'=>$item);
  3391. $rows = array_merge($rows, $items);
  3392. }
  3393. $rows[] = array('label'=>-1, 'item'=>'<input type="submit" value="'.zt('Update').'"/>', 'class'=>'center');
  3394. $lang_while = zt('This could take a while.');
  3395. $lang_sure = zt('Are your sure you want to do this?');
  3396. $funcs = array();
  3397. if ($zc['is_admin']) {
  3398. if ($zc['database']) {
  3399. $funcs['regen'] = array(
  3400. 'title' => zt('Update Database'),
  3401. 'help' => zt('This will re-synchronize or add directory to the database.').' '.zt('Not usually necessary.'),
  3402. 'path'=>$path,
  3403. 'query'=>'l=45'
  3404. );
  3405. }
  3406. if ($dir['dir_write'] && $path != '') {
  3407. $funcs['dir_rename'] = array(
  3408. 'title' => zt('Rename Directory'),
  3409. 'help' => ($zc['dir_tags']) ? zt('This will have no affect if this is an album and ID3 tags are present.') : '',
  3410. 'path'=>$path,
  3411. 'query'=>'l=78');
  3412. }
  3413. }
  3414. if (!empty($funcs)) {
  3415. $output = '<ul class="zina-list">';
  3416. foreach ($funcs as $i) {
  3417. $output .= '<li class="zina-list">'.zl($i['title'], $i['path'], $i['query']);
  3418. if (isset($i['help']) && !empty($i['help'])) $output .= '<br/><small>'.$i['help'].'</small>';
  3419. $output .= '</li>';
  3420. }
  3421. $output .= '</ul>';
  3422. $row1 = array('label'=>-1, 'item'=> ztheme('admin_section_header', zt('Directory Functions'), 'top').'<br/>'.$output);
  3423. array_unshift($rows,$row1);
  3424. }
  3425. $form = array(
  3426. 'attr'=>'action="'.zurl($path, $query).'" id="zina-dir-form"',
  3427. 'rows'=>$rows,
  3428. );
  3429. $zina['content'] = ztheme('config',$form);
  3430. }
  3431. function zina_content_3rd_images($path, $m) {
  3432. global $zc;
  3433. $extra_opts = zina_get_extras_images_opts();
  3434. if (!empty($path) && in_array($m, array_keys($extra_opts))) {
  3435. $source = $extra_opts[$m];
  3436. require_once($zc['zina_dir_abs'].'/extras/extras_images_'.$source.'.php');
  3437. if (isset($_SESSION['zina_extra_images'][$path])) {
  3438. $artist = $_SESSION['zina_extra_images'][$path]['artist'];
  3439. $album = $_SESSION['zina_extra_images'][$path]['album'];
  3440. } else {
  3441. unset($_SESSION['zina_extra_images']);
  3442. $artist = $album = null;
  3443. $dir = zina_get_directory($path);
  3444. if ($dir['files']) {
  3445. $current = current($dir['files']);
  3446. } elseif ($dir['subdirs']) {
  3447. $current = current($dir['subdirs']);
  3448. } else {
  3449. #EMPTY DIRECTORY...
  3450. $dir['subdirs'] = array('title'=>$path);
  3451. $current = array('title'=>$path);
  3452. }
  3453. if (isset($current['info'])) {
  3454. $mp3 = &$current['info'];
  3455. if ($mp3->tag) {
  3456. if (isset($mp3->artist)) $artist = $mp3->artist;
  3457. if (isset($mp3->album)) $album = $mp3->album;
  3458. }
  3459. }
  3460. if ($dir['subdirs']) { # ARTIST
  3461. if (empty($artist)) $artist = $current['title'];
  3462. $album = null;
  3463. } else { # ALBUM
  3464. if (empty($album)) $album = $current['title'];
  3465. if (empty($artist)) {
  3466. $x = explode('/', $path);
  3467. $len = sizeof($x);
  3468. if ($len > 1) {
  3469. $artist = $x[$len - 2];
  3470. } else {
  3471. echo zt('Error');
  3472. exit;
  3473. }
  3474. }
  3475. }
  3476. $_SESSION['zina_extra_images'][$path]['artist'] = $artist;
  3477. $_SESSION['zina_extra_images'][$path]['album'] = $album;
  3478. }
  3479. $result = false;
  3480. if (isset($_SESSION['zina_images_source'][$path][$source]) && !empty($_SESSION['zina_images_source'][$path][$source])) {
  3481. $result = array_pop($_SESSION['zina_images_source'][$path][$source]);
  3482. } elseif (($results = call_user_func('zina_extras_images_'.$source, $artist, $album)) !== false) {
  3483. $num = sizeof($results);
  3484. if ($num == 1) {
  3485. $result = $results[0];
  3486. } elseif ($num > 1) {
  3487. $result = array_pop($results);
  3488. $_SESSION['zina_images_source'][$path][$source] = $results;
  3489. }
  3490. }
  3491. if ($result) {
  3492. $output = '';
  3493. $src = (isset($result['thumbnail_url'])) ? $result['thumbnail_url'] : $result['image_url'];
  3494. $output .= '<img src="'.$src.'" />';
  3495. #TODO: have opt to display artist summaries...elsewhere
  3496. #if (isset($result['summary'])) echo $result['summary'];
  3497. $save_url = zurl($path, 'l=61&amp;img='.rawurlencode($result['image_url']));
  3498. $class = "zina-newimg-".$m;
  3499. $output .= '<div class="'.$class.'"><a href="'.$result['source_url'].'">'.$source.'</a>';
  3500. if (isset($result['size'])) $output .= ' ('.$result['size'].')';
  3501. if (isset($result['thumbnail_url'])) $output .= ' | <a href="'.$result['image_url'].'">'.zt('View Original').'</a>';
  3502. $output .= ' | <a href="'.$save_url.'" onclick="zinaSaveImage(\''.$save_url.'\',\''.$class.'\'); return false;">'.zt('Save this image').'</a></div>';
  3503. echo $output;
  3504. } else {
  3505. if ($zc['debug']) echo $source.': '.zt('Not found: ').$artist.'->'.$album;
  3506. }
  3507. }
  3508. }
  3509. function zina_content_sitemap() {
  3510. global $zc;
  3511. $dirs = zina_core_cache('dirs');
  3512. $items = array();
  3513. $mp3_dir = $zc['mp3_dir'];
  3514. $item['mtime'] = filemtime($mp3_dir);
  3515. $item['url'] = zurl('',NULL,NULL,TRUE);
  3516. $item['priority'] = .8;
  3517. $items[] = $item;
  3518. foreach($dirs as $dir) {
  3519. $path = $mp3_dir.'/'.$dir;
  3520. if (!empty($dir) && file_exists($path) && is_dir($path)) {
  3521. $item = null;
  3522. $item['path'] = $path;
  3523. $item['mtime'] = filemtime($path);
  3524. $item['url'] = zurl($dir,NULL,NULL,TRUE);
  3525. $items[] = $item;
  3526. }
  3527. }
  3528. if ($items) {
  3529. return ztheme('sitemap', $items);
  3530. }
  3531. return false;
  3532. }
  3533. function zina_content_rss($path) {
  3534. global $zc;
  3535. if ($zc['database']) {
  3536. $other = zdb_get_others($path);
  3537. if (isset($other['rss']) && !empty($other['rss'])) {
  3538. return $other['rss'];
  3539. }
  3540. }
  3541. $rss['page_url'] = preg_replace('/&([^a])/','&amp;${1}', zurl($path,NULL,NULL,TRUE));
  3542. $rss['link_url'] = $rss['page_url'].'/'.$zc['rss_file'];
  3543. $direct = preg_match('#^'.$_SERVER['DOCUMENT_ROOT'].'#i', $zc['mp3_dir']);
  3544. $zina = array();
  3545. zina_content_breadcrumb($zina, $path);
  3546. $rss['title'] = $zina['title'];
  3547. $rss['lang_code'] = $zc['lang'];
  3548. $dir = zina_get_directory($path);
  3549. $rss['desc'] = (isset($dir['description'])) ? $dir['description'] : '';
  3550. if (!empty($dir['images'])) {
  3551. $rss['image_url'] = preg_replace('/&([^a])/','&amp;${1}', zina_get_image_url($path, $dir['images'][0], 'sub', true));
  3552. } else {
  3553. $rss['image_url'] = false;
  3554. }
  3555. if (!empty($dir['files'])) {
  3556. #todo: redudancy with zina_stats_feed()
  3557. foreach ($dir['files'] as $key => $item) {
  3558. if ($item['fake']) continue;
  3559. if (!isset($rss['genre']) && isset($item['genre'])) {
  3560. $rss['genre'] = $item['genre'];
  3561. }
  3562. $info = &$item['info'];
  3563. $i = array();
  3564. $i['title'] = $item['title'];
  3565. $i['url'] = preg_replace('/&([^a])/','&amp;${1}',zurl($key,NULL,NULL,TRUE,$direct));
  3566. $i['url_enc'] = utf8_encode(rawurldecode($i['url']));
  3567. $i['artist'] = (isset($info->artist)) ? $info->artist : false;
  3568. $i['album'] = (isset($info->album)) ? $info->album : false;
  3569. $i['duration'] = (isset($info->time)) ? $info->time : false;
  3570. $i['size'] = (isset($info->filesize)) ? $info->filesize : false;
  3571. $i['pub'] = (isset($dir['files'][$key]['mtime'])) ? date('r',$dir['files'][$key]['mtime']) : false;
  3572. $i['type'] = (preg_match('/\.('.$zc['ext_mus'].')$/i', $key, $exts)) ? $zc['media_types'][strtolower($exts[1])]['mime'] : 'audio/mpeg';
  3573. $i['description'] = (!empty($item['description'])) ? preg_replace('/&([^a])/','&amp;${1}',$item['description']) : false;
  3574. if ($dir['various']) {
  3575. if ($i['artist'] && $i['title']) {
  3576. $i['title'] = ztheme('artist_song', $i['title'], $i['artist']);
  3577. }
  3578. }
  3579. $rss['items'][] = $i;
  3580. }
  3581. }
  3582. if ($zc['mm'] && $zc['rss_mm'] && isset($dir['mm']) && !empty($dir['mm'])) {
  3583. foreach ($dir['mm'] as $key => $item) {
  3584. $i = array();
  3585. $i['title'] = $item['title'];
  3586. $i['url'] = preg_replace('/&([^a])/','&amp;${1}',zurl($key,NULL,NULL,TRUE,$direct));
  3587. $i['url_enc'] = utf8_encode(rawurldecode($i['url']));
  3588. $i['size'] = (isset($item['filesize'])) ? $item['filesize'] : false;
  3589. $i['type'] = (preg_match('/\.('.$zc['mm_ext'].')$/i', $key, $exts)) ? $zc['mm_types'][strtolower($exts[1])]['mime'] : 'audio/mpeg';
  3590. $i['description'] = (!empty($item['description'])) ? preg_replace('/&([^a])/','&amp;${1}',$item['description']) : false;
  3591. $rss['items'][] = $i;
  3592. }
  3593. }
  3594. return ztheme('rss', $rss, $zc['rss_podcast']);
  3595. }
  3596. #move to theme?
  3597. function zina_content_edit_images(&$zina, $path) {
  3598. global $zc;
  3599. $dir = zina_get_directory($path);
  3600. $title = $dir['title'];
  3601. #$title = ztheme('title',basename($path));
  3602. zina_content_breadcrumb($zina, $path, $title, true);
  3603. $js = '';
  3604. if (!is_writeable($zc['cur_dir'])) {
  3605. zina_set_message(zt('Directory is not writeable. You cannot save or delete images.'),'warn');
  3606. $dir_write = false;
  3607. } else {
  3608. $dir_write = true;
  3609. $js2 = 'function zinaDeleteImage(url, imgclass){'.
  3610. 'if (confirm("'.zt('Delete this image?').'")){'.
  3611. '$.get(url, function(data){'.
  3612. '$("div."+imgclass).html(data);'.
  3613. '});'.
  3614. '}'.
  3615. '}';
  3616. $js2 .= 'function zinaSaveImage(url, imgclass){'.
  3617. '$.get(url, function(data){'.
  3618. '$("div."+imgclass).html(data);'.
  3619. '});'.
  3620. '}';
  3621. zina_set_js('inline', $js2);
  3622. }
  3623. $dir = zina_get_directory($path);
  3624. $images = array();
  3625. if (isset($dir['images'])) {
  3626. foreach($dir['images'] as $key=>$image) {
  3627. $img = array();
  3628. $source = $zc['cur_dir'].'/'.$image;
  3629. if ($info = getimagesize($source)) {
  3630. #$img['width'] = $info[0];
  3631. #$img['height'] = $info[1];
  3632. }
  3633. $img_path = (!empty($path) ? $path.'/'.$image : $image);
  3634. $img['image_raw'] = $image_raw = ztheme('image', zina_get_image_url($path, $image,'dir'), $image, null, 'class="dir-image"');
  3635. $img['image'] = zl($image_raw, $img_path, 'l=46');
  3636. $class = 'zina-imginfo-'.$key;
  3637. $img['image'] .= '<div class="'.$class.'">'.$info[0].'x'.$info[1];
  3638. if ($dir_write) {
  3639. $img['image'] .= ' | '.zl(zt('Delete'),$img_path,'l=60',NULL,FALSE, ' onclick="zinaDeleteImage(\''.zurl($img_path,'l=60').'\',\''.$class.'\');return false;"');
  3640. }
  3641. $img['image'] .= '</div>';
  3642. $images[] = $img;
  3643. }
  3644. }
  3645. $holder = array();
  3646. $missing_nav = '';
  3647. if ($zc['third_images'] || isset($_SESSION['zina_missing'])) {
  3648. if (isset($_SESSION['zina_missing'])) {
  3649. if (isset($zc['url_query'])) {
  3650. foreach($zc['url_query'] as $query) {
  3651. $parts = explode('=', $query);
  3652. $queries[$parts[0]] = $parts[1];
  3653. }
  3654. }
  3655. $queries['l'] = 58;
  3656. $select = ztheme('images_missing_form', array('action'=>zurl(''), 'queries'=>$queries), $_SESSION['zina_missing'], $path);
  3657. $missing_nav = ztheme('image_missing_nav',$select, array('path'=>$path, 'query'=>'l=63'));
  3658. }
  3659. zina_set_js('file', 'extras/jquery.js');
  3660. $opts = zina_get_extras_images_opts();
  3661. foreach($opts as $key => $val) {
  3662. $js .= '$(".zina-img-ajax-'.$key.'").load("'.zurl($path, 'l=59&m='.$key).'");';
  3663. $holder[] = array('image'=>'<p class="zina-img-ajax-'.$key.'">'.zt('Loading...').'</p>');
  3664. }
  3665. }
  3666. zina_set_js('jquery', $js);
  3667. return ztheme('edit_images_page', $title, $images, $holder, $missing_nav);
  3668. }
  3669. function zina_content_genre_hierarchy() {
  3670. global $zc;
  3671. zina_set_js('file', 'extras/jquery.js');
  3672. zina_set_js('file', 'extras/drupal.js');
  3673. $hierarchy = zdbq_array("SELECT g.*, gt.path, gt.weight FROM {genres} AS g INNER JOIN {genre_tree} AS gt ON g.id = gt.id ".
  3674. "ORDER BY gt.weight");
  3675. if (empty($hierarchy)) {
  3676. zina_set_message(zt('Please generate genre caches'));
  3677. zina_goto('','l-20');
  3678. }
  3679. $next_id = zdbq_single('SELECT MAX(id) FROM {genres}') + 1;
  3680. foreach($hierarchy as $key => $genre) {
  3681. $g = &$hierarchy[$key];
  3682. $g['view_query'] = 'l=13&pl='.rawurlencode($genre['genre']);
  3683. $g['delete_url'] = zurl('','l=52&amp;m='.$genre['id']);
  3684. }
  3685. return ztheme('genre_hierarchy', $hierarchy, $next_id, 'action="'.zurl('', 'l=49').'"', $zc['genres_custom']);
  3686. }
  3687. function zina_content_settings($path) {
  3688. global $zc;
  3689. if ($zc['cache']) {
  3690. if (zina_check_directory($zc['cache_dir_private_abs'],1)) {
  3691. $key_file = $zc['cache_dir_private_abs'].'/sitekey.txt';
  3692. if (!file_exists($key_file)) {
  3693. file_put_contents($key_file, md5(uniqid(mt_rand(), true)) . md5(uniqid(mt_rand(), true)));
  3694. }
  3695. }
  3696. zina_check_directory($zc['cache_dir_public_abs'],1);
  3697. }
  3698. if ($zc['playlists'])
  3699. zina_check_directory($zc['cache_pls_dir'],1);
  3700. if ($zc['cache_tmpl'])
  3701. zina_check_directory($zc['cache_tmpl_dir'],1);
  3702. if ($zc['cmp_sel'])
  3703. zina_check_directory($zc['cache_zip_dir'],1);
  3704. if ($zc['cache_imgs'])
  3705. zina_check_directory($zc['cache_imgs_dir'],1);
  3706. if ($zc['zinamp']) {
  3707. if ($zc['pos']) zina_set_message(zt('The Flash Player and Play on Server are incompatible options.'), 'warn');
  3708. if (!$zc['stream_int']) zina_set_message(zt('The Flash Player must have Internal Streaming set to true.'), 'warn');
  3709. if ($zc['playlist_format'] != 'xspf') zina_set_message(zt('The Flash Player must use the "xspf" Playlist Format.'), 'warn');
  3710. if ($zc['apache_auth']) zina_set_message(zt('Apache Authentication may be incompatible (and unnecessary) with the Flash Player option.'), 'warn');
  3711. }
  3712. $rows = array();
  3713. $query = 'l=20';
  3714. $fields = zina_get_settings('cfg');
  3715. $lang = zina_get_settings('lang');
  3716. $cats = &$lang['cats'];
  3717. $titles = &$lang['titles'];
  3718. $subs = &$lang['subs'];
  3719. # CRON #
  3720. $cron_row = '';
  3721. #todo: aren't we always admin here?
  3722. if ($zc['is_admin']) {
  3723. $cron_row = 'X: <select><option selected="selected">'.zt('FOR REFERENCE ONLY: NOT ALL THESE OPTIONS MAKE SENSE').'</option>';
  3724. foreach($fields as $cat => $x) {
  3725. foreach($x as $name => $field) {
  3726. if (isset($field['opts']) && $field['opts'] == 'zina_get_opt_tf') {
  3727. $cron_row .= '<option>'.$name.' &nbsp; ('.$titles[$name].')</option>';
  3728. }
  3729. }
  3730. }
  3731. $cron_row .= '</select>';
  3732. }
  3733. # END CRON
  3734. $rows[] = array('label'=>-1, 'item'=>'<input type="submit" value="'.zt('Update').'"/>', 'class'=>'center');
  3735. foreach($fields as $cat => $x) {
  3736. $items = null;
  3737. if (($zc['embed'] != 'standalone') && ($cat == 'auth' || $cat == 'integration' ||
  3738. ($cat == 'db' && $zc['db_cms']))) {
  3739. continue;
  3740. }
  3741. foreach($x as $name => $field) {
  3742. if ($name == 'adm_pwd') {
  3743. $pass_fields = array('adm_pwd_old', 'adm_pwd', 'adm_pwd_con');
  3744. foreach($pass_fields as $pf) {
  3745. $item = zina_content_form_helper($pf, $field, $zc[$name]);
  3746. $items[] = array('label'=>$titles[$pf], 'item'=>$item);
  3747. }
  3748. } else {
  3749. $value = $zc[$name];
  3750. if ($name == 'main_dir_title') $value = zt($value);
  3751. $item = zina_content_form_helper($name, $field, $value);
  3752. $row = array('label'=>$titles[$name], 'item'=>$item);
  3753. if (isset($subs[$name])) {
  3754. $row['desc'] = $subs[$name];
  3755. }
  3756. $items[] = $row;
  3757. }
  3758. if (isset($field['break'])) $items[] = array('label'=>-1,'item'=>'<hr/>');
  3759. }
  3760. $nav[] = zl($cats[$cat]['t'],'','l=20',$cat);
  3761. # CAT HEADER
  3762. $item = ztheme('admin_section_header', $cats[$cat]['t'], $cat, $query);
  3763. $desc = $cats[$cat]['d'];
  3764. if (is_array($desc)) {
  3765. $output = '';
  3766. foreach ($desc as $d) {
  3767. $output .= '<p>'.$d.'</p>';
  3768. }
  3769. $item .= $output;
  3770. } else {
  3771. $item .= '<em>'.$desc.'</em>';
  3772. }
  3773. if ($cat == 'cron') {
  3774. $item = str_replace('%CRON_SELECT%', $cron_row, $item);
  3775. }
  3776. $rows[] = array('label'=>-1, 'item'=>$item);
  3777. $rows = array_merge($rows, $items);
  3778. }
  3779. $nav = ztheme('admin_nav', $nav);
  3780. array_unshift($rows,array('label'=>-1,'item'=>$nav));
  3781. $row = ztheme('admin_section_header', zt('Settings Navigation'), 'settings_nav', 'l=20');
  3782. $rows[] = array('label'=>-1, 'item'=>'<input type="submit" value="'.zt('Update').'"/>', 'class'=>'center');
  3783. array_unshift($rows,array('label'=>-1,'item'=>$row));
  3784. $install = false;
  3785. if ($zc['database'] && file_exists($zc['zina_dir_abs'].'/install.php') && !zdbq('SELECT 1 FROM {file_ratings} LIMIT 0')) {
  3786. $funcs['install']['install_db'] = '<h2>'.zl(zt('Install the database'), $path, 'l=18&amp;m=install').'</h2>';
  3787. $install = true;
  3788. }
  3789. $lang_while = zt('This could take a while.');
  3790. $lang_sure = zt('Are your sure you want to do this?');
  3791. if ($zc['database'] && !$install && file_exists($zc['zina_dir_abs'].'/update.php')) {
  3792. require_once($zc['zina_dir_abs'].'/update.php');
  3793. if ($update = zina_updates_check()) {
  3794. $funcs['install']['update_db'] = '<h2>'.zl(zt('Database Update: ').zt($update), $path, 'l=18&amp;m=update').'</h2>';
  3795. }
  3796. }
  3797. if ($zc['genres'] && $zc['database']) $funcs['general']['genre_hierarchy'] = zl(zt('Genres and Hierarchy'),$path,'l=48');
  3798. $funcs['cron']['regen'] = zl(zt('Regenerate Directory/File Caches'),$path,'l=26&amp;m=1',NULL,FALSE,
  3799. " onclick='return(confirm(\"".$lang_while.'\\n\\n'.$lang_sure."\"))'");
  3800. if ($zc['genres']) {
  3801. $funcs['cron']['regen_genres'] = zl(zt('Regenerate Genre Cache'),$path,'l=26&amp;m=2',NULL,FALSE,
  3802. " onclick='return(confirm(\"".$lang_while.'\\n\\n'.$lang_sure."\"))'");
  3803. }
  3804. if ($zc['database']) {
  3805. $db_search_text = ($zc['db_search']) ? ' / '. zt('Update search index') : '';
  3806. $funcs['cron']['populate_db'] = zl(zt('Populate the database with missing entries'),$path,'l=26&amp;m=3',NULL,FALSE,
  3807. " onclick='return(confirm(\"".$lang_while.' '.zt('Especially the first time!').'\\n\\n'.$lang_sure."\"))'");
  3808. $funcs['adv']['repopulate_db'] = zl(zt('Synchronize database to filesystem').$db_search_text,$path,'l=26&amp;m=4',NULL,FALSE,
  3809. " onclick='return(confirm(\"".$lang_while.'\\n\\n'.$lang_sure."\"))'");
  3810. $help['repopulate_db'] = zt('This will re-populate the database with information from the entire filesystem.').' '.
  3811. zt('It should only be necessary after upgrading your database or if files are changed and their timestamps are not modified for some reason.');
  3812. $funcs['adv']['sync_db'] = zl(zt('Clean up database'),$path,'l=27',NULL,FALSE,
  3813. " onclick='return(confirm(\"".$lang_while.'\\n\\n'.$lang_sure."\"))'");
  3814. $help['sync_db'] = zt('This will find entries in the database that no longer exist in the filesystem and give you an opportunity to delete, ignore or update them.');
  3815. if ($zc['cache_stats']) {
  3816. $funcs['cron']['regen_stats'] = zl(zt('Regenerate Statistics'),$path,'l=47',NULL,FALSE,
  3817. " onclick='return(confirm(\"".$lang_while.'\\n\\n'.$lang_sure."\"))'");
  3818. }
  3819. if (is_writeable($zc['mp3_dir'])) {
  3820. $funcs['general']['extract_images'] = zl(zt('Extract ID3 images'),$path,'l=26&m=5',NULL,FALSE,
  3821. " onclick='return(confirm(\"".$lang_while.'\\n\\n'.$lang_sure."\"))'");
  3822. }
  3823. }
  3824. $funcs['general']['find_images'] = zl(zt('Find Missing Images/Artwork'),null,'l=62');
  3825. if ($zc['cache_tmpl']) {
  3826. $funcs['adv']['delete_cache'] = zl(zt('Delete template and statistics cache files'),$path,'l=30',NULL,FALSE,
  3827. " onclick='return(confirm(\"".$lang_sure."\"))'");
  3828. }
  3829. if ($zc['cache_imgs']) {
  3830. $funcs['adv']['delete_imgs_cache'] = zl(zt('Delete cached images files'),$path,'l=31',NULL,FALSE,
  3831. " onclick='return(confirm(\"".$lang_sure."\"))'");
  3832. }
  3833. if ($zc['cmp_cache'] && is_writeable($zc['cache_zip_dir'])) {
  3834. $funcs['adv']['delete_zip_cache'] = zl(zt('Delete cached compressed files'),$path,'l=34',NULL,FALSE,
  3835. " onclick='return(confirm(\"".$lang_sure."\"))'");
  3836. }
  3837. if ($zc['sitemap']) {
  3838. if (file_exists($zc['cache_dir_public_abs'].'/'.$zc['sitemap_file'])) {
  3839. $funcs['cron']['sitemap'] = zl(zt('Sitemap: Delete cached file'), $path, 'l=33');
  3840. } else {
  3841. $funcs['cron']['sitemap'] = zl(zt('Sitemap: View and generate cached file'), $path, 'l=51');
  3842. }
  3843. }
  3844. $funcs['adv']['getlang'] = zl(zt('Get language phrases for translation or modifications'),$path,'l=32');
  3845. if ($zc['database']) {
  3846. $pls = zina_get_playlists_custom();
  3847. if (!empty($pls)) {
  3848. $funcs['adv']['importpls'] = zl(zt('Import Old Format Playlists'),$path,'l=67');
  3849. }
  3850. }
  3851. $funcs['help']['help'] = zl(zt('Help and Support Information'),$path,'l=64');
  3852. if ($zc['lastfm'] && file_exists($zc['cache_dir_private_abs'].'/scrobbler_queue_'.$zc['user_id'].'.txt')) {
  3853. $funcs['general']['lastfm_queue'] = zl(zt('Manually submit last.fm queue'), $path, 'l=19');
  3854. }
  3855. $lang = array(
  3856. 'install' => array(
  3857. 'title' => zt('Install & Updates'),
  3858. 'desc' => zt('These should be run immediately'),
  3859. ),
  3860. 'general' => array(
  3861. 'title' => zt('General'),
  3862. ),
  3863. 'cron' => array(
  3864. 'title' => zt('Cron'),
  3865. 'desc' => zt('All these functions will be run automatically if your CMSes cron functionality is setup, or if the cron.php file in the zina root directly is setup to run regularly (via cron?). If not, you may manually run them here.'),
  3866. ),
  3867. 'adv' => array(
  3868. 'title' => zt('Advanced'),
  3869. 'desc' => zt('These should not be needed very often.'),
  3870. ),
  3871. 'help' => array(
  3872. 'title' => zt('Help and Support'),
  3873. ),
  3874. );
  3875. $output = '<table><tr>';
  3876. $class = 'zina-list';
  3877. $row = 0;
  3878. foreach($lang as $func => $item) {
  3879. if ($row == 0) $output .= '<td width="50%" valign="top" style="padding-right:10px;">';
  3880. if (isset($funcs[$func])) {
  3881. $output .= '<h3 style="font-weight:bold;font-size:1.1em;">'.$item['title'].'</h3>';
  3882. if (isset($item['desc'])) $output .= '<span>'.$item['desc'].'</span>';
  3883. $output .= '<ul class="zina-list">';
  3884. foreach ($funcs[$func] as $key => $i) {
  3885. $output .= '<li class="zina-list">'.$i;
  3886. if (isset($help[$key])) $output .= '<br/><small>'.$help[$key].'</small>';
  3887. $output .= '</li>';
  3888. }
  3889. $output .= '</ul>';
  3890. unset($funcs[$func]);
  3891. }
  3892. $row = ++$row % 3;
  3893. if ($row == 0) $output .= '</td>';
  3894. }
  3895. if ($row != 0) $output .= '</td>';
  3896. $output .= '</tr></table>';
  3897. $row1 = array('label'=>-1, 'item'=> ztheme('admin_section_header', zt('Administrative Functions'), 'top').'<br/>'.$output);
  3898. array_unshift($rows,$row1);
  3899. $form = array(
  3900. 'attr'=>'action="'.zurl($path, 'l=21').'" name="zinaadminform"',
  3901. 'rows'=>$rows,
  3902. );
  3903. return ztheme('config',$form);
  3904. }
  3905. function zina_content_pathlinks($path, $type, $play, $title = false, $id3 = false) {
  3906. global $zc;
  3907. $arr = explode('/', $path);
  3908. $num = sizeof($arr);
  3909. if (sizeof($arr) == 1 && ($arr[0] == '.' || $arr[0] == '/' || $arr[0] == '\\')) {
  3910. return zl(zt($zc['main_dir_title']), '');
  3911. }
  3912. $titles = array();
  3913. $ppath = '';
  3914. for ($i=0; $i < $num; $i++) {
  3915. $part = $arr[$i];
  3916. if ($ppath != '') $ppath = $ppath.'/';
  3917. if (zvalidate_utf8($part)) $part = utf8_decode($part);
  3918. $ppath .= $part;
  3919. if ($i == $num - 1) {
  3920. if ($type == 's') {
  3921. # Sloooowww... (not used)
  3922. if ($id3) {
  3923. $song = $zc['mp3_dir'].'/'.$path;
  3924. $ft = zina_content_song_title($song, true);
  3925. } else {
  3926. if ($title)
  3927. $ft = zina_content_song_title($title);
  3928. else
  3929. $ft = zina_content_song_title($path);
  3930. }
  3931. $titles[] = ($play) ? zl($ft,$ppath,'l=8&amp;m=1', null, false, 'class="zinamp"') : $ft;
  3932. } else {
  3933. if ($part == '.lp') continue;
  3934. $titles[] = zl(ztheme('title',$part),$ppath);
  3935. }
  3936. } else {
  3937. $titles[] = zl(ztheme('title',$part),$ppath);
  3938. }
  3939. }
  3940. return ztheme('search_song_titles', $titles);
  3941. }
  3942. function zina_content_form_helper($name, $field, $setting, $disable = false) {
  3943. $type = $field['type'];
  3944. $foo = false;
  3945. $value = ($field['def'] == $setting) ? $field['def'] : $setting;
  3946. $disabled = ($disable) ? ' disabled="disabled"' : '';
  3947. $disabled = ($disable) ? ' disabled="disabled" class="disabled"' : '';
  3948. $id = (isset($field['id'])) ? ' id="'.$field['id'].'"' : '';
  3949. $i = 0;
  3950. $item = '';
  3951. if ($type == 'textarea') {
  3952. $cols = (isset($field['cols'])) ? $field['cols'] : 50;
  3953. $rows = (isset($field['rows'])) ? $field['rows'] : 8;
  3954. $item = '<textarea name="'.$name.'" cols="'.$cols.'" rows="'.$rows.'"'.$id.'>'.$value.'</textarea>';
  3955. } elseif ($type == 'radio') {
  3956. $opts = (is_array($field['opts'])) ? $field['opts'] : call_user_func($field['opts']);
  3957. foreach($opts as $key=>$val) {
  3958. $checked = '';
  3959. if ($value == $key) $checked = ' checked="checked"';
  3960. $item .= '<input type="radio" name="'.$name.'" value="'.$key.'"'.$checked.$disabled.$id.' /> '.$val.' ';
  3961. }
  3962. } elseif ($type == 'textfield') {
  3963. $size = (isset($field['size'])) ? $field['size'] : 30;
  3964. if(!empty($value)) {
  3965. if (is_array($value)) $value = implode(',',$value);
  3966. $len = strlen($value);
  3967. if (!isset($field['size'])) {
  3968. $len = strlen($value);
  3969. if ($len < 30) $size = $len+2;
  3970. elseif ($len < 60) $size = $len+10;
  3971. else $size = 60;
  3972. } else {
  3973. if ($len > $size) $size = $len+10;
  3974. }
  3975. if (isset($field['max']) && $size > $field['max']) $size = $field['max'];
  3976. }
  3977. $item = '<input type="text" name="'.$name.'" value="'.$value.'" size="'.$size.'"'.$disabled.$id.'/>';
  3978. if (isset($field['suf'])) $item .= ' '.zt($field['suf']);
  3979. } elseif ($type == 'select') {
  3980. $tmp = $value;
  3981. $opts = (is_array($field['opts'])) ? $field['opts'] : call_user_func($field['opts']);
  3982. $item = '<select name="'.$name.'"'.$disabled.$id.'>';
  3983. foreach($opts as $key=>$val) {
  3984. $sel = '';
  3985. if ($value == $key) $sel = ' selected="selected"';
  3986. $item .= '<option value="'.$key.'"'.$sel.'>'.$val.'</option>';
  3987. }
  3988. $item .= '</select>';
  3989. } elseif ($type == 'password_adm') {
  3990. $item = '<input type="password" name="'.$name.'"'.$disabled.' />';
  3991. } elseif ($type == 'password') {
  3992. $item = '<input type="password" name="'.$name.'" value="'.$value.'"'.$disabled.'/>';
  3993. } elseif ($type == 'checkboxes') {
  3994. $opts = (is_array($field['opts'])) ? $field['opts'] : call_user_func($field['opts']);
  3995. foreach($opts as $key=>$val) {
  3996. $checked = '';
  3997. if (in_array($key, $value)) $checked = ' checked="checked"';
  3998. $item .= '<input type="checkbox" name="'.$name.'[]" value="'.$key.'"'.$checked.$disabled.$id.' /> '.$val.' ';
  3999. }
  4000. } elseif ($type == 'hidden') {
  4001. #todo: use ztheme('form_hidden', $name, $value); #also for all other hiddens
  4002. $item .= '<input type="hidden" name="'.$name.'" value="'.$value.'"'.$id.'/>';
  4003. } elseif ($type == 'checkbox') {
  4004. $checked = (!empty($value)) ? ' checked="checked"' : '';
  4005. $onclick = (isset($field['onclick'])) ? " onClick='".$field['onclick']."'" : '';
  4006. $item .= '<input type="checkbox" name="'.$name.'" '.$checked.$disabled.$id.$onclick.' />';
  4007. }
  4008. # only text, radio, password utilize...
  4009. if ($disable) {
  4010. $field['type'] = 'hidden';
  4011. $item .= zina_content_form_helper($name, $field, $setting);
  4012. }
  4013. return $item;
  4014. }
  4015. function zina_content_subdir_opts(&$item, $path, $checkbox, $opts=null) {
  4016. global $zc;
  4017. if ($zc['play']) {
  4018. if (strpos($path, '/') !== false) {
  4019. $item['opts']['play'] = array('path'=>$path, 'query'=>'l=8&amp;m=0');
  4020. } elseif ($zc['play_rec_rand']) {
  4021. $item['opts']['play_rec_rand'] = array('path'=>$path, 'query'=>'l=8&amp;m=10&amp;c');
  4022. }
  4023. }
  4024. if ($zc['low'] && ($zc['resample'] || (isset($opts['lofi']) && !empty($opts['lofi'])))) {
  4025. $item['opts']['play_lofi'] = array('path'=>$path, 'query'=>'l=8&amp;m=0&amp;lf');
  4026. }
  4027. if ($zc['cmp_sel']) {
  4028. if (!(isset($item['type']) && $item['type'] == 'artist')) {
  4029. $item['opts']['download'] = array('path'=>$path.'/.lp', 'query'=>'l=5');
  4030. }
  4031. }
  4032. if ($checkbox) {
  4033. $item['checkbox'] = array('name'=>'mp3s[]', 'value'=>zrawurlencode($path).'/.lp', 'checked'=>false);
  4034. }
  4035. }
  4036. /*
  4037. * $song must be full path
  4038. */
  4039. function zina_content_song_title($song, $id3 = false) {
  4040. global $zc;
  4041. if ($id3) {
  4042. $mp3 = zina_get_file_info($song, false);
  4043. if ($mp3->tag) return ztheme('song_title', $mp3->title, true);
  4044. }
  4045. $ext = ($zc['remote']) ? $zc['ext_mus'].'|'.$zc['remote_ext'] : $zc['ext_mus'];
  4046. $ext = ($zc['fake']) ? $ext.'|'.$zc['fake_ext'] : $ext;
  4047. $song = preg_replace('/\.('.$ext.')$/i', '', basename($song));
  4048. return ztheme('song_title', $song);
  4049. }
  4050. function zina_content_playlist_form($item) {
  4051. global $zc;
  4052. $rows[] = array('label'=>zt('Title'),
  4053. 'item'=>zina_content_form_helper('title', array('type'=>'textfield', 'def'=>'', 'size'=>30, 'v'=>array('req')), htmlentities($item['title'])));
  4054. $rows[] = array('label'=>zt('Description'),
  4055. 'item'=>zina_content_form_helper('description', array('type'=>'textarea', 'def'=>''), htmlentities($item['description'])),
  4056. 'help'=>zt('HTML tags allowed: @tags', array('@tags' => $zc['pls_tags'])));
  4057. if ($zc['genres']) {
  4058. $genres = zdbq_assoc_list("SELECT id, genre FROM {genres} ORDER BY genre");
  4059. if (!empty($genres)) {
  4060. $row = '<select name="genre_id">'.
  4061. '<option value="">'.zt('None').'</option>';
  4062. foreach($genres as $key => $genre) {
  4063. $selected = ($key == $item['genre_id']) ? ' selected="selected"' : '';
  4064. $row .= '<option value="'.$key.'"'.$selected.'>'.htmlentities($genre).'</option>';
  4065. }
  4066. $row .= '</select>';
  4067. $rows[] = array('label'=>zt('Genre'),'item'=>$row);
  4068. }
  4069. }
  4070. #TODO: if art/tit
  4071. $dirs = zdbq_assoc_list("SELECT id, path FROM {dirs} WHERE level = 1 AND path != '.' ORDER by path");
  4072. if (!empty($dirs)) {
  4073. $row = '<select name="dir_id">';
  4074. $row .= '<option value="">'.zt('None').'</option>';
  4075. foreach($dirs as $key=> $dir) {
  4076. $selected = ($key == $item['dir_id']) ? ' selected="selected"' : '';
  4077. $row .= '<option value="'.$key.'"'.$selected.'>'.htmlentities($dir).'</option>';
  4078. }
  4079. $row .= '</select>';
  4080. $rows[] = array('label'=>zt('Arist'),'item'=>$row);
  4081. }
  4082. $row = '<select name="image_type">';
  4083. $types = array(0=>zt('None'), 1=>zt('Artist'));
  4084. if ($zc['genres']) $types[2] = zt('Genre');
  4085. foreach($types as $key=> $type) {
  4086. $selected = ($key == $item['image_type']) ? ' selected="selected"' : '';
  4087. $row .= '<option value="'.$key.'"'.$selected.'>'.$type.'</option>';
  4088. }
  4089. $row .= '</select>';
  4090. $rows[] = array('label'=>zt('Show Image'),'item'=>$row);
  4091. if ($zc['pls_public']) {
  4092. $rows[] = array('label'=>zt('Public'),
  4093. 'item'=>zina_content_form_helper('visible', array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>true), $item['visible']));
  4094. }
  4095. return $rows;
  4096. }
  4097. #TODO: move
  4098. #$type = insert or update
  4099. function zina_playlist_form_submit($type, $pls_id = null) {
  4100. global $zc;
  4101. if ($type == 'update') {
  4102. $user_id = zdbq_single("SELECT user_id FROM {playlists} WHERE id = $pls_id");
  4103. } else {
  4104. $user_id = $zc['user_id'];
  4105. }
  4106. if (!zina_cms_access('edit_playlists', $user_id)) return zina_access_denied();
  4107. $visible = (isset($_POST['visible'])) ? (int)$_POST['visible'] : 1;
  4108. $where = (!$zc['is_admin']) ? ' AND user_id = %d' : '';
  4109. $dir_id = $genre_id = null;
  4110. if (!empty($_POST['dir_id'])) {
  4111. $exists = zdbq_single("SELECT 1 FROM {dirs} WHERE id = %d", array($_POST['dir_id']));
  4112. if ($exists) $dir_id = $_POST['dir_id'];
  4113. }
  4114. if (!empty($_POST['genre_id'])) {
  4115. $exists = zdbq_single("SELECT 1 FROM {genres} WHERE id = %d", array($_POST['genre_id']));
  4116. if ($exists) $genre_id = $_POST['genre_id'];
  4117. }
  4118. $image_type = (in_array($_POST['image_type'], array(0,1,2))) ? $_POST['image_type'] : 0;
  4119. $title = strip_tags($_POST['title']);
  4120. $desc = strip_tags($_POST['description'], $zc['pls_tags']);
  4121. $time = time();
  4122. if ($type == 'update') {
  4123. if (zdbq("UPDATE {playlists} SET title = '%s', description = '%s', dir_id = %d, genre_id = %d, image_type = %d, visible = %d, mtime = %d ".
  4124. "WHERE id = %d $where",
  4125. array($title, $desc, $dir_id, $genre_id, $image_type, $visible, $time, $pls_id, $zc['user_id']))) {
  4126. return true;
  4127. }
  4128. } else {
  4129. if (zdbq("INSERT {playlists} (title, description, user_id, date_created, visible, mtime, dir_id, genre_id, image_type) ".
  4130. "VALUES ('%s', '%s', %d, %d, %d, %d, %d, %d, %d)",
  4131. array($title, $desc, $zc['user_id'], $time, $visible, $time, $dir_id, $genre_id, $image_type))) {
  4132. return zdb_last_insert_id('playlists', 'id');
  4133. }
  4134. }
  4135. zina_set_message(zt('Cannot @type playlist.', array('@type'=>$type)), 'warn');
  4136. return false;
  4137. }
  4138. function zina_content_playlist_form_opts($form, $playlist_sel='', $type='l a x p r q v') {
  4139. global $zc;
  4140. $options = array_flip(explode(' ', $type));
  4141. $sess = (isset($_SESSION['z_sp']) && strlen($_SESSION['z_sp']) > 0) ? 1 : 0;
  4142. $lang_no = zt('No playlist selected.');
  4143. $opts_url = array(
  4144. 'd' => "javascript:selectCheck('$form','".zurl(null,'l=43')."', '".zt('Nothing to delete.')."', $sess, 'view');",
  4145. 'a' => "javascript:selectCheckAjax('".zurl(null,'l=40')."', '$form', 'zina_messages', '".zt('Nothing to add to playlist.')."');",
  4146. 'v' => "javascript:selectCheck('$form','".zurl(null,'l=2')."','".zt('Nothing to view.')."', $sess, 'view');",
  4147. 'p' => "javascript:selectCheck('$form','".zurl(null,'l=8&amp;m=3')."','".$lang_no."', $sess, 'play');",
  4148. 'r' => "javascript:selectCheck('$form','".zurl(null,'l=8&amp;m=3&amp;rand')."','".$lang_no."', $sess, 'play');",
  4149. 'q' => "javascript:selectCheck('$form','".zurl(null,'l=8&amp;m=3&amp;lf')."','".$lang_no."', $sess, 'play');",
  4150. 'l' => 'l=2'
  4151. );
  4152. if (!$zc['play']) unset($options['p']);
  4153. if (!$zc['low']) unset($options['q']);
  4154. if (!$zc['database']) unset($options['r']);
  4155. if ($zc['database']) {
  4156. unset($options['d']); # let them do it through playlist interface
  4157. $playlists = array();
  4158. $access = false;
  4159. if (zina_cms_access('edit_playlists', $zc['user_id'])) {
  4160. $playlists = zdbq_array("SELECT id, title FROM {playlists} WHERE user_id = %d ORDER BY title", array($zc['user_id']));
  4161. $access = true;
  4162. }
  4163. $display = ($zc['is_admin'] || $zc['session_pls'] || $zc['pls_user'] || !empty($playlists));
  4164. if (!$zc['is_admin'] && !$zc['session_pls'] && !$zc['pls_user']) unset($options['a']);
  4165. $options = array_flip($options);
  4166. $new = ($access && strstr($type,'a'));
  4167. } else {
  4168. $playlists = zina_get_playlists_custom();
  4169. $display = (!$zc['is_admin'] && (empty($playlists) && !$zc['session_pls'])) ? false : true;
  4170. if (!$zc['is_admin'] || !$zc['cache']) {
  4171. unset($options['d']);
  4172. if (!$zc['session_pls']) unset($options['a']);
  4173. }
  4174. $options = array_flip($options);
  4175. $new = ($zc['is_admin'] && strstr($type,'a') && $zc['cache']);
  4176. }
  4177. $pl = ztheme('playlist_form_select', 'playlist', $playlists, $playlist_sel, $new, $zc['session_pls'], $zc['database']);
  4178. return ztheme('playlist_form_elements', $display, $form, $options, $opts_url, $pl);
  4179. }
  4180. function zina_content_song_list_opts($custom_pls, $lofi, $check_boxes, $form, $search = false) {
  4181. global $zc;
  4182. $items = array();
  4183. if (!$search && $zc['is_admin'] && $zc['cache']) {
  4184. $items['submit']['js'] = 'SubmitForm(\''.$form.'\',\'?l=42\', \'add\');';
  4185. $items['submit']['exists'] = $custom_pls;
  4186. }
  4187. if ($check_boxes) {
  4188. $items['checkboxes'] = true;
  4189. $err = zt('At least one song must be selected.');
  4190. if ($zc['play_sel'] || $zc['cmp_sel']) {
  4191. if ($zc['play'] && $zc['play_sel']) {
  4192. $items['opts']['play'] = array('path'=>'javascript:CheckIt(\''.$form.'\',\''.zurl('','l=8&amp;m=7').'\',\''.$err.'\',\'play\');',
  4193. 'query'=>null, 'attr'=>null);
  4194. }
  4195. if ($zc['play'] && $zc['play_rec_rand']) {
  4196. $items['opts']['play_rec_rand'] = array('path'=>'javascript:CheckIt(\''.$form.'\',\''.zurl('','l=8&amp;m=8').'\',\''.$err.'\',\'play\');',
  4197. 'query'=>null, 'attr'=>null);
  4198. }
  4199. if ($lofi) {
  4200. $items['opts']['play_lofi'] = array('path'=>'javascript:CheckIt(\''.$form.'\',\''.zurl('','l=8&amp;m=7&amp;lf').'\',\''.$err.'\',\'play\');',
  4201. 'query'=>null, 'attr'=>null);
  4202. }
  4203. if ($zc['cmp_sel']) {
  4204. $items['opts']['download'] = array('path'=>'javascript:CheckIt(\''.$form.'\',\''.zurl('','l=3').'\',\''.$err.'\',\'download\');',
  4205. 'query'=>null, 'attr'=>null);
  4206. }
  4207. }
  4208. }
  4209. $items['playlist_form_elements'] = zina_content_playlist_form_opts($form);
  4210. return $items;
  4211. }
  4212. #TODO: ADD type = search, genre, year ???
  4213. function zina_search_pager_query($term, $query, &$count, &$navigation, $sql = array(), $genre=false, &$selected = null) {
  4214. global $zc;
  4215. $cstart = 0;
  4216. $per_page = $zc['search_pp'];
  4217. if (!empty($sql)) {
  4218. $type_opts = array_keys(zina_search_opts_type());
  4219. $order_opts = array_keys(zina_search_opts_order());
  4220. $sort_opts = array_keys(zina_search_opts_sort());
  4221. $per_page_opts = array_keys(zina_search_opts_per_page());
  4222. if (isset($_POST['type'])) {
  4223. $type = $_POST['type'];
  4224. } elseif (!empty($_SESSION['zina']['search_type'])) {
  4225. $type = $_SESSION['zina']['search_type'];
  4226. }
  4227. if (isset($_POST['order'])) {
  4228. $order = $_POST['order'];
  4229. } elseif (!empty($_SESSION['zina']['search_order'])) {
  4230. $order = $_SESSION['zina']['search_order'];
  4231. }
  4232. if (isset($_POST['sort'])) {
  4233. $sort = $_POST['sort'];
  4234. } elseif (!empty($_SESSION['zina']['search_sort'])) {
  4235. $sort = $_SESSION['zina']['search_sort'];
  4236. }
  4237. if (isset($_POST['per_page'])) {
  4238. $per_page = $_POST['per_page'];
  4239. } elseif (!empty($_SESSION['zina']['search_per_page'])) {
  4240. $per_page = $_SESSION['zina']['search_per_page'];
  4241. }
  4242. if (!isset($sort) || !in_array($sort, $sort_opts)) $sort = 'title';
  4243. if (!isset($order) || !in_array($order, $order_opts)) $order = 'asc';
  4244. if (!isset($per_page) || !in_array($per_page, $per_page_opts)) $per_page = $zc['search_pp'];
  4245. if (!isset($type) || !in_array($type, $type_opts)) $type = 'album';
  4246. $selected['order'] = $_SESSION['zina']['search_order'] = $order;
  4247. $selected['sort'] = $_SESSION['zina']['search_sort'] = $sort;
  4248. $selected['per_page'] = $_SESSION['zina']['search_per_page'] = $per_page;
  4249. $selected['type'] = $_SESSION['zina']['search_type'] = $type;
  4250. if ($sort != 'title') {
  4251. $pre = (in_array($sort, array('mtime', 'sum_votes', 'sum_rating'))) ? '' : 'i.';
  4252. $sort = "$pre$sort $order, i.title";
  4253. $order = '';
  4254. }
  4255. $sql['orderby'] = "$sort $order";
  4256. $sql['type'] = '';
  4257. if ($_GET['l'] != 4) {
  4258. $sql['type'] = "i.type = '$type' AND ";
  4259. }
  4260. $count = $cend = zdbq_single("SELECT count(*) FROM {search_index} AS i WHERE ".$sql['type'].$sql['where'], array($term));
  4261. } elseif ($genre) {
  4262. $genres = zina_core_cache('genre');
  4263. $found = isset($genres[$term]) ? $genres[$term] : array();
  4264. $count = $cend = sizeof($found);
  4265. } else {
  4266. $results = zina_search_cache($term);
  4267. $count = $cend = count($results);
  4268. }
  4269. if ($count > $per_page) {
  4270. $page = isset($_GET['page']) ? $_GET['page'] : 1;
  4271. $pages_total = ceil($count/$per_page);
  4272. if (!zina_validate('int', $page) || $page < 1 || $page > $pages_total) $page = 1;
  4273. $navigation = ztheme('category_pages', null, $page, $pages_total, $query.'&amp;pl='.rawurlencode($term).'&amp;');
  4274. $cstart = ($page - 1) * $per_page;
  4275. if ($cstart > $count) $cstart = 0;
  4276. $cend = $per_page;
  4277. }
  4278. if (!empty($sql)) {
  4279. return zdbq_array("SELECT i.path, i.type, i.title, i.context, i.genre, i.year, i.file_mtime as mtime, ".
  4280. "if(i.type='song', f.sum_votes, d.sum_votes) as sum_votes, ".
  4281. "if(i.type='song', f.sum_rating, d.sum_rating) as sum_rating, f.id3_info ".
  4282. ",if(i.type='playlist', p.image_type, FALSE) as image_type ".
  4283. ",if(i.type='playlist', pd.path, FALSE) as image_path ".
  4284. ",if(i.type='playlist', p.id, FALSE) as id ".
  4285. "FROM {search_index} as i ".
  4286. "LEFT OUTER JOIN {files} AS f ON (i.type = 'song' AND i.type_id = f.id) ".
  4287. "LEFT OUTER JOIN {dirs} AS d ON (i.type != 'song' AND i.type !='playlist' AND i.type_id = d.id) ".
  4288. "LEFT OUTER JOIN {playlists} AS p ON (i.type = 'playlist' AND i.type_id = p.id) ".
  4289. "LEFT OUTER JOIN {dirs} AS pd ON (i.type = 'playlist' AND i.type_id = p.id AND p.dir_id = pd.id) ".
  4290. "WHERE ".$sql['type'].$sql['where']." ORDER BY ".$sql['orderby']." LIMIT %d OFFSET %d",
  4291. array($term, $cend, $cstart));
  4292. } elseif ($genre) {
  4293. $results = array();
  4294. $found = array_slice($found, $cstart, $cend);
  4295. foreach($found as $path) $results[] = zina_search_dir_helper($path);
  4296. return $results;
  4297. } else {
  4298. return array_slice($results, $cstart, $cend);
  4299. }
  4300. }
  4301. function zina_playlist_pager_query($query, &$count, &$navigation, &$selected = null, $dir_id = false) {
  4302. global $zc;
  4303. $cstart = 0;
  4304. $per_page = $zc['search_pp'];
  4305. $where = '';
  4306. $terms = array();
  4307. if ($zc['pls_user']) {
  4308. $all_opts = array_keys(zina_playlist_opts_all());
  4309. if (isset($_POST['all'])) {
  4310. $all = $_POST['all'];
  4311. } elseif (!empty($_SESSION['zina']['playlist_all'])) {
  4312. $all = $_SESSION['zina']['playlist_all'];
  4313. }
  4314. if (!isset($all) || !in_array($all, $all_opts)) $all = 'all';
  4315. $selected['all'] = $_SESSION['zina']['playlist_all'] = $all;
  4316. if ($all == 'all') {
  4317. if (!$zc['is_admin']) {
  4318. if ($zc['pls_public']) {
  4319. $where = 'p.user_id = %d OR p.visible = 1';
  4320. $terms[] = $zc['user_id'];
  4321. } else {
  4322. $where = 'p.user_id = %d';
  4323. $terms[] = $zc['user_id'];
  4324. }
  4325. }
  4326. } else { #single
  4327. $where = 'p.user_id = %d';
  4328. $terms[] = $zc['user_id'];
  4329. }
  4330. } else { # no user playlists
  4331. if ($zc['pls_public']) {
  4332. $where = 'visible = 1';
  4333. if (!$zc['is_admin']) return array();
  4334. }
  4335. }
  4336. $sort_opts = array_keys(zina_playlist_opts_sort());
  4337. $order_opts = array_keys(zina_search_opts_order());
  4338. if (isset($_POST['sort'])) {
  4339. $sort = $_POST['sort'];
  4340. } elseif (!empty($_SESSION['zina']['playlist_sort'])) {
  4341. $sort = $_SESSION['zina']['playlist_sort'];
  4342. }
  4343. if (isset($_POST['order'])) {
  4344. $order = $_POST['order'];
  4345. } elseif (!empty($_SESSION['zina']['playlist_order'])) {
  4346. $order = $_SESSION['zina']['playlist_order'];
  4347. }
  4348. if (!isset($sort) || !in_array($sort, $sort_opts)) $sort = 'playlist';
  4349. if (!isset($order) || !in_array($order, $order_opts)) $order = 'asc';
  4350. $selected['sort'] = $_SESSION['zina']['playlist_sort'] = $sort;
  4351. $selected['order'] = $_SESSION['zina']['playlist_order'] = $order;
  4352. /*
  4353. $per_page_opts = array_keys(zina_search_opts_per_page());
  4354. if (isset($_POST['per_page'])) {
  4355. $per_page = $_POST['per_page'];
  4356. } elseif (!empty($_SESSION['zina']['search_per_page'])) {
  4357. $per_page = $_SESSION['zina']['search_per_page'];
  4358. }
  4359. if (!isset($per_page) || !in_array($per_page, $per_page_opts)) $per_page = $zc['search_pp'];
  4360. $selected['per_page'] = $_SESSION['zina']['search_per_page'] = $per_page;
  4361. if ($sort != 'title') {
  4362. $pre = (in_array($sort, array('mtime', 'sum_votes', 'sum_rating'))) ? '' : 'i.';
  4363. $sort = "$pre$sort $order, i.title";
  4364. $order = '';
  4365. }
  4366. $sql['orderby'] = "$sort $order";
  4367. */
  4368. if ($dir_id) {
  4369. $where = "WHERE (dd.id = %d OR f.dir_id = %d)". ((!empty($where)) ? " AND ($where)" : '');
  4370. array_unshift($terms, $dir_id);
  4371. array_unshift($terms, $dir_id);
  4372. $count = $cend = zdbq_single("SELECT count(DISTINCT p.id) FROM {playlists} AS p ".
  4373. "INNER JOIN {playlists_map} as pm ON (p.id = pm.playlist_id) ".
  4374. "LEFT OUTER JOIN {files} AS f ON (pm.type = 'song' AND pm.type_id = f.id) ".
  4375. "LEFT OUTER JOIN {dirs} AS dd ON (pm.type = 'album' AND pm.type_id = dd.id) ".
  4376. "$where GROUP BY p.id", $terms);
  4377. } else {
  4378. $joins = '';
  4379. $where = (!empty($where)) ? "WHERE ".$where : '';
  4380. $count = $cend = zdbq_single("SELECT count(*) FROM {playlists} AS p ".$where, $terms);
  4381. }
  4382. if ($sort != 'playlist') {
  4383. if ($sort == 'genre') {
  4384. $sort = "g.genre IS NULL, g.genre $order, playlist";
  4385. } else {
  4386. $sort = "$sort $order, playlist";
  4387. }
  4388. $order = '';
  4389. }
  4390. $orderby = "$sort $order";
  4391. if ($count > $per_page) {
  4392. $page = isset($_GET['page']) ? $_GET['page'] : 1;
  4393. $pages_total = ceil($count/$per_page);
  4394. if (!zina_validate('int', $page) || $page < 1 || $page > $pages_total) $page = 1;
  4395. $navigation = ztheme('category_pages', null, $page, $pages_total, $query.'&amp;');
  4396. $cstart = ($page - 1) * $per_page;
  4397. if ($cstart > $count) $cstart = 0;
  4398. $cend = $per_page;
  4399. }
  4400. if ($dir_id) {
  4401. $sql = "SELECT p.title as playlist, p.*, d.path AS image_path, g.genre ".
  4402. "FROM {playlists} as p ".
  4403. "INNER JOIN {playlists_map} as pm ON (p.id = pm.playlist_id) ".
  4404. "LEFT OUTER JOIN {dirs} AS d ON (p.dir_id = d.id) ".
  4405. "LEFT OUTER JOIN {genres} AS g ON (p.genre_id = g.id) ".
  4406. "LEFT OUTER JOIN {files} AS f ON (pm.type = 'song' AND pm.type_id = f.id) ".
  4407. "LEFT OUTER JOIN {dirs} AS dd ON (pm.type = 'album' AND pm.type_id = dd.id) ".
  4408. "$where ".
  4409. "GROUP BY p.id ".
  4410. "ORDER BY $orderby LIMIT %d OFFSET %d";
  4411. } else {
  4412. $sql = "SELECT p.title as playlist, p.*, d.path AS image_path, g.genre ".
  4413. "FROM {playlists} AS p ".
  4414. "LEFT OUTER JOIN {dirs} AS d ON (p.dir_id = d.id) ".
  4415. "LEFT OUTER JOIN {genres} AS g ON (p.genre_id = g.id) ".
  4416. $where." ORDER BY ".$orderby." LIMIT %d OFFSET %d";
  4417. }
  4418. $terms[] = $cend;
  4419. $terms[] = $cstart;
  4420. return zdbq_array($sql, $terms);
  4421. }
  4422. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  4423. * GET functions
  4424. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  4425. /*
  4426. * Almost all of the information for directories and files
  4427. * is done through this function
  4428. *
  4429. * @dir is full path relative to mp3_dir
  4430. * @category is bool
  4431. */
  4432. #todo: could potentially use db for category as opt?
  4433. function zina_get_directory($root, $category = false, $opts = array()) {
  4434. global $zc;
  4435. $opts += array(
  4436. 'cat_images' => false,
  4437. 'get_files' => true,
  4438. 'dir_tags' => $zc['dir_tags']
  4439. );
  4440. $current_full_path = $zc['mp3_dir'].(!empty($root) ? '/'.$root : '');
  4441. $current_path = (!empty($root)) ? $root.'/' : '';
  4442. if (!$result = @scandir($current_full_path)) {
  4443. zina_debug(zt('Could not read directory'));
  4444. return array();
  4445. }
  4446. $mp3_dir = $zc['mp3_dir'];
  4447. $ext_mus = $zc['ext_mus'];
  4448. $dir_skip = $zc['dir_skip'];
  4449. $dir_tags = $opts['dir_tags'];
  4450. $low_look = ($zc['low_lookahead'] && !$category);
  4451. $id3 = ($zc['mp3_id3'] || $zc['mp3_info']);
  4452. $check_boxes = (($zc['is_admin'] && $zc['cache']) || ($zc['playlists'] && $zc['session_pls']) || $zc['play_sel'] || $zc['cmp_sel']);
  4453. $rating = ($zc['database'] && $zc['rating_files']);
  4454. $dir['lofi'] = false;
  4455. $dir['images'] = $dir['subdirs'] = $dir['files'] = $dir['captions'] = $dir = array();
  4456. $dir['image'] = null;
  4457. $dir['dir_write'] = $dir_write = ($zc['is_admin'] && is_writeable($zc['cur_dir']));
  4458. $dir['dir_edit'] = $dir_edit = (zina_cms_access('editor') && ($zc['database'] || ($zc['is_admin'] && $dir_write)));
  4459. $subdirs = &$dir['subdirs'];
  4460. $files = &$dir['files'];
  4461. $db_subdirs = array();
  4462. $db_dir = array();
  4463. $db_files = array();
  4464. $db = false;
  4465. $file_dir_info = false;
  4466. $now = time();
  4467. $diff = $zc['new_time']*86400;
  4468. #todo: cat_sort is overridable...?
  4469. $get_mtime = ($zc['new_highlight'] || $zc['cat_sort']);
  4470. if ($zc['database']) {
  4471. $db_path = (empty($root)) ? '.' : $root;
  4472. $db_dir = zdbq_array("SELECT * FROM {dirs} WHERE path = '%s'", $db_path);
  4473. if (!empty($db_dir)) {
  4474. $db = true;
  4475. $dir = array_merge($dir, $db_dir[0]);
  4476. $dir_other = unserialize_utf8($dir['other']);
  4477. if (!empty($dir_other)) {
  4478. $dir = array_merge($dir, $dir_other);
  4479. }
  4480. if ($opts['get_files']) {
  4481. $db_files = zdbq_assoc('full_path',
  4482. "SELECT *, IF(path != '.', CONCAT(path, IF(ISNULL(path), '', '/'), file), file) AS full_path ".
  4483. "FROM {files} WHERE dir_id = %d", $dir['id']);
  4484. }
  4485. if (!isset($dir['various'])) {
  4486. $dir['various'] = ($zc['various'] && zina_is_various($current_full_path, $root));
  4487. } else {
  4488. $dir['various'] = ($dir['various'] && $zc['various']);
  4489. }
  4490. #TODO: get_files???
  4491. if (!$category || ($dir_tags && $dir['various']) || $opts['cat_images']) {
  4492. $db_subdirs = zdbq_assoc('path',
  4493. "SELECT d.*, f.id3_info FROM {dirs} AS d LEFT OUTER JOIN {files} AS f ON d.id = f.dir_id ".
  4494. "WHERE d.parent_id = %d", $dir['id']);
  4495. } else {
  4496. $db_subdirs = zdbq_assoc('path', "SELECT * FROM {dirs} WHERE parent_id = %d", $dir['id']);
  4497. }
  4498. }
  4499. #todo: logic is old...
  4500. if ($opts['get_files'] && (($zc['rating_files'] && $zc['rating_files_public']) || $zc['is_admin'])) {
  4501. $ratings = true;
  4502. if ($zc['user_id'] > 0) {
  4503. $user_ratings = zdb_get_song_user_ratings($root, $zc['user_id']);
  4504. }
  4505. }
  4506. }
  4507. if (!isset($dir['various'])) {
  4508. $dir['various'] = ($zc['various'] && zina_is_various($current_full_path, $root));
  4509. }
  4510. #TODO: zc['cat_split']? wha about dir overrides???
  4511. $various_lookahead = ($category && $zc['various'] && $zc['cat_various_lookahead'] && ($zc['cat_split'] == 2 || $zc['cat_split'] == 3));
  4512. # Custom Playlists
  4513. $c_pls = $zc['cache_pls_dir'].'/'.str_replace('/',' - ',$root).'.m3u';
  4514. if ($zc['cache'] && $opts['get_files'] && file_exists($c_pls)) {
  4515. $c_pls_arr = zunserialize_alt(file_get_contents($c_pls));
  4516. } else {
  4517. $c_pls_arr = array();
  4518. }
  4519. # will probably fuck up on non-Art/Dir structures? test!
  4520. if ($dir_tags) {
  4521. if (isset($dir['title']) && !$category) {
  4522. if (strpos($root, '/') === false) $dir['title'] = null;
  4523. } else {
  4524. $dir['title'] = null;
  4525. }
  4526. } else {
  4527. $dir['title'] = null;
  4528. }
  4529. foreach($result as $filename) {
  4530. #$dir_tags = $opts['dir_tag'];
  4531. if ($filename == '.' || $filename == '..') continue;
  4532. $full_path = $current_full_path.'/'.$filename;
  4533. $path = $current_path.$filename;
  4534. $path_enc = utf8_encode($path);
  4535. if (isset($db_subdirs[$path_enc]) || is_dir($full_path)) {
  4536. if ($filename[0] == $dir_skip) continue;
  4537. $subdir = &$subdirs[$path];
  4538. $subdir = array(
  4539. 'image' => null,
  4540. 'query' => null,
  4541. 'path' => $path,
  4542. 'new' => false,
  4543. 'various' => null,
  4544. 'person' => false,
  4545. );
  4546. if (isset($db_subdirs[$path_enc]['other'])) {
  4547. $other = unserialize_utf8($db_subdirs[$path_enc]['other']);
  4548. if (isset($other['image'])) {
  4549. if ($other['image']) $subdir['image'] = $other['image'];
  4550. $subdir['various'] = $other['various'];
  4551. $subdir['category'] = $other['category'];
  4552. if (isset($other['person'])) $subdir['person'] = $other['person'];
  4553. }
  4554. }
  4555. if (empty($subdir['image']) && (!$category || $opts['cat_images'])) {
  4556. $subdir['image'] = zina_get_dir_item($full_path,'/\.('.$zc['ext_graphic'].')$/i');
  4557. }
  4558. if (is_null($subdir['various']) && $various_lookahead){
  4559. $subdir['various'] = file_exists($full_path.'/'.$zc['various_file']);
  4560. }
  4561. /*
  4562. * TODO: XXX QQQ try to simply below...
  4563. */
  4564. if (!$category && $id3) {
  4565. if (isset($db_subdirs[$path_enc]['id3_info'])) {
  4566. $subdir['info'] = unserialize_utf8($db_subdirs[$path_enc]['id3_info']);
  4567. } else {
  4568. $subdir_file = zina_get_dir_item($full_path,'/\.('.$ext_mus.')$/i');
  4569. if (!empty($subdir_file)) {
  4570. $subdir['info'] = zina_get_file_info($full_path.'/'.$subdir_file, false, true, $zc['genres']);
  4571. }
  4572. }
  4573. if (isset($db_subdirs[$path_enc]) && !empty($db_subdirs[$path_enc]['title'])) {
  4574. #if ($dir_tags && isset($db_subdirs[$path]) && !empty($db_subdirs[$path]['title'])) {
  4575. $subdir['title'] = $db_subdirs[$path_enc]['title'];
  4576. } else if ($dir_tags && isset($subdir['info']->album)) {
  4577. $subdir_title = trim($subdir['info']->album);
  4578. if (!empty($subdir_title)) $subdir['title'] = $subdir_title;
  4579. }
  4580. } elseif ($dir_tags && $id3) {
  4581. if (isset($db_subdirs[$path_enc]) && !empty($db_subdirs[$path_enc]['title'])) {
  4582. $subdir['title'] = $db_subdirs[$path_enc]['title'];
  4583. } #elseif (isset('id3_onfo? ??? for backward compat?
  4584. if ($dir['various'] && isset($db_subdirs[$path_enc]['id3_info'])) {
  4585. $subdir['info'] = unserialize_utf8($db_subdirs[$path_enc]['id3_info']);
  4586. }
  4587. }
  4588. if (!isset($subdir['title'])) {
  4589. $subdir['title'] = ztheme('title',$filename);
  4590. }
  4591. if ((!$category || $opts['cat_images']) && (empty($subdir['image']) || $subdir['image'] == 'cover_id3_zina.jpg') && isset($subdir['info']->image)) {
  4592. $subdir['image'] = 'zina_id3_zina.jpg';
  4593. }
  4594. if ($low_look) {
  4595. $subdir['lofi'] = zina_get_dir_item($full_path, '/('.$zc['low_suf'].')\.('.$zc['ext_mus'].')$/i');
  4596. }
  4597. if ($get_mtime) {
  4598. $subdir['mtime'] = $mtime = (isset($db_subdirs[$path_enc]['mtime'])) ? $db_subdirs[$path_enc]['mtime'] : filemtime($full_path);
  4599. $subdir['new'] = ($zc['new_highlight'] && $now - $mtime < $diff);
  4600. }
  4601. #TODO: see if can be used elsewhere...e.g. other zina_get_dir()s
  4602. } elseif ($opts['get_files']) { # file
  4603. if (preg_match('/\.('.$ext_mus.')$/i', $filename, $matches)) {
  4604. $file_ext = $matches[1];
  4605. $extras = array();
  4606. if ($zc['low'] && preg_match('/('.$zc['low_suf'].')\.('.$ext_mus.')$/i', $filename)) {
  4607. $lofi_path = $path;
  4608. $path = preg_replace('/('.$zc['low_suf'].')\.('.$ext_mus.')$/i', '.$2', $path);
  4609. $dir['lofi'] = $files[$path]['lofi'] = true;
  4610. $files[$path]['lofi_path'] = $lofi_path;
  4611. continue;
  4612. }
  4613. $file = &$files[$path];
  4614. $file['fake'] = $file['remote'] = false;
  4615. } elseif ($filename == $zc['dir_file']) {
  4616. if (!isset($dir['description'])) $dir['description'] = file_get_contents($full_path);
  4617. } elseif (preg_match('/\.('.$zc['ext_graphic'].')$/i', $filename)) {
  4618. $dir['images'][] = $filename;
  4619. if ($zc['image_captions']) {
  4620. if (file_exists($full_path.'.txt')) {
  4621. $dir['captions'][$filename] = rtrim(file_get_contents($full_path.'.txt'),"\r\n");
  4622. } else {
  4623. $dir['captions'][$filename] = '';
  4624. }
  4625. }
  4626. } elseif ($zc['remote'] && preg_match('/\.('.$zc['remote_ext'].')$/i', $filename, $matches)) {
  4627. $file = &$files[$path];
  4628. $file['remote'] = true;
  4629. $file['fake'] = false;
  4630. $file_ext = $matches[1];
  4631. } elseif ($zc['fake'] && preg_match('/\.('.$zc['fake_ext'].')$/i', $filename, $matches)) {
  4632. $file = &$files[$path];
  4633. $file['fake'] = true;
  4634. $file['remote'] = false;
  4635. $file_ext = $matches[1];
  4636. } elseif ($zc['mm'] && preg_match('/\.('.$zc['mm_ext'].')$/i', $filename, $matches)) {
  4637. #todo: consider putting mm in files...
  4638. $mm = &$dir['mm'][$path];
  4639. $mm['full_path'] = $path;
  4640. $mm['path'] = $root;
  4641. $mm['file'] = $filename;
  4642. $mm['filesize'] = filesize($full_path);
  4643. $mm['ext'] = $ext = strtolower($matches[1]);
  4644. $mm['description'] = zina_get_file_desc($zc['song_blurbs'], $full_path.'.txt');
  4645. $mm['new'] = false;
  4646. if ($get_mtime) {
  4647. $mm['mtime'] = $mtime = filemtime($full_path);
  4648. $mm['new'] = ($zc['new_highlight'] && $now - $mtime < $diff);
  4649. }
  4650. $mm['checkbox'] = false;
  4651. $mm['title'] = ztheme('song_title', substr($filename,0,-(strlen($ext)+1)));
  4652. if (isset($zc['mm_types'][$ext]['player'])) {
  4653. $mm['opts']['play'] = array('path'=>$path, 'query'=>'l=24&amp;m=1');
  4654. $mm['opts']['play']['local'] = (!$zc['stream_int'] || preg_match('#^'.$_SERVER['DOCUMENT_ROOT'].'#i',$zc['mp3_dir']));
  4655. $mm['opts']['play']['full_path'] = $full_path;
  4656. }
  4657. if ($zc['mm_down']) $mm['opts']['download'] = array('path'=>$path, 'query'=>'l=25');
  4658. if ($dir_write) $mm['opts_edit']['edit'] = array('path'=>$path, 'query'=>'l=22&amp;m=4');
  4659. }
  4660. if (isset($files[$path])) {
  4661. $db_filepath = zcheck_utf8($path, false);
  4662. #$db_filepath = utf8_encode($path);;
  4663. if (isset($db_files[$db_filepath])) {
  4664. $file = array_merge($file, $db_files[$db_filepath]);
  4665. $file['info'] = unserialize_utf8($files[$path]['id3_info']);
  4666. $extras = unserialize_utf8($files[$path]['other']);
  4667. }
  4668. $file['full_path'] = $path;
  4669. $file['path'] = $root;
  4670. $file['file'] = $filename;
  4671. $file['new'] = $file['checkbox'] = $file['ratings'] = false;
  4672. if ($get_mtime) {
  4673. $file['mtime'] = filemtime($full_path);
  4674. $file['new'] = ($zc['new_highlight'] && $now - $file['mtime'] < $diff);
  4675. }
  4676. if (!isset($file['info']) && ($id3 || $file['remote'])) {
  4677. $file['info'] = zina_get_file_info($full_path, $zc['mp3_info'], ($zc['mp3_id3']|| $file['remote']), $zc['genres']);
  4678. }
  4679. if (!isset($file['description'])) {
  4680. $file['description'] = zina_get_file_desc($zc['song_blurbs'], substr($full_path, 0, -strlen($file_ext)).'txt');
  4681. }
  4682. if (isset($file['description'])) {
  4683. $file['description'] = zina_url_filter($file['description']);
  4684. }
  4685. if (isset($file['info']) && !$file_dir_info && !$db) {
  4686. $dir['info'] = $file['info'];
  4687. if (isset($dir['info']->year)) $dir['year'] = $dir['info']->year;
  4688. if (isset($dir['info']->genre)) $dir['genre'] = $dir['info']->genre;
  4689. $file_dir_info = true;
  4690. }
  4691. if (isset($file['info']->title)) {
  4692. $file['title'] = ztheme('song_title', $file['info']->title, true);
  4693. } else {
  4694. $file['title'] = zina_content_song_title($filename);
  4695. }
  4696. if ($zc['song_extras']) {
  4697. foreach ($zc['song_es_exts'] as $ext) {
  4698. if (isset($extras[$ext]) || file_exists(substr($full_path, 0, -strlen($file_ext)).$ext) || (isset($zc['third_'.$ext]) && $zc['third_'.$ext])) {
  4699. if ($zc['song_es'][$ext]['type'] == 'page_internal') {
  4700. $href = $path;
  4701. $query = 'l=29&amp;m='.$ext;
  4702. $attr = '';
  4703. } elseif ($zc['song_es'][$ext]['type'] == 'page_popup') {
  4704. $href = 'javascript: void 0;';
  4705. $query = NULL;
  4706. $attr = " onclick=\"WindowOpen('".zurl($path, 'l=29&amp;m='.$ext)."','lyrics',".($zc['song_es'][$ext]['page_width']+20).",".$zc['song_es'][$ext]['page_height'].",'no');\"";
  4707. } elseif ($zc['song_es'][$ext]['type'] == 'external') {
  4708. $href = 'javascript: alert(\''.zt('Error').'\');';
  4709. $query = $attr = null;
  4710. $extra_file = substr($full_path, 0, -strlen($file_ext)).$ext;
  4711. $content = trim(file_get_contents($extra_file));
  4712. if (!empty($content)) $href = $content;
  4713. } else {
  4714. $href = 'javascript: alert(\''.zt('Error').'\');';
  4715. $query = $attr = null;
  4716. }
  4717. $file['extras'][$ext] = array('path'=>$href, 'query'=>$query, 'attr'=>$attr,
  4718. 'text'=>$zc['song_es'][$ext]['name'] );
  4719. }
  4720. if ($dir_edit) { #edit
  4721. $file['extras_edit'][$ext] = array('path'=>$path,
  4722. 'query'=>'l=22&amp;m='.$ext,
  4723. 'attr'=>null, 'text'=>zt('Edit @extra', array('@extra'=>$zc['song_es'][$ext]['name']))
  4724. );
  4725. }
  4726. }
  4727. } # end extras
  4728. if ($zc['play'] && !$file['fake'] && (!$file['remote'] || isset($file['info']->url))) {
  4729. $file['title_link'] = $file['opts']['play'] = array('path'=>$path, 'query'=>'l=8&amp;m=1', 'attr'=>' class="zinamp"');
  4730. }
  4731. if ($check_boxes && !$file['fake'] && (!$file['remote'] || isset($file['info']->url))) {
  4732. $file['checkbox'] = array('name'=>'mp3s[]', 'value'=>zrawurlencode($path), 'checked'=>(!empty($c_pls_arr) && in_array($path, $c_pls_arr)));
  4733. }
  4734. if (isset($file['lofi'])) {
  4735. $file['opts']['play_lofi'] = array('path'=>$file['lofi_path'], 'query'=>'l=8&amp;m=1');
  4736. } elseif ($zc['resample'] && preg_match('/\.('.$zc['ext_enc'].')$/i', $filename)) {
  4737. $file['opts']['play_lofi'] = array('path'=>$path, 'query'=>'l=8&amp;m=1&amp;lf');
  4738. }
  4739. if ($zc['download']) {
  4740. if ($file['remote']) {
  4741. if (isset($file['info']->download)) $file['opts']['download'] = array('path'=>$file['info']->download, 'query'=>null);
  4742. } elseif (!$file['fake']) {
  4743. $file['opts']['download'] = array('path'=>$path, 'query'=>'l=12');
  4744. }
  4745. }
  4746. if ($dir_edit) $file['opts_edit']['edit'] = array('path'=>$path, 'query'=>'l=22&amp;m=3');
  4747. if ($dir_write) $file['delete'] = array('path'=>$path, 'query'=>'l=75');
  4748. $file['ratings'] = ($rating && !$file['fake']);
  4749. if (!isset($file['sum_votes'])) {
  4750. $file['sum_votes'] = 0;
  4751. $file['sum_rating'] = 0;
  4752. $file['sum_plays'] = 0;
  4753. $file['sum_downloads'] = 0;
  4754. }
  4755. $file['user_rating'] = (isset($user_ratings[$db_filepath])) ? $user_ratings[$db_filepath]['rating'] : 0;
  4756. } # end isset(file)
  4757. } #end file
  4758. } #end loop
  4759. if (isset($dir['description'])) $dir['description'] = zina_url_filter(nl2br($dir['description']));
  4760. if (empty($dir['images']) && isset($file['info']->image)) {
  4761. $dir['images'][] = 'zina_id3_zina.jpg';
  4762. }
  4763. return $dir;
  4764. }
  4765. function zina_url_filter($input) {
  4766. return preg_replace('/\{internal:(.*?)\}/ie', 'zurl("$1");', $input);
  4767. }
  4768. function zina_get_file_desc($allow, $file) {
  4769. return ($allow && file_exists($file)) ? file_get_contents($file) : false;
  4770. }
  4771. function zina_get_form_token() {
  4772. global $zc;
  4773. return ztheme('form_hidden', 'token', zina_token_sess($zc['user_id']));
  4774. }
  4775. function zina_get_tmpl_cache_file($path) {
  4776. if (empty($path)) {
  4777. $cache_file = md5($_SERVER['REQUEST_URI']).'_'.zina_get_page_opt($path).zina_get_catsort_opt($path);
  4778. } else {
  4779. $cache_file = md5($path);
  4780. }
  4781. return $cache_file;
  4782. }
  4783. function zina_get_catsort_opt($path) {
  4784. global $zc;
  4785. $cat_sort = $zc['cat_sort_default'];
  4786. if ($zc['cat_sort']) {
  4787. if (isset($_GET['zs']) && in_array($_GET['zs'], array('a','ad','d','dd'))) {
  4788. $cat_sort = $_SESSION['zina']['catsort'][$path] = $_GET['zs'];
  4789. } elseif (isset($_SESSION['zina']['catsort'][$path])) {
  4790. $cat_sort = $_SESSION['zina']['catsort'][$path];
  4791. }
  4792. }
  4793. return $cat_sort;
  4794. }
  4795. function zina_get_page_opt($path='') {
  4796. #todo: cat_splits might not honor overrides...
  4797. global $zc;
  4798. $page = ($zc['cat_split'] == 2) ? 'A' : 1;
  4799. if ($zc['cat_split']) {
  4800. if (isset($_GET['page']) && zina_validate('alpha_numeric',$_GET['page'])) {
  4801. $page = $_SESSION['zina'][$path]['page'] = $_GET['page'];
  4802. } elseif (isset($_GET['page']) && $zc['cat_split'] >= 2 && $zc['cat_various_lookahead'] && !strstr($path,'..') && is_dir($zc['mp3_dir'].'/'.$_GET['page'])) {
  4803. $page = $_SESSION['zina'][$path]['page'] = $_GET['page'];
  4804. } elseif (isset($_SESSION['zina'][$path]['page'])) {
  4805. $page = $_SESSION['zina'][$path]['page'];
  4806. }
  4807. }
  4808. return $page;
  4809. }
  4810. function zina_get_genres_list($genres = array(), $image_type = 'genre') {
  4811. global $zc;
  4812. $items = array();
  4813. if (empty($genres)) {
  4814. if ($zc['database']) {
  4815. #TODO:XXX...ordering options? obsolete? integrate? make opt?
  4816. # cant be by weight or cat split wont work?
  4817. $genres = zdbq_array_list("SELECT genre FROM {genres} AS g INNER JOIN {genre_tree} as gt ON g.id=gt.id ".
  4818. "WHERE pid = 0 ORDER BY genre");
  4819. } else {
  4820. $genres = zina_core_cache('genres');
  4821. }
  4822. }
  4823. if (!empty($genres)) {
  4824. foreach ($genres as $g) {
  4825. $items[$g] = array(
  4826. 'path' => null,
  4827. 'query' => 'l=13&amp;pl='.rawurlencode($g),
  4828. 'title' => zcheck_utf8($g),
  4829. 'new' => false,
  4830. );
  4831. if ($zc['genres_images']) {
  4832. $path = zina_get_genre_image_path($g, $image_type);
  4833. $items[$g]['image_raw'] = $image_raw = ztheme('image', $path, $g, null, 'class="genre-image"');
  4834. $items[$g]['image'] = zl($image_raw, null, $items[$g]['query']);
  4835. }
  4836. }
  4837. }
  4838. return $items;
  4839. }
  4840. function zina_get_genre_image_path($g, $type = 'genre') {
  4841. global $zc;
  4842. $genre_file = ztheme('image_genre', $g);
  4843. if ($zc['res_genre_img']) {
  4844. $path = zurl(null,'l=7&amp;it='.$type.'&amp;img='.rawurlencode($g), null);
  4845. } elseif (file_exists($zc['theme_path_abs'].'/images/'.$genre_file)) {
  4846. $path = zpath_to_theme().'/images/'.$genre_file;
  4847. } else {
  4848. $path = zpath_to_theme().'/images/'.ztheme('missing_image','genre');
  4849. }
  4850. return $path;
  4851. }
  4852. #todo: your using this to get images!
  4853. function zina_get_dir_list(&$dirs, $sort = true) {
  4854. global $zc;
  4855. $checkbox = ($zc['is_admin'] || ($zc['playlists'] && $zc['session_pls']));
  4856. $sort = ($zc['dir_list_sort'] && $sort);
  4857. if ($sort) {
  4858. if ($zc['dir_list_sort_asc']) {
  4859. $sort = SORT_ASC;
  4860. $empty = 9000;
  4861. } else {
  4862. $sort = SORT_DESC;
  4863. $empty = 0;
  4864. }
  4865. }
  4866. foreach ($dirs as $key=>$opts) {
  4867. if (empty($key)) {
  4868. } elseif (substr_count($key, '/') < 1) {
  4869. #if ($zc['play'] && $zc['play_rec'] && $subdir_num > 1) {
  4870. # $zina['dir_opts']['play_rec'] = array('path'=>$path, 'query'=>'l=8&amp;m=10');
  4871. #}
  4872. if ($zc['play'] && $zc['play_rec_rand']) {
  4873. $dirs[$key]['opts']['play_rec_rand'] = array('path'=>$opts['path'], 'query'=>'l=8&amp;m=10&amp;c');
  4874. }
  4875. } else {
  4876. zina_content_subdir_opts($dirs[$key], $opts['path'], $checkbox, $opts);
  4877. }
  4878. if (!isset($opts['title'])) {
  4879. $dirs[$key]['title'] = ztheme('title',$opts['path']);
  4880. }
  4881. $dirs[$key]['image_raw'] = $image_raw = ztheme('image', zina_get_image_url($opts['path'], $opts['image'],'sub'), $dirs[$key]['title'], null, 'class="sub-image"');
  4882. $dirs[$key]['image'] = zl($image_raw, $opts['path']);
  4883. if ($sort) {
  4884. $year[$key] = (isset($dirs[$key]['info']->year)) ? $dirs[$key]['info']->year : $empty;
  4885. }
  4886. }
  4887. if ($sort) array_multisort($year, $sort, $dirs);
  4888. }
  4889. function zina_get_image_url($path, $image, $type, $absolute = false) {
  4890. global $zc;
  4891. if (!in_array($type, array('sub','dir','full','search'))) $type = 'dir';
  4892. if (empty($image)) {
  4893. if ($zc['res_'.$type.'_img'] && $zc[$type.'_img_txt']) {
  4894. return zurl($path,'l=7&amp;it='.$type, null, $absolute);
  4895. } else {
  4896. return zpath_to_theme().'/images/'.ztheme('missing_image',$type);
  4897. }
  4898. } else {
  4899. if ($zc['res_'.$type.'_img'] && preg_match('/\.('.$zc['resize_types'].')$/i', $image)) {
  4900. if ($zc['cache_imgs']) {
  4901. $res_out_type = ($zc['res_out_type'] == 'jpeg') ? 'jpg' : $zc['res_out_type'];
  4902. $cache_img = $type.md5($zc['mp3_dir'].'/'.$path.'/'.$image).'.'.$res_out_type;
  4903. if (file_exists($zc['cache_imgs_dir'].'/'.$cache_img)) {
  4904. if ($absolute) {
  4905. $base_root = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') ? 'https' : 'http';
  4906. $base_url = $base_root .= '://'.$zc['auth']. preg_replace('/[^a-z0-9-:._]/i', '', $_SERVER['HTTP_HOST']);
  4907. return $base_url.$zc['zina_dir_rel'].'/'.$zc['cache_imgs_dir_rel'].'/'.$cache_img;
  4908. } else {
  4909. return $zc['zina_dir_rel'].'/'.$zc['cache_imgs_dir_rel'].'/'.$cache_img;
  4910. }
  4911. }
  4912. }
  4913. return zurl($path,'l=7&amp;img='.rawurlencode($image).'&amp;it='.$type, null, $absolute);
  4914. } elseif ($zc['stream_int']) {
  4915. return zurl($path,'l=11&amp;img='.rawurlencode($image), null, $absolute);
  4916. } else { #NORMAL
  4917. return zurl($path.'/'.$image,NULL,NULL,$absolute,TRUE);
  4918. }
  4919. }
  4920. }
  4921. function zina_get_vote_url($path) {
  4922. return zurl($path,'l=16').'&n=';
  4923. }
  4924. function zina_get_page_title($array=null) {
  4925. static $title;
  4926. if ($array) $title = $array;
  4927. return $title;
  4928. }
  4929. function zina_get_current_dir($current=null) {
  4930. static $dir;
  4931. if ($current) $dir = $current;
  4932. return $dir;
  4933. }
  4934. function zina_get_breadcrumb($path, $alt_title = null, $full = false, $links = array()) {
  4935. global $zc;
  4936. if (empty($links)) {
  4937. $tmp_path = '';
  4938. $crumbs = explode('/',$path);
  4939. $size = sizeof($crumbs);
  4940. for($i=0; $i < $size; $i++) {
  4941. if ($tmp_path != '') $tmp_path = $tmp_path.'/';
  4942. $tmp_path .= $crumbs[$i];
  4943. $title = ztheme('title',$crumbs[$i]);
  4944. $links[] = zl($title,$tmp_path);
  4945. $titles[] = $title;
  4946. }
  4947. if (empty($alt_title)) {
  4948. zina_get_current_dir(ztheme('title',$crumbs[$size-1]));
  4949. zina_get_page_title($titles);
  4950. } else {
  4951. array_pop($titles);
  4952. $titles[] = $alt_title;
  4953. if ($full) {
  4954. array_pop($links);
  4955. $links[] = zl($alt_title, $path);
  4956. }
  4957. zina_get_current_dir(ztheme('title',$alt_title));
  4958. zina_get_page_title($titles);
  4959. }
  4960. if (!$full) array_pop($links);
  4961. }
  4962. $home[] = (!empty($path) || isset($_GET['l'])) ? zl(zt($zc['main_dir_title']),'') : zt($zc['main_dir_title']);
  4963. if ($zc['genres'])
  4964. $home[] = (isset($_GET['l']) && $_GET['l'] == '14') ? zt('Genres') : zl(zt('Genres'),null,'l=14');
  4965. if ($zc['playlists'] && ($zc['pls_public'] || $zc['is_admin']))
  4966. $home[] = zl(zt('Playlists'),null,'l=2');
  4967. if ($zc['database'] && $zc['stats'] && ($zc['is_admin'] || $zc['stats_public']))
  4968. $home[] = (isset($_GET['l']) && $_GET['l'] == '15') ? zt('Statistics') : zl(zt('Statistics'),'','l=15');
  4969. array_unshift($links,ztheme('breadcrumb_home', $home));
  4970. return $links;
  4971. }
  4972. /*
  4973. * @path must be full
  4974. */
  4975. function zina_get_file_info($path, $info=true, $id3=true, $genre=false, $image = false) {
  4976. global $zc;
  4977. $mp3 = false;
  4978. if ($zc['remote'] && preg_match('/\.('.$zc['remote_ext'].')$/i', $path)) {
  4979. $mp3 = new remoteFile($path, $info, $id3);
  4980. } else {
  4981. $mp3 = new mp3($path, $info, $id3, $zc['mp3_info_faster'], $genre, $image);
  4982. }
  4983. return $mp3;
  4984. }
  4985. function zina_get_file_xml($path) {
  4986. global $zc;
  4987. $output = '<?xml version="1.0" encoding="UTF-8"?'.'><track>';
  4988. $mp3 = null;
  4989. $result = array();
  4990. if ($zc['database']) {
  4991. $result = zdbq_array_single("SELECT * FROM {files} WHERE path = '%s' AND file = '%s'", dirname($path), basename($path));
  4992. if (!empty($result)) {
  4993. /*
  4994. foreach ($result as $key => $val) {
  4995. if (in_array($key, array('file', 'path', 'id3_info', 'other'))) continue;
  4996. $output .= xml_field($key, $val);
  4997. }
  4998. */
  4999. $other = unserialize_utf8($result['other']);
  5000. unset($result['other']);
  5001. $mp3 = unserialize_utf8($result['id3_info']);
  5002. unset($result['id3_info']);
  5003. if ($zc['user_id'] > 0) {
  5004. $result['user_rating'] = zdbq_single("SELECT rating FROM {file_ratings} WHERE file_id = %d AND user_id = %d LIMIT 1", array($result['id'], $zc['user_id']));
  5005. $output .= xml_field('user_rating', $result['user_rating']);
  5006. }
  5007. }
  5008. if ($zc['rating_files']) {
  5009. $output .= xml_field('vote_url', zurl($path,'l=16',null,true).'&n=');
  5010. }
  5011. }
  5012. if (empty($mp3)) {
  5013. $mp3 = zina_get_file_info($zc['mp3_dir'].'/'.$path,true,true,true);
  5014. }
  5015. $result = array_merge($result, get_object_vars($mp3));
  5016. if (empty($result['title'])) $result['title'] = ztheme('song_title', preg_replace('/\.('.$zc['ext_mus'].')$/i', '', $path));
  5017. $items = array('bitrate', 'frequency', 'sum_rating', 'stereo');
  5018. foreach ($items as $item) {
  5019. if (isset($result[$item]) && !empty($result[$item])) {
  5020. $output .= xml_field($item, $result[$item]);
  5021. }
  5022. }
  5023. $img_path = dirname($path);
  5024. $img = zina_get_dir_item($zc['mp3_dir'].'/'.$img_path,'/\.('.$zc['ext_graphic'].')$/i');
  5025. if (empty($img) && isset($mp3->image)) $img = 'zina_id3_zina.jpg';
  5026. #todo: make 'sub' configable?
  5027. $img_url = zina_get_image_url($img_path, $img, 'sub', true);
  5028. $output .= xml_field('image', $img_url);
  5029. if ($zc['zinamp'] && $zc['lastfm']) {
  5030. zina_zinamp_start($path);
  5031. $output .= xml_field('complete_url', zurl($path,'l=56',null,true).'&n=');
  5032. $output .= xml_field('start_url', zurl($path,'l=66',null,true));
  5033. }
  5034. $result['path'] = $path;
  5035. $parts = explode('/', $path);
  5036. if (sizeof($parts) == 3) {
  5037. $result['artist_url'] = zurl($parts[0], null, null, true);
  5038. $result['album_url'] = zurl($parts[0].'/'.$parts[1], null, null, true);
  5039. $output .= xml_field('artist_url', $result['artist_url']);
  5040. $output .= xml_field('album_url', $result['album_url']);
  5041. }
  5042. #todo: genre url?
  5043. if ($zc['song_extras'] && in_array('lyr', $zc['song_es_exts'])) {
  5044. $output .= xml_field('lyric_url', zurl($path,'l=57&m=lyr&pl=zinamp',null,true));
  5045. }
  5046. $output .= "<info>\n<![CDATA[".ztheme('zinamp_song_info',$result)."]]>\n</info>";
  5047. return $output.'</track>';
  5048. }
  5049. function zina_zinamp_start($path) {
  5050. $now = time();
  5051. $_SESSION['zinamp_track'][$path] = $now;
  5052. if (sizeof($_SESSION['zinamp_track']) > 2) {
  5053. foreach($_SESSION['zinamp_track'] as $track => $time) {
  5054. if ($now > $time + (60*60*1)) {
  5055. unset($_SESSION['zinamp_track'][$track]);
  5056. }
  5057. }
  5058. }
  5059. }
  5060. function zina_get_dir_item($path, $regex) {
  5061. global $zc;
  5062. @set_time_limit($zc['timeout']);
  5063. if ($results = @scandir($path)) {
  5064. foreach($results as $file) {
  5065. if (preg_match($regex, $file)) return $file;
  5066. }
  5067. }
  5068. return false;
  5069. /*
  5070. @set_time_limit($zc['timeout']);
  5071. if (is_dir($path) && $dh = opendir($path)) {
  5072. while (($file = readdir($dh)) !== false) {
  5073. if (preg_match($regex, $file)) {
  5074. closedir($dh);
  5075. return $file;
  5076. }
  5077. }
  5078. closedir($dh);
  5079. }
  5080. return false;
  5081. */
  5082. }
  5083. function zina_get_title_playlist($path, $custom = false, $low = false) {
  5084. global $zc;
  5085. $dirs = zina_core_cache('files_assoc', $path, array('low'=>$low,'file_sort'=>$zc['files_sort'],'custom'=>$custom,'force'=>(empty($path))));
  5086. $files = array();
  5087. if (isset($dirs[$path])) {
  5088. foreach($dirs[$path] as $file) {
  5089. $files[] = (empty($path)) ? $file : $path.'/'.$file;
  5090. }
  5091. }
  5092. return zina_get_playlist($files, $low);
  5093. }
  5094. function zina_get_song_url($file, $resample = false) {
  5095. global $zc;
  5096. static $count = 0;
  5097. $format = $zc['playlist_format'];
  5098. $remote = ($zc['remote'] && preg_match('/\.('.$zc['remote_ext'].')$/i', $file));
  5099. #if (!$zc['pos'] && !$zc['play_local']) { ???
  5100. if ($zc['stream_int'] || $resample || $remote) {
  5101. if ($remote || ($zc['stream_extinf'] && $zc['mp3_id3'] && $count++ < $zc['stream_extinf_limit'])) {
  5102. $mp3 = zina_get_file_info($zc['mp3_dir'].'/'.$file);
  5103. if ($mp3->tag) {
  5104. $at = ztheme('artist_song', $mp3->title, $mp3->artist);
  5105. } else {
  5106. $at = zina_get_file_artist_title($file, false);
  5107. }
  5108. $length = isset($mp3->length) ? $mp3->length : -1;
  5109. } else {
  5110. $mp3 = false;
  5111. $at = zina_get_file_artist_title($file, false);
  5112. $length = -1;
  5113. }
  5114. $query = ($resample && !$remote) ? 'l=6' : 'l=10';
  5115. if (isset($zc['token'])) $query .= '&'.$zc['token'];
  5116. $url = zurl($file, $query, null, true);
  5117. if ($format == 'm3u') {
  5118. $at = utf8_decode(zdecode_entities($at));
  5119. $playlist = ($zc['stream_extinf']) ? "#EXTINF:$length,$at\n" : '';
  5120. $ext = '';
  5121. if (!$zc['clean_urls']) {
  5122. # winamp
  5123. $match = strtolower(substr($file, strrpos($file, '.')));
  5124. if ($match != '.mp3') $ext = '&ext='.$match;
  5125. }
  5126. return $playlist.$url.$ext."\n";
  5127. } elseif ($format == 'asx') {
  5128. $at = utf8_decode(zdecode_entities($at));
  5129. return '<entry><title>'.$at.'</title><ref href="'.$url.'"><STARTTIME VALUE="00:00:00.0" /></ref></entry>'."\n";
  5130. } elseif ($format == 'xspf') {
  5131. if ($mp3 && $mp3->tag) {
  5132. $meta = '';
  5133. if (isset($mp3->artist) && !empty($mp3->artist)) {
  5134. $meta .= xml_field('creator', $mp3->artist);
  5135. $meta .= xml_field('title', $mp3->title);
  5136. } else {
  5137. $meta .= xml_field('title', $at);
  5138. }
  5139. if ($length > 0) $meta .= xml_field('duration', ($length*1000));
  5140. } else {
  5141. $meta = xml_field('title', $at);
  5142. }
  5143. $meta .= xml_field('link', zurl($file,'l=54',NULL,TRUE));
  5144. $meta .= xml_field('meta', 'audio');
  5145. return '<track><location>'.$url.'</location>'.$meta.'</track>'."\n";
  5146. }
  5147. } else {
  5148. return zurl($file,NULL,NULL,TRUE,TRUE)."\n";
  5149. }
  5150. }
  5151. function zina_get_playlist($songs, $low, $c_pls = false) {
  5152. global $zc;
  5153. static $pls_ids = array();
  5154. $playlist = '';
  5155. if (!empty($songs)) {
  5156. if ($zc['pos'] || $zc['play_local']) {
  5157. foreach($songs as $song) {
  5158. $song = zrawurldecode($song);
  5159. if (preg_match('/\.lp$/i', $song)) {
  5160. $song = preg_replace('/\/\.lp$/i', '', $song);
  5161. $playlist .= zina_get_title_playlist($song, $zc['honor_custom'], $low);
  5162. } elseif (preg_match('/\.pls/i', $song)) {
  5163. $song = preg_replace('/\.pls/i', '', $song);
  5164. if (in_array($song, $pls_ids)) continue;
  5165. $pls_ids[] = $song;
  5166. $playlist .= zina_get_playlist(zina_get_playlist_custom($song, $zc['honor_custom'], $low), $low);
  5167. } else {
  5168. $playlist .= $zc['mp3_dir'].'/'.$song."\n";
  5169. }
  5170. }
  5171. } else { # NOT POS
  5172. foreach($songs as $song) {
  5173. $song = zrawurldecode($song);
  5174. if (preg_match('/\.lp$/i', $song)) {
  5175. $song = preg_replace('/\/\.lp$/i', '', $song);
  5176. $playlist .= zina_get_title_playlist($song, $zc['honor_custom'], $low);
  5177. } elseif (preg_match('/\.pls$/i', $song)) {
  5178. $song = preg_replace('/\.pls/i', '', $song);
  5179. if (in_array($song, $pls_ids)) continue;
  5180. $pls_ids[] = $song;
  5181. $playlist .= zina_get_playlist(zina_get_playlist_custom($song, $zc['honor_custom'], $low), $low);
  5182. } elseif ($zc['remote'] && preg_match('/\.('.$zc['remote_ext'].')$/i', $song)) {
  5183. $playlist .= zina_get_song_url($song);
  5184. } elseif ($low) {
  5185. $song_lofi = preg_replace('/(\.'.$zc['ext_mus'].')$/i', $zc['low_suf'].'$1', $song);
  5186. if ($c_pls && file_exists($zc['mp3_dir'].'/'.$song_lofi)) {
  5187. $playlist .= zina_get_song_url($song_lofi);
  5188. } elseif (preg_match('/('.$zc['low_suf'].')\.('.$zc['ext_mus'].')$/i', $song)) {
  5189. $playlist .= zina_get_song_url($song);
  5190. } elseif($zc['resample'] && preg_match('/\.('.$zc['ext_enc'].')$/i', $song)) {
  5191. $playlist .= zina_get_song_url($song, true);
  5192. } else {
  5193. $playlist .= zina_get_song_url($song);
  5194. }
  5195. } else {
  5196. $playlist .= zina_get_song_url($song);
  5197. }
  5198. }
  5199. }
  5200. }
  5201. return $playlist;
  5202. }
  5203. function zina_get_playlists_custom() {
  5204. global $zc;
  5205. $custom_playlists = null;
  5206. if (file_exists($zc['cache_pls_dir'])) {
  5207. $d = dir($zc['cache_pls_dir']);
  5208. while($entry = $d->read()) {
  5209. #use last for insteadh of preg
  5210. if (substr($entry,0,6) == '_zina_' && preg_match('/\.m3u$/i', $entry) ) {
  5211. $entry = preg_replace('/^_zina_/i','',$entry);
  5212. $custom_playlists[] = preg_replace('/\.m3u$/i','',$entry);
  5213. }
  5214. }
  5215. $d->close();
  5216. if (!empty($custom_playlists)) natcasesort($custom_playlists);
  5217. }
  5218. return $custom_playlists;
  5219. }
  5220. function zina_core_cache($type, $path = '', $opts = array()) {
  5221. global $zc;
  5222. $serial = true;
  5223. if ($type == 'dirs') {
  5224. $cache_file = $zc['cache_dirs_file'];
  5225. } elseif ($type == 'files') {
  5226. $files = array();
  5227. $files_assoc = zina_core_cache('files_assoc',$path, $opts);
  5228. foreach($files_assoc as $dir=> $array) {
  5229. foreach ($array as $file) {
  5230. $files[] = (empty($dir)) ? $file : $dir.'/'.$file;
  5231. }
  5232. }
  5233. return $files;
  5234. } elseif ($type == 'files_assoc') {
  5235. $cache_file = $zc['cache_files_assoc_file'];
  5236. if (isset($opts['low']) && $opts['low']) $cache_file = preg_replace('/(\.gz)$/i', $zc['low_suf'].'$1', $cache_file);
  5237. } elseif ($type == 'genre') {
  5238. #[genre]=>array(albums)
  5239. $cache_file = $zc['cache_genre_file'];
  5240. } elseif ($type == 'genres') {
  5241. # genre list
  5242. if ($zc['database']) {
  5243. $keys = zdbq_array_list("SELECT genre FROM {genres} ORDER BY genre");
  5244. if (empty($keys)) $keys[] = zt('No genres found.');
  5245. } else {
  5246. $genre = zina_core_cache('genre');
  5247. if (!empty($genre)) {
  5248. $keys = array_keys($genre);
  5249. natcasesort($keys);
  5250. } else {
  5251. $keys[] = zt('No genres found.');
  5252. }
  5253. }
  5254. return $keys;
  5255. } else {
  5256. return array();
  5257. }
  5258. if ($zc['cache'] && !(isset($opts['force']) && $opts['force']) && empty($path) && file_exists($cache_file)) {
  5259. if ($serial) {
  5260. return unserialize(implode('', gzfile($cache_file)));
  5261. } else {
  5262. return gzfile($cache_file);
  5263. }
  5264. }
  5265. $result_array = zina_scandir($type, $path, $opts);
  5266. if ($result_array) {
  5267. if ($zc['cache'] && empty($path)) {
  5268. if ($serial) {
  5269. $result = serialize($result_array);
  5270. } else {
  5271. $result = implode("\n", $result_array);
  5272. }
  5273. if (zina_check_directory(dirname($cache_file),1)) {
  5274. $fp = gzopen($cache_file, 'w1');
  5275. gzwrite($fp,$result);
  5276. gzclose($fp);
  5277. } else {
  5278. zina_debug(zt('Cache directories do not exist. Create them under "Settings."'));
  5279. }
  5280. }
  5281. return $result_array;
  5282. }
  5283. return array();
  5284. }
  5285. /*
  5286. */
  5287. function zina_scandir($type, $root='', $opts = array()) {
  5288. global $zc;
  5289. @set_time_limit($zc['timeout']);
  5290. $root = $zc['mp3_dir'] . ((!empty($root)) ? '/'.$root : '');
  5291. if(!is_dir($root)) return false;
  5292. if ($type == 'genre') {
  5293. $genres = array();
  5294. $files = zina_core_cache('files_assoc');
  5295. $dwm = array_keys($files);
  5296. foreach ($dwm as $dir) {
  5297. $file = $files[$dir][0];
  5298. $path = (!empty($dir)) ? $dir.'/'.$file : $file;
  5299. $path_full = $zc['mp3_dir'].'/'.$path;
  5300. if (file_exists($path_full)) {
  5301. $mp3 = zina_get_file_info($path_full, false, true, true);
  5302. $genre = ($mp3->tag && isset($mp3->genre)) ? $mp3->genre : zt('Unknown');
  5303. $genres[$genre][] = $dir;
  5304. }
  5305. }
  5306. return $genres;
  5307. }
  5308. $dirs_get = ($type == 'dirs');
  5309. $files_get_assoc = ($type == 'files_assoc');
  5310. if (!($dirs_get || $files_get_assoc)) return false;
  5311. $dir_sort = (isset($opts['dir_sort'])) ? $opts['sort'] : 1;
  5312. $file_sort = (isset($opts['file_sort'])) ? $opts['file_sort'] : 0;
  5313. $custom = (isset($opts['custom'])) ? $opts['custom'] : $zc['honor_custom'];
  5314. $low = (isset($opts['low']) && $opts['low']);
  5315. $dirs_all = $files = array();
  5316. $dirs_all[] = '';
  5317. $start = strlen($zc['mp3_dir'])+1;
  5318. $dirs = array($root);
  5319. while(($dir = array_pop($dirs)) !== null) {
  5320. if ($result = @scandir($dir)) {
  5321. @set_time_limit($zc['timeout']);
  5322. $custom_check = false;
  5323. foreach($result as $filename) {
  5324. if ($filename == '.' || $filename == '..') continue;
  5325. $path = $dir . '/' . $filename;
  5326. if (is_dir($path)) {
  5327. if ($filename[0] == $zc['dir_skip']) continue;
  5328. $dirs[] = $path;
  5329. if ($dirs_get) {
  5330. $dirs_all[] = substr($path, $start);
  5331. }
  5332. } elseif ($files_get_assoc && (preg_match('/\.('.$zc['ext_mus'].')$/i', $filename, $matches) ||
  5333. ($zc['remote'] && preg_match('/\.('.$zc['remote_ext'].')$/i', $filename)))) {
  5334. if ($files_get_assoc) {
  5335. $directory = substr($dir, $start);
  5336. if (empty($directory)) $directory = '';
  5337. if ($custom && !$custom_check) {
  5338. $custom_file = $zc['cache_pls_dir'].'/'.str_replace('/', ' - ', $directory).'.m3u';
  5339. if (file_exists($custom_file)) {
  5340. $custom_files = zunserialize_alt(file_get_contents($custom_file));
  5341. foreach($custom_files as $cf) {
  5342. if ($low) {
  5343. $lofi_file = preg_replace('/\.('.$zc['ext_mus'].')$/i', $zc['low_suf'].'.$1', $cf);
  5344. if (file_exists($zc['mp3_dir'].'/'.$lofi_file)) {
  5345. $files[$directory][] = basename($lofi_file);
  5346. if ($file_sort > 1) {
  5347. $mtimes[$directory][] = filemtime($zc['mp3_dir'].'/'.$lofi_file);
  5348. }
  5349. continue;
  5350. }
  5351. }
  5352. $files[$directory][] = basename($cf);
  5353. if ($file_sort > 1) {
  5354. $mtimes[$directory][] = filemtime($zc['mp3_dir'].'/'.$cf);
  5355. }
  5356. }
  5357. continue 2; # go to next dir
  5358. }
  5359. $custom_check = true;
  5360. }
  5361. if ($low) {
  5362. $lofi_file = preg_replace('/\.('.$zc['ext_mus'].')$/i', $zc['low_suf'].'.$1', $filename);
  5363. $lofi_path = (empty($directory)) ? $lofi_file : $directory.'/'.$lofi_file;
  5364. if (file_exists($zc['mp3_dir'].'/'.$lofi_path)) {
  5365. $files[$directory][] = $lofi_file;
  5366. $files_assoc_uniq[$directory] = true;
  5367. continue;
  5368. }
  5369. }
  5370. $files[$directory][] = $filename;
  5371. if ($file_sort > 1) {
  5372. $mtimes[$directory][] = filemtime($path);
  5373. }
  5374. }
  5375. }
  5376. }
  5377. } else {
  5378. zina_debug(zt('Could not read directory: @dir'),array('@dir'=>$dir));
  5379. }
  5380. }
  5381. if ($files_get_assoc) {
  5382. if (!empty($files)) {
  5383. if ($low) {
  5384. foreach ($files_assoc_uniq as $directory => $x) {
  5385. $files[$directory] = array_unique($files[$directory]);
  5386. }
  5387. }
  5388. if ($file_sort) {
  5389. foreach($files as $dir => $contents) {
  5390. if ($file_sort == 1) {
  5391. rsort($files[$dir]);
  5392. } elseif ($file_sort == 2) {
  5393. array_multisort($mtimes[$dir], SORT_ASC, $files[$dir], SORT_DESC);
  5394. } elseif ($file_sort == 3) {
  5395. array_multisort($mtimes[$dir], SORT_DESC, $files[$dir]);
  5396. }
  5397. }
  5398. }
  5399. if ($dir_sort) ($zc['dir_sort_ignore']) ? uksort($files, 'zsort_ignore') : uksort($files, 'strnatcasecmp');
  5400. return $files;
  5401. }
  5402. } else {
  5403. $result = &$dirs_all;
  5404. if (!empty($result)) {
  5405. if ($low) $result = array_unique($result);
  5406. #todo: ???
  5407. #($zc['dir_sort_ignore']) ? uksort($files, 'zsort_ignore') : uksort($files, 'strnatcasecmp');
  5408. if ($dir_sort) natcasesort($result);
  5409. }
  5410. }
  5411. return $result;
  5412. }
  5413. /*
  5414. * only called when generating playlists & stat blocks
  5415. * otherwise, info should already be available
  5416. */
  5417. function zina_get_file_artist_title($file, $id3, &$result = null) {
  5418. global $zc;
  5419. if ($id3) {
  5420. $mp3 = zina_get_file_info($file, false, true);
  5421. if ($mp3->tag) {
  5422. $result['artist'] = $mp3->artist;
  5423. $result['title'] = $mp3->title;
  5424. return ztheme('artist_song', $mp3->title, $mp3->artist);
  5425. }
  5426. }
  5427. $x = explode('/', $file);
  5428. $len = sizeof($x);
  5429. $song = zina_content_song_title($x[$len - 1]);
  5430. if ($len > 2) {
  5431. $artist = ztheme('title',$x[$len - 3]);
  5432. } elseif (!empty($x[$len-2])) {
  5433. $artist = ztheme('title',$x[$len - 2]);
  5434. } else {
  5435. $artist = false;
  5436. }
  5437. $result['artist'] = $artist;
  5438. $result['title'] = $song;
  5439. return ztheme('artist_song', $song, $artist);
  5440. }
  5441. function zina_get_themes() {
  5442. global $zc;
  5443. $dir = $zc['zina_dir_abs'].'/themes';
  5444. if ($d = @dir($dir)) {
  5445. while($entry = $d->read()) {
  5446. if ($entry == '.' || $entry == '..') continue;
  5447. $opts[$entry] = $entry;
  5448. }
  5449. $d->close();
  5450. return $opts;
  5451. }
  5452. zina_set_message(zt('Cannot read themes directory'),'error');
  5453. return array('zinaGarland'=>'zinaGarland');
  5454. }
  5455. function zina_get_languages() {
  5456. global $zc;
  5457. if ($zc['cache']) {
  5458. $lang_file = $zc['cache_dir_private_abs'].'/languages.txt';
  5459. if (file_exists($lang_file)) {
  5460. return unserialize(file_get_contents($lang_file));
  5461. }
  5462. }
  5463. $dir = $zc['zina_dir_abs'].'/lang';
  5464. if ($d = @dir($dir)) {
  5465. while($entry = $d->read()) {
  5466. if ($entry == '.' || $entry == '..') continue;
  5467. $base = basename($entry,'.php');
  5468. if (substr($base,0,1) != '.') {
  5469. $contents = file_get_contents($dir.'/'.$entry);
  5470. if (preg_match('/\$language\s+=\s+[\'"](.*?)[\'"]/si',$contents, $matches)) {
  5471. $opts[$base] = zt('@lang', array('@lang'=> $matches[1]));
  5472. } else {
  5473. $opts[$base] = zt('Unknown: @code', array('@code'=>$base));
  5474. }
  5475. }
  5476. }
  5477. $d->close();
  5478. asort($opts);
  5479. if ($zc['cache']) {
  5480. file_put_contents($lang_file, serialize($opts));
  5481. }
  5482. return $opts;
  5483. }
  5484. zina_debug(zt('Cannot read languages directory'),'error');
  5485. return array('en'=>zt('English'));
  5486. }
  5487. function zina_get_setting($setting, $default = false) {
  5488. global $zc;
  5489. return (isset($zc[$setting])) ? $zc[$setting] : $default;
  5490. }
  5491. function zina_playlist_opts_all() {
  5492. return array(
  5493. 'all'=>zt('All'),
  5494. 'solo'=>zt('Just Mine')
  5495. );
  5496. }
  5497. function zina_playlist_opts_sort() {
  5498. global $zc;
  5499. $opts = array(
  5500. 'date_created'=> zt('Created Date'),
  5501. 'genre' => zt('Genre'),
  5502. 'sum_items' => zt('Items'),
  5503. 'sum_plays' => zt('Plays'),
  5504. 'sum_rating' => zt('Rating'),
  5505. 'playlist' => zt('Title'),
  5506. 'sum_views' => zt('Views'),
  5507. 'sum_votes' => zt('Votes'),
  5508. );
  5509. if (!$zc['genres']) unset($opts['genre']);
  5510. if (!$zc['pls_ratings']) {
  5511. unset($opts['sum_votes']);
  5512. unset($opts['sum_rating']);
  5513. }
  5514. return $opts;
  5515. }
  5516. function zina_search_opts_sort() {
  5517. return array(
  5518. 'title' => zt('Title'),
  5519. #'mtime' => zt('File Date'),
  5520. 'genre' => zt('Genre'),
  5521. 'sum_rating' => zt('Rating'),
  5522. 'type' => zt('Type'),
  5523. 'sum_votes' => zt('Votes'),
  5524. 'year' => zt('Year'),
  5525. );
  5526. }
  5527. function zina_search_opts_order() {
  5528. return array(
  5529. 'asc' => zt('Ascending'),
  5530. 'desc' => zt('Descending'),
  5531. );
  5532. }
  5533. function zina_search_opts_type($type = false) {
  5534. $types = array(
  5535. 'artist' => zt('Artists'),
  5536. 'album' => zt('Albums'),
  5537. 'song' => zt('Songs'),
  5538. 'playlist' => zt('Playlists'),
  5539. );
  5540. if ($type == 'year') {
  5541. unset($types['playlist']);
  5542. unset($types['artist']);
  5543. }
  5544. return $types;
  5545. }
  5546. function zina_search_opts_per_page() {
  5547. global $zc;
  5548. $array = explode(',', $zc['search_pp_opts']);
  5549. return array_combine($array, $array);
  5550. }
  5551. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  5552. * SEND functions
  5553. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  5554. function zina_send_playlist($content, $store = false) {
  5555. #$mem1=memory_get_usage();$time_start=microtime(true);
  5556. #$time=microtime(true)-$time_start;$mem2=memory_get_peak_usage();printf("<pre>db dir info\nMax memory: %0.2f kbytes\nRunning time: %0.3f s</pre>",($mem2-$mem1)/1024.0, $time);
  5557. #zdbg($content,1);
  5558. global $zc;
  5559. if ($zc['pos']) {
  5560. $tmpfname = tempnam('/tmp', 'zina-');
  5561. file_put_contents($tmpfname, $content);
  5562. $temp_file = $tmpfname.'.m3u';
  5563. if (file_exists($temp_file)) unlink($temp_file);
  5564. rename($tmpfname, $temp_file);
  5565. if ($zc['pos_kill']) exec($zc['pos_kill_cmd']);
  5566. $pos_cmd = str_replace('%TEMPFILENAME%', $tmpfname, $zc['pos_cmd']);
  5567. @session_write_close();
  5568. exec($pos_cmd);
  5569. #sleep(2);
  5570. #unlink("$tmpfname.m3u");
  5571. while(@ob_end_clean());
  5572. header('Location: '.$_SERVER['HTTP_REFERER']);
  5573. exit;
  5574. } else {
  5575. $format = $zc['playlist_format'];
  5576. if ($zc['other_media_types']) {
  5577. $content = preg_replace('#.*?://(.*\.)('.$zc['ext_mus'].')(\n|$)#ie', "\$zc['media_types'][strtolower('$2')][\"protocol\"].\"://\".'$1'.'$2'.'$3'", $content);
  5578. if (preg_match_all('/\.('.$zc['ext_mus'].')(\n|$|\?|&)/i', $content, $ext) && isset($zc['media_types'][$ext[1][0]])) {
  5579. $ext = $ext[1][0];
  5580. $playlist_ext = $zc['media_types'][$ext]['playlist_ext'];
  5581. if ($format == 'asx' && $playlist_ext == 'asx') {
  5582. $content = "<ASX VERSION=\"3.0\">\n<title>".zt('Playlist')."</title>\n".$content.'</ASX>';
  5583. } elseif ($playlist_ext == 'm3u' && $zc['stream_extinf']) {
  5584. $content = "#EXTM3U\n".$content;
  5585. } elseif ($playlist_ext == 'xspf') {
  5586. $content = '<?xml version="1.0" encoding="UTF-8"?'.'>'.
  5587. '<playlist version="1" xmlns="http://xspf.org/ns/0/">'.
  5588. xml_field('title', zt('Playlist')).
  5589. '<trackList>'.$content.'</trackList></playlist>';
  5590. }
  5591. while(@ob_end_clean());
  5592. header('Content-type: '.$zc['media_types'][$ext]['playlist_mime']);
  5593. header('Content-Disposition: inline; filename=playlist.'.$playlist_ext);
  5594. } else {
  5595. zina_debug('Bad other media type');
  5596. }
  5597. } else {
  5598. if ($format == 'm3u') {
  5599. if ($zc['stream_extinf']) $content = "#EXTM3U\n".$content;
  5600. } elseif ($format == 'asx') {
  5601. $content = "<ASX VERSION=\"3.0\">\n<title>".zt('Playlist')."</title>\n".$content.'</ASX>';
  5602. } elseif ($format == 'xspf') {
  5603. $content = '<?xml version="1.0" encoding="UTF-8"?'.'>'.
  5604. '<playlist version="1" xmlns="http://xspf.org/ns/0/">'.
  5605. xml_field('title', zt('Playlist')).
  5606. '<trackList>'.$content.'</trackList></playlist>';
  5607. }
  5608. }
  5609. if ($store) {
  5610. $_SESSION['zina_store'] = array('type'=>$format, 'content'=>$content);
  5611. zina_send_playlist_content('store', zurl('','l=74&rand='.time()));
  5612. } else {
  5613. zina_send_playlist_content($format, $content);
  5614. }
  5615. }
  5616. exit;
  5617. }
  5618. function zina_send_playlist_content($type, $content) {
  5619. while(@ob_end_clean());
  5620. if ($type == 'm3u') {
  5621. header("Content-type: audio/mpegurl", true, 200);
  5622. header('Content-Disposition: inline; filename=playlist.m3u');
  5623. } elseif ($type == 'asx') {
  5624. header('Content-type: application/vnd.ms-asx', true, 200);
  5625. header('Content-Disposition: inline; filename=playlist.asx');
  5626. } elseif ($type == 'xspf') {
  5627. header('Content-type: application/xspf+xml', true, 200);
  5628. header('Content-Disposition: inline; filename=playlist.xml');
  5629. $content = preg_replace('/&[^; ]{0,6}.?/e', "((substr('\\0',-1) == ';') ? '\\0' : '&amp;'.substr('\\0',1))", $content);
  5630. $content = preg_replace('/&zid/', '&amp;', $content);
  5631. }
  5632. header('Cache-control: private'); #IE seems to need this.
  5633. echo $content;
  5634. exit;
  5635. }
  5636. function zina_send_playlist_song($path, $low = false) {
  5637. zina_send_playlist(zina_get_playlist(array($path), $low, false));
  5638. }
  5639. function zina_send_playlist_title($path, $custom, $low = false) {
  5640. zina_send_playlist(zina_get_title_playlist($path, $custom, $low));
  5641. }
  5642. function zina_send_playlist_selected($songs, $low = false, $store = false) {
  5643. zina_send_playlist(zina_get_playlist($songs, $low, true), $store);
  5644. }
  5645. # hack central...fix this
  5646. function zina_send_playlist_selected_random($items, $low = false, $store = false) {
  5647. global $zc;
  5648. $items = zina_get_playlist($items, $low, true);
  5649. if ($zc['stream_extinf']) {
  5650. if ($zc['playlist_format'] == 'xspf') {
  5651. $delim = '<track>';
  5652. } else {
  5653. $delim = '#EXTINF';
  5654. }
  5655. $x = explode($delim, $items);
  5656. array_shift($x);
  5657. zo_shuffle($x);
  5658. $songs = $delim.implode($delim, $x);
  5659. } else {
  5660. $delim = "\n";
  5661. $x = explode($delim, $items);
  5662. array_pop($x);
  5663. zo_shuffle($x);
  5664. $songs = implode($delim, $x).$delim;
  5665. }
  5666. zina_send_playlist($songs, $store);
  5667. }
  5668. function zina_get_playlist_custom($pls_id) {
  5669. global $zc;
  5670. $where = 'p.id = %d';
  5671. if (!$zc['is_admin']) {
  5672. if ($zc['pls_public']) {
  5673. $where .= ' AND (p.user_id = %d OR p.visible = 1)';
  5674. } else {
  5675. $where .= ' AND p.user_id = %d';
  5676. }
  5677. }
  5678. $sql = "SELECT ".
  5679. "CASE pm.type ".
  5680. "WHEN 'song' THEN IF(f.path!='.' && f.path!='',CONCAT(f.path,IF(ISNULL(f.path), '','/'),f.file), f.file) ".
  5681. "WHEN 'album' THEN CONCAT(d.path,'/.lp') ".
  5682. "WHEN 'playlist' THEN CONCAT(pm.type_id,'.pls') ".
  5683. "END AS path ".
  5684. "FROM {playlists_map} as pm ".
  5685. "INNER JOIN {playlists} as p ON (pm.playlist_id = p.id) ".
  5686. "LEFT OUTER JOIN {files} AS f ON pm.type = 'song' AND pm.type_id = f.id ".
  5687. "LEFT OUTER JOIN {dirs} AS d ON pm.type = 'album' AND pm.type_id = d.id ".
  5688. "WHERE $where ".
  5689. "ORDER BY weight";
  5690. return zdbq_array_list($sql, array($pls_id, $zc['user_id']));
  5691. }
  5692. function zina_send_playlist_custom($playlist, $low, $random = false) {
  5693. global $zc;
  5694. $items = array();
  5695. if($zc['session_pls'] && $playlist == 'zina_session_playlist') {
  5696. if ($zc['database']) {
  5697. $results = zina_get_session_playlist();
  5698. foreach($results as $item) {
  5699. if ($item['type'] == 'album') {
  5700. $items[] = $item['path'].'/.lp';
  5701. } elseif ($item['type'] == 'playlist') {
  5702. $items[] = $item['type_id'].'.pls';
  5703. } else {
  5704. $items[] = $item['path'];
  5705. }
  5706. }
  5707. if (!empty($items) && $random) zina_send_playlist_selected_random($items);
  5708. } else {
  5709. if (isset($_SESSION['z_sp'])) $items = unserialize_utf8($_SESSION['z_sp']);
  5710. }
  5711. } else {
  5712. if ($playlist != 'new_zina_list') {
  5713. if ($zc['database']) {
  5714. $items = zina_get_playlist_custom($playlist);
  5715. if (!empty($items)) {
  5716. zdb_log_stat_playlist($playlist, 'plays');
  5717. if ($random) zina_send_playlist_selected_random($items);
  5718. }
  5719. } else {
  5720. $filename = $zc['cache_pls_dir'].'/_zina_'.str_replace('/',' - ',$playlist).'.m3u';
  5721. if (file_exists($filename)) {
  5722. $items = zunserialize_alt(file_get_contents($filename));
  5723. }
  5724. }
  5725. }
  5726. }
  5727. zina_send_playlist(zina_get_playlist($items, $low, true));
  5728. }
  5729. /*
  5730. * Sends various playlists via cache
  5731. * - random by albums, song
  5732. * - directory recursive
  5733. * - directory recursive random
  5734. * - random by song ratings
  5735. * - random by album ratings
  5736. * - random by genre
  5737. * Also, non-cached
  5738. * - above minus genre and db stuff
  5739. *
  5740. * type:
  5741. * 't' => title,
  5742. * 's' => song
  5743. * 's' && num ==0 => resursive & random recursive ($rand = true)
  5744. * 'tt' => songs via rated songs
  5745. * 'artist' => 'songs via rated albums
  5746. */
  5747. function zina_send_playlist_random($num, $type, $low, $rand = true, $path = null, $genre = null, $year = false) {
  5748. global $zc;
  5749. @set_time_limit($zc['timeout']);
  5750. $opts = explode(',',$zc['rating_random_opts']);
  5751. $rating = isset($_POST['rating']) ? $_POST['rating'] : (isset($_GET['rating']) ? $_GET['rating'] : null);
  5752. if ($zc['database'] && $zc['rating_random'] && in_array($rating, $opts)) {
  5753. $random_rating = true;
  5754. } else {
  5755. $random_rating = false;
  5756. if ($type == 'tt' && $rating == 0) $type = 's';
  5757. }
  5758. if ($year) {
  5759. $array = array();
  5760. if ($zc['db_search']) {
  5761. $total = zdbq_single('SELECT COUNT(*) FROM {files} WHERE year = %d', array($year));
  5762. if ($zc['random_least_played'] && $total > $num) {
  5763. $array = zina_least_played($num, 'year = %d AND', array($year));
  5764. } else {
  5765. $array = zdbq_array_list("SELECT IF(path!='.',CONCAT(path,IF(ISNULL(path), '','/'),file),file) as path ".
  5766. "FROM {files} ".
  5767. "WHERE year = %d", array($year));
  5768. }
  5769. #TODO:
  5770. if ($type == 't') {
  5771. } elseif ($type == 'artist') {
  5772. } else { #if ($type == 's') {
  5773. }
  5774. }
  5775. } elseif ($zc['genres'] && !empty($genre) && $genre != 'zina') {
  5776. if ($zc['database']) {
  5777. $array = array();
  5778. $children = zdb_genres_get_children($genre);
  5779. $children[] = $genre;
  5780. $in = str_repeat("'%s',", sizeof($children)-1)."'%s'";
  5781. $vars = $children;
  5782. $vars[] = $num;
  5783. if ($type == 's' || $type == 'artist') {
  5784. $rand = false;
  5785. $array = zdbq_array_list("SELECT CONCAT(path,IF(ISNULL(path), '','/'),file) ".
  5786. "FROM {files} WHERE genre IN ($in) ORDER BY RAND() LIMIT %d", $vars);
  5787. } else {
  5788. $rand = false;
  5789. $array = zdbq_array_list("SELECT path ".
  5790. "FROM {dirs} WHERE genre IN ($in) ORDER BY RAND() LIMIT %d", $vars);
  5791. }
  5792. # probably could make one sql stmt w/ above
  5793. if ($random_rating) { #dir and files?
  5794. #todo: opt to have random honor user_id? pass user_id???
  5795. $files_rated = zdb_get_random_by_rating($type, $rating);
  5796. $array = array_values(array_intersect($array, $files_rated));
  5797. }
  5798. } else {
  5799. $genres = zina_core_cache('genre');
  5800. $array = $genres[$genre];
  5801. if ($type == 's' || $type == 'artist') {
  5802. #todo: could be better artist stuff
  5803. $files = array();
  5804. $dirs = zina_core_cache('files_assoc', $path, array('low'=>$low));
  5805. foreach($array as $title) {
  5806. foreach($dirs[$title] as $file) {
  5807. $files[] = $title.'/'.$file;
  5808. }
  5809. }
  5810. $array = $files;
  5811. }
  5812. }
  5813. } elseif ($random_rating) {
  5814. # artist or tt or s
  5815. if ($type == 't' || $type == 'tt')
  5816. $dirs = zina_core_cache('files_assoc', $path, array('low'=>$low));
  5817. $array = zdb_get_random_by_rating($type, $rating, $num);
  5818. if ($type == 'artist' && $zc['honor_custom']) {
  5819. #todo: by passing $num above && least_played, might return < $num
  5820. $files = zina_core_cache('files', $path, array('low'=>$low));
  5821. $array = array_values(array_intersect($array, $files));
  5822. }
  5823. } else { # normal
  5824. if ($type == 't') {
  5825. $sort = ($rand) ? 0 : $zc['files_sort'];
  5826. $dir_sort = ($rand) ? 0 : 1;
  5827. $dirs = zina_core_cache('files_assoc', $path, array('low'=>$low, 'file_sort'=>$sort, 'dir_sort'=>$dir_sort));
  5828. $array = array_keys($dirs);
  5829. } else {
  5830. $type = 's';
  5831. if ($zc['database'] && $zc['random_least_played']) {
  5832. #todo: doesn't honor "custom"
  5833. $total = zdbq_single('SELECT COUNT(*) FROM {files}');
  5834. if ($total <= $num || $num == 0) {
  5835. $array = zina_core_cache('files', $path, array('low'=>$low));
  5836. } else {
  5837. $array = zina_least_played($num);
  5838. }
  5839. } else {
  5840. $array = zina_core_cache('files', $path, array('low'=>$low));
  5841. }
  5842. }
  5843. }
  5844. # Songs via Rated Albums
  5845. if ($type == 'tt') {
  5846. foreach($array as $title) {
  5847. foreach($dirs[$title] as $file) {
  5848. $files[] = $title.'/'.$file;
  5849. }
  5850. }
  5851. $array = $files;
  5852. }
  5853. if ($rand) zo_shuffle($array);
  5854. $total = sizeof($array);
  5855. if ($num == 0 || $num > $total) $num = $total;
  5856. $array = array_slice($array,0,$num);
  5857. if ($type == 't') {
  5858. foreach($array as $title) {
  5859. foreach($dirs[$title] as $file) {
  5860. $files[] = $title.'/'.$file;
  5861. }
  5862. }
  5863. $array = $files;
  5864. }
  5865. zina_send_playlist(zina_get_playlist($array, $low));
  5866. }
  5867. #TODO: move
  5868. function zina_least_played($total, $where = '', $where_vars = array()) {
  5869. global $zc;
  5870. $result = array();
  5871. $count = 0;
  5872. $floor = $zc['random_lp_floor'];
  5873. $limit = $least = ceil($total*$zc['random_lp_perc']/100);
  5874. while ($count < $least) {
  5875. #todo: by user_id?
  5876. $vars = $where_vars;
  5877. $vars[] = $floor;
  5878. $vars[] = $limit;
  5879. $result += zdbq_assoc_list("SELECT id, CONCAT(path,IF(ISNULL(path), '','/'),file) ".
  5880. "FROM {files} WHERE $where sum_plays = %d ORDER BY RAND() LIMIT %d", $vars);
  5881. $count = sizeof($result);
  5882. if ($count < $least) {
  5883. $limit = $least - $count;
  5884. $floor++;
  5885. }
  5886. }
  5887. if ($count < $total) {
  5888. $vars = $where_vars;
  5889. $vars[] = $floor;
  5890. $vars[] = implode(',', array_keys($result));
  5891. $vars[] = $total - $count;
  5892. $result = array_merge($result, zdbq_array_list("SELECT CONCAT(path,IF(ISNULL(path), '','/'),file) ".
  5893. "FROM {files} WHERE $where sum_plays >= %d AND id NOT IN(%s) ORDER BY RAND() LIMIT %d", $vars));
  5894. }
  5895. return $result;
  5896. }
  5897. function zina_send_zip_selected($songs, $lofi = false, $filename = 'selectedmusic') {
  5898. global $zc;
  5899. #todo: lowfi, baby
  5900. if ($zc['cmp_sel']) {
  5901. $zipfile = $zc['cache_zip_dir'] .'/'. md5(serialize($songs)).'.zip';
  5902. $files = null;
  5903. if ($zc['cmp_sel'] == 1) { #EXTERNAL
  5904. #todo: make opt to limit on number of files??? or dirs??? or opt on search pages?
  5905. foreach ($songs as $song) {
  5906. $song = zrawurldecode($song);
  5907. if ($zc['database'] && $zc['stats']) zdb_log_stat('down', dirname($song), basename($song));
  5908. $files .= '"'.$zc['mp3_dir'].'/'.$song.'" ';
  5909. }
  5910. if ($zc['cmp_cache']) {
  5911. if (zina_send_zip_helper($zipfile, $zc['cmp_mime'], $filename.'.'.$zc['cmp_extension']))
  5912. exit;
  5913. } else {
  5914. $zipfile = '-';
  5915. }
  5916. $opts = str_replace(array('%FILE%','%FILELIST%'), array($zipfile, $files), $zc['cmp_set']);
  5917. $passthru = $zc['cmp_pgm'].' '.$opts;
  5918. zina_send_zip_helper($zipfile,
  5919. $zc['cmp_mime'],
  5920. $filename.'.'.$zc['cmp_extension'],
  5921. $passthru,
  5922. $zc['cmp_cache']);
  5923. }
  5924. else { # internal
  5925. if ($zc['cmp_cache']) {
  5926. if (zina_send_zip_helper($zipfile, 'application/zip', $filename.'.zip'))
  5927. exit;
  5928. }
  5929. $zip = new ZipArchive;
  5930. if (($result = $zip->open($zipfile,ZIPARCHIVE::CREATE)) === TRUE) {
  5931. foreach ($songs as $song) {
  5932. $song = zrawurldecode($song);
  5933. if ($zc['database'] && $zc['stats']) zdb_log_stat('down', dirname($song), basename($song));
  5934. $file = $zc['mp3_dir'].'/'.$song;
  5935. $zip->addFile($file, $song);
  5936. }
  5937. $zip->close();
  5938. }
  5939. else {
  5940. #todo: might be able to redirect...
  5941. zina_debug(zt('Could not open archive file: @err', array('@err'=>$result)), 'error');
  5942. exit;
  5943. }
  5944. zina_send_zip_helper($zipfile, 'application/zip', $filename.'.zip');
  5945. if (!$zc['cmp_cache'] && file_exists($zipfile)) {
  5946. @unlink($zipfile);
  5947. }
  5948. }
  5949. }
  5950. exit;
  5951. }
  5952. function zina_send_zip_selected_dir($dir, $custom, $low) {
  5953. $path = preg_replace('/\/\.lp$/i', '', $dir);
  5954. if (empty($path)) $path = false;
  5955. $dirs = zina_core_cache('files_assoc', $path, array('low'=>$low,'custom'=>$custom,'force'=>(empty($path))));
  5956. $files = array();
  5957. $filename = 'not found';
  5958. if (isset($dirs[$path])) {
  5959. foreach($dirs[$path] as $file) {
  5960. $files[] = (empty($path)) ? $file : $path.'/'.$file;
  5961. }
  5962. $filename = str_replace('/', ' - ', $path);
  5963. }
  5964. zina_send_zip_selected($files, $low, $filename);
  5965. }
  5966. function zina_send_zip_helper($file, $mime, $filename, $passthru = false, $cache = true) {
  5967. zina_set_header('Content-type: '.$mime);
  5968. zina_set_header('Content-Disposition: inline; filename="'.$filename.'"');
  5969. @session_write_close();
  5970. if ($passthru) {
  5971. if (!$cache) {
  5972. while(@ob_end_clean());
  5973. zina_get_headers();
  5974. passthru($passthru);
  5975. return;
  5976. }
  5977. else {
  5978. passthru($passthru);
  5979. }
  5980. }
  5981. if (file_exists($file)) {
  5982. while(@ob_end_clean());
  5983. header('Content-Length: '.filesize($file));
  5984. if (zina_send_file($file)) {
  5985. return true;
  5986. }
  5987. else {
  5988. zina_debug(zt('Cannot stream compressed downloads'), 'error');
  5989. }
  5990. }
  5991. return false;
  5992. }
  5993. function zina_add_now_playing($path) {
  5994. global $zc;
  5995. $_SESSION[''][$path] = $zc['mp3_dir'].'/'.$path;
  5996. if (preg_match('/\.('.$zc['ext_mus'].')$/i', $path, $exts)) {
  5997. $result = false;
  5998. $file = $zc['mp3_dir'].'/'.$path;
  5999. if ($zc['lastfm'] && $zc['user_id'] > 0) {
  6000. if ($zc['lastfm']) require_once($zc['zina_dir_abs'].'/extras/scrobbler.2.0.class.php');
  6001. $mp3 = zina_get_file_info($file);
  6002. if ($mp3->tag) {
  6003. $_SESSION[''][$path.'_start_time'] = time();
  6004. // Set the start timestamp so we can get it later, this is used to ensure that the
  6005. // entire track was listened to.
  6006. if (!isset($mp3->track)) $mp3->track = '';
  6007. if ($zc['lastfm']) {
  6008. if (isset($_SESSION['scrobbler_sk'])) {
  6009. $scrobbler = new scrobbler($zc['lastfm_username'],$zc['lastfm_password'],$_SESSION['scrobbler_sk']);
  6010. }
  6011. else
  6012. {
  6013. $scrobbler = new scrobbler($zc['lastfm_username'],$zc['lastfm_password']);
  6014. if (!$scrobbler->do_auth()) {
  6015. zina_debug(zt('Do Auth failed'));
  6016. unset($_SESSION['scrobbler_sk']);
  6017. }
  6018. else {
  6019. // Store off the session key
  6020. $_SESSION['scrobbler_sk'] = $scrobbler->sk;
  6021. }
  6022. }
  6023. if (!$scrobbler->now_playing($mp3->artist, $mp3->title)) {
  6024. zina_debug('Zina Error: scrobbler cannot submit now playing: '.$scrobbler->lfm_err_str);
  6025. }
  6026. }
  6027. }
  6028. }
  6029. }
  6030. exit;
  6031. }
  6032. function zina_complete_scrobble($path) {
  6033. global $zc;
  6034. if (preg_match('/\.('.$zc['ext_mus'].')$/i', $path)) {
  6035. if ($zc['lastfm'] && $zc['user_id'] > 0) {
  6036. require_once($zc['zina_dir_abs'].'/extras/scrobbler.2.0.class.php');
  6037. $mp3 = zina_get_file_info($zc['mp3_dir'].'/'.$path);
  6038. if ($mp3->tag) {
  6039. $played = time() - $_SESSION[''][$path.'_start_time'];
  6040. if ($played < $mp3->length/2) {
  6041. exit;
  6042. }
  6043. // Clear the start time
  6044. $_SESSION[''][$path.'_start_time'] = 0;
  6045. /*
  6046. #TODO: when last.fm allows Love submissions...
  6047. if ($zc['database'] && $zc['stats']) {
  6048. $rating = zdbq_single("SELECT r.rating ".
  6049. "FROM {files} as f INNER JOIN {file_ratings} AS r ON (f.id = r.file_id) ".
  6050. "WHERE file = '%s' AND r.user_id = %d", array($path, $zc['user_id']));
  6051. if (!empty($rating) && $rating == 5) $mp3->love = true;
  6052. }
  6053. */
  6054. $t = new stdClass();
  6055. $t->artist = $mp3->artist;
  6056. $t->track = $mp3->title;
  6057. $t->timestamp = time();
  6058. if ($_SESSION['scrobbler_sk'] != null) {
  6059. $scrobbler = new scrobbler($zc['lastfm_username'],$zc['lastfm_password'],$_SESSION['scrobbler_sk'],$t);
  6060. }
  6061. else {
  6062. $scrobbler = new scrobbler($zc['lastfm_username'],$zc['lastfm_password']);
  6063. if (!$scrobbler->do_auth()) {
  6064. zina_debug(zt('Do Auth failed'));
  6065. unset($_SESSION['scrobbler_sk']);
  6066. exit;
  6067. }
  6068. else {
  6069. // Store off the session key
  6070. $_SESSION['scrobbler_sk'] = $scrobbler->sk;
  6071. }
  6072. }
  6073. $scrobbler->queued_tracks = zina_set_scrobbler_queue();
  6074. if (!$scrobbler->scrobble()) {
  6075. zina_set_scrobbler_queue($scrobbler->queued_tracks);
  6076. }
  6077. else {
  6078. zina_set_scrobbler_queue(array(), true);
  6079. }
  6080. unset($_SESSION['zinamp_track'][$path]);
  6081. }
  6082. }
  6083. }
  6084. exit;
  6085. }
  6086. function zina_send_file_music($path, $resample = false) {
  6087. global $zc;
  6088. if (preg_match('/\.('.$zc['ext_mus'].')$/i', $path, $exts)) {
  6089. $result = false;
  6090. $ext = strtolower($exts[1]);
  6091. $file = $zc['mp3_dir'].'/'.$path;
  6092. if (($zc['lastfm'] || $zc['twitter']) && $zc['user_id'] > 0) {
  6093. if ($zc['lastfm']) require_once($zc['zina_dir_abs'].'/extras/scrobbler.class.php');
  6094. if ($zc['twitter']) require_once($zc['zina_dir_abs'].'/extras/twitter.class.php');
  6095. $mp3 = zina_get_file_info($file);
  6096. if ($mp3->tag) {// && $mp3->info) {
  6097. $icy = ztheme('artist_song', $mp3->title, $mp3->artist);
  6098. // Set the start timestamp so we can get it later, this is used to ensure that the
  6099. // entire track was listened to.
  6100. $_SESSION['zinamp_track'][$path.'timestamp'] = time();
  6101. if (!isset($mp3->track)) $mp3->track = '';
  6102. if (!isset($mp3->album)) $mp3->album = '';
  6103. if ($zc['lastfm'] && $zc['zinamp'] == 3) {
  6104. $scrobbler = new scrobbler($zc['lastfm_username'],$zc['lastfm_password']);
  6105. if (!$scrobbler->now_playing($mp3)) {
  6106. zina_debug('Zina Error: scrobbler cannot submit now playing: '.$scrobbler->error_msg);
  6107. }
  6108. }
  6109. if ($zc['twitter']) {
  6110. $twitter = new twitter($zc['twitter_username'], $zc['twitter_password']);
  6111. if (!$twitter->set_status('Listening to '.$icy)) {
  6112. zina_debug('Zina Error: twitter cannot set status: '.$scrobbler->error_msg);
  6113. }
  6114. }
  6115. }
  6116. else {
  6117. $icy = zina_get_file_artist_title($path, false);
  6118. }
  6119. }
  6120. if (!isset($icy)) {
  6121. $icy = zina_get_file_artist_title($file, $zc['mp3_id3']);
  6122. }
  6123. if ($resample) {
  6124. if (!preg_match('/\.('.$zc['ext_enc'].')$/i', $path, $exts)) {
  6125. zina_debug('Zina Error: Bad song sent to resample function.');
  6126. exit;
  6127. }
  6128. zina_debug(zt('encoder'));
  6129. $type = $zc['encoders'][$ext]['mime'];
  6130. } else {
  6131. $type = $zc['media_types'][$ext]['mime'];
  6132. $filesize = filesize($file);
  6133. }
  6134. $sapi_type = php_sapi_name();
  6135. if (substr($sapi_type, 0, 3) == 'cgi') {
  6136. zina_set_header('HTTP/1.0 200 OK');
  6137. }
  6138. else {
  6139. zina_set_header('ICY 200 OK');
  6140. }
  6141. zina_set_header('icy-name: '.$icy);
  6142. zina_set_header('Connection: close');
  6143. zina_set_header('Content-type: '.$type);
  6144. zina_set_header('Content-Disposition: inline; filename="'.$icy.'"');
  6145. if ($resample) {
  6146. @set_time_limit(0);
  6147. @session_write_close();
  6148. $opts = str_replace('%FILE%', '"'.$file.'"', $zc['encoders'][$ext]['opts']);
  6149. $begin = time();
  6150. while(@ob_end_clean());
  6151. zina_get_headers();
  6152. passthru($zc['encoders'][$ext]['encoder'].' '.$opts);
  6153. if (isset($scrobbler)) {
  6154. $result = (time() - $begin > $mp3->length / 2);
  6155. }
  6156. }
  6157. else {
  6158. zina_set_header('Content-Length: '.$filesize);
  6159. if ($end = zina_send_file($file)) {
  6160. $result = ($end > $filesize / 3 * 2);
  6161. if ($zc['zinamp'] && isset($scrobbler)) {
  6162. $result = false;
  6163. $_SESSION['zinamp_track'][$path] = time();
  6164. }
  6165. }
  6166. }
  6167. if (isset($scrobbler) && $result) {
  6168. zina_scrobbler_submit($scrobbler, $mp3);
  6169. }
  6170. }
  6171. exit;
  6172. }
  6173. function zina_play_complete($path, $length) {
  6174. global $zc;
  6175. zina_debug(zt('called zina_play_complete()'));
  6176. if (preg_match('/\.('.$zc['ext_mus'].')$/i', $path)) {
  6177. if ($zc['lastfm'] && $zc['user_id'] > 0) {
  6178. require_once($zc['zina_dir_abs'].'/extras/scrobbler.class.php');
  6179. if (isset($_SESSION['zinamp_track'][$path])) {
  6180. $mp3 = zina_get_file_info($zc['mp3_dir'].'/'.$path);
  6181. if ($mp3->tag) {
  6182. $icy = ztheme('artist_song', $mp3->title, $mp3->artist);
  6183. $mp3->timestamp = $_SESSION['zinamp_track'][$path.'timestamp'];
  6184. $mp3->length = $length;
  6185. /*
  6186. #TODO: when last.fm allows Love submissions...
  6187. if ($zc['database'] && $zc['stats']) {
  6188. $rating = zdbq_single("SELECT r.rating ".
  6189. "FROM {files} as f INNER JOIN {file_ratings} AS r ON (f.id = r.file_id) ".
  6190. "WHERE file = '%s' AND r.user_id = %d", array($path, $zc['user_id']));
  6191. if (!empty($rating) && $rating == 5) $mp3->love = true;
  6192. }
  6193. */
  6194. $scrobbler = new scrobbler($zc['lastfm_username'],$zc['lastfm_password']);
  6195. zina_scrobbler_submit($scrobbler, $mp3);
  6196. unset($_SESSION['zinamp_track'][$path]);
  6197. }
  6198. }
  6199. else {
  6200. zina_debug(zt('scrobbler session not set: @path', array('@path'=>$path)), 'error');
  6201. }
  6202. }
  6203. }
  6204. }
  6205. function zina_scrobbler_submit(&$scrobbler, $mp3) {
  6206. $scrobbler->queued_tracks = zina_set_scrobbler_queue();
  6207. if (!isset($mp3->track)) $mp3->track = '';
  6208. if (!isset($mp3->album)) $mp3->album = '';
  6209. if ($scrobbler->submit_track($mp3)) {
  6210. zina_set_scrobbler_queue(array(), true);
  6211. }
  6212. else {
  6213. zina_debug('scrobbler cannot submit tracks: '.$scrobbler->error_msg);
  6214. zina_set_scrobbler_queue($scrobbler->queued_tracks);
  6215. }
  6216. }
  6217. function zina_send_file($file) {
  6218. @set_time_limit(0);
  6219. @session_write_close();
  6220. $fp = @fopen($file, 'rb');
  6221. if ($fp !== false) {
  6222. ignore_user_abort(true);
  6223. # various embeds
  6224. while(@ob_end_clean());
  6225. zina_get_headers();
  6226. while(!feof($fp)) {
  6227. echo fread($fp, 8192);
  6228. flush();
  6229. if (connection_status() != 0) {
  6230. break;
  6231. }
  6232. }
  6233. $end = ftell($fp);
  6234. fclose($fp);
  6235. return $end;
  6236. }
  6237. return false;
  6238. }
  6239. function zina_send_image_resized($source, $type, $txt = null, $cache_file = false, $string = false) {
  6240. global $zc;
  6241. $types = array(1=>'gif', 2=>'jpeg', 3=>'png', 7=>'tiff', 8=>'tiff');
  6242. if ($string || $info = getimagesize($source)) {
  6243. if ($string) {
  6244. $org_image = imagecreatefromstring($string['data']);
  6245. $org_x = imagesx($org_image);
  6246. $org_y = imagesy($org_image);
  6247. $org_type = ($string['type'] == 'jpg') ? 'jpeg' : $string['type'];
  6248. }
  6249. else {
  6250. $org_type = $types[$info[2]];
  6251. $org_image = call_user_func('imagecreatefrom'.$org_type,$source);
  6252. $org_x = $info[0];
  6253. $org_y = $info[1];
  6254. }
  6255. $new_x = $zc['res_'.$type.'_x'];
  6256. $quality = $zc['res_'.$type.'_qual'];
  6257. $res_out_type = $zc['res_out_type'];
  6258. if (!$zc['res_out_x_lmt'] || $org_x > $new_x) {
  6259. $new_y = intval($org_y * $new_x / $org_x);
  6260. $new_image = imagecreatetruecolor($new_x, $new_y);
  6261. imagecopyresampled($new_image, $org_image, 0, 0, 0, 0, $new_x, $new_y, $org_x, $org_y);
  6262. }
  6263. else {
  6264. $res_out_type = $org_type;
  6265. $new_image = $org_image;
  6266. $new_x = $org_x;
  6267. $new_y = $org_y;
  6268. }
  6269. $font = (isset($zc[$type.'_img_txt_font'])) ? $zc[$type.'_img_txt_font'] : false;
  6270. if (!empty($txt) && $font && file_exists($font) && function_exists('imagettftext')) {
  6271. $clr_str = $zc[$type.'_img_txt_color'];
  6272. $font_size = $zc[$type.'_img_txt_font_size'];
  6273. $txt = wordwrap(html_entity_decode($txt), $zc[$type.'_img_txt_wrap'], "\r\n");
  6274. $box = imagettfbbox($font_size, 0, $font, $txt);
  6275. $rgb = explode(',',$clr_str);
  6276. $color = imagecolorallocate($new_image, $rgb[0], $rgb[1], $rgb[2]);
  6277. $bx = $box[2] - $box[0];
  6278. $by = $box[5] - $box[3];
  6279. $mod = ($type == 'search') ? 1 : .5;
  6280. $vert = 2 + (substr_count($txt, "\r\n") * $mod);
  6281. $txt_x = ($new_x - $bx)/2;
  6282. $txt_y = ($new_y - $by)/$vert;
  6283. imagettftext($new_image, $font_size, 0, $txt_x, $txt_y, $color, $font, $txt);
  6284. }
  6285. imageinterlace($new_image, true);
  6286. if (function_exists('image'.$res_out_type)) {
  6287. if ($res_out_type == 'png') $quality = round(abs(($quality - 100) / 11.111111));
  6288. if ($zc['cache_imgs'] && $cache_file && is_writeable($zc['cache_imgs_dir'])) {
  6289. call_user_func('image'.$res_out_type,$new_image,$cache_file,$quality);
  6290. }
  6291. while(@ob_end_clean());
  6292. Header('Content-type: image/'.$res_out_type);
  6293. call_user_func('image'.$res_out_type,$new_image,null,$quality);
  6294. }
  6295. @imagedestroy($new_image);
  6296. @imagedestroy($org_image);
  6297. }
  6298. else {
  6299. zina_debug(zt('Zina Error: Could not open image file: @file', array('@file'=>$source)));
  6300. }
  6301. }
  6302. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  6303. * WRITE/UPDATE/DELETE functions
  6304. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  6305. function zina_write_playlist($songs, $filename, $type = '') {
  6306. global $zc;
  6307. $files = array();
  6308. if (!empty($songs)) {
  6309. foreach ($songs as $song) {
  6310. $files[] = zrawurldecode($song);
  6311. }
  6312. }
  6313. if($zc['session_pls'] && strstr($filename,'zina_session_playlist')) {
  6314. if (empty($files)) {
  6315. unset($_SESSION['z_sp']);
  6316. }
  6317. else { # new/additions
  6318. if ($type == 'a' && isset($_SESSION['z_sp'])) {
  6319. $existing = unserialize_utf8($_SESSION['z_sp']);
  6320. $files = array_merge($existing, $files);
  6321. }
  6322. if (sizeof($files) > $zc['pls_length_limit']) {
  6323. $files = array_slice($files, 0, 100);
  6324. zina_set_message(zt('Session playlists limited to @num items.', array('@num'=>$zc['pls_length_limit'])), 'warn');
  6325. }
  6326. $_SESSION['z_sp'] = utf8_encode(serialize($files));
  6327. }
  6328. }
  6329. else {
  6330. $content = serialize($files);
  6331. $filename = $zc['cache_pls_dir'].'/'.$filename;
  6332. if ($type == 'a' && file_exists($filename)) {
  6333. $existing = zunserialize_alt(file_get_contents($filename));
  6334. if (!empty($existing)) $content = serialize(array_merge($existing, $files));
  6335. }
  6336. file_put_contents($filename, $content);
  6337. if (empty($files) && ($type == 't') && file_exists($filename)) unlink($filename);
  6338. }
  6339. }
  6340. function zina_delete_playlist_custom($pls_name) {
  6341. global $zc;
  6342. if ($pls_name == 'zina_session_playlist') {
  6343. unset($_SESSION['z_sp']);
  6344. }
  6345. elseif ($pls_name != 'new_zina_list') {
  6346. $filename = $zc['cache_pls_dir'].'/_zina_'.$pls_name.'.m3u';
  6347. if (file_exists($filename)) {
  6348. unlink($filename);
  6349. }
  6350. }
  6351. }
  6352. function zina_delete_tmpl_file($file) {
  6353. global $zc;
  6354. if (strstr($file,'..')) {
  6355. return false;
  6356. }
  6357. $cache_file = $zc['cache_tmpl_dir'].'/'.$file;
  6358. if (file_exists($cache_file)) {
  6359. return unlink($cache_file);
  6360. }
  6361. return true;
  6362. }
  6363. function zina_delete_files($path) {
  6364. if (file_exists($path) && is_dir($path) && is_writeable($path)) {
  6365. if ($d = @dir($path)) {
  6366. while($entry = $d->read()) {
  6367. if ($entry != '.' && $entry != '..') {
  6368. unlink($path.'/'.$entry);
  6369. }
  6370. }
  6371. $d->close();
  6372. return true;
  6373. }
  6374. }
  6375. zina_set_message(zt('Cannot open directory to delete files.'));
  6376. return false;
  6377. }
  6378. function zina_write_settings() {
  6379. global $zc;
  6380. $fields = zina_get_settings('cfg');
  6381. $lang = zina_get_settings('lang');
  6382. $titles = &$lang['titles'];
  6383. $errors = false;
  6384. if (!zina_token_sess_check()) {
  6385. zina_debug(zt('Session token does not match.'));
  6386. return false;
  6387. }
  6388. $config = "<?php\n";
  6389. $settings = array();
  6390. foreach($fields as $cat => $x) {
  6391. if (($zc['embed'] != 'standalone') && ($cat == 'auth' || $cat == 'integration' ||
  6392. ($cat == 'db' && (!isset($POST['db']) || !$POST['db'])))) {
  6393. continue;
  6394. }
  6395. foreach($x as $name => $field) {
  6396. if (isset($_POST[$name])) {
  6397. $input = $_POST[$name];
  6398. }
  6399. else {
  6400. $input = null;
  6401. }
  6402. if ($input != $field['def']) {
  6403. if ($name == 'adm_pwd') {
  6404. if (!empty($input)) {
  6405. if ($input == $_POST['adm_pwd_con']) {
  6406. if (zina_check_password($zc['adm_name'], $_POST['adm_pwd_old'])) {
  6407. $config .= "\$adm_pwd = '".zina_get_hash($_POST['adm_pwd'])."';\n";
  6408. }
  6409. else {
  6410. $errors = true;
  6411. zina_set_message(zt('Old password is incorrect.').' '.zt('Password not changed'),'warn');
  6412. }
  6413. }
  6414. else {
  6415. $errors = true;
  6416. zina_set_message(zt('New password and confirmation password do not match.').' '.zt('Password not changed'),'warn');
  6417. }
  6418. }
  6419. else {
  6420. $config .= "\$adm_pwd = \"".$zc['adm_pwd']."\";\n";
  6421. }
  6422. }
  6423. else {
  6424. if ($name == 'main_dir_title' && $input == zt('Artists')) {
  6425. continue;
  6426. }
  6427. if (isset($field['v'])) {
  6428. foreach($field['v'] as $key => $type) {
  6429. $opts = null;
  6430. if (is_array($type)) {
  6431. $opts = $type;
  6432. $type = $key;
  6433. }
  6434. if (!zina_validate($type, $input, $opts)) {
  6435. $errors = true;
  6436. $title = $titles[$name];
  6437. if ($opts) $type = current($opts);
  6438. zina_validate_error_message($type, $title, $input);
  6439. continue 2;
  6440. }
  6441. }
  6442. }
  6443. $quote = '"';
  6444. if (is_array($input)) {
  6445. $input = serialize($input);
  6446. $quote = "'";
  6447. }
  6448. $arr = array("\n"=>"\\n","\t"=>"\\t","\r"=>"\\r","\t"=>"\\t");
  6449. $config .= "\$$name = $quote". str_replace(array_keys($arr),array_values($arr),$input)."$quote;\n";
  6450. $settings[$name] = $input;
  6451. }
  6452. }
  6453. }
  6454. }
  6455. $config .= "?".">"; // This looks goofy, but splitting the ? and > apart allows vim to highlight correctly
  6456. if (!$errors) {
  6457. $file = $zc['zina_dir_abs'].'/zina.ini.php';
  6458. if ($zc['embed'] != 'standalone' && $zc['database'] && (!isset($_POST['db']) || !$_POST['db'])) {
  6459. if (!zvar_set('settings', $settings)) {
  6460. $errors = true;
  6461. zina_set_message(zt('Cannot save settings to cms database'),'error');
  6462. }
  6463. }
  6464. elseif ((file_exists($file) && is_writeable($file)) || (!file_exists($file) && is_writeable($zc['zina_dir_abs']))) {
  6465. if (!file_put_contents($file, $config)) {
  6466. $errors = true;
  6467. zina_set_message(zt('Cannot write config file'),'error');
  6468. }
  6469. }
  6470. else {
  6471. $errors = true;
  6472. zina_set_message(zt('Config file or directory is not writeable.'),'error');
  6473. }
  6474. if ($errors) {
  6475. zina_set_message(
  6476. '<p>'.zt('You may manually put the following in %cfg', array('%cfg'=>$zc['zina_dir_abs'].'/zina.ini.php')).
  6477. '<form><textarea cols="80" rows="20">'.$config.'</textarea></form>'
  6478. ,'warn'
  6479. );
  6480. }
  6481. }
  6482. return !$errors;
  6483. }
  6484. function zina_validate_error_message($type, $title, $input) {
  6485. if ($type == 'req') {
  6486. zina_set_message(zt('@title: This option is required', array('@title'=>$title)),'warn');
  6487. } elseif ($type == 'tf') {
  6488. zina_set_message(zt('@title: Must be true or false (this should not happen)', array('@title'=>$title)),'warn');
  6489. } elseif ($type == 'int') {
  6490. zina_set_message(zt('@title: Must be an integer', array('@title'=>$title)),'warn');
  6491. } elseif ($type == 'int_split') {
  6492. zina_set_message(zt('@title: Must be a string of integers separated by ",".', array('@title'=>$title)),'warn');
  6493. } elseif ($type == 'file_exists') {
  6494. zina_set_message(zt('@title: File @file does not exists', array('@file'=>$input, '@title'=>$title)),'warn');
  6495. } elseif ($type == 'dir_exists') {
  6496. zina_set_message(zt('@title: Directory @dir does not exists', array('@dir'=>$input, '@title'=>$title)),'warn');
  6497. } elseif ($type == 'path_relative') {
  6498. zina_set_message(zt('@title: Directory @dir must exist and be relative to the zina directory', array('@dir'=>$input, '@title'=>$title)),'warn');
  6499. } else {
  6500. zina_set_message(zt('Unknown validation error[@type][@title][@input]', array('@type'=>$type, '@title'=>$title,'@input'=>$input)),'warn');
  6501. }
  6502. }
  6503. function zina_set_scrobbler_queue($queue = array(), $clear = false) {
  6504. global $zc;
  6505. if ($zc['cache']) {
  6506. $que_file = $zc['cache_dir_private_abs'].'/scrobbler_queue_'.$zc['user_id'].'.txt';
  6507. if (empty($queue)) {
  6508. if ($clear) {
  6509. if (file_exists($que_file)) unlink($que_file);
  6510. } elseif (file_exists($que_file)) {
  6511. return unserialize(file_get_contents($que_file));
  6512. }
  6513. } else {
  6514. return file_put_contents($que_file, serialize($queue));
  6515. }
  6516. }
  6517. return array();
  6518. }
  6519. function zina_rename_playlist($old, $new) {
  6520. global $zc;
  6521. $filename = $zc['cache_pls_dir'].'/_zina_'.$new.'.m3u';
  6522. if ($new == '') return false;
  6523. if ($new == $old) return true;
  6524. if (file_exists($filename)) return false;
  6525. if (!rename($zc['cache_pls_dir'].'/_zina_'.$old.'.m3u', $filename)) return false;
  6526. return true;
  6527. }
  6528. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  6529. * SEARCH functions
  6530. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  6531. function zina_search_embed($term, $limit = 0) {
  6532. global $zc;
  6533. if ($zc['db_search']) {
  6534. $results = zdbq_array("SELECT path, type, title, context FROM {search_index} WHERE title LIKE '%%%s%%' ORDER BY title LIMIT %d",
  6535. array($term, $limit));
  6536. } else {
  6537. $results = zina_search_cache($term, $limit);
  6538. }
  6539. zina_content_search_list($results, false);
  6540. return $results;
  6541. }
  6542. function zina_search_cache($term, $limit = false) {
  6543. $results = array();
  6544. $num = 0;
  6545. $results = array_merge($results, zina_search_dirs($term, $limit));
  6546. if ($limit) {
  6547. $limit -= sizeof($results);
  6548. if (!$limit) return $results;
  6549. }
  6550. $results = array_merge($results, zina_search_files($term, $limit));
  6551. if (!empty($results)) usort($results, 'zsort_title');
  6552. return $results;
  6553. }
  6554. function zina_search_dirs($term, $limit = false) {
  6555. $found = array();
  6556. $dirs = zina_core_cache('dirs');
  6557. $num = 0;
  6558. if (!empty($dirs)) {
  6559. foreach ($dirs as $path) {
  6560. if (stristr($path, $term)) {
  6561. $found[] = zina_search_dir_helper($path);
  6562. if ($limit && ++$num >= $limit) break;
  6563. }
  6564. }
  6565. }
  6566. return $found;
  6567. }
  6568. function zina_search_dirs_for_missing_images($limit = false) {
  6569. global $zc;
  6570. $missing = array();
  6571. $dirs = zina_core_cache('dirs');
  6572. $num = 0;
  6573. if (!empty($dirs)) {
  6574. foreach ($dirs as $path) {
  6575. if (empty($path)) continue;
  6576. $full_path = $zc['mp3_dir'].(!empty($path) ? '/'.$path : '');
  6577. if (!zina_get_dir_item($full_path,'/\.('.$zc['ext_graphic'].')$/i')) {
  6578. $missing[$path] = $path;
  6579. }
  6580. }
  6581. }
  6582. return $missing;
  6583. }
  6584. function zina_search_dir_helper($path) {
  6585. global $zc;
  6586. $type = 'directory';
  6587. $context = null;
  6588. $count = substr_count($path, '/');
  6589. if ($zc['search_structure']) {
  6590. if ($count == 0) {
  6591. $type = 'artist';
  6592. } elseif ($count == 1) {
  6593. $type = 'album';
  6594. $context = ztheme('title',substr($path, 0, strpos($path,'/')));
  6595. }
  6596. }
  6597. $title = ($count > 0) ? substr($path, strrpos($path,'/')+1) : $path;
  6598. # order is important
  6599. return array(
  6600. 'title' => ztheme('title',$title),
  6601. 'type' => zt($type),
  6602. 'context' => $context,
  6603. 'id' => $path,
  6604. 'path' => $path,
  6605. 'genre' => null,
  6606. 'image' => null,
  6607. 'year' => null,
  6608. 'mtime' => null,
  6609. );
  6610. }
  6611. function zina_search_files($term, $limit = false) {
  6612. global $zc;
  6613. $found = array();
  6614. $num = 0;
  6615. $files = zina_core_cache('files');
  6616. if (!empty($files)) {
  6617. foreach ($files as $path) {
  6618. $file = basename($path);
  6619. if (stristr($file, $term)) {
  6620. $x = explode('/', $path);
  6621. $len = sizeof($x);
  6622. if ($len == 2)
  6623. $context = ztheme('title',$x[0]);
  6624. elseif ($len > 2)
  6625. $context = ztheme('title',$x[$len - 3]);
  6626. else
  6627. $context = null;
  6628. # order is important
  6629. $found[] = array(
  6630. 'title' => ztheme('song_title', preg_replace('/\.('.$zc['ext_mus'].')$/i', '', $file)),
  6631. 'type' => 'song',
  6632. 'context' => $context,
  6633. 'id' => $path,
  6634. 'path' => $path,
  6635. 'genre' => null,
  6636. 'image' => null,
  6637. 'year' => null,
  6638. 'mtime' => null,
  6639. );
  6640. if ($limit && ++$num >= $limit) break;
  6641. }
  6642. }
  6643. }
  6644. return $found;
  6645. }
  6646. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  6647. * MISC functions
  6648. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  6649. #todo: incorp timelimit?
  6650. #todo: private not implemented or used...
  6651. #type sitemap
  6652. function zina_cache($type, $func, $args = null, $gz, $public = true, $force = false) {
  6653. global $zc;
  6654. $cache = $zc[$type.'_cache'];
  6655. $file = $zc[$type.'_file'];
  6656. $cache_file = (($public) ? $zc['cache_dir_public_abs'] : $zc['cache_dir_private_abs']).'/'.$file;
  6657. if ($cache && !$force) {
  6658. if (file_exists($cache_file)) {
  6659. if ($public) {
  6660. while(@ob_end_clean());
  6661. header('Location: '.$zc['zina_dir_rel'].'/'.$zc['cache_dir_public_rel'].'/'.$file);
  6662. exit;
  6663. } else {
  6664. return implode("\n", gzfile($cache_file));
  6665. }
  6666. }
  6667. }
  6668. $output = call_user_func_array($func, $args);
  6669. if (!$output) return false;
  6670. if ($cache || $force) {
  6671. if ($gz) {
  6672. $gz = gzopen($cache_file,'w1');
  6673. gzwrite($gz, $output);
  6674. gzclose($gz);
  6675. } else {
  6676. file_put_contents($cache_file, $output);
  6677. }
  6678. }
  6679. return $output;
  6680. }
  6681. function zina_reorder_playlist($songs, $order) {
  6682. $new = $neworder = array();
  6683. $count = sizeof($songs);
  6684. if ($count == 0) return null;
  6685. for ($i = 0; $i < $count; $i++){
  6686. if (empty($order[$i])) continue; # 0 == delete
  6687. $j = (zina_validate('int', $order[$i])) ? $order[$i] : 99;
  6688. $new[$j][] = $songs[$i];
  6689. }
  6690. ksort($new);
  6691. $songs = array();
  6692. foreach($new as $neworder) {
  6693. foreach($neworder as $song) $songs[] = $song;
  6694. }
  6695. return $songs;
  6696. }
  6697. function zina_is_admin() {
  6698. global $zc;
  6699. if (isset($zc['conf']['is_admin'])) return $zc['conf']['is_admin'];
  6700. if (isset($_SESSION['za-'.ZINA_VERSION]) && $_SESSION['za-'.ZINA_VERSION] == true) return true;
  6701. if ($zc['adm_ip'] && strstr($zc['adm_ips'], $_SERVER['REMOTE_ADDR'])) return true;
  6702. if ($zc['loc_is_adm'] && $_SERVER['SERVER_ADDR'] == $_SERVER['REMOTE_ADDR']) return true;
  6703. if ($zc['session'] && isset($_COOKIE['ZINA_SESSION'])) {
  6704. $sess_file = $zc['cache_dir_private_abs'].'/sess_'.zcheck_plain($_COOKIE['ZINA_SESSION']);
  6705. if (file_exists($sess_file) && filemtime($sess_file) + (60*60*$zc['session_lifetime']) > time()) {
  6706. @touch($sess_file);
  6707. $_SESSION['za-'.ZINA_VERSION] = true;
  6708. return true;
  6709. }
  6710. }
  6711. if (!$_SESSION && isset($_GET['zid']) && isset($_GET['l']) && ($_GET['l'] == '6' || $_GET['l'] == '10')) {
  6712. return (zina_token('verify', $_GET['zid']));
  6713. }
  6714. return false;
  6715. }
  6716. function zina_is_various($cur_dir, $path) {
  6717. global $zc;
  6718. if ($zc['various']) {
  6719. if (file_exists($cur_dir.'/'.$zc['various_file'])) return true;
  6720. if ($zc['various_above'] && !empty($path)) {
  6721. $parts = explode('/', $path);
  6722. $size = sizeof($parts);
  6723. if ($size > 1) {
  6724. $dir_above = preg_replace('/'.preg_quote($parts[($size-1)]).'$/i', '', $cur_dir);
  6725. if (file_exists($dir_above.$zc['various_file'])) return true;
  6726. }
  6727. }
  6728. }
  6729. return false;
  6730. }
  6731. function zina_is_category($path) {
  6732. global $zc;
  6733. $cat_file = $path.'/'.$zc['cat_file'];
  6734. $cat_file_exists = $category = file_exists($cat_file);
  6735. if (!$category && $zc['cat_auto']) {
  6736. $num = $zc['cat_auto_num'];
  6737. $dir_skip = $zc['dir_skip'];
  6738. $i = 1;
  6739. if ($result = scandir($path)) {
  6740. foreach($result as $file) {
  6741. if ($file== "." || $file== '..' || $file[0] == $dir_skip) continue;
  6742. if (is_dir($path.'/'.$file)) {
  6743. if (++$i > $num) {
  6744. $category = true;
  6745. break;
  6746. }
  6747. }
  6748. }
  6749. }
  6750. }
  6751. if ($category) {
  6752. $cat['images'] = $zc['cat_images'];
  6753. $cat['cols'] = $zc['cat_cols'];
  6754. $cat['truncate'] = $zc['cat_truncate'];
  6755. $cat['split'] = $zc['cat_split'];
  6756. $cat['sort'] = $zc['cat_sort'];
  6757. $cat['pp'] = $zc['cat_pp'];
  6758. if ($cat_file_exists) {
  6759. $cat_xml = file_get_contents($cat_file);
  6760. if (!empty($cat_xml)) {
  6761. $cat_settings = xml_to_array($cat_xml, 'category');
  6762. if (!empty($cat_settings)) {
  6763. $cat_settings = $cat_settings[0];
  6764. $cat['images'] = isset($cat_settings['images']) ? $cat_settings['images'] : $cat['images'];
  6765. $cat['cols'] = isset($cat_settings['columns']) ? $cat_settings['columns'] : $cat['cols'];
  6766. $cat['truncate'] = isset($cat_settings['truncate']) ? $cat_settings['truncate'] : $cat['truncate'];
  6767. $cat['split'] = isset($cat_settings['split']) ? $cat_settings['split'] : $cat['split'];
  6768. $cat['pp'] = isset($cat_settings['per_page']) ? $cat_settings['per_page'] : $cat['pp'];
  6769. $cat['sort'] = isset($cat_settings['sort']) ? $cat_settings['sort'] : $cat['sort'];
  6770. }
  6771. $settings = xml_to_array($cat_xml, 'override');
  6772. if (!empty($settings)) {
  6773. $settings = $settings[0];
  6774. foreach($settings as $key => $val) {
  6775. if (in_array($key, array('dir_tags'))) {
  6776. $zc[$key] = $val;
  6777. #$cat['override'][$key] = $val;
  6778. }
  6779. }
  6780. }
  6781. }
  6782. }
  6783. return $cat;
  6784. }
  6785. return false;
  6786. }
  6787. function zina_check_password($un, $up) {
  6788. global $zc;
  6789. $hash = base64_decode($zc['adm_pwd']);
  6790. $new_hash = pack("H*", sha1($up.substr($hash,20)));
  6791. return ($zc['adm_name'] == $un && substr($hash,0,20) == $new_hash);
  6792. }
  6793. function zina_get_hash($password) {
  6794. $salt = substr(pack("H*", sha1( substr(pack('h*', sha1(mt_rand())), 0, 8).$password)), 0, 4);
  6795. return base64_encode( pack("H*", sha1($password.$salt)).$salt);
  6796. }
  6797. function zina_cron_run($opts = array()) {
  6798. global $zc;
  6799. $semaphore = $zc['cache_dir_private_abs'].'/.cron';
  6800. if (file_exists($semaphore)) {
  6801. if (time() - filemtime($semaphore) > 3600) {
  6802. zina_debug(zt('Cron has been running for more than an hour and is most likely stuck.'));
  6803. @unlink($semaphore);
  6804. } else {
  6805. zina_debug(zt('Attempting to re-run cron while it is already running.'));
  6806. }
  6807. } else {
  6808. touch($semaphore);
  6809. if ($zc['database']) {
  6810. require_once($zc['zina_dir_abs'].'/batch.php');
  6811. $operations = array();
  6812. foreach(array('dirs', 'files_assoc', 'genre') as $type) {
  6813. $cache_file = $zc['cache_'.$type.'_file'];
  6814. $mtime = (file_exists($cache_file)) ? filemtime($cache_file) : 0;
  6815. if (time() - $mtime > $zc['cache_expire'] * 86400 ) {
  6816. @set_time_limit($zc['timeout']);
  6817. $operations[] = array('zina_core_cache_batch', array($type, '', array('force'=>true)));
  6818. }
  6819. }
  6820. if ($zc['low']) {
  6821. foreach(array('files_assoc') as $type) {
  6822. @set_time_limit($zc['timeout']);
  6823. $cache_file = $zc['cache_'.$type.'_file'];
  6824. $mtime = (file_exists($cache_file)) ? filemtime($cache_file) : 0;
  6825. if (time() - $mtime > $zc['cache_expire'] * 86400 ) {
  6826. $operations[] = array('zina_core_cache_batch', array($type, '', array('force'=>true, 'low'=>true)));
  6827. }
  6828. }
  6829. }
  6830. zdb_cron_run($operations);
  6831. if ($zc['sitemap']) {
  6832. $cache_file = $zc['cache_dir_public_abs'].'/'.$zc['sitemap_file'];
  6833. $mtime = (file_exists($cache_file)) ? filemtime($cache_file) : 0;
  6834. if (time() - $mtime > $zc['sitemap_cache_expire'] * 86400 ) {
  6835. $operations[] = array('zina_cache', array('sitemap', 'zina_content_sitemap', null, ($zc['sitemap'] == 2), true, true));
  6836. }
  6837. }
  6838. $batch = array(
  6839. 'title' => zt('Cron Run'),
  6840. 'finished_message' => zt('Cron completed successfully.'),
  6841. 'operations' => $operations,
  6842. 'finished' => 'zina_cron_finished',
  6843. );
  6844. zbatch_set($batch);
  6845. $redirect_path = (isset($opts['redirect_path'])) ? $opts['redirect_path'] : null;
  6846. $redirect_query = (isset($opts['redirect_query'])) ? $opts['redirect_query'] : null;
  6847. zbatch_process(null, $redirect_query, $opts);
  6848. } else { # NO DATABASE
  6849. foreach(array('dirs', 'files_assoc', 'genre') as $type) {
  6850. $cache_file = $zc['cache_'.$type.'_file'];
  6851. $mtime = (file_exists($cache_file)) ? filemtime($cache_file) : 0;
  6852. if (time() - $mtime > $zc['cache_expire'] * 86400 ) {
  6853. @set_time_limit($zc['timeout']);
  6854. zina_core_cache($type, '', array('force'=>true));
  6855. }
  6856. }
  6857. if ($zc['low']) {
  6858. foreach(array('files_assoc') as $type) {
  6859. @set_time_limit($zc['timeout']);
  6860. $cache_file = $zc['cache_'.$type.'_file'];
  6861. $mtime = (file_exists($cache_file)) ? filemtime($cache_file) : 0;
  6862. if (time() - $mtime > $zc['cache_expire'] * 86400 ) {
  6863. zina_core_cache($type, '', array('force'=>true,'low'=>true));
  6864. }
  6865. }
  6866. }
  6867. if ($zc['sitemap']) {
  6868. $cache_file = $zc['cache_dir_public_abs'].'/'.$zc['sitemap_file'];
  6869. $mtime = (file_exists($cache_file)) ? filemtime($cache_file) : 0;
  6870. if (time() - $mtime > $zc['sitemap_cache_expire'] * 86400 ) {
  6871. zina_cache('sitemap', 'zina_content_sitemap', null, ($zc['sitemap'] == 2), true, true);
  6872. }
  6873. }
  6874. }
  6875. @unlink($semaphore);
  6876. }
  6877. }
  6878. function zina_cron_feature($cron) {
  6879. global $zc;
  6880. $now = getdate();
  6881. #$now = getdate(mktime ( 8, 45, 0, 12, 29, 2003));
  6882. $n[0] = $now['wday']; # 0-6; 0 = sun
  6883. $n[1] = $now['mon']; # 1-12
  6884. $n[2] = $now['mday']; # 0-31
  6885. $n[3] = ($now['hours'] * 60) + $now['minutes']; #0-23:0-59
  6886. foreach($cron as $feature=>$crontabs) {
  6887. foreach($crontabs as $key=>$crontab) {
  6888. $zc[$feature] = zina_cron_feature_check($crontab, $n);
  6889. }
  6890. }
  6891. }
  6892. #crontab = 'WDAY MON MDAY HH:MM';
  6893. function zina_cron_feature_check($crontab, $now) {
  6894. $tab = explode(' ',$crontab);
  6895. $size = sizeof($tab);
  6896. if ($size != 4) {
  6897. zina_debug(zt('Bad zina_cron_feature_check option'),'warn');
  6898. return false;
  6899. }
  6900. for($i=0; $i<4; $i++) {
  6901. $cur = $tab[$i];
  6902. $n = $now[$i];
  6903. if($cur[0] == '*') continue;
  6904. if(strpos($cur,',') !== false) { #multi
  6905. $multi = explode(',',$cur);
  6906. if (!in_array($n, $multi)) return false;
  6907. } elseif (strpos($cur,'-') !== false) { #range
  6908. $range = explode('-',$cur);
  6909. if ($i == 3) {
  6910. $hm = explode(':',$range[0]);
  6911. $r0 = ($hm[0] * 60) + $hm[1];
  6912. $hm = explode(':',$range[1]);
  6913. $r1 = ($hm[0] * 60) + $hm[1];
  6914. } else {
  6915. $r0 = $range[0];
  6916. $r1 = $range[1];
  6917. }
  6918. if ($r0 < $r1) {
  6919. if($n < $r0 || $n > $r1) return false;
  6920. } else {
  6921. if($n < $r0 && $n > $r1) return false;
  6922. }
  6923. } else { #single
  6924. if ($n != $cur) return false;
  6925. }
  6926. }
  6927. return true;
  6928. }
  6929. class remoteFile {
  6930. function remoteFile($file, $info=false, $tag=false) {
  6931. $this->tag = $this->info = false;
  6932. $this->filesize = 0;
  6933. $this->remote = true;
  6934. $this->genre = 'Unknown';
  6935. $content = file_get_contents($file);
  6936. $arr = xml_to_array($content);
  6937. $arr = (empty($arr)) ? get_meta_tags($file) : $arr[0];
  6938. if (empty($arr)) return;
  6939. $this->url = $arr['url'];
  6940. $this->download = isset($arr['download']) ? $arr['download'] : null;
  6941. if ($info) {
  6942. if (isset($arr['time'])) {
  6943. $this->time = $arr['time'];
  6944. $this->filesize = isset($arr['filesize']) ? $arr['filesize'] : 0;
  6945. $this->bitrate = isset($arr['bitrate']) ? $arr['bitrate'] : 0;
  6946. $this->frequency = isset($arr['frequency']) ? $arr['frequency'] : 0;
  6947. $this->length = isset($arr['length']) ? $arr['length'] : 0;
  6948. $this->stereo = isset($arr['stereo']) ? $arr['stereo'] : 1;
  6949. $this->info = true;
  6950. }
  6951. }
  6952. if ($tag) {
  6953. if (isset($arr['title'])) {
  6954. $this->title = $arr['title'];
  6955. $this->artist = isset($arr['artist']) ? $arr['artist'] : '';
  6956. $this->album = isset($arr['album']) ? $arr['album'] : '';
  6957. $this->year = isset($arr['year']) ? $arr['year'] : '';
  6958. $this->genre = isset($arr['genre']) ? $arr['genre'] : 'Unknown';
  6959. $this->tag = true;
  6960. }
  6961. }
  6962. }
  6963. }
  6964. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  6965. * SETTINGS & INIT
  6966. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  6967. function zina_init($conf) {
  6968. global $zc, $z_dbc, $zina_lang_code, $zina_lang_path;
  6969. if ($conf['embed'] == 'standalone') {
  6970. ini_set('arg_separator.output', '&amp;');
  6971. ini_set('magic_quotes_runtime', 0);
  6972. ini_set('magic_quotes_sybase', 0);
  6973. ini_set('session.cache_expire', 259200); # 3 days
  6974. ini_set('session.cache_limiter', 'none');
  6975. ini_set('session.cookie_lifetime', 1209600); # 14 days
  6976. ini_set('session.gc_maxlifetime', 259200);
  6977. ini_set('session.use_only_cookies', 1);
  6978. ini_set('session.use_trans_sid', 0);
  6979. ini_set('url_rewriter.tags', '');
  6980. session_start();
  6981. $zc['login'] = true;
  6982. }
  6983. else {
  6984. $zc['login'] = false;
  6985. }
  6986. # FOR IIS
  6987. if (!isset($_SERVER['DOCUMENT_ROOT'])) {
  6988. if (isset($_SERVER['SCRIPT_FILENAME'])) {
  6989. $_SERVER['DOCUMENT_ROOT'] = str_replace( '\\', '/',
  6990. substr($_SERVER['SCRIPT_FILENAME'], 0,
  6991. 0-strlen($_SERVER['PHP_SELF'])));
  6992. }
  6993. elseif (isset($_SERVER['PATH_TRANSLATED'])) {
  6994. $_SERVER['DOCUMENT_ROOT'] = str_replace( '\\', '/',
  6995. substr(str_replace('\\\\', '\\',
  6996. $_SERVER['PATH_TRANSLATED']), 0,
  6997. 0-strlen($_SERVER['PHP_SELF'])));
  6998. }
  6999. }
  7000. $zc['conf'] = $conf;
  7001. $zc['database'] = $zc['db_cms'] = $zc['is_admin'] = $zc['play_local'] = false;
  7002. $zc['charset'] = (isset($conf['charset'])) ? $conf['charset'] : 'utf-8'; #needed for blocks
  7003. $zc['windows'] = (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN');
  7004. $zc['zina_dir_abs'] = (($zc['windows']) ?
  7005. str_replace("\\",'/',$conf['index_abs']) :
  7006. $conf['index_abs']).'/zina';
  7007. # for modules
  7008. if (isset($conf['index_rel'])) {
  7009. $zc['index_rel'] = $conf['index_rel'];
  7010. }
  7011. $settings = zina_get_settings('cfg');
  7012. require_once($zc['zina_dir_abs'].'/common.php');
  7013. require_once($zc['zina_dir_abs'].'/theme.php');
  7014. require_once($zc['zina_dir_abs'].'/mp3.class.php');
  7015. $ini = $zc['zina_dir_abs'].'/zina.ini.php';
  7016. if (file_exists($ini)) {
  7017. require($ini);
  7018. }
  7019. if ($conf['embed'] != 'standalone') {
  7020. if ($z_dbc = zina_get_active_db($db_opts)) {
  7021. if (in_array($db_opts['type'], zina_get_db_types())) {
  7022. $zc['db_pre'] = $db_opts['prefix'].'zina_';
  7023. $zc['db_type'] = $db_opts['type'];
  7024. require_once($zc['zina_dir_abs'].'/database-'.$zc['db_type'].'.php');
  7025. require_once($zc['zina_dir_abs'].'/database.php');
  7026. $zinaini = zvar_get('settings', null);
  7027. if (!empty($zinaini)) extract($zinaini, EXTR_OVERWRITE);
  7028. $zc['database'] = $zc['db_cms'] = true;
  7029. }
  7030. else {
  7031. zina_debug(zt('Unsupported CMS database type: @type', array($db_opts['type'])));
  7032. }
  7033. }
  7034. }
  7035. if (isset($login)) $zc['login'] = $login;
  7036. foreach($settings as $section => $cat) {
  7037. # dont allow defaults to override cms db settings
  7038. if ($section == 'db' && $zc['db_cms']) continue;
  7039. foreach($cat as $key => $val) {
  7040. if ($key == 'res_in_types') {
  7041. $zc[$key] = isset($$key) ? unserialize($$key) : $val['def'];
  7042. }
  7043. else {
  7044. $zc[$key] = isset($$key) ? $$key : $val['def'];
  7045. }
  7046. if ($key == 'media_types_cfg') {
  7047. $media_types_default = $val['def'];
  7048. }
  7049. }
  7050. }
  7051. $zina_lang_code = $zc['lang'];
  7052. #TODO: get confirmation this works
  7053. if (!empty($zc['locale'])) {
  7054. if (($locale = setlocale(LC_ALL, $zc['locale'])) === false) {
  7055. if ($_GET['l'] != 21) {
  7056. zina_set_message(zt('Locale setting not supported by your system. Locale is set to @locale.',
  7057. array('@locale'=> setlocale(LC_ALL,null))),'warn');
  7058. $zc['locale'] = setlocale(LC_ALL,0);
  7059. }
  7060. }
  7061. }
  7062. @date_default_timezone_set($zc['timezone']);
  7063. @set_time_limit($zc['timeout']);
  7064. zpath_to_theme($zc['zina_dir_rel'].'/themes/'.$zc['theme']);
  7065. $zc['theme_path_abs'] = $zc['zina_dir_abs'].'/themes/'.$zc['theme'];
  7066. $zina_lang_path = false;
  7067. $lang_user = $zc['theme_path_abs'].'/'.$zina_lang_code.'.php';
  7068. if (file_exists($lang_user)) {
  7069. $zina_lang_path = $lang_user;
  7070. }
  7071. elseif (file_exists($zc['zina_dir_abs'].'/lang/'.$zina_lang_code.'.php')) {
  7072. $zina_lang_path = $zc['zina_dir_abs'].'/lang/'.$zina_lang_code.'.php';
  7073. }
  7074. if (function_exists('mb_strlen')) {
  7075. $zc['multibyte'] = true;
  7076. mb_internal_encoding($zc['charset']);
  7077. mb_language('uni');
  7078. }
  7079. else {
  7080. $zc['multibyte'] = false;
  7081. zina_debug(zt('No multibyte support.'));
  7082. }
  7083. #todo: still needed with new error checking???
  7084. if (!is_dir($zc['mp3_dir'])) {
  7085. $default_music = $zc['zina_dir_abs'].'/demo';
  7086. if (!is_dir($default_music)) $default_music = $zc['zina_dir_abs'];
  7087. zina_set_message(zt('Your music directory does not exist!'),'error');
  7088. $zc['mp3_dir'] = $default_music;
  7089. }
  7090. if ($zc['stream_int'] || !preg_match('#^'.$_SERVER['DOCUMENT_ROOT'].'#i',$zc['mp3_dir'])) {
  7091. $zc['stream_int'] = true;
  7092. }
  7093. else {
  7094. $zc['www_path'] = preg_replace('#^'.$_SERVER['DOCUMENT_ROOT'].'#i', '', $zc['mp3_dir']);
  7095. }
  7096. $zc['cache_dir_public_abs'] = $zc['zina_dir_abs'].'/'.$zc['cache_dir_public_rel'];
  7097. $zc['cache_imgs_dir'] = $zc['zina_dir_abs'].'/'.$zc['cache_imgs_dir_rel'];
  7098. $zc['cache_tmpl_dir'] = $zc['cache_dir_private_abs'].'/tmpl';
  7099. $zc['cache_pls_dir'] = $zc['cache_dir_private_abs'].'/playlist';
  7100. $zc['cache_zip_dir'] = $zc['cache_dir_private_abs'].'/zip';
  7101. $md5 = md5($zc['mp3_dir']);
  7102. $zc['cache_dirs_file'] = $zc['cache_dir_private_abs'].'/'.$md5.'_dirs.gz';
  7103. $zc['cache_files_assoc_file'] = $zc['cache_dir_private_abs'].'/'.$md5.'_files_assoc.gz';
  7104. $zc['cache_genre_file'] = $zc['cache_dir_private_abs'].'/'.$md5.'_genre.gz';
  7105. $zc['sitemap_file'] = ($zc['sitemap'] == 2) ? 'sitemap.xml.gz' : 'sitemap.xml';
  7106. $zc['encoders'] = zina_parse_ini_string($zc['enc_arr']);
  7107. $zc['ext_enc'] = implode('|',array_keys($zc['encoders']));
  7108. $types = ($zc['other_media_types']) ? $zc['media_types_cfg'] : $media_types_default;
  7109. $zc['media_types'] = zina_parse_ini_string($types);
  7110. $zc['ext_mus'] = implode('|',array_keys($zc['media_types']));
  7111. $zc['ran_opts'] = explode(',', $zc['ran_opts']);
  7112. $zc['auth'] = ($zc['apache_auth'] && isset($_SERVER['PHP_AUTH_USER'])) ? $_SERVER['PHP_AUTH_USER'].':'.$_SERVER['PHP_AUTH_PW'].'@' : '';
  7113. $zc['resize_types'] = implode('|',$zc['res_in_types']);
  7114. if ($zc['mm']) {
  7115. $zc['mm_types'] = zina_parse_ini_string($zc['mm_types_cfg']);
  7116. $zc['mm_ext'] = implode('|',array_keys($zc['mm_types']));
  7117. }
  7118. if ($zc['cron']) {
  7119. $zc['cron_options'] = zina_parse_ini_string($zc['cron_opts']);
  7120. if (is_array($zc['cron_options'])) $zc['cron_options'] = current($zc['cron_options']);
  7121. }
  7122. if ($zc['song_extras']) {
  7123. $zc['song_es'] = zina_parse_ini_string($zc['song_extras_opt']);
  7124. $zc['song_es_exts'] = array_keys($zc['song_es']);
  7125. }
  7126. $zc['embed'] = (isset($conf['embed'])) ? $conf['embed'] : 'standalone';
  7127. if (isset($conf['clean_urls'])) {
  7128. $zc['clean_urls'] = $conf['clean_urls'];
  7129. if (isset($conf['clean_urls_hack'])) $zc['clean_urls_hack'] = $conf['clean_urls_hack'];
  7130. }
  7131. if (isset($conf['url_query'])) {
  7132. $zc['url_query'] = $conf['url_query'];
  7133. }
  7134. if (isset($conf['lastfm'])) {
  7135. $zc['lastfm'] = $conf['lastfm'];
  7136. $zc['lastfm_username'] = $conf['lastfm_username'];
  7137. $zc['lastfm_password'] = $conf['lastfm_password'];
  7138. }
  7139. if (isset($conf['twitter'])) {
  7140. $zc['twitter'] = $conf['twitter'];
  7141. $zc['twitter_username'] = $conf['twitter_username'];
  7142. $zc['twitter_password'] = $conf['twitter_password'];
  7143. }
  7144. $theme_file = $zc['theme_path_abs'].'/index.php';
  7145. if (file_exists($theme_file)) {
  7146. require_once($theme_file);
  7147. }
  7148. if (isset($zc['db']) && $zc['db'] && in_array($zc['db_type'], zina_get_db_types())) {
  7149. require_once($zc['zina_dir_abs'].'/database-'.$zc['db_type'].'.php');
  7150. if ($z_dbc = zdb_connect($zc['db_host'], $zc['db_name'], $zc['db_user'], $zc['db_pwd'], ($conf['embed'] != 'standalone'))) {
  7151. require_once($zc['zina_dir_abs'].'/database.php');
  7152. $zc['database'] = true;
  7153. }
  7154. }
  7155. $zc['search'] = ($zc['search'] || $zc['db_search']);
  7156. $zc['db_search'] = ($zc['db_search'] && $zc['search'] && $zc['database']);
  7157. if ($zc['clean_urls'] && $zc['clean_urls_hack']) {
  7158. $zc['index_rel'] = (isset($zc['index_rel'])) ? $zc['index_rel'].'/'.$zc['clean_urls_index'] : $zc['clean_urls_index'];
  7159. if (isset($_GET['p']) && !(strpos($_GET['p'],$zc['clean_urls_index'])===false)) {
  7160. $_GET['p'] = substr($_GET['p'],strlen($zc['index_rel'])+1);
  7161. }
  7162. }
  7163. $zc['session'] = ($zc['cache'] && $zc['embed'] == 'standalone' && $zc['session']);
  7164. $zc['is_admin'] = zina_is_admin();
  7165. if ($_SERVER['SERVER_ADDR'] == $_SERVER['REMOTE_ADDR'] || $zc['pos']) {
  7166. if ($zc['local_path'] || $zc['pos']) {
  7167. $zc['stream_int'] = false;
  7168. $zc['play_local'] = true;
  7169. }
  7170. }
  7171. if (!$zc['is_admin'] && $zc['cron'] && !empty($zc['cron_options'])) {
  7172. zina_cron_feature($zc['cron_options']);
  7173. }
  7174. $zc['user_id'] = (isset($conf['user_id']) &&
  7175. is_numeric($conf['user_id'])) ? (int)$conf['user_id'] : (int)($zc['is_admin']);
  7176. if ($zc['user_id'] > 0 && isset($_SESSION)) {
  7177. if (function_exists('zina_token')) {
  7178. $token_value = (isset($conf['token_value'])) ? $conf['token_value'] : $zc['user_id'];
  7179. if ($token = zina_token('get', $token_value)) {
  7180. $zc['token'] = 'zid='.$token;
  7181. }
  7182. }
  7183. }
  7184. if ($zc['zinamp']==1 || $zc['zinamp']==2) {
  7185. $xml = file_get_contents($zc['zina_dir_abs'].'/zinamp/skins/'.$zc['zinamp_skin'].'/skin.xml');
  7186. $mp_cfg = xml_to_array($xml,'skin');
  7187. $zc['zinamp_width'] = $mp_cfg[0]['width'];
  7188. $zc['zinamp_height'] = $mp_cfg[0]['height'];
  7189. $zc['zinamp_url'] = zurl('','l=55', null, true);
  7190. }
  7191. if ($zc['zinamp']==3) {
  7192. $zc['jplayer_width'] = 200;
  7193. $zc['jplayer_height'] = 200;
  7194. $zc['jplayer_url'] = zurl('','l=100', null, true);
  7195. }
  7196. }
  7197. function zina_get_opt_zip() {
  7198. $opts[0] = zt('None');
  7199. $opts[1] = zt('External');
  7200. if (function_exists('zip_open')) {
  7201. $opts[2] = zt('Internal PHP Zip Library');
  7202. }
  7203. return $opts;
  7204. }
  7205. function zina_get_opt_playlist_format() {
  7206. return array(
  7207. 'm3u' => zt('m3u'),
  7208. 'asx' => zt('asx'),
  7209. 'xspf' => zt('xspf'),
  7210. );
  7211. }
  7212. function zina_get_opt_search() {
  7213. return array(
  7214. 'browse' => zt('Browse'),
  7215. 'play' => zt('Play'),
  7216. );
  7217. }
  7218. function zina_get_opt_filesort() {
  7219. return array(
  7220. 0 => zt('Alphabetically'),
  7221. 1 => zt('Alphabetically Descending'),
  7222. 2 => zt('By Date'),
  7223. 3 => zt('By Date Descending'),
  7224. 4 => zt('ID3 Track Number'),
  7225. );
  7226. }
  7227. # currently only for lyr
  7228. function zina_get_extras_opts($type) {
  7229. #TODO: get from directory... extras/extras_'.$m.'_*
  7230. #$opts = array('lyricwiki', 'lyricsfly');
  7231. return array('lyricwiki', 'chartlyrics', 'lyricsmania');
  7232. }
  7233. function zina_get_extras_lyr() {
  7234. return implode(',', zina_get_extras_opts('lyr'));
  7235. }
  7236. function zina_get_extras_images_opts() {
  7237. #TODO: get from directory...
  7238. #$opts = array( 'amazon' => array('num'=>2, 'artist'=>false, 'album'=> true, 'order'=>0)??, 'lastfm' = > 1);
  7239. return array('amazon', 'amazon', 'lastfm', 'google', 'google', 'google');
  7240. }
  7241. function zina_get_opt_catsplit() {
  7242. return array(
  7243. 0 => zt('Full Page'),
  7244. 3 => zt('Full Page (split Alphabetically)'),
  7245. 1 => zt('Split by Number Per Page'),
  7246. 2 => zt('Split Alphabetically'),
  7247. );
  7248. }
  7249. function zina_get_opt_sitemap() {
  7250. return array(
  7251. 0 => zt('None'),
  7252. 1 => zt('sitemap.xml'),
  7253. 2 => zt('sitemap.xml.gz'),
  7254. );
  7255. }
  7256. function zina_get_cat_sorts() {
  7257. return array(
  7258. 'a' => zt('Alphabetical Ascending'),
  7259. 'ad' => zt('Alphabetical Descending'),
  7260. 'd' => zt('Date Ascending'),
  7261. 'dd' => zt('Date Descending'),
  7262. );
  7263. }
  7264. function zina_get_zinamp() {
  7265. return array(
  7266. 0 => zt('None'),
  7267. 1 => zt('Inline'),
  7268. 2 => zt('Pop-up'),
  7269. 3 => zt('HTML5 (jPlayer)'),
  7270. );
  7271. }
  7272. function zina_get_jplayer() {
  7273. return array (
  7274. 0 => zt('No'),
  7275. 1 => zt('Yes'),
  7276. );
  7277. }
  7278. function zina_get_zinamp_skins() {
  7279. global $zc;
  7280. $dir = $zc['zina_dir_abs'].'/zinamp/skins';
  7281. if ($d = @dir($dir)) {
  7282. while($entry = $d->read()) {
  7283. if ($entry == '.' || $entry == '..' || !is_dir($dir.'/'.$entry)) continue;
  7284. $opts[$entry] = $entry;
  7285. }
  7286. $d->close();
  7287. return $opts;
  7288. }
  7289. zina_set_message(zt('Cannot read skins directory'),'error');
  7290. return array('WinampClassic'=>'WinampClassic');
  7291. }
  7292. function zina_get_opt_tf() {
  7293. return array(1=>zt('True'), 0=>zt('False'));
  7294. }
  7295. function zina_get_db_types() {
  7296. return array('mysql'=>'mysql','mysqli'=>'mysqli');
  7297. }
  7298. function zina_get_settings($type = '') {
  7299. global $zc;
  7300. if ($type == 'cfg') {
  7301. $len = strlen($_SERVER['DOCUMENT_ROOT']);
  7302. $zina_dir_rel = ($len < strlen($zc['zina_dir_abs'])) ? str_replace('\\','/',substr($zc['zina_dir_abs'], $len)) : '';
  7303. if (function_exists('gd_info')) {
  7304. $gd = gd_info();
  7305. $img_resize = true;
  7306. $freetype = (bool)$gd['FreeType Support'];
  7307. #$freetype = function_exists('imagettftext');
  7308. if ((isset($gd['JPG Support']) && $gd['JPG Support']) ||
  7309. (isset($gd['JPEG Support']) && $gd['JPEG Support'])) {
  7310. $img_ins['jpg'] = 'jpg';
  7311. $img_ins['jpeg'] = 'jpeg';
  7312. $img_outs['jpeg'] = 'jpeg';
  7313. $img_out_def = 'jpeg';
  7314. }
  7315. if ($gd['PNG Support']) {
  7316. $img_ins['png'] = 'png';
  7317. $img_outs['png'] = 'png';
  7318. }
  7319. if ($gd['GIF Read Support']) {
  7320. $img_ins['gif'] = 'gif';
  7321. }
  7322. if ($gd['GIF Create Support']) {
  7323. $img_outs['gif'] = 'gif';
  7324. }
  7325. $img_ins_def = $img_ins;
  7326. }
  7327. else {
  7328. $img_resize = false;
  7329. $freetype = false;
  7330. $gdno = (function_exists('zt')) ? zt('GD not detected') : 'GD not detected';
  7331. $img_ins = array('none'=>$gdno);
  7332. $img_ins_def = array('none'=>'none');
  7333. $img_outs['none'] = $gdno;
  7334. $img_out_def = 'none';
  7335. }
  7336. if ($zc['conf']['embed'] == 'standalone') {
  7337. $default_theme = 'zinaGarland';
  7338. $cat_cols = 4;
  7339. $cat_pp = 100;
  7340. $clean_url_hack = ($zc['windows']) ? true : false;
  7341. }
  7342. else {
  7343. $default_theme = 'zinaEmbed';
  7344. $cat_cols = 3;
  7345. $cat_pp = 99;
  7346. $clean_url_hack = false;
  7347. }
  7348. $lyrics = zina_get_extras_lyr();
  7349. return array(
  7350. 'config' => array(
  7351. 'mp3_dir' => array('type'=>'textfield', 'size'=>40, 'def'=>$zc['zina_dir_abs'].'/demo', 'v'=>array('dir_exists')),
  7352. 'clean_urls' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>0, 'v'=>array('tf')),
  7353. ),
  7354. 'auth' => array(
  7355. 'adm_name' => array('type'=>'textfield', 'def'=>'admin', 'v'=>array('req')),
  7356. 'adm_pwd' => array('type'=>'password_adm', 'def'=>'1GiuvuvgdFGQwfQkIiZ04Ro6K7s1VWnm'),
  7357. 'loc_is_adm' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>0, 'v'=>array('tf')),
  7358. 'adm_ip' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>0, 'v'=>array('tf')),
  7359. 'adm_ips' => array('type'=>'textfield', 'def'=>'', 'v'=>array('if'=>array('adm_ip'=>'req'))),
  7360. 'apache_auth' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>0, 'v'=>array('tf')),
  7361. 'session' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>1, 'v'=>array('tf')),
  7362. 'session_lifetime' => array('type'=>'textfield', 'suf'=>'hours', 'def'=>336, 'v'=>array('if'=>array ('session'=>'int'))),
  7363. ),
  7364. 'db' => array(
  7365. 'db' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>0, 'v'=>array('tf')),
  7366. 'db_type' => array('type'=>'select', 'opts'=>'zina_get_db_types', 'def'=>'mysql', 'v'=>array('if'=>array('db'=>'req'))),
  7367. 'db_host' => array('type'=>'textfield', 'def'=>'localhost', 'v'=>array('if'=>array('db'=>'req'))),
  7368. 'db_name' => array('type'=>'textfield', 'def'=>'zina', 'v'=>array('if'=>array('db'=>'req'))),
  7369. 'db_user' => array('type'=>'textfield', 'def'=>'username', 'v'=>array('if'=>array('db'=>'req'))),
  7370. 'db_pwd' => array('type'=>'password', 'def'=>'password', 'v'=>array('if'=>array('db'=>'req'))),
  7371. 'db_pre' => array('type'=>'textfield', 'def'=>'z_'),
  7372. ),
  7373. 'caches' => array(
  7374. 'cache' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>1, 'v'=>array('tf')),
  7375. 'cache_dir_abs' => array('type'=>'textfield', 'def'=>$zc['zina_dir_abs'].'/cache', 'v'=>array('if'=>array('cache'=>'dir_writeable'))),
  7376. 'cache_expire' => array('type'=>'textfield', 'def'=>7, 'suf'=> 'days', 'v'=>array('if'=>array('cache'=>'int')),
  7377. 'break'=>1),
  7378. 'cache_tmpl' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>0, 'v'=>array('tf')),
  7379. 'cache_tmpl_expire' => array('type'=>'textfield', 'def'=>21, 'suf'=>'days', 'v'=>array('if'=>array('cache_tmpl'=>'int'))) ,
  7380. ),
  7381. 'general' => array(
  7382. 'theme' => array('type'=>'select', 'opts'=>'zina_get_themes', 'def'=>$default_theme, 'v'=>array('req')),
  7383. 'lang' => array('type'=>'select', 'opts'=>'zina_get_languages', 'def'=>'en', 'v'=>array('req')),
  7384. 'main_dir_title' => array('type'=>'textfield', 'def'=>'Artists'),
  7385. 'amg' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>0, 'v'=>array('tf')),
  7386. 'play_sel' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>1, 'v'=>array('tf'),
  7387. 'break'=>1),
  7388. 'random' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>1, 'v'=>array('tf')),
  7389. 'ran_opts' => array('type'=>'textfield', 'def'=>'1,5,10,25,50,0', 'v'=>array('if'=>array('random'=>'int_split'))),
  7390. #todo: val && in ran_opts...
  7391. 'ran_opts_def' => array('type'=>'textfield', 'def'=>25, 'v'=>array('if'=>array('random'=>'int'))),
  7392. 'play_rec' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>0, 'v'=>array('tf')),
  7393. 'play_rec_rand' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>1, 'v'=>array('tf')),
  7394. 'honor_custom' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>1, 'v'=>array('tf'),
  7395. 'break'=>1),
  7396. #todo: make a random section???
  7397. 'random_least_played' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>0, 'v'=>array('tf')),
  7398. 'random_lp_floor' => array('type'=>'textfield', 'def'=>0, 'v'=>array('if'=>array('random_least_played'=>'int'))),
  7399. 'random_lp_perc' => array('type'=>'textfield', 'def'=>75, 'v'=>array('if'=>array('random_least_played'=>'int')), 'suf'=>'%',
  7400. 'break'=>1),
  7401. 'new_highlight' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>0, 'v'=>array('tf')),
  7402. 'new_time' => array('type'=>'textfield', 'suf'=>'days', 'def'=>14, 'v'=>array('if'=>array('new_highlight'=>'int'))),
  7403. ),
  7404. 'dirs' => array(
  7405. 'dir_file' => array('type'=>'textfield', 'def'=>'index.txt', 'v'=>array('req')),
  7406. 'ext_graphic' => array('type'=>'textfield', 'def'=>'jpg|gif|png|jpeg', 'v'=>array('req')),
  7407. 'image_captions' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>0, 'v'=>array('tf')),
  7408. #todo: val if (not empty) strlen == 1
  7409. 'dir_skip' => array('type'=>'textfield', 'def'=>'_'),
  7410. 'dir_sort_ignore' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>1, 'v'=>array('tf')),
  7411. 'dir_si_str' => array('type'=>'textfield', 'def'=>'the|a|an', 'v'=>array('if'=>array('dir_sort_ignore'=>'req')),
  7412. 'break'=>1),
  7413. 'dir_list' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>1, 'v'=>array('tf')),
  7414. 'subdir_truncate' => array('type'=>'textfield', 'def'=>25, 'suf'=>'characters', 'v'=>array('int')),
  7415. #TODO: make drop Down title ASC, title DESC, year ASC, year DESC
  7416. 'dir_list_sort' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>0, 'v'=>array('tf')),
  7417. 'dir_list_sort_asc' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>0, 'v'=>array('tf')),
  7418. 'subdir_images' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>1, 'v'=>array('tf')),
  7419. 'subdir_cols' => array('type'=>'textfield', 'def'=>3, 'v'=>array('int'),
  7420. 'break'=>1),
  7421. 'alt_dirs' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>0, 'v'=>array('tf')),
  7422. 'alt_file' => array('type'=>'textfield', 'def'=>'zina_alt', 'v'=>array('if'=>array('alt_dirs'=>'req'))),
  7423. ),
  7424. 'categories' => array(
  7425. 'cat_auto' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>1, 'v'=>array('tf')),
  7426. 'cat_auto_num' => array('type'=>'textfield', 'def'=>20, 'v'=>array('if'=>array('cat_auto'=>'int'))),
  7427. 'cat_file' => array('type'=>'textfield', 'def'=>'zina_category', 'v'=>array('req')),
  7428. #todo: val: if cat_auto || cat_file
  7429. 'cat_split' => array('type'=>'select', 'opts'=>'zina_get_opt_catsplit', 'def'=>1, 'v'=>array('req')),
  7430. 'cat_various_lookahead' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>0, 'v'=>array('tf')),
  7431. #todo val: if cat_split == 1
  7432. 'cat_cols' => array('type'=>'textfield', 'def'=>$cat_cols, 'v'=>array('int')),
  7433. 'cat_pp' => array('type'=>'textfield', 'def'=>$cat_pp, 'v'=>array('if'=>array('cat_split'=>'int'))),
  7434. 'cat_sort' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>1, 'v'=>array('tf')),
  7435. 'cat_sort_default' => array('type'=>'select', 'opts'=>'zina_get_cat_sorts', 'def'=>'a', 'v'=>array('req')),
  7436. 'cat_truncate' => array('type'=>'textfield', 'def'=>25, 'suf'=>'characters', 'v'=>array('int')),
  7437. 'cat_images' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>0, 'v'=>array('tf')),
  7438. ),
  7439. 'files' => array(
  7440. 'play' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>1, 'v'=>array('tf')),
  7441. 'download' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>1, 'v'=>array('tf')),
  7442. 'stream_int' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>1, 'v'=>array('tf')) ,
  7443. 'playlist_format' => array('type'=>'select', 'opts'=>'zina_get_opt_playlist_format', 'def'=>'m3u', 'v'=>array('req'),
  7444. 'break'=>1),
  7445. # todo: use xml_field for more crap...? must test though =(
  7446. 'zinamp' => array('type'=>'radio', 'opts'=>'zina_get_zinamp', 'def'=>0, 'v'=>array('req')),
  7447. 'zinamp_skin' => array('type'=>'select', 'opts'=>'zina_get_zinamp_skins', 'def'=>'WinampClassic', 'v'=>array('req'), 'break'=>1),
  7448. // 'jplayer' => array('type'=>'radio', 'opts'=>'zina_get_jplayer', 'def'=>1, 'v'=>array('req'),
  7449. // 'break'=>1),
  7450. 'files_sort' => array('type'=>'select', 'opts'=>'zina_get_opt_filesort', 'def'=>0, 'v'=>array('req')),
  7451. 'mp3_id3' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>1, 'v'=>array('tf')),
  7452. 'dir_tags' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>1, 'v'=>array('tf')),
  7453. 'mp3_info' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>1, 'v'=>array('tf')),
  7454. 'mp3_info_faster' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>1, 'v'=>array('tf')),
  7455. 'stream_extinf' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>1,'v'=>array('tf')),
  7456. 'stream_extinf_limit' => array('type'=>'textfield', 'def'=>100, 'v'=>array('if'=>array('stream_extinf'=>'int')),'suf'=>'items'),
  7457. 'song_blurbs' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>1, 'v'=>array('tf'), 'break'=>1),
  7458. 'song_extras' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>0, 'v'=>array('tf')),
  7459. 'song_extras_opt' => array('type'=>'textarea', 'def'=>"[lyr]\r\nname=Lyrics\r\ntype=page_internal\r\n",
  7460. 'rows'=>5, 'v'=>array('if'=>array('song_extras'=>'req')),
  7461. 'break'=>1),
  7462. 'playlists' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>1, 'v'=>array('tf')),
  7463. 'session_pls' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>1, 'v'=>array('tf')),
  7464. 'pls_ratings' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>1, 'v'=>array('tf')),
  7465. 'pls_length_limit' => array('type'=>'textfield', 'def'=>50, 'suf'=>'items', 'v'=>array('int')),
  7466. 'pls_limit' => array('type'=>'textfield', 'def'=>10, 'suf'=>'playlists', 'v'=>array('int')),
  7467. 'pls_public' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>1, 'v'=>array('tf')),
  7468. 'pls_included' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>1, 'v'=>array('tf')),
  7469. 'pls_included_limit' => array('type'=>'textfield', 'def'=>5, 'suf'=>'playlists', 'v'=>array('if'=>array('pls_included'=>'int')),
  7470. 'break'=>1),
  7471. 'various' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>0, 'v'=>array('tf')),
  7472. 'various_file' => array('type'=>'textfield', 'def'=>'zina_various', 'v'=>array('if'=>array('various-'>'req'))),
  7473. 'various_above' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>1, 'v'=>array('tf'),
  7474. 'break'=>1),
  7475. 'low' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>0, 'v'=>array('tf')),
  7476. 'low_suf' => array('type'=>'textfield', 'def'=>'.lofi', 'v'=>array('if'=>array('low'=>'req'))),
  7477. 'low_lookahead' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>0, 'v'=>array('tf'),
  7478. 'break'=>1),
  7479. 'resample' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>0, 'v'=>array('tf')),
  7480. 'enc_arr' => array('type'=>'textarea', 'def'=>
  7481. "[mp3]\r\nencoder = lame\r\nopts = --mp3input -f -b56 --lowpass 12.0 --resample 22.05 -S %FILE% -\r\nmime = audio/mpeg\r\n\r\n".
  7482. "[wav]\r\nencoder = lame\r\nopts = -f -b56 --lowpass 12.0 --resample 22.05 -S %FILE% -\r\nmime = audio/mpeg",
  7483. 'v'=>array('if'=>array('resample'=>'req')),
  7484. 'break'=>1),
  7485. 'remote' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>0, 'v'=>array('tf')),
  7486. 'remote_ext' => array('type'=>'textfield', 'def'=>'rem', 'v'=>array('if'=>array('remote'=>'req')),
  7487. 'break'=>1),
  7488. 'fake' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>0, 'v'=>array('tf')),
  7489. 'fake_ext' => array('type'=>'textfield', 'def'=>'fake', 'v'=>array('if'=>array('fake'=>'req'))),
  7490. ),
  7491. 'tags' => array(
  7492. 'tags_cddb_server' => array('type'=>'textfield', 'def'=>'freedb.freedb.org', 'v'=>array('req')),
  7493. 'tags_format' => array('type'=>'textfield', 'def'=>'UTF-8'),
  7494. 'tags_keep_existing_data' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>1, 'v'=>array('tf')),
  7495. 'tags_filemtime' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>1, 'v'=>array('tf')),
  7496. 'tags_cddb_auto_start' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>1, 'v'=>array('tf')),
  7497. ),
  7498. 'search' => array(
  7499. 'search' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>1, 'v'=>array('tf')),
  7500. 'search_images' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>1, 'v'=>array('tf')),
  7501. 'search_min_chars' => array('type'=>'textfield', 'def'=>3, 'v'=>array('if'=>array('search'=>'int'))),
  7502. 'search_live_limit' => array('type'=>'textfield', 'def'=>12, 'v'=>array('if'=>array('db_search'=>'int'))),
  7503. 'search_default' => array('type'=>'select', 'opts'=>'zina_get_opt_search', 'def'=>'browse', 'v'=>array('req')),
  7504. 'search_structure' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>1, 'v'=>array('tf')),
  7505. 'search_pp' => array('type'=>'textfield', 'def'=>20, 'v'=>array('if'=>array('search'=>'int')),
  7506. 'break'=>1),
  7507. 'db_search' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>0, 'v'=>array('tf')),
  7508. 'search_pp_opts' => array('type'=>'textfield', 'def'=>'20,50,100', 'v'=>array('if'=>array('search'=>'int_split'))),
  7509. ),
  7510. 'genres' => array(
  7511. 'genres' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>1, 'v'=>array('tf')),
  7512. 'genres_custom' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>0, 'v'=>array('tf')),
  7513. 'dir_genre_look' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>0, 'v'=>array('tf')),
  7514. 'genres_split' => array('type'=>'select', 'opts'=>'zina_get_opt_catsplit', 'def'=>0, 'v'=>array('req')),
  7515. 'genres_cols' => array('type'=>'textfield', 'def'=>4, 'v'=>array('int')),
  7516. 'genres_pp' => array('type'=>'textfield', 'def'=>200, 'v'=>array('if'=>array('genres_split'=>'int'))),
  7517. 'genres_truncate' => array('type'=>'textfield', 'def'=>30, 'suf'=>'characters', 'v'=>array('int')),
  7518. 'genres_images' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>1, 'v'=>array('tf')),
  7519. ),
  7520. 'compress' => array(
  7521. #todo: val cmp_sel value
  7522. 'cmp_sel' => array('type'=>'select', 'opts'=>'zina_get_opt_zip', 'def'=>0, 'v'=>array('int')),
  7523. 'cmp_cache' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>0, 'v'=>array('tf')),
  7524. 'cmp_pgm' => array('type'=>'textfield', 'def'=>'C:\cygwin\bin\zip', 'v'=>array('if'=>array('cmp_sel'=>'req'))),
  7525. 'cmp_set' => array('type'=>'textfield', 'def'=>'-0 -j -q %FILE% %FILELIST%', 'v'=>array('if'=>array('cmp_sel'=>'req'))),
  7526. 'cmp_extension' => array('type'=>'textfield', 'def'=>'zip', 'v'=>array('if'=>array('cmp_sel'=>'req'))),
  7527. 'cmp_mime' => array('type', 'type'=>'textfield', 'def'=>'application/zip', 'v'=>array('if'=>array('cmp_sel'=>'req'))),
  7528. ),
  7529. 'podcasts' => array(
  7530. #todo: val: if sitemap 1 or 2 tf
  7531. 'sitemap' => array('type'=>'radio', 'opts'=>'zina_get_opt_sitemap', 'def'=>1, 'v'=>array('int')),
  7532. 'sitemap_cache' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>1, 'v'=>array('if'=>array('sitemap'=>'tf'))),
  7533. 'sitemap_cache_expire' => array('type'=>'textfield', 'def'=>21, 'suf'=>'days', 'v'=>array('if'=>array('sitemap_cache'=>'int')),
  7534. 'break'=>1),
  7535. 'rss' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>1, 'v'=>array('tf')),
  7536. 'rss_podcast' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>1, 'v'=>array('tf')),
  7537. 'rss_file' => array('type'=>'textfield', 'def'=>'rss.xml', 'v'=>array('if'=>array('rss'=>'req'))),
  7538. 'rss_mm' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>0, 'v'=>array('tf')),
  7539. ),
  7540. #todo: could loop dir, sub, genre
  7541. 'images' => array(
  7542. 'res_in_types' => array('type'=>'checkboxes', 'opts'=>$img_ins, 'def'=>$img_ins_def, 'v'=>array('req')),
  7543. 'res_out_type' => array('type'=>'radio', 'opts'=>$img_outs, 'def'=> $img_out_def, 'v'=>array('req')),
  7544. 'res_out_x_lmt' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>1, 'v'=>array('tf')),
  7545. 'cache_imgs' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>0, 'v'=>array('tf'),
  7546. 'break' =>1),
  7547. 'res_dir_img' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>$img_resize, 'v'=>array('tf')),
  7548. 'res_dir_qual' => array('type'=>'textfield', 'def'=>75, 'v'=>array('int')),
  7549. 'res_dir_x' => array('type'=>'textfield', 'def'=>300, 'v'=>array('if'=>array('res_dir_img'=>'int')),'suf'=>'pixels'),
  7550. 'dir_img_txt' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>$freetype, 'v'=>array('tf')),
  7551. 'dir_img_txt_color' => array('type'=>'textfield', 'def'=>'255,255,255', 'v'=>array('if'=>array('dir_img_txt'=>'int_split')),'suf'=>'(R,G,B)'),
  7552. 'dir_img_txt_wrap' => array('type'=>'textfield', 'def'=>20, 'v'=>array('if'=>array('dir_img_txt'=>'int'))),
  7553. 'dir_img_txt_font' => array('type'=>'textfield', 'def'=>$zc['zina_dir_abs'].'/extras/LiberationSans-Bold.ttf',
  7554. 'v'=>array('if'=>array('dir_img_txt'=>'file_exists'))
  7555. ),
  7556. 'dir_img_txt_font_size' => array('type'=>'textfield', 'def'=>12, 'v'=>array('if'=>array('dir_img_txt'=>'int')), 'suf'=>'pt',
  7557. 'break'=>1
  7558. ),
  7559. 'res_sub_img' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>$img_resize, 'v'=>array('tf')),
  7560. 'res_sub_qual' => array('type'=>'textfield', 'def'=>75, 'v'=>array('int') ),
  7561. 'res_sub_x' => array('type'=>'textfield', 'def'=>200, 'v'=>array('int'),'suf'=>'pixels'),
  7562. 'sub_img_txt' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>$freetype, 'v'=>array('tf')),
  7563. 'sub_img_txt_color' => array('type'=>'textfield', 'def'=>'0,0,0', 'v'=>array('if'=>array('sub_img_txt'=>'int_split')),'suf'=>'(R,G,B)'),
  7564. 'sub_img_txt_wrap' => array('type'=>'textfield', 'def'=>20, 'v'=>array('if'=>array('sub_img_txt'=>'int'))),
  7565. 'sub_img_txt_font' => array('type'=>'textfield', 'def'=>$zc['zina_dir_abs'].'/extras/LiberationSans-Bold.ttf',
  7566. 'v'=>array('if'=>array('sub_img_txt'=>'file_exists'))
  7567. ),
  7568. 'sub_img_txt_font_size' => array('type'=>'textfield', 'def'=>12, 'v'=>array('if'=>array('sub_img_txt'=>'int')),'suf'=>'pt',
  7569. 'break'=>1
  7570. ),
  7571. 'res_full_img' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>$img_resize, 'v'=>array('tf')),
  7572. 'res_full_qual' => array('type'=>'textfield', 'def'=>75, 'v'=>array('int') ),
  7573. 'res_full_x' => array('type'=>'textfield', 'def'=>780, 'v'=>array('int'),'suf'=>'pixels',
  7574. 'break'=>1),
  7575. 'res_genre_img' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>$img_resize, 'v'=>array('tf')),
  7576. 'res_genre_qual' => array('type'=>'textfield', 'def'=>75, 'v'=>array('int') ),
  7577. 'res_genre_x' => array('type'=>'textfield', 'def'=>200, 'v'=>array('int'),'suf'=>'pixels'),
  7578. 'genre_img_txt' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>$freetype, 'v'=>array('tf')),
  7579. 'genre_img_txt_color' => array('type'=>'textfield', 'def'=>'255,255,255', 'v'=>array('if'=>array('genre_img_txt'=>'int_split')),'suf'=>'(R,G,B)'),
  7580. 'genre_img_txt_wrap' => array('type'=>'textfield', 'def'=>16, 'v'=>array('if'=>array('genre_img_txt'=>'int'))),
  7581. 'genre_img_txt_font' => array('type'=>'textfield', 'def'=>$zc['zina_dir_abs'].'/extras/LiberationSans-Bold.ttf',
  7582. 'v'=>array('if'=>array('sub_img_txt'=>'file_exists'))),
  7583. 'genre_img_txt_font_size' => array('type'=>'textfield', 'def'=>14, 'v'=>array('if'=>array('genre_img_txt'=>'int')),'suf'=>'pt',
  7584. 'break'=>1),
  7585. 'res_search_img' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>$img_resize, 'v'=>array('tf')),
  7586. 'res_search_qual' => array('type'=>'textfield', 'def'=>100, 'v'=>array('int') ),
  7587. 'res_search_x' => array('type'=>'textfield', 'def'=>65, 'v'=>array('int'),'suf'=>'pixels'),
  7588. 'search_img_txt' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>$freetype, 'v'=>array('tf')),
  7589. 'search_img_txt_color' => array('type'=>'textfield', 'def'=>'0,0,0', 'v'=>array('if'=>array('search_img_txt'=>'int_split')),'suf'=>'(R,G,B)'),
  7590. 'search_img_txt_wrap' => array('type'=>'textfield', 'def'=>12, 'v'=>array('if'=>array('search_img_txt'=>'int'))),
  7591. 'search_img_txt_font' => array('type'=>'textfield', 'def'=>$zc['zina_dir_abs'].'/extras/LiberationSans-Bold.ttf',
  7592. 'v'=>array('if'=>array('sub_img_txt'=>'file_exists'))),
  7593. 'search_img_txt_font_size' => array('type'=>'textfield', 'def'=>8, 'v'=>array('if'=>array('search_img_txt'=>'int')),'suf'=>'pt'),
  7594. ),
  7595. 'pos' => array(
  7596. 'pos' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>0, 'v'=>array('tf')),
  7597. 'pos_cmd' => array('type'=>'textfield', 'def'=>'bgrun.exe C:\Progra~1\Winamp\winamp.exe %TEMPFILENAME%.m3u >NUL',
  7598. 'v'=>array('if'=>array('pos'=>'req'))),
  7599. 'pos_kill' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>0, 'v'=>array('tf')),
  7600. 'pos_kill_cmd' => array('type'=>'textfield', 'def'=>'killall mpg123', 'v'=>array('if'=>array('pos_kill'=>'req'))),
  7601. ),
  7602. 'other_media' => array(
  7603. 'other_media_types' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>0, 'v'=>array('tf')),
  7604. 'media_types_cfg' => array('type'=>'textarea', 'def'=>
  7605. "[mp3]\r\nmime = audio/mpeg\r\nprotocol = http\r\nplaylist_ext = m3u\r\nplaylist_mime = audio/mpegurl\r\n\r\n".
  7606. "[ogg]\r\nmime = audio/ogg\r\nprotocol = http\r\nplaylist_ext = m3u\r\nplaylist_mime = audio/mpegurl\r\n\r\n".
  7607. "[m4a]\r\nmime = audio/m4a\r\nprotocol = http\r\nplaylist_ext = m3u\r\nplaylist_mime = audio/mpegurl\r\n\r\n".
  7608. "[wav]\r\nmime = audio/x-wav\r\nprotocol = http\r\nplaylist_ext = m3u\r\nplaylist_mime = audio/mpegurl\r\n\r\n".
  7609. "[wma]\r\nmime = audio/x-ms-wma\r\nprotocol = http\r\nplaylist_ext = m3u\r\nplaylist_mime = audio/mpegurl",
  7610. 'v'=>array('if'=>array('other_media_types'=>'req'))
  7611. ),
  7612. ),
  7613. 'mm' => array(
  7614. 'mm' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>0, 'v'=>array('tf')),
  7615. 'mm_down' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>1, 'v'=>array('tf')),
  7616. 'mm_types_cfg' => array('type'=>'textarea', 'def'=>
  7617. "[pdf]\r\nmime = application/pdf\r\ndisposition = inline\r\n\r\n".
  7618. "[avi]\r\nmime = video/msvideo\r\nplayer = WMP\r\n\r\n[mpg]\r\nmime = video/mpeg\r\nplayer = WMP\r\n\r\n".
  7619. "[mpeg]\r\nmime = video/mpeg\r\nplayer = WMP\r\n\r\n[asf]\r\nmime = video/x-ms-asf\r\nplayer = WMP\r\n\r\n".
  7620. "[wmv]\r\nmime = video/x-ms-wmv\r\nplayer = WMP\r\n\r\n[mov]\r\nmime = video/quicktime\r\nplayer = QT",
  7621. 'v'=>array('if'=>array('mm'=>'req'))
  7622. ),
  7623. ),
  7624. 'cron' => array(
  7625. 'cron' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>0, 'v'=>array('tf')),
  7626. 'cron_opts' => array('type'=>'textarea', 'rows'=>5, 'def'=>'', 'v'=>array('if'=>array('cron'=>'req'))),
  7627. ),
  7628. 'cms' => array(
  7629. 'cms_editor' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>0, 'v'=>array('tf')),
  7630. 'cms_tags' => array('type'=>'textfield', 'def'=>'<a><strong><em><ul><ol><li><cite><code>',
  7631. 'break'=>1),
  7632. 'pls_user' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>1, 'v'=>array('tf')),
  7633. 'pls_tags' => array('type'=>'textfield', 'def'=>'<b><i>'),
  7634. ),
  7635. 'integration' => array(
  7636. 'lastfm' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>0, 'v'=>array('tf')),
  7637. 'lastfm_username' => array('type'=>'textfield', 'def'=>'', 'v'=>array('if'=>array('lastfm'=>'req'))),
  7638. 'lastfm_password' => array('type'=>'password', 'def'=>'', 'v'=>array('if'=>array('lastfm'=>'req')),
  7639. 'break'=>1),
  7640. 'twitter' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>0, 'v'=>array('tf')),
  7641. 'twitter_username' => array('type'=>'textfield', 'def'=>'', 'v'=>array('if'=>array('twitter'=>'req'))),
  7642. 'twitter_password' => array('type'=>'password', 'def'=>'', 'v'=>array('if'=>array('twitter'=>'req')),
  7643. 'break'=>1),
  7644. ),
  7645. 'third' => array(
  7646. 'third_images' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>1, 'v'=>array('tf')),
  7647. 'third_amazon_private' => array('type'=>'textfield', 'def'=>''),
  7648. 'third_amazon_public' => array('type'=>'textfield', 'def'=>''),
  7649. 'third_amazon_region' => array('type'=>'textfield', 'def'=>'com',
  7650. 'break'=>1),
  7651. 'third_lyr' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>0, 'v'=>array('tf')),
  7652. 'third_lyr_order' => array('type'=>'textfield', 'def'=>$lyrics),
  7653. 'third_lyr_save' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>0, 'v'=>array('tf'),
  7654. 'break'=>1),
  7655. 'third_addthis' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>1, 'v'=>array('tf')),
  7656. 'third_addthis_id' => array('type'=>'textfield', 'def'=>'YOUR-ACCOUNT-ID'),
  7657. 'third_addthis_options' => array('type'=>'textfield', 'def'=>'email, favorites, digg, delicious, facebook, google, live, myspace, twitter, more'),
  7658. ),
  7659. 'stats' => array(
  7660. 'stats' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>1, 'v'=>array('tf')),
  7661. 'stats_public' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>1, 'v'=>array('tf')),
  7662. 'stats_images' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>1, 'v'=>array('tf')),
  7663. 'stats_rss' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>1, 'v'=>array('tf')),
  7664. 'stats_limit' => array('type'=>'textfield', 'def'=>'10', 'v'=>array('if'=>array('stats'=>'int'))),
  7665. 'stats_to' => array('type'=>'textfield', 'def'=>'90', 'suf'=>'seconds', 'v'=>array('if'=>array('stats'=>'int'))),
  7666. 'stats_org' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>1, 'v'=>array('tf'),
  7667. 'break'=>1),
  7668. 'rating_dirs' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>1, 'v'=>array('tf')),
  7669. 'rating_dirs_public' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>1, 'v'=>array('tf')),
  7670. 'rating_files' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>1, 'v'=>array('tf')),
  7671. 'rating_files_public' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>1, 'v'=>array('tf')),
  7672. 'rating_limit' => array('type'=>'textfield', 'def'=>'1,1,1,1,1', 'v'=>array('if'=>array('stats'=>'int_split'))),
  7673. 'rating_random' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>1, 'v'=>array('tf')),
  7674. #todo: val -> if float_split
  7675. 'rating_random_opts' => array('type'=>'textfield', 'def'=>'5,4.5,4', 'v'=>0,
  7676. 'break'=>1),
  7677. 'cache_stats' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>0, 'v'=>array('tf')),
  7678. 'cache_stats_expire' => array('type'=>'textfield', 'def'=>3, 'suf'=>'hours', 'v'=>array('if'=>array('cache_stats'=>'int'))),
  7679. ),
  7680. 'advanced' => array(
  7681. #todo: val->path_exists? try path_relative?
  7682. 'zina_dir_rel' => array('type'=>'textfield', 'def'=>$zina_dir_rel),
  7683. 'local_path' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>0, 'v'=>array('tf')),
  7684. 'timeout' => array('type'=>'textfield', 'def'=>120, 'v'=>array('int')),
  7685. 'charset' => array('type'=>'textfield', 'def'=>'utf-8', 'v'=>array('req')),
  7686. 'locale' => array('type'=>'textfield', 'def'=> setlocale(LC_ALL,0)),
  7687. 'timezone' => array('type'=>'textfield', 'def'=>@date_default_timezone_get()),
  7688. 'debug' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>0, 'v'=>array('tf'),
  7689. 'break'=>1),
  7690. 'settings_override' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>0, 'v'=>array('tf')),
  7691. 'settings_override_file' => array('type'=>'textfield', 'def'=>'zina_settings.xml', 'v'=>array('if'=>array('settings_override'=>'req')),
  7692. 'break'=>1),
  7693. 'cache_dir_private_abs' => array('type'=>'textfield', 'def'=>$zc['zina_dir_abs'].'/cache/private', 'v'=>array('if'=>array('cache'=>'dir_writeable'))),
  7694. 'cache_dir_public_rel' => array('type'=>'textfield', 'def'=>'cache/public', 'v'=>array('if'=>array('cache'=>'dir_writeable'))),
  7695. 'cache_imgs_dir_rel' => array('type'=>'textfield', 'def'=>'cache/public/images', 'v'=>array('if'=>array('cache_imgs'=>'path_relative')),
  7696. 'break'=>1),
  7697. 'clean_urls_hack' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>$clean_url_hack, 'v'=>array('tf')),
  7698. 'clean_urls_index' => array('type'=>'textfield', 'def'=>'music', 'v'=>array('if'=>array('clean_urls_hack'=>'req'))),
  7699. ),
  7700. );
  7701. }
  7702. elseif ($type == 'lang') {
  7703. require_once('lang-cfg.php');
  7704. return array('cats' => $cats, 'titles' => $titles, 'subs' => $subs);
  7705. }
  7706. elseif ($type == 'directory') {
  7707. return array(
  7708. 'directory_opts' => array(
  7709. 'person' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>0, 'v'=>array('tf')),
  7710. 'various' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>0, 'v'=>array('tf')),
  7711. ),
  7712. 'categories' => array(
  7713. 'category' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>0, 'v'=>array('tf')),
  7714. 'split' => array('type'=>'select', 'opts'=>'zina_get_opt_catsplit', 'def'=>$zc['cat_split'], 'v'=>array('req')),
  7715. 'cols' => array('type'=>'textfield', 'def'=>$zc['cat_cols'], 'v'=>array('if'=>array('category'=>'int'))),
  7716. 'pp' => array('type'=>'textfield', 'def'=>$zc['cat_pp'], 'v'=>array('if'=>array('split'=>'int'))),
  7717. 'sort' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>$zc['cat_sort'], 'v'=>array('tf')),
  7718. 'sort_default' => array('type'=>'select', 'opts'=>'zina_get_cat_sorts', 'def'=>'a', 'v'=>array('req')),
  7719. 'truncate' => array('type'=>'textfield', 'def'=>$zc['cat_truncate'], 'suf'=>'characters', 'v'=>array('if'=>array('category'=>'int'))),
  7720. 'images' => array('type'=>'radio', 'opts'=>'zina_get_opt_tf', 'def'=>$zc['cat_images'], 'v'=>array('tf')),
  7721. ),
  7722. );
  7723. }
  7724. }
  7725. ?>