PageRenderTime 60ms CodeModel.GetById 13ms RepoModel.GetById 1ms app.codeStats 0ms

/zina/theme.php

https://bitbucket.org/helmespc/zina2
PHP | 2627 lines | 2098 code | 335 blank | 194 comment | 409 complexity | 40374136df0ede9f79ec5558f4bcf280 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. * TODO:
  21. * - organize this file
  22. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  23. /*
  24. * YOU SHOULD NOT MODIFY THIS FILE...
  25. *
  26. * You should override all these functions in your own theme:
  27. * 1) Copy a theme folder
  28. * 2) in MYTHEME/index.php copy any function you want to
  29. * override into that file
  30. * 3) rename that function to MYTHEME_function()
  31. * - e.g. ztheme_icon -> MYTHEME_icon
  32. * 4) modify that function to suit your needs
  33. * x) An easy way to see what a function is passing is zdbg($var);
  34. */
  35. /*
  36. * Complete Page (Standalone)
  37. */
  38. function ztheme_page_complete($zina) {
  39. $theme_path = $zina['theme_path'];
  40. $output = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'.
  41. '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"><head><title>'.$zina['title'].'</title>'.
  42. '<meta http-equiv="Content-Type" content="text/html; charset='.$zina['charset'].'" />'.
  43. '<link rel="shortcut icon" href="'.$theme_path.'/zina.ico" type="image/x-icon" />'.
  44. '<link rel="stylesheet" href="'.$theme_path.'/index.css" type="text/css" />'.
  45. '<!--[if lt IE 7]><link type="text/css" rel="stylesheet" media="all" href="'.$theme_path.'/fix-ie.css" /><![endif]-->'.
  46. $zina['head_html'].$zina['head_css'].$zina['head_js'].'</head><body>';
  47. $output .= '<div id="header-region" class="clear-block"></div>'.
  48. '<div id="wrapper"><div id="container" class="clear-block">'.
  49. '<div id="header"><h1>'.$zina['title'].'</h1>'.
  50. '<div class="header-right">';
  51. if (isset($zina['dir_year']) || isset($zina['dir_genre'])) {
  52. $output .= '<span class="title_details">';
  53. if (isset($zina['dir_genre'])) $output .= $zina['dir_genre'];
  54. if (!empty($zina['dir_year'])) $output .= ' ('.$zina['dir_year'].')';
  55. $output .= '</span>';
  56. }
  57. $output .= '</div></div>'.
  58. '<div id="center"><div class="right-corner"><div class="left-corner">'.
  59. '<div class="breadcrumb">'.ztheme('breadcrumb',$zina['breadcrumb']).'</div>'.
  60. '<div class="breadcrumb-right">';
  61. if (isset($zina['admin_config'])) {
  62. $output .= zl(ztheme('icon','config.gif',zt('Settings')),$zina['admin_config']['path'],$zina['admin_config']['query']);
  63. }
  64. $lang['login'] = zt('Login');
  65. $lang['logout'] = zt('Logout');
  66. if (isset($zina['login'])) {
  67. $output .= zl(ztheme('icon',$zina['login']['type'].'.gif',$lang[$zina['login']['type']]), $zina['login']['path'], $zina['login']['query']);
  68. }
  69. $output .= '</div><div id="zina" class="clear-block">';
  70. if (!isset($zina['popup'])) {
  71. $output .= '<div class="subheader clear-block"><div class="subheader-left">'.$zina['searchform'].'</div>'.
  72. '<div class="subheader-right">'.$zina['randomplayform'].'</div></div>';
  73. if (!empty($zina['zinamp']) && (!isset($zina['page_main']) || isset($zina['category']))) {
  74. $output .= '<div style="text-align:right;">'.$zina['zinamp'].'</div>';
  75. }
  76. }
  77. $output .= '<div id="zina_messages">'.$zina['messages'].'</div>'.$zina['content'].ztheme('page_footer',$zina).
  78. '</div></div></div></div></div></div></body></html>';
  79. return $output;
  80. }
  81. function ztheme_page_main($zina) {
  82. $path = $zina['path'];
  83. $output = '';
  84. $lang['dir'] = zt('Edit Text');
  85. $lang['dir_opts'] = zt('Options');
  86. $lang['podcast'] = zt('Edit Podcast');
  87. $lang['rename'] = zt('Rename');
  88. $lang['images'] = zt('Edit Images');
  89. $lang['tags'] = zt('Edit Tags');
  90. if (isset($zina['category'])) {
  91. if (!empty($zina['description']) || isset($zina['dir_edit_opts'])) {
  92. $output .= '<table border="0" cellpadding="5" cellspacing="0" width="100%">'.
  93. '<tr><td valign="top" width="100%">';
  94. if (!empty($zina['description'])) $output .= '<p>'.$zina['description'].'</p>';
  95. # todo: dup with below...
  96. if (isset($zina['dir_edit_opts'])) {
  97. $options = array();
  98. foreach ($zina['dir_edit_opts'] as $opt => $opts) {
  99. $options[] = zl($lang[$opt],$opts['path'], $opts['query']);
  100. }
  101. $output .= '<p class="small">';
  102. $output .= implode(' | ', $options);
  103. $output .= '</p>';
  104. }
  105. $output .= '</td></tr></table>';
  106. }
  107. if (isset($zina['category']) && !empty($zina['category']['sort'])) {
  108. $output .= '<table width="100%"><tr><td class="quarterwidth">'.$zina['category']['sort'].'</td>';
  109. if (isset($zina['category']['navigation'])) {
  110. $output .= '<td class="halfwidth" align="center">'.$zina['category']['navigation'].'</td>'.
  111. '<td class="quarterwidth"></td>';
  112. }
  113. $output .= '</tr></table>';
  114. } else {
  115. if (isset($zina['category']['navigation'])) $output .= $zina['category']['navigation'];
  116. }
  117. $output .= ''.$zina['category']['content'];
  118. if (isset($zina['category']['navigation'])) $output .= $zina['category']['navigation'];
  119. } else {
  120. $output .= '<div class="section">';
  121. $subdirs = ($zina['subdir_num'] > 0);
  122. $altdirs = ($zina['alt_num'] > 0);
  123. if (($subdirs && $zina['dir_list']) || $altdirs || isset($zina['alt_list_edit']) || !empty($zina['zinamp']) || $zina['pls_included']) {
  124. $output .= '<div class="directory_list">';
  125. if (!empty($zina['zinamp'])) $output .= '<div style="margin-bottom:5px;">'.$zina['zinamp'].'</div>';
  126. $form_content = '';
  127. if ($subdirs && $zina['dir_list']) $form_content .= ztheme('directory_list', $zina['subdirs'], $zina['subdir_truncate']);
  128. if ($altdirs || isset($zina['alt_list_edit'])) {
  129. $form_content .= ztheme('directory_alt_list', $zina['alt_items'], $zina['subdir_truncate']);
  130. if (isset($zina['alt_list_edit'])) {
  131. $form_content .= '<div class="small">'.zl(zt('Edit "See Also"'),$path,$zina['alt_list_edit']['query']).'</div>';
  132. }
  133. }
  134. if ($zina['pls_included']) {
  135. $form_content .= '<div style="margin:10px 0 10px 0">'.ztheme('playlists_block', $zina['pls_included']['items'], $zina['subdir_truncate']);
  136. if (isset($zina['pls_included']['more'])) {
  137. $form_content .= '<div class="small">'.zl(zt('More'),$zina['pls_included']['more']['path'],$zina['pls_included']['more']['query']).'</div>';
  138. }
  139. $form_content .= '</div>';
  140. }
  141. $output .= (!empty($zina['list_form_opts'])) ? ztheme('form', $zina['list_form_opts'], $form_content.$zina['list_form']) : $form_content;
  142. if ($zina['amg']) {
  143. $output .= '<div class="amg">'.ztheme('amg',$zina).'</div>';
  144. }
  145. $output .= '</div>';
  146. }
  147. if (isset($zina['dir_image'])) $output .= '<div class="directory-image">'.$zina['dir_image'].'</div>';
  148. if (isset($zina['dir_opts'])) {
  149. $output .= '<p class="dir-opts">'.ztheme('dir_opts',$zina['dir_opts'],$zina['title_raw']).'</p>';
  150. }
  151. $votes = (isset($zina['dir_rating']) && $zina['dir_rating']['sum_votes'] > 0);
  152. if ($votes || isset($zina['dir_rate'])) {
  153. $output .= '<p class="small">';
  154. if ($votes) {
  155. $output .= ztheme('rating_display', $zina['dir_rating']['sum_rating']).
  156. ztheme('votes_display',$zina['dir_rating']['sum_votes']);
  157. if (isset($zina['dir_rate'])) $output .= '&nbsp; | ';
  158. }
  159. if (isset($zina['dir_rate'])) $output .= zt('Rate').': '.$zina['dir_rate'];
  160. $output .= '</p>';
  161. }
  162. if (isset($zina['description'])) $output .= $zina['description'];
  163. if (isset($zina['podcast'])) {
  164. $type = $zina['podcast']['type'];
  165. $icon_title = ($type == 'podcast') ? zt('Podcast') : zt('RSS Feed');
  166. $output .= '<p>'.zl(ztheme('icon',$type.'.gif', $icon_title),$zina['podcast']['url'],$zina['podcast']['query']).'</p>';
  167. }
  168. $output .= ztheme('addthis', $zina, 'bookmark');
  169. if (isset($zina['dir_edit_opts'])) {
  170. $options = array();
  171. foreach ($zina['dir_edit_opts'] as $opt => $opts) {
  172. $options[] = zl($lang[$opt],$opts['path'], $opts['query']);
  173. }
  174. $output .= '<p class="small">';
  175. $output .= implode(' | ', $options);
  176. $output .= '</p>';
  177. }
  178. $output .= '</div>';
  179. if ($subdirs && $zina['subdir_images']) {
  180. $output .= '<div class="section">'.ztheme('image_list', $zina['subdirs'], $zina['subdir_cols']).'</div>';
  181. }
  182. if ($altdirs) {
  183. $output .= '<div class="section">'.ztheme('image_alt_list', $zina['alt_items'], $zina['subdir_cols']).'</div>';
  184. }
  185. }
  186. if (isset($zina['songs'])) $output .= '<div class="section">'.$zina['songs'].'</div>';
  187. if (isset($zina['multimedia'])) {
  188. $output .= '<div class="section">'.
  189. ztheme('multimedia_section', ztheme('multimedia_list', $zina['multimedia'])).
  190. '</div>';
  191. }
  192. return $output;
  193. }
  194. #todo: try <ul>
  195. function ztheme_category($dirs, $cols, $images = false, $truncate = 25, $full_page_split = false) {
  196. $output = '';
  197. if (!empty($dirs)) {
  198. if ($images) {
  199. if ($full_page_split) {
  200. $output = '';
  201. foreach($dirs as $letter => $items) {
  202. if (strlen($letter) > 3) {
  203. $output .= '<h1 class="zina-cat-letter"><a name="'.strtolower($letter).'" href="'.zurl($letter).'" class="zina-cat-letter">'.$letter.'</a></h1>';
  204. } else {
  205. $letter = ($letter == 'zzz') ? zt('Other') : $letter;
  206. $output .= '<h1 class="zina-cat-letter">'.$letter.'<a name="'.strtolower($letter).'" class="zina-cat-letter" /></h1>';
  207. }
  208. $output .= '<br style="clear:both;"/>'.ztheme('image_list_category', $items, $cols);
  209. }
  210. return $output;
  211. } else {
  212. return ztheme('image_list_category', $dirs, $cols);
  213. }
  214. }
  215. $columns = $i = $row = 0;
  216. $letter_height = 3;
  217. $items = ($full_page_split) ? $full_page_split + (count($dirs)*$letter_height) : count($dirs);
  218. $rows_in_col = ceil($items/$cols);
  219. if ($rows_in_col < $cols) $cols = ceil($items/$rows_in_col);
  220. $col_width = round(100/$cols);
  221. $img_new = ztheme('icon','new.gif',zt('New'));
  222. zina_set_css('inline','.catcolwidth{width:'.$col_width.'%;}');
  223. $output .= '<table width="100%" class="category"><tr>';
  224. if ($full_page_split) {
  225. zina_set_css('inline', 'td.catcolwidth a{margin-left:5px;}');
  226. $first = true;
  227. foreach($dirs as $letter => $dir) {
  228. $count = count($dir) + $letter_height;
  229. $row += $count;
  230. if (($first || $row > $rows_in_col + ($letter_height*2)) && $columns < $cols) {
  231. $row = $count;
  232. if (!$first) $output .= '</td>';
  233. $output .= '<td class="catcolwidth'.(($cols != ++$i) ? ' category_cols' : '').'" valign="top">';
  234. $first = false;
  235. $columns++;
  236. } else {
  237. $output .= "<br/>\n";
  238. }
  239. if (strlen($letter) > 3) {
  240. $output .= '<h1 class="zina-cat-letter"><a name="'.strtolower($letter).'" href="'.zurl($letter).'" class="zina-cat-letter">'.$letter.'</a></h1>';
  241. } else {
  242. $letter = ($letter == 'zzz') ? zt('Other') : $letter;
  243. $output .= '<h1 class="zina-cat-letter">'.$letter.'<a name="'.strtolower($letter).'" class="zina-cat-letter" /></h1>';
  244. }
  245. foreach($dir as $key => $opts) {
  246. $title = ztheme('truncate', $opts['title'], $truncate);
  247. $output .= zl($title,$opts['path'],$opts['query']);
  248. if ($opts['new']) $output .= '&nbsp;'.$img_new;
  249. $output .= ' <br/>'."\n";
  250. }
  251. }
  252. $output .= '</td>'."\n";
  253. } else {
  254. foreach ($dirs as $opts) {
  255. if ($row == 0) {
  256. $output .= '<td class="catcolwidth'.(($cols != ++$i) ? ' category_cols' : '').'" valign="top">';
  257. }
  258. $title = ztheme('truncate', $opts['title'], $truncate);
  259. $output .= zl($title,$opts['path'],$opts['query']);
  260. if ($opts['new']) $output .= '&nbsp;'.$img_new;
  261. $output .= '<br/>'."\n";
  262. $row = ++$row % $rows_in_col;
  263. if ($row == 0) $output .= '</td>';
  264. }
  265. if ($row != 0) $output .= '</td>';
  266. }
  267. $output .= '</tr></table>';
  268. }
  269. return $output;
  270. }
  271. /*
  272. * Category Pages Navigation
  273. *
  274. * e.g. Start - First - 1 - 2 - Next - Last
  275. */
  276. function ztheme_category_pages($path, $current, $total, $query='') {
  277. $output = '';
  278. if ($total > 1) {
  279. $output .= '<div class="category_pages">';
  280. if ($current != 1) {
  281. $output .= zl(ztheme('icon','first.gif',zt('First')),$path,$query.'page=1');
  282. $output .= zl(ztheme('icon','back.gif',zt('Previous')),$path,$query.'page='.($current-1));
  283. } else {
  284. $output .= ztheme('icon','first_un.gif',zt('First'));
  285. $output .= ztheme('icon','back_un.gif',zt('Previous'));
  286. }
  287. $output .= '&nbsp;';
  288. for($i=1;$i<=$total;$i++) {
  289. $arr[] = ($current == $i) ? "<strong>$i</strong>" : zl($i,$path,$query.'page='.$i);
  290. }
  291. $output .= implode(' &middot; ',$arr);
  292. $output .= '&nbsp;';
  293. if ($current == $total) {
  294. $output .= ztheme('icon','forward_un.gif',zt('Next'));
  295. $output .= ztheme('icon','last_un.gif',zt('Last'));
  296. } else {
  297. $output .= zl(ztheme('icon','forward.gif',zt('Next')),$path,$query.'page='.($current+1));
  298. $output .= zl(ztheme('icon','last.gif',zt('Last')),$path,$query.'page='.$total);
  299. }
  300. $output .= '</div>';
  301. }
  302. return $output;
  303. }
  304. /*
  305. * Category Alphabet Navigation
  306. *
  307. * e.g. A - B - C - D...
  308. */
  309. function ztheme_category_alphabet($path, $current, $letters, $query='', $full_page = false) {
  310. $output = '<div class="category_pages">';
  311. if ($full_page) {
  312. foreach ($letters as $key) {
  313. $letter = ($key == 'zzz') ? zt('Other') : $key;
  314. $links[] = zl($letter,$path,$query,strtolower($letter));
  315. }
  316. } else {
  317. foreach ($letters as $key) {
  318. $letter = ($key == 'zzz') ? zt('Other') : $key;
  319. $links[] = ($current == $key) ? "<strong>$letter</strong>" : zl($letter,$path,$query.'page='.$key);
  320. }
  321. }
  322. $output .= implode(' &middot; ',$links);
  323. return $output.'</div>';
  324. }
  325. /*
  326. * Category Split by Alphabet helper
  327. */
  328. function ztheme_category_alphabet_split($dirs, $sort_ignore) {
  329. $splits = array();
  330. foreach ($dirs as $key=>$item) {
  331. $key = $item['title'];
  332. if ($item['person']) {
  333. if (($pos = strripos($key, ' ')) !== false) {
  334. $letter = zina_strtoupper(zcheck_utf8(zina_substr($key, $pos+1,1)));
  335. } else {
  336. $letter = zina_strtoupper(zcheck_utf8($key[0]));
  337. }
  338. } else if ($sort_ignore && preg_match('/^('.$sort_ignore.')\s/i',$key, $matches)) {
  339. # ignore certain thing like "the" and "a"
  340. $letter = zina_strtoupper(zina_substr($key, zina_strlen($matches[1])+1, 1));
  341. } elseif (preg_match('/^(\W|\d)/', $key, $matches)) {
  342. # non-alpha characters get grouped together...
  343. $letter = 'zzz';
  344. } else {
  345. # upper and lowercase are same
  346. $letter = zina_strtoupper(zcheck_utf8($key[0]));
  347. }
  348. $splits[$letter][$key] = $item;
  349. }
  350. ksort($splits);
  351. return $splits;
  352. }
  353. /*
  354. * Category Sort Alpha/Date
  355. */
  356. function ztheme_category_sort($path, $cat) {
  357. $lang['asc'] = zt('Sort Ascending');
  358. $lang['desc'] = zt('Sort Descending');
  359. return '<span class="small">'.zt('Sort').': '.
  360. zl(zt('Alpha'), $path, $cat['alpha']['query']).' '.
  361. zl(ztheme('icon','sort_'.$cat['alpha']['sort'].'.gif', $lang[$cat['alpha']['sort']]), $path,$cat['alpha']['query']).
  362. '&nbsp;'.
  363. zl(zt('Date'), $path, $cat['date']['query']).' '.
  364. zl(ztheme('icon','sort_'.$cat['date']['sort'].'.gif',$lang[$cat['date']['sort']]),$path,$cat['date']['query']).'</span>';
  365. }
  366. function ztheme_playlists_block($playlists, $truncate=25) {
  367. $output='';
  368. if ($playlists) {
  369. $output .= '<h3>'.zt('Tracks Appear On').'</h3>';
  370. $output .= ztheme('directory_list_helper', $playlists, $truncate);
  371. }
  372. return $output;
  373. }
  374. function ztheme_directory_list($dirs, $truncate=25) {
  375. $output='';
  376. if ($dirs) {
  377. $output .= '<h3>'.zt('Albums').'</h3>';
  378. $output .= ztheme('directory_list_helper', $dirs, $truncate);
  379. }
  380. return $output;
  381. }
  382. function ztheme_directory_alt_list($dirs, $truncate=25) {
  383. $output='';
  384. $output .= '<h3>'.zt('See Also').'</h3>';
  385. if ($dirs) {
  386. $output .= ztheme('directory_list_helper', $dirs, $truncate);
  387. }
  388. return $output;
  389. }
  390. function ztheme_directory_list_helper($dirs, $truncate=25) {
  391. global $zc;
  392. $lang['play'] = zt('Play');
  393. $lang['play_lofi'] = zt('Play Low Fidelity');
  394. $lang['download'] = zt('Download');
  395. $lang['play_rec'] = zt('Play recursively');
  396. $lang['play_rec_rand'] = zt('Play recursively random');
  397. $class = "zinamp";
  398. $img_new = ztheme('icon','new.gif',zt('New'));
  399. $output = '<ul>';
  400. foreach ($dirs as $opts) {
  401. $output .= '<li>';
  402. if (isset($opts['opts'])) {
  403. foreach ($opts['opts'] as $type=>$opt) {
  404. $attr = (substr($type,0,4) == 'play') ? 'class="'.$class.'"' : '';
  405. //$attr = (substr($type,0,4) == 'play') ? 'class="zinamp"' : '';
  406. $output .= zl(ztheme('icon',$type.'.gif',$lang[$type]),$opt['path'],$opt['query'], null, false, $attr);
  407. }
  408. }
  409. if (isset($opts['checkbox'])) $output .= ztheme('form_checkbox', $opts['checkbox']['name'], $opts['checkbox']['value'], $opts['checkbox']['checked']).'&nbsp;';
  410. $title = ztheme('truncate', $opts['title'], $truncate);
  411. $output .= zl($title,$opts['path'], isset($opts['query']) ? $opts['query'] : null);
  412. if (!empty($opts['info']->year)) $output .= ' ('.$opts['info']->year.')';
  413. if ($opts['new']) $output .= '&nbsp;'.$img_new;
  414. $output .= '</li>';
  415. }
  416. $output .= '</ul>';
  417. return $output;
  418. }
  419. function ztheme_image_list($dirs, $cols) {
  420. return '<h3>'.zt('Albums').'</h3>'.ztheme('image_list_helper', $dirs, $cols);
  421. }
  422. function ztheme_image_alt_list($dirs, $cols) {
  423. return '<h3>'.zt('See Also').'</h3>'.ztheme('image_list_helper', $dirs, $cols);
  424. }
  425. function ztheme_image_list_helper($dirs, $cols) {
  426. $col = 0;
  427. $col_width = round(100/$cols).'%';
  428. zina_set_css('inline', 'td.zinaimgcolwidth{width:'.$col_width.';}');
  429. $align[$cols - 1] = 'right';
  430. $align[0] = 'left';
  431. for($i=1; $i < $cols - 1; $i++) $align[$i] = 'center';
  432. $first = 1;
  433. $output = '<table cellpadding="5" width="100%">';
  434. foreach($dirs as $dir => $opts) {
  435. if ($col==0) {
  436. if ($first) {
  437. $output .= '<tr>';
  438. $first = false;
  439. } else {
  440. $output .= '</tr><tr>';
  441. }
  442. }
  443. #$title = $opts['title'];
  444. $output .= '<td class="zinaimgcolwidth" align="'.$align[$col].'" valign="top">'.$opts['image'].'</td>';
  445. /*
  446. * outputs a play icon over album covers
  447. $output .= '<td class="zinaimgcolwidth" align="'.$align[$col].'" valign="top">'.
  448. $opts['image'].'<span class="image-inner">'.zl(ztheme('icon','play.gif',zt('Play')),$dir,'l=8&amp;m=0').'</span></td>';
  449. */
  450. if ($col==$cols) $output .= '</tr>';
  451. $col = ++$col % $cols;
  452. }
  453. if ($col <> 0 ) {
  454. for ($i = $col; $i < $cols; $i++) $output .= '<td class="zinaimgcolwidth">&nbsp;</td>';
  455. }
  456. $output .= '</tr></table>';
  457. return $output;
  458. }
  459. function ztheme_image_list_category($dirs, $cols) {
  460. $col = 0;
  461. $col_width = round(100/$cols).'%';
  462. zina_set_css('inline','.imglistcatwidth{width:'.$col_width.';}');
  463. $output = '<table cellpadding="0" cellspacing="0" width="100%" class="image-list-category">';
  464. foreach($dirs as $dir => $opts) {
  465. if ($col==0) { $row = $row1 = '<tr>'; }
  466. $row .= '<td class="imglistcatwidth" align="center">'.$opts['image'].'</td>';
  467. $row1 .= '<td class="imglistcatwidth" align="center" valign="top"><h3>'.zl($opts['title'], $opts['path'], $opts['query']).'</h3></td>';
  468. if (++$col==$cols) { $output .= $row.'</tr>'."\n".$row1.'</tr>'."\n"; }
  469. $col = $col % $cols;
  470. }
  471. if ($col <> 0 ) {
  472. for ($i = $col; $i < $cols; $i++) {
  473. $row .= '<td class="imglistcatwidth">&nbsp;</td>';
  474. $row1 .= '<td class="imglistcatwidth">&nbsp;</td>';
  475. }
  476. $output .= $row.'</tr>'.$row1.'</tr>';
  477. }
  478. $output .= '</table>';
  479. return $output;
  480. }
  481. #TODO: rename? and then have song_list call "generic" func? use array for opts
  482. function ztheme_song_list($songs, $various = false, $images = false, $stats = false, $reorder = false, $song_info = true, $checkbox = true) {
  483. global $zc;
  484. if (empty($songs)) return '';
  485. $class = "zinamp";
  486. if ($reorder){
  487. zina_add_tabledrag('table-playlist', 'order', 'sibling', 'order');
  488. zina_set_css('file', 'extras/tabledrag.css');
  489. $table_id = ' id="table-playlist"';
  490. $row_class = 'draggable ';
  491. $row_id = ' id="order"';
  492. $row_order = true;
  493. } else {
  494. $table_id = $row_class = $row_id = '';
  495. $row_order = false;
  496. }
  497. $img_new = ztheme('icon','new.gif',zt('New'));
  498. $lang['download'] = zt('Download');
  499. $lang['play'] = zt('Play');
  500. $lang['play_lofi'] = zt('Play Low Fidelity');
  501. $lang['edit'] = zt('Edit');
  502. $lang['more'] = zt('More');
  503. #remove next two - > used to be for playlists...test?
  504. $lang['rename'] = zt('Rename');
  505. $lang['delete'] = zt('Delete');
  506. $lang['play_lofi'] = zt('Play low fidelity');
  507. $lang['play_lofi_custom'] = zt('Play custom low fidelity');
  508. $lang['play_rec'] = zt('Play recursively');
  509. $lang['play_rec_rand'] = zt('Play recursively random');
  510. $i = $stat_prev = 0;
  511. $p = 1;
  512. $output = '<table cellpadding="5" cellspacing="0" width="100%"'.$table_id.'>';
  513. foreach($songs as $song) {
  514. #todo: $class = ++$i % 2 == 0 ? 'even' : 'odd';
  515. $v = (isset($song['description']) && !$images) ? ' valign="top"' : '';
  516. $output .= '<tr class="'.$row_class.'row'.$i.'"'.$v.$row_id.'>';
  517. if ($row_order) $output .= '<td></td><td style="display:none;"><input type="hidden" name="order[]" value="'.($p).'" size="2" class="order" /></td>';
  518. $output .= '<td class="song'.$i.' nowrap">';
  519. if (isset($song['opts'])) {
  520. foreach ($song['opts'] as $type=>$opt) {
  521. $attr = (substr($type,0,4) == 'play') ? ' class="'.$class.'"' : '';
  522. $output .= zl(ztheme('icon',$type.'.gif',$lang[$type]),$opt['path'],$opt['query'], null, false, $attr);
  523. }
  524. }
  525. if (isset($song['extras'])) {
  526. foreach ($song['extras'] as $type=>$extra) {
  527. $output .= zl(ztheme('icon',$type.'.gif',$extra['text']),$extra['path'],$extra['query'],NULL,FALSE,$extra['attr']);
  528. }
  529. }
  530. $output .= '</td>';
  531. if (isset($song['opts_edit']) || isset($song['extras_edit'])) {
  532. $output .= '<td class="song'.$i.' nowrap">';
  533. if (isset($song['opts_edit'])) {
  534. foreach ($song['opts_edit'] as $type=>$opt) {
  535. $output .= zl(ztheme('icon',$type.'.gif',$lang[$type]),$opt['path'],$opt['query']);
  536. }
  537. }
  538. if (isset($song['extras_edit'])) {
  539. foreach ($song['extras_edit'] as $type=>$extra) {
  540. $output .= zl(ztheme('icon',$type.'_edit.gif',$extra['text']),$extra['path'],$extra['query'],NULL,FALSE,$extra['attr']);
  541. }
  542. }
  543. if (isset($song['delete'])) {
  544. $type = 'delete';
  545. $output .= zl(ztheme('icon',$type.'.gif',$lang[$type], $lang[$type], " onclick='return(confirm(\"".zt('Delete file?')."\"));'"),$song['delete']['path'],$song['delete']['query']);
  546. }
  547. $output .= '</td>';
  548. }
  549. if ($checkbox) {
  550. $output .= '<td class="song'.$i.' nowrap">';
  551. if (isset($song['checkbox']) && $song['checkbox']) {
  552. $output .= ztheme('form_checkbox', $song['checkbox']['name'], $song['checkbox']['value'], $song['checkbox']['checked']);
  553. }
  554. $output .= '</td>';
  555. }
  556. #if (isset($song['track'])) $output .= '</td><td align="right" class="song'.$i.' nowrap">'. $song['track'];
  557. if ($images) {
  558. $output .= '<td class="song'.$i.'"'.$v.'>';
  559. if (isset($song['image']) && !empty($song['image'])) {
  560. $output .= '<div class="search-results">';
  561. #if (isset($song['title_link'])) {
  562. # $output .= zl($song['image'],$song['title_link']['path'],$song['title_link']['query']);
  563. if (isset($song['image_link'])) {
  564. $output .= zl($song['image'],$song['image_link']['path'],$song['image_link']['query']);
  565. } else {
  566. $output .= $song['image'];
  567. }
  568. $output .= '</div>';
  569. }
  570. $output .= '</td>';
  571. }
  572. $td = '<td align="right" class="song_info'.$i.' nowrap"'.$v.'>';
  573. if ($stats) {
  574. $output .= $td.(($stat_prev == $song['stat']) ? '' : $p.'.').'</td>';
  575. $stat_prev = $song['stat'];
  576. }
  577. $output .= '<td class="song'.$i.' fullwidth"'.$v.'>';
  578. $title = $song['title'];
  579. if ($various) {
  580. if (isset($song['info']->artist)) $title = $song['info']->artist.' - '.$title;
  581. }
  582. if (isset($song['title_link'])) {
  583. $output .= zl($title,$song['title_link']['path'],$song['title_link']['query'], null, false, isset($song['title_link']['attr']) ? $song['title_link']['attr'] : '');
  584. } else {
  585. $output .= '<span class="song_title">'.$title.'</span>';
  586. }
  587. if ($song['new']) $output .= $img_new;
  588. if (isset($song['description']) && !empty($song['description'])) {
  589. $output .= '<br/><span class="song_blurb'.$i.'">'.$song['description'].'</span>';
  590. }
  591. if (isset($song['options'])) {
  592. $output .= '<br/><span class="song_blurb'.$i.'"><small>'.implode(' | ', $song['options']).'</small></span>';
  593. }
  594. $output .= '</td>';
  595. if ($stats) {
  596. if ($song['stat_type'] == 'votes' || $song['stat_type'] == 'rating') {
  597. $output .= $td.'<span class="zina-rating">'.ztheme('votes_display',$song['votes']).'</span></td>';
  598. $output .= '<td class="song_info'.$i.' nowrap"'.$v.'>'.ztheme('rating_display', $song['stat']).'</td>';
  599. } elseif ($song['stat_type'] == 'latest' || $song['stat_type'] == 'added') {
  600. $output .= $td.ztheme('stat_date', $song['stat']).'</td>';
  601. } else {
  602. $output .= $td.number_format($song['stat']).'</td>';
  603. }
  604. } else {
  605. if ($song['ratings']) {
  606. $output .= $td.'<span class="zina-rating">'.ztheme('votes_display',$song['sum_votes']).'</span></td>';
  607. $output .= '<td class="song_info'.$i.' nowrap"'.$v.'>'.
  608. '<div class="stars-song">'.ztheme('rating_display', $song['sum_rating']).'</div></td>';
  609. if (isset($song['full_path']))
  610. $output .= $td.'<div class="stars-song">'.ztheme('vote', zina_get_vote_url($song['full_path']), $song['user_rating']).'</div></td>';
  611. else
  612. $output .= $td.'&nbsp;'.'</td>';
  613. /*
  614. * If you are using statistics, there are also
  615. * $song['sum_plays'] & $songs['sum_downloads']
  616. */
  617. } else {
  618. $output .= $td.'&nbsp;'.'</td>';
  619. $output .= $td.'&nbsp;'.'</td>';
  620. $output .= $td.'&nbsp;'.'</td>';
  621. }
  622. if ($song_info) {
  623. if (isset($song['info']->info)) {
  624. $info = &$song['info'];
  625. $output .= $td.((isset($info->time) && !empty($info->time)) ? $info->time : '&nbsp;').'</td>';
  626. $output .= $td.((isset($info->bitrate) && !empty($info->bitrate)) ? $info->bitrate.' kbps' : '&nbsp;').'</td>';
  627. $output .= $td.((isset($info->frequency) && !empty($info->frequency)) ? round($info->frequency/1000,1).' kHz' : '&nbsp;').'</td>';
  628. $output .= $td.((isset($info->filesize) && !empty($info->filesize)) ? sprintf("%.2f", round($info->filesize/1000000,2)).' Mb' : '&nbsp;').'</td>';
  629. } else {
  630. $output .= $td.'</td>';
  631. $output .= $td.'</td>';
  632. $output .= $td.'</td>';
  633. $output .= $td.((isset($song['info']->filesize)) ? sprintf("%.2f", round($song['info']->filesize/1000000,2)).' Mb' : '&nbsp;').'</td>';
  634. }
  635. }
  636. }
  637. $output .= '</tr>'."\n";
  638. $i = ++$i % 2;
  639. $p++;
  640. }
  641. zevenodd($i);
  642. $output .= '</table>';
  643. return $output;
  644. }
  645. function ztheme_stats_form_select($action, $selects) {
  646. $form = '<form id="sform" method="post" action="'.$action.'" class="z_small"><div>';
  647. $form .= '<strong>'.zt('Statistic').': </strong>';
  648. foreach($selects as $name=>$select) {
  649. $form .= '<select class="z_form_select" name="'.$name.'" onchange=\'this.form.submit();\'>';
  650. foreach($select['options'] as $key=>$value) {
  651. $sel = ($key == $select['default']) ? ' selected="selected"' : '';
  652. $form .= '<option value="'.$key.'"'.$sel.'>'.$value.'</option>';
  653. }
  654. $form .= '</select>';
  655. }
  656. $form .= ' '.zl(ztheme('icon','more.gif',zt('More')),"javascript:document.forms.sform.submit();").'</div></form>';
  657. return $form;
  658. }
  659. function ztheme_stats_list($items, $various = false, $images = false) {
  660. return ztheme_song_list($items, $various, $images, true);
  661. }
  662. function ztheme_breadcrumb($links) {
  663. return (!empty($links)) ? implode(' &gt;&nbsp;',$links) : '';
  664. }
  665. function ztheme_breadcrumb_home($links) {
  666. return implode(' / ', $links);
  667. }
  668. function ztheme_page_title($links) {
  669. #return implode(' &#8226; ',$links);
  670. return implode(' &middot; ',$links);
  671. }
  672. function ztheme_search_song_titles($titles) {
  673. return implode(' / ', $titles);
  674. }
  675. /*
  676. * Theme file to use for missing image
  677. * $type is 'dir' or 'sub'
  678. */
  679. function ztheme_missing_image($type) {
  680. return 'missing_'.$type.'.jpg';
  681. }
  682. /*
  683. * Theme for rating (currently "stars")
  684. * $rating is float with one decimal place, e.g. 4.5
  685. */
  686. function ztheme_rating_display($rating) {
  687. $output='';
  688. if ($rating > 0) {
  689. $output .= '<span class="stars">';
  690. $star = ztheme('icon','star.gif','*');
  691. $rating = number_format($rating,1);
  692. $arr = explode('.',$rating);
  693. $output .= str_repeat($star, $arr[0]);
  694. if ($arr[1] >= 5) $output .= ztheme('icon','star-half.gif','½');
  695. $output .= '</span>';
  696. }
  697. return $output;
  698. }
  699. /*
  700. * Theme for voting
  701. *
  702. * currently "stars" and utilizes ajax
  703. */
  704. function ztheme_vote($url, $user_rating = 0) {
  705. static $num = 0;
  706. if ($num == 0) zina_set_js('vars', ztheme('vote_js').'var zv=new Array();');
  707. $pr = 'zv'.$num;
  708. zina_set_js('vars', 'zv['.$num.']=\''.$url.'\';');
  709. $remove = '';
  710. if ($user_rating > 0) {
  711. $remove = zl(ztheme('icon','delete.gif',zt('Remove Vote')),'javascript: void 0;', null, null, null, ' onclick="ajax(zv['.$num.']+\'0\',\'span'.$pr.'\');"');
  712. }
  713. $output = '<span id="span'.$pr.'">'.$remove.ztheme('icon','stars-0.gif',NULL,NULL,'id="'.$pr.'" height="14" width="70" usemap="#'.$pr.'map"').
  714. '</span>'.
  715. '<map name="'.$pr.'map" id="'.$pr.'map">';
  716. for($i=1;$i<=5;$i++) {
  717. $output .= '<area coords="'.(($i-1)*14).',0,'.($i*14).',14" onmouseover="imgOn(\''.$pr.'\','.$i.
  718. ');" onmouseout="imgOff(\''.$pr.'\');" title="'.$i.'" alt="'.$i.'" '.
  719. 'href="javascript: void 0;" onclick="vote(\''.$pr.'\','.$i.');ajax('.
  720. 'zv['.$num.']+\''.$i.'\',\'span'.$pr.'\');" />';
  721. }
  722. $output .= '</map>';
  723. if ($user_rating > 0) $output .= '<script type="text/javascript">vote(\''.$pr.'\','.$user_rating.');</script>';
  724. $num++;
  725. return $output;
  726. }
  727. /*
  728. * Star voting javascript
  729. *
  730. * gets put in html head
  731. */
  732. function ztheme_vote_js() {
  733. $theme = zpath_to_theme().'/icons/stars-';
  734. $output = '';
  735. for($i=0;$i<=5;$i++) {
  736. $output .= "onImgArr[$i]=new Image(70,14);onImgArr[$i].src=zImgBase+'$i.gif';";
  737. }
  738. return 'var onImgArr=new Array();var zImgBase=\''.$theme.'\';'.
  739. $output.'var aVote=new Array();'.
  740. 'function imgOn(img,i){if(aVote[img]==null)document.getElementById(img).src=onImgArr[i].src;}'.
  741. 'function imgOff(img){if(aVote[img]==null)document.getElementById(img).src=zImgBase+\'0.gif\';}'.
  742. 'function vote(img,i){aVote[img]=null;imgOn(img,i);aVote[img]=i;}';
  743. }
  744. /*
  745. * Voting plurality
  746. *
  747. * "(1 vote)" or "(2 votes)"
  748. */
  749. function ztheme_votes_display($votes) {
  750. if (!empty($votes)) {
  751. return ' ('.$votes.' '.(($votes == 1) ? zt('vote') : zt('votes')) .')';
  752. }
  753. return '';
  754. }
  755. function ztheme_genres($dirs, $cols, $images, $truncate, $zina, $navigation = false, $full_page_split = false) {
  756. $output = '';
  757. if (!empty($zina['messages'])) $output .= '<div id="zina_messages">'.$zina['messages'].'</div>';
  758. if ($navigation) $output .= $navigation;
  759. $output .= ztheme('category', $dirs, $cols, $images, $truncate, $full_page_split);
  760. return $output;
  761. }
  762. function ztheme_multimedia_section($list) {
  763. return '<h3>'.zt('Multimedia').'</h3>'.$list;
  764. }
  765. function ztheme_image_missing_nav($select, $close) {
  766. return zt('Directories with no image:').$select.zl(zt('Close'), $close['path'], $close['query']).'<br/><br/>';
  767. }
  768. function ztheme_edit_images_page($title, $images, $new, $missing_navigation = '') {
  769. $output = '';
  770. if (!empty($missing_navigation)) $output .= $missing_navigation;
  771. if (!empty($images)) {
  772. $output .= '<div class="section">'.
  773. '<h3>'.zt('Current Images').'</h3>'.
  774. ztheme('image_list_helper', $images, 3).
  775. '</div>';
  776. }
  777. if (!empty($new)) {
  778. $output .= '<div class="section"><h3>'.zt('Remote Images').'</h3>';
  779. foreach($new as $opt) {
  780. $output .= $opt['image'];
  781. }
  782. }
  783. return $output;
  784. }
  785. function ztheme_addthis($zina, $type = 'bookmark') {
  786. global $zc;
  787. static $first = true;
  788. $output = '';
  789. if ($zina['addthis']) {
  790. if ($first) {
  791. $output .= '<script type="text/javascript" src="http://s7.addthis.com/js/250/addthis_widget.js"></script>';
  792. zina_set_js('vars', 'var addthis_pub = "'.$zina['addthis_id'].'";');
  793. if (!empty($zina['site_name'])) zina_set_js('vars', 'var addthis_brand = "'.$zina['site_name'].'";');
  794. $first = false;
  795. }
  796. $source = zurl($zina['addthis_path'], $zina['addthis_query'], null, true);
  797. if ($type == 'feed') {
  798. $output .= ' <a href="http://www.addthis.com/feed.php" '.
  799. 'onclick="return addthis_open(this, \'feed\', \''.$source.'\')">' .
  800. '<img src="http://s7.addthis.com/static/btn/sm-rss-en.gif" width="83" height="16" alt="'.zt('Subscribe').'" title="'.zt('Subscribe using any feed reader!').'" class="icon"/></a>';
  801. } else { # bookmark
  802. $output .= '<p><a href="http://www.addthis.com/bookmark.php" '.
  803. 'onmouseover="return addthis_open(this,\'\',\''.$source.'\',\''.$zina['title'].'\');" '.
  804. 'onmouseout="addthis_close();" '.
  805. 'onclick="return addthis_sendto();"><img src="http://s7.addthis.com/static/btn/lg-share-en.gif" width="125" height="16" title="'.zt('Share').'" alt="'.zt('Share').'" /></a></p>';
  806. }
  807. }
  808. return $output;
  809. }
  810. function ztheme_stats_page($form_attr, $stats, $stat_opts, $zina) {
  811. $output = '';
  812. $output .= '<div class="clear-block" style="margin-bottom:20px;">'.$zina['statsformselect'].'</div>';
  813. if (empty($stats)) {
  814. $output .= '<h3>'.zt('No data found for this period.').'</h3>';
  815. } else {
  816. $output .= ztheme('form', $form_attr, $stats.'<div class="section">'.$stat_opts.'</div>');
  817. }
  818. return $output;
  819. }
  820. function ztheme_stats_section($title, $list, $type, $zina, $rss_title = '', $rss_path = false) {
  821. if ($rss_path) {
  822. $rss_icon = ($type == 'song') ? 'podcast.gif' : 'rss.png';
  823. $zina['addthis_path'] = $rss_path;
  824. $zina['addthis_query'] = null;
  825. $addthis = ztheme('addthis', $zina, 'feed');
  826. return '<div class="section"><div class="stats">'.
  827. '<div class="stats-left"><h3>'.$title.'</h3></div>'.
  828. '<div class="stats-right">'.zl(ztheme('icon', $rss_icon, $rss_title),$rss_path).$addthis.'</div></div>'.
  829. $list.'</div>';
  830. } else {
  831. return '<div class="section"><h3>'.$title.'</h3>'.$list.'</div>';
  832. }
  833. }
  834. function ztheme_stat_date($time) {
  835. return date("M j, Y g:i a", $time);
  836. }
  837. /*
  838. * NEXT THREE FUNCTIONS:
  839. * Take an array, expect an array back
  840. * - unset ones you don't want
  841. * - reorder, change text, etc.
  842. */
  843. function ztheme_stats_pages($pages) { return $pages; }
  844. function ztheme_stats_periods($periods) { return $periods; }
  845. function ztheme_stats_types($types) { return $types; }
  846. function ztheme_stats_list_opts($items, $form) {
  847. return ztheme('song_list_opts',$items, $form);
  848. }
  849. function ztheme_search_list($items, $images = false) {
  850. return ztheme('song_list',$items, false, $images);
  851. }
  852. function ztheme_playlist_list($items, $images = false, $reorder = false) {
  853. return ztheme('song_list',$items, false, $images, false, $reorder, false);
  854. }
  855. function ztheme_playlists_list_db($items, $count, $navigation, $action, $form_attr, $list_opts, $selected = false, $checkbox = false) {
  856. $output = '';
  857. if ($count > 0) {
  858. if ($navigation) $output .= $navigation;
  859. $output .= '<table class="search-header"><tr><td align="left">'.
  860. '<em>'.zt('@total Playlists', array('@total'=>$count)).'</em></td>';
  861. if ($selected) $output .= '<td align="right" style="text-align:right;">'.ztheme('playlist_header', $action, $selected).'</td>';
  862. $output .= '</tr></table>';
  863. }
  864. $list = ztheme('song_list',$items, false, true, false, false, false, $checkbox);
  865. return $output.ztheme('form', $form_attr, $list.$list_opts);
  866. #return $output.ztheme('song_list',$items, false, true, false, false, false, $checkbox);
  867. }
  868. function ztheme_playlists_list($items, $zina, $reorder = false) {
  869. global $zc;
  870. if (empty($items)) return '';
  871. if ($reorder) {
  872. zina_add_tabledrag('table-playlist', 'order', 'sibling', 'order');
  873. zina_set_css('file', 'extras/tabledrag.css');
  874. }
  875. $class = "zinamp";
  876. $songs = &$items;
  877. zina_set_css('inline', '.zinaplswidthA{width:90px;}.zinaplswidthB{width:20px}');
  878. $lang['download'] = zt('Download');
  879. $lang['play'] = zt('Play');
  880. $lang['more'] = zt('More');
  881. $lang['rename'] = zt('Rename');
  882. $lang['delete'] = zt('Delete');
  883. $lang['play_rec_rand'] = zt('Play random');
  884. $i = 0;
  885. $j = 1;
  886. $output = '';
  887. $output .= '<table cellpadding="5" cellspacing="0" id="table-playlist">';
  888. foreach($songs as $song) {
  889. $v = (isset($song['description'])) ? ' valign="top"' : '';
  890. $output .= '<tr class="draggable row'.$i.'"'.$v.' id="order'.($j).'"><td class="song'.$i.' zinaplswidthA nowrap">';
  891. if (isset($song['opts'])) {
  892. foreach ($song['opts'] as $type=>$opt) {
  893. $attr = (substr($type,0,4) == 'play') ? "class='$class'" : '';
  894. $output .= zl(ztheme('icon',$type.'.gif',$lang[$type]),$opt['path'],$opt['query'], null, false, $attr);
  895. }
  896. }
  897. if (isset($song['checkbox'])) {
  898. $output .= '</td><td class="song'.$i.' zinaplswidthB nowrap">'.
  899. ztheme('form_checkbox', $song['checkbox']['name'], $song['checkbox']['value'], $song['checkbox']['checked']).'</td>'.
  900. '<td style="display:none;"><input type="hidden" name="order[]" value="'.($j).'" size="2" class="order" />';
  901. }
  902. $output .= '</td><td class="song'.$i.'"'.$v.'>';
  903. $title = $song['title'];
  904. if (isset($song['title_link'])) {
  905. $output .= zl($title,$song['title_link']['path'],$song['title_link']['query']);
  906. } else {
  907. $output .= $title;
  908. }
  909. if (isset($song['description'])) $output.= '<br/>'.$song['description'];
  910. $output .= '</td>';
  911. $output .= '</tr>';
  912. $i = ++$i % 2;
  913. $j++;
  914. }
  915. zevenodd($i);
  916. $output .= '</table>';
  917. return $output;
  918. }
  919. function ztheme_form_checkbox($name, $value, $check = false) {
  920. $checked = ($check) ? ' checked="checked"' : '';
  921. return '<input type="checkbox" name="'.$name.'" value="'.$value.'"'.$checked.'/>';
  922. }
  923. function ztheme_form_hidden($name, $value) {
  924. return '<input type="hidden" name="'.$name.'" value="'.$value.'"/>';
  925. }
  926. function ztheme_multimedia_list($items) {
  927. if (empty($items)) return '';
  928. $img_new = ztheme('icon','new.gif',zt('New'));
  929. $lang['edit'] = zt('Edit');
  930. $i = 0;
  931. $output = '<table cellpadding="5" cellspacing="0" width="100%">';
  932. foreach($items as $song) {
  933. $v = (isset($song['description'])) ? ' valign="top"' : '';
  934. $output .= '<tr class="row'.$i.'"'.$v.'><td class="song'.$i.' nowrap">';
  935. if (isset($song['opts'])) {
  936. if (isset($song['opts']['play']) && $song['opts']['play']['local']) {
  937. $output .= zl(ztheme('icon','mm/'.$song['ext'].'.gif',zt('Play')),$song['opts']['play']['path'],$song['opts']['play']['query']);
  938. }
  939. if (isset($song['opts']['download'])) {
  940. $icon = (isset($song['opts']['play']) && $song['opts']['play']['local']) ? 'download' : 'mm/'.$song['ext'];
  941. $output .= zl(ztheme('icon',$icon.'.gif',zt('Download')),$song['opts']['download']['path'],$song['opts']['download']['query']);
  942. }
  943. }
  944. if (isset($song['opts_edit'])) {
  945. $output .= '</td><td class="song'.$i.' nowrap">';
  946. foreach ($song['opts_edit'] as $type=>$opt) {
  947. $output .= zl(ztheme('icon',$type.'.gif',$lang[$type]),$opt['path'],$opt['query']);
  948. }
  949. }
  950. $output .= '</td><td class="song'.$i.' fullwidth"'.$v.'>';
  951. $title = $song['title'];
  952. if (isset($song['title_link'])) {
  953. $output .= zl($title,$song['title_link']['path'],$song['title_link']['query']);
  954. } else {
  955. $output .= $title;
  956. }
  957. if ($song['new']) $output .= $img_new;
  958. if (isset($song['description'])) {
  959. $output .= '<br/><span class="song_blurb'.$i.'">'.$song['description'].'</span>';
  960. }
  961. $output .= '</td>';
  962. $output .= '</tr>';
  963. $i = ++$i % 2;
  964. }
  965. zevenodd($i);
  966. $output .= '</table>';
  967. return $output;
  968. }
  969. function ztheme_playlists_section($page,$form_attr,$list,$list_opts, $opts = array()) {
  970. $lang['play'] = zt('Play');
  971. $lang['playlist'] = zt('View Playlists');
  972. $lang['rename'] = zt('Rename');
  973. $lang['delete'] = zt('Delete');
  974. $output = '';
  975. $output .= '<div class="genre-page clear-block">';
  976. if ($page['image']) $output .= $page['image'];
  977. if ($opts['user']) {
  978. $lang['download'] = zt('Download');
  979. $lang['play'] = zt('Play');
  980. $lang['play_lofi'] = zt('Play Low Fidelity');
  981. $lang['play_rec_rand'] = zt('Play random');
  982. $output .= '<p>';
  983. $items = &$opts['user'];
  984. foreach($items as $type=>$opt) {
  985. $output.= zl(ztheme('icon',$type.'.gif',$lang[$type]),$items[$type]['path'],$items[$type]['query'],NULL,FALSE,$items[$type]['attr']);
  986. }
  987. $output .= zl(zt('Play @pls Playlist', array('@pls'=>$page['title'])),$items['play']['path'], $items['play']['query'], null, false, $items['play']['attr']).
  988. '</p>';
  989. }
  990. $votes = (isset($page['pls_ratings']) && $page['sum_votes'] > 0);
  991. if ($votes || isset($page['pls_rate_output'])) {
  992. $output .= '<p class="small">';
  993. if ($votes) {
  994. $output .= ztheme('rating_display', $page['sum_rating']).
  995. ztheme('votes_display',$page['sum_votes']);
  996. if (isset($page['pls_rate_output'])) $output .= '&nbsp; | ';
  997. }
  998. if (isset($page['pls_rate_output'])) $output .= zt('Rate').': '.$page['pls_rate_output'];
  999. $output .= '</p>';
  1000. }
  1001. if (isset($page['description']) && !empty($page['description'])) {
  1002. $output .= '<p>'.$page['description'].'</p>';
  1003. }
  1004. if (isset($page['podcast'])) {
  1005. $type = $page['podcast']['type'];
  1006. $icon_title = ($type == 'podcast') ? zt('Podcast') : zt('RSS Feed');
  1007. $output .= '<p>'.zl(ztheme('icon',$type.'.gif', $icon_title),$page['podcast']['url'],$page['podcast']['query']).'</p>';
  1008. }
  1009. $output .= ztheme('addthis', $page, 'bookmark');
  1010. $date = (!empty($page['date_created'])) ? zina_date('F j, Y', $page['date_created']) : null;
  1011. $output .= '<p class="small">';
  1012. if (isset($page['username'])) {
  1013. $name = (isset($page['profile_url'])) ? '<a href="'.$page['profile_url'].'">'.$page['username'].'</a>' : $page['username'];
  1014. if (!empty($date)) {
  1015. $output.= zt('Created by !name on @date.', array('!name'=>$name, '@date'=>$date));
  1016. }
  1017. } else {
  1018. if (!empty($date)) {
  1019. $output.= zt('Created on @date.', array('@date'=>$date));
  1020. }
  1021. }
  1022. if (isset($page['sum_views'])) $output .= ' '.zt('Viewed @num times.', array('@num'=>$page['sum_views']));
  1023. if (isset($page['sum_plays'])) $output .= ' '.zt('Played @num times.', array('@num'=>$page['sum_plays']));
  1024. $output .= '</p>';
  1025. $admin = &$opts['admin'];
  1026. if ($admin['edit'] || $admin['delete']) {
  1027. $output .= '<p class="small">';
  1028. if ($admin['edit']) $output .= zl(zt('Edit Playlist'),$admin['edit']['path'], $admin['edit']['query']).' | ';
  1029. if ($admin['delete']) $output .= zl(zt('Delete Playlist'),$admin['delete']['path'], $admin['delete']['query']);
  1030. $output .= '</p>';
  1031. }
  1032. $output .= '</div>';
  1033. if ($page['count'] > 0) {
  1034. $output .= '<table class="search-header"><tr><td align="left">'.
  1035. '<em>'.zt('@total Items', array('@total'=>$page['count'])).'</em></td>';
  1036. #if ($selected) $output .= '<td align="right">'.ztheme('search_header', 'XXX', $genre, $action, $selected).'</td>';
  1037. $output .= '</tr></table>';
  1038. }
  1039. $output .= ztheme('form', $form_attr, $list.$list_opts);
  1040. return $output;
  1041. }
  1042. function ztheme_form($attr, $content, $method = 'post') {
  1043. return '<form method="'.$method.'" '.$attr.'><div>'.$content.zina_get_form_token().'</div></form>';
  1044. }
  1045. function ztheme_song_section($form_attr,$song_list,$song_list_opts) {
  1046. return '<h3>'.zt('Songs').'</h3>'.ztheme('form', $form_attr, $song_list.$song_list_opts);
  1047. }
  1048. function ztheme_search_page($term, $results, $total, $navigation, $form_attr, $list, $list_opts, $action, $selected, $zina) {
  1049. $output = '';
  1050. $output .= '<h3>'.zt('Search Results').'</h3>';
  1051. if (empty($results)) {
  1052. $output .= '<p><em>'.zt('0 total items found').'</em></p>';
  1053. } else {
  1054. if ($navigation) $output .= $navigation;
  1055. $output .= '<table class="search-header"><tr><td align="left">';
  1056. $output .= '<em>'.zt('@total items found', array('@total'=>$total)).'</em>';
  1057. $output .= '</td>';
  1058. if ($selected) $output .= '<td align="right">'.ztheme('search_header', 'search', $term, $action, $selected).'</td>';
  1059. $output .= '</tr></table>';
  1060. $output .= ztheme('form', $form_attr, $list.$list_opts);
  1061. }
  1062. return $output;
  1063. }
  1064. function ztheme_year_page($term, $results, $total, $search_navigation, $navigation, $form_attr, $list, $list_opts, $opts, $action, $selected, $zina) {
  1065. return ztheme('genres_page',$term, $results, $total, $search_navigation, $navigation, $form_attr, $list, $list_opts, $opts, $action, $selected, $zina);
  1066. }
  1067. function ztheme_genres_page($genre, $results, $total, $navigation, $genre_navigation, $form_attr, $list, $list_opts, $opts, $action, $selected, $zina) {
  1068. global $zc;
  1069. $class="zinamp";
  1070. $output = '';
  1071. if (!empty($zina['messages'])) $output .= '<div id="zina_messages">'.$zina['messages'].'</div>';
  1072. $output .= '<div class="genre-page clear-block">';
  1073. if ($opts['image']) $output .= ztheme('image', zina_get_genre_image_path($genre), $genre, null, 'class="genre-image"');
  1074. if ($genre_navigation) $output .= '<div class="genre-select">'.$genre_navigation.'</div>';
  1075. $output .= '<p>'.
  1076. zl(ztheme('icon','play.gif',zt('Play')),'',$opts['play_query'], null, false, "class='$class'").
  1077. zl(zt('Play @genre', array('@genre'=>$genre)),'', $opts['play_query'], null, false, "class='$class'").
  1078. '</p>';
  1079. if ($opts['description'] && !empty($opts['description'])) {
  1080. $output .= '<p>'.$opts['description'].'</p>';
  1081. }
  1082. if ($opts['genre_edit']) {
  1083. $output .= '<p class="small">'.zl(zt('Edit Genre'),$opts['genre_edit']['path'], $opts['genre_edit']['query']).'</p>';
  1084. }
  1085. $output .= '</div>';
  1086. if (isset($zina['subgenres'])) {
  1087. $output .= '<table class="search-header"><tr><td align="left"><h3>'.zt('Genre Family').'</h3></td></tr></table>';
  1088. $output .= $zina['subgenres'];
  1089. }
  1090. $output .= '<table class="search-header"><tr><td align="left" width="30%">';
  1091. $output .= '<em>'.zt('@total items found', array('@total'=>$total)).'</em>';
  1092. $output .= '</td><td>'.(($navigation) ? $navigation : '').'</td>';
  1093. $output .= '<td align="right" width="30%">';
  1094. if ($selected) $output .= ztheme('search_header', $zina['search_page_type'], $genre, $action, $selected);
  1095. $output .= '</td></tr></table>';
  1096. if (empty($results) || $selected['type'] == 'artist') $list_opts = '';
  1097. $output .= ztheme('form', $form_attr, $list.$list_opts);
  1098. return $output;
  1099. }
  1100. function ztheme_playlist_list_opts($items, $form) {
  1101. if (empty($items)) return '';
  1102. if (empty($items['submit']) && empty($items['checkbox']) && !isset($items['playlist_form_elements'])) return '';
  1103. $submit = ($items['submit']) ? '<input type="submit" value="'.zt('Update Playlist').'"/>' : '';
  1104. if ($items['checkbox']) {
  1105. $checkbox = ' '.zt('Check').': &nbsp;'.
  1106. zl(zt('All'),'javascript: void 0;',NULL,NULL,FALSE,' onclick="CheckBoxes(\''.$form.'\',true);"').' | '.
  1107. zl(zt('None'),'javascript:void 0;',NULL,NULL,FALSE,' onclick="CheckBoxes(\''.$form.'\',false);"');
  1108. } else {
  1109. $checkbox = '';
  1110. }
  1111. $output = '<table cellpadding="5" cellspacing="0" width="100%"><tr class="row'.zevenodd().'">';
  1112. $output .= '<td>'.$submit.$checkbox.'</td>';
  1113. $output .= '<td align="right">'.((isset($items['playlist_form_elements'])) ? $items['playlist_form_elements'] : '&nbsp;').'</td>';
  1114. $output .= '</tr></table>';
  1115. return $output;
  1116. }
  1117. function ztheme_search_list_opts($items, $form) {
  1118. return ztheme('song_list_opts',$items, $form);
  1119. }
  1120. function ztheme_song_list_opts($items, $form) {
  1121. if (empty($items)) return '';
  1122. $output = '<table cellpadding="5" cellspacing="0" width="100%"><tr class="row'.zevenodd().'">';
  1123. if (isset($items['checkboxes'])) {
  1124. $submit = '';
  1125. if (isset($items['submit'])) {
  1126. $val = ($items['submit']['exists']) ? zt('Update custom playlist') : zt('Create custom playlist');
  1127. $submit = '<input type="submit" value="'.$val.'" onclick="'.$items['submit']['js'].'"/>&nbsp;';
  1128. }
  1129. $output .= '<td>'.$submit.zt('Check').': &nbsp;'.
  1130. zl(zt('All'),'javascript: void 0;',NULL,NULL,FALSE,' onclick="CheckBoxes(\''.$form.'\',true);"').' | '.
  1131. zl(zt('None'),'javascript:void 0;',NULL,NULL,FALSE,' onclick="CheckBoxes(\''.$form.'\',false);"').'</td>';
  1132. }
  1133. if (isset($items['opts'])) {
  1134. $lang['download'] = zt('Download');
  1135. $lang['play'] = zt('Play');
  1136. $lang['play_lofi'] = zt('Play Low Fidelity');
  1137. $lang['play_rec_rand'] = zt('Play random');
  1138. $output .= '<td >'.zt('Selected').': ';
  1139. foreach($items['opts'] as $type=>$opt) {
  1140. $output.= zl(ztheme('icon',$type.'.gif',$lang[$type]),$opt['path'],$opt['query'],NULL,FALSE,$opt['attr']);
  1141. }
  1142. $output .= '</td>';
  1143. }
  1144. $output .= '<td align="right">'.((isset($items['playlist_form_elements'])) ? $items['playlist_form_elements'] : '&nbsp;').'</td>';
  1145. $output .= '</tr></table>';
  1146. return $output;
  1147. }
  1148. function ztheme_song_extra($type, $title, $content, $url = false) {
  1149. if ($url) {
  1150. $content = zt('Loading...');
  1151. zina_set_js('jquery', '$("p#zina-'.$type.'").load("'.$url.'");');
  1152. }
  1153. $output = '';
  1154. $output .= '<div class="extras '.$type.'"><h3>'.$title.'</h3><p id="zina-'.$type.'">'.$content.'</p></div>';
  1155. return $output;
  1156. }
  1157. function ztheme_page_footer($zina) {
  1158. return '<div class="footer">'.zl(ztheme('icon','zina2.gif','Zina Icon','Powered by Zina2v.'.ZINA_VERSION.
  1159. ' ('.round(microtime(true) - $zina['time'],3).'s'. ((isset($zina['cached'])) ? ' cached' : '') .')'
  1160. ),'https://bitbucket.org/helmespc/zina2/wiki/Home').'</div>';
  1161. }
  1162. function ztheme_amg($zina) {
  1163. $selected = array_fill(1,3,'');
  1164. $count = substr_count($zina['path'], '/')+1;
  1165. $selected[$count] = ' selected="selected"';
  1166. return ztheme('form', 'action="http://www.allmusic.com/cg/amg.dll"',
  1167. '<input type="hidden" name="P" value="amg"/>'.
  1168. '<input type="text" name="sql" size="20" maxlength="30" value="'.$zina['html_title'].'"/>'.
  1169. '<select name="opt1"><option value="1"'.$selected[1].'>'.$zina['lang']['main_dir_title'].'</option>'.
  1170. '<option value="2"'.$selected[2].'>'.zt('Albums').'</option>'.
  1171. '<option value="3"'.$selected[3].'>'.zt('Songs').'</option>'.
  1172. '</select><input type="submit" value="AMG"/>');
  1173. }
  1174. /*
  1175. * Directory Play/Download Options (icons,text,link)
  1176. */
  1177. function ztheme_dir_opts($options, $title){
  1178. global $zc;
  1179. if (empty($options)) return null;
  1180. $class = "zinamp";
  1181. $lang['delete'] = zt('Delete');
  1182. $lang['play'] = zt('Play');
  1183. $lang['play_custom'] = zt('Play custom playlist');
  1184. $lang['play_lofi'] = zt('Play low fidelity');
  1185. $lang['play_lofi_custom'] = zt('Play custom low fidelity');
  1186. $lang['play_rec'] = zt('Play recursively');
  1187. $lang['play_rec_rand'] = zt('Play recursively random');
  1188. $lang['download'] = zt('Download');
  1189. $lang['download_custom'] = zt('Download custom files');
  1190. $output = '';
  1191. foreach ($options as $type=>$opt) {
  1192. $attr = '';
  1193. if (substr($type,0,4) == 'play') {
  1194. $attr = "class='$class'";
  1195. } else if ($type == 'delete') {
  1196. $attr = "onclick='return(confirm(\"".zt('Delete this directory and ALL files in it?')."\"));'";
  1197. }
  1198. $output .= zl(ztheme('icon',$type.'.gif',$lang[$type]),$opt['path'],$opt['query'], null, false, $attr);
  1199. }
  1200. # Play "Directory" Text / Link
  1201. if (isset($options['play'])) {
  1202. $output .= ' '.zl(zt('Play @title',array('@title'=>$title)),$options['play']['path'],$options['play']['query'], null, false, "class='$class'");
  1203. } elseif (isset($options['play_rec'])) {
  1204. $output .= ' '.zl(zt('Play @title',array('@title'=>$title)),$options['play_rec']['path'],$options['play_rec']['query'], null, false, "class='$class'");
  1205. } elseif (isset($options['play_rec_rand'])) {
  1206. $output .= ' '.zl(zt('Play @title',array('@title'=>$title)),$options['play_rec_rand']['path'],$options['play_rec_rand']['query'], null, false, "class='$class'");
  1207. } else {
  1208. $output .= $title;
  1209. }
  1210. return $output;
  1211. }
  1212. /*
  1213. * Login Display
  1214. */
  1215. function ztheme_login($form) {
  1216. #todo: css this
  1217. return '<div style="width:300px;margin:auto;">'.ztheme('form_table', $form).'</div>';
  1218. }
  1219. function ztheme_newplaylist($form) {
  1220. return ztheme('form_table', $form);
  1221. }
  1222. function ztheme_config($form) {
  1223. return ztheme('form_table', $form);
  1224. }
  1225. function ztheme_clean($form) {
  1226. return ztheme('form_table', $form);
  1227. }
  1228. function ztheme_blurb($form, $type, $url = false) {
  1229. if ($url) {
  1230. $content = zt('Loading...');
  1231. zina_set_js('jquery', '$("#zina-'.$type.'").load("'.$url.'");');
  1232. }
  1233. return ztheme('form_table', $form);
  1234. }
  1235. function ztheme_extras_source($source) {
  1236. return '<p class="small">'.$source.'</p>';
  1237. }
  1238. function ztheme_renameplaylist($form) {
  1239. return ztheme('form_table', $form);
  1240. }
  1241. function ztheme_messages($display = NULL) {
  1242. $output = '';
  1243. foreach (zina_get_messages($display) as $type => $messages) {
  1244. $output .= "<div class=\"messages $type\">";
  1245. if (count($messages) > 1) {
  1246. $output .= ztheme('list', $messages, "zina-list");
  1247. } else {
  1248. $output .= $messages[0];
  1249. }
  1250. $output .= "</div>";
  1251. }
  1252. return $output;
  1253. }
  1254. function ztheme_list($list, $class = '') {
  1255. $output = '';
  1256. if (!empty($list)) {
  1257. if (!empty($class)) $class = ' class="'.$class.'"';
  1258. $output .= "<ul$class>";
  1259. foreach ($list as $item) {
  1260. $output .= "<li$class>". $item .'</li>';
  1261. }
  1262. $output .= '</ul>';
  1263. }
  1264. return $output;
  1265. }
  1266. /*
  1267. * For error messages...
  1268. */
  1269. function ztheme_placeholder($text) {
  1270. return '<em>'. zcheck_plain($text) .'</em>';
  1271. }
  1272. /*
  1273. * Zina Generic Form/Table Display
  1274. *
  1275. * Mainly administrative displays
  1276. */
  1277. function ztheme_form_table($form) {
  1278. $output='';
  1279. if (isset($form['title'])) $output .= '<h3>'.$form['title'].'</h3>';
  1280. $output .= '<table>';
  1281. foreach($form['rows'] as $row) {
  1282. $output .= '<tr>';
  1283. $class = (isset($row['class'])) ? ' class="'.$row['class'].'"' : '';
  1284. if (!empty($row['label'])) {
  1285. if ($row['label'] == -1) {
  1286. $output .= '<td colspan="2"'.$class.'>';
  1287. } else {
  1288. $output .= '<td valign="top">'.$row['label'].':';
  1289. if (isset($row['desc'])) $output .= '<div class="small">'.$row['desc'].'</div>';
  1290. $output .= '</td><td valign="top">';
  1291. }
  1292. } else {
  1293. $output .= '<td>&nbsp;</td><td>';
  1294. }
  1295. $output .= $row['item'];
  1296. if (isset($row['help']) && !empty($row['help'])) $output .= '<br/><small>'.$row['help'].'</small>';
  1297. $output .= '</td></tr>';
  1298. #if (isset($row['desc'])) $output .= '<tr><td colspan="2"><span class="small">'.$row['desc'].'</span></td></tr>';
  1299. }
  1300. $output .= '</table>';
  1301. if (isset($form['hidden'])) $output .= $form['hidden'];
  1302. return ztheme('form', $form['attr'], $output);
  1303. }
  1304. function ztheme_page_image($zina, $path, $images, $image, $captions = array()) {
  1305. return '<div class="directory-image-full" align="center">'.
  1306. ztheme('images', 'full', $zina, $path, $images, null, $image, $captions).
  1307. '</div>';
  1308. }
  1309. /*
  1310. * Directory Image
  1311. */
  1312. function ztheme_images($type, $zina, $path, $images, $query = null, $image = null, $captions = array()) {
  1313. $output = '';
  1314. $num = sizeof($images);
  1315. if ($num > 1) {
  1316. #if ($type != 'full') $captions = array();
  1317. $img_js3 = '';
  1318. $img_js = 'zImages=new Array(';
  1319. $img_js2 = 'zImagesURL=new Array(';
  1320. if (!empty($captions)) $img_js3 = 'zImagesText=new Array(';
  1321. foreach($images as $img) {
  1322. $img_js .= '"'.str_replace("&amp;","&",zina_get_image_url($path, $img, $type)).'",';
  1323. $img_js2 .= '"'.zurl((empty($path) ? $img : $path.'/'.$img), $query).'",';
  1324. if (!empty($captions)) $img_js3 .= '"'.addslashes($captions[$img]).'",';
  1325. }
  1326. $img_js = substr($img_js,0,-1).');';
  1327. $img_js2 = substr($img_js2,0,-1).');';
  1328. if (!empty($img_js3)) $img_js3 = substr($img_js3,0,-1).');';
  1329. if (($key = array_search($image, $images)) === false) {
  1330. $key = 0;
  1331. } else {
  1332. $img_js .= 'zi='.$key.';';
  1333. }
  1334. zina_set_js('vars', $img_js.$img_js2.$img_js3);
  1335. $image = ztheme('image',zina_get_image_url($path, $images[$key], $type), $zina['title'], $zina['title'],'id="zImage" class="directory-image"');
  1336. if ($type == 'full') {
  1337. $output .= zl($image, 'javascript:nextImage()');
  1338. } else {
  1339. $output .= zl($image, 'javaScript:viewImage();');
  1340. }
  1341. if (!empty($captions))
  1342. $output .= '<div id="zImageText" class="directory-image-'.$type.'-text">'.$captions[$images[$key]].'</div>';
  1343. $output .= '<div class="image-browser">'.
  1344. zl(zt('Previous'),'javascript:prevImage();').' | '.
  1345. zl(zt('Stop'),'javascript:stopSlideShow();').' | '.
  1346. zl(zt('Start'),'javascript:startSlideShow(1800);').' | '.
  1347. zl(zt('Next'),'javascript:nextImage();').'</div>';
  1348. return $output;
  1349. } else {
  1350. #if (empty($images[0])) { #missing image
  1351. $file = (($num == 1) ? $images[0] : $images);
  1352. $image = ztheme('image', zina_get_image_url($path, $file, $type), $zina['title']);
  1353. if ($type == 'full' || empty($images[0])) {
  1354. return $image;
  1355. } else {
  1356. return zl($image, ((empty($path)) ? $file : $path.'/'.$file), $query);
  1357. }
  1358. }
  1359. }
  1360. function ztheme_mm($player, $src) {
  1361. return '<div align="center">'.ztheme('mm_'.$player, $src, 600, 450).'</div>';
  1362. }
  1363. /*
  1364. * Only seems to work if src is actual www path to file =(
  1365. */
  1366. function ztheme_mm_QT($src, $w, $h) {
  1367. return '<object CLASSID="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" WIDTH="'.$w.'" HEIGHT="'.$h.'" CODEBASE="http://www.apple.com/qtactivex/qtplugin.cab#version=6,0,2,0">'.
  1368. '<param NAME="controller" VALUE="true">'.
  1369. '<param NAME="autoplay" VALUE="true">'.
  1370. '<param NAME="pluginspage" VALUE="http://www.apple.com/quicktime/download/">'.
  1371. '<param NAME="src" VALUE="'.$src.'">'.
  1372. '<embed WIDTH="'.$w.'" HEIGHT="'.$h.'" AUTOPLAY="true" SRC="'.$src.'" '.
  1373. 'PLUGINSPAGE="http://www.apple.com/quicktime/download"></embed>'.
  1374. '</object>';
  1375. }
  1376. /*
  1377. * Only seems to work if src is actual www path to file =(
  1378. */
  1379. function ztheme_mm_WMP($src, $w, $h) {
  1380. return '<OBJECT ID=MediaPlayer '.
  1381. 'CLASSID=CLSID:6BF52A52-394A-11D3-B153-00C04F79FAA6 '.
  1382. 'TYPE="application/x-oleobject" width="'.$w.'" height="'.$h.'">'.
  1383. '<PARAM NAME="url" VALUE="'.$src.'">'.
  1384. '<embed type="application/x-mplayer2" '.
  1385. 'pluginspage="http://www.microsoft.com/windows/windowsmedia/download/" '.
  1386. 'filename="'.$src.'" src="'.$src.'" '.
  1387. 'autosize="1" '.
  1388. 'width="'.$w.'" height="'.$h.'"> </embed>' .
  1389. '</OBJECT>';
  1390. }
  1391. /*
  1392. * Search Form
  1393. */
  1394. function ztheme_searchform($opts, $term='') {
  1395. zina_set_js('file', 'extras/jquery.js');
  1396. zina_set_js('file', 'extras/jquery.autocomplete.pack.js');
  1397. zina_set_css('file', 'extras/jquery.autocomplete.css');
  1398. $js = 'function zinaSearchItem(row){';
  1399. if (isset($opts['images'])) {
  1400. $js .= 'var output=\'<div class="zina-live-search">\';'.
  1401. 'if(row[6]!=""){output+=row[6];}'.
  1402. 'output+=\'<p>\'+row[0]+\'<br><span class="ac_results-sub">\';'.
  1403. 'if(row[2]!=\'\'){output+=row[2]+"<br>";}'.
  1404. 'output+=row[1];'.
  1405. 'if(row[5]!=\'\')output+=\' | \'+row[5];'.
  1406. 'return output+="</span></p></div>";';
  1407. } else {
  1408. $js .= 'var output=row[0]+\'<br><span class="ac_results-sub">\'+row[1];'.
  1409. 'if(row[2]!=\'\')output+=\' | \'+row[2];'.
  1410. 'output+=\'</span>\';'.
  1411. 'return output;';
  1412. }
  1413. $js .= '}'.
  1414. '$("#remotesearch").autocomplete("'.$opts['live_url'].'",{'.
  1415. 'max:'.$opts['search_live_limit'].','.
  1416. 'minChars:'.$opts['search_min_chars'].','.
  1417. 'selectFirst:false,'.
  1418. 'scroll:false,'.
  1419. 'cacheLength:0,'.
  1420. 'width:350,'.
  1421. 'formatItem:zinaSearchItem'.
  1422. '});'.
  1423. '$("#remotesearch").result(function(event,data,formatted){'.
  1424. 'if(data){'.
  1425. '$("input#searchtype").val(data[1]);'.
  1426. '$("input#searchid").val(data[3]);'.
  1427. '$("img.icon-search-play").css("display","inline");'.
  1428. '}'.
  1429. '});'.
  1430. '$("form#zinasearch").submit(function(){'.
  1431. 'searchClear=true;'.
  1432. '});';
  1433. zina_set_js('jquery', $js);
  1434. if (empty($term)) {
  1435. $term = zt('Search');
  1436. $searchClear = 'true';
  1437. } else {
  1438. $searchClear = 'false';
  1439. }
  1440. zina_set_js('inline', 'var searchClear='.$searchClear.';');
  1441. zina_set_js('inline',
  1442. 'function zinaClearSearch(e){if(searchClear){e.value="";document.forms.zinasearch.searchid.value="";searchClear=false;}}'
  1443. );
  1444. return '<div class="search-form">'.
  1445. ztheme('form', 'id="zinasearch" action="'.$opts['action'].'"',
  1446. '<input name="searchterm" type="text" size="25" value="'.$term.'" id="remotesearch" onclick="zinaClearSearch(this);" />'.
  1447. '<input name="searchtype" type="hidden" id="searchtype" />'.
  1448. '<input name="searchid" type="hidden" id="searchid" />'.
  1449. zl(ztheme('icon','more.gif',zt('More')),"javascript:zinaSubmit('zinasearch','m=browse');").
  1450. zl(ztheme('image', zpath_to_theme().'/icons/play.gif', zt('Play'), zt('Play'), 'style="display:none;" class="icon icon-search-play"'),"javascript:zinaSubmit('zinasearch','m=play');")
  1451. ).'</div>';
  1452. }
  1453. function ztheme_search_description($path_links, $opts) {
  1454. $output = (!empty($path_links)) ? $path_links.'<br/>' : '';
  1455. if (isset($opts['genre'])) $opts['genre'] = '<em>'.$opts['genre'].'</em>';
  1456. $output .= implode(' | ', $opts);
  1457. return $output;
  1458. }
  1459. function ztheme_description_teaser($desc) {
  1460. $output = '';
  1461. if (!empty($desc)) {
  1462. if (($pos = strpos($desc, "\n")) !== false) {
  1463. $output .= substr($desc, 0, $pos);
  1464. } else {
  1465. $output .= $desc;
  1466. }
  1467. }
  1468. return $output;
  1469. }
  1470. function ztheme_playlist_description($desc, $opts, $stats, $item) {
  1471. $output = ztheme('description_teaser', $desc);
  1472. if (!empty($desc)) $output .= '<br/>';
  1473. if (isset($opts['profile_url'])) {
  1474. $opts['profile_url'] = '<a href="'.$opts['profile_url'].'" class="zina-profile-url">'.$opts['username'].'</a>';
  1475. unset($opts['username']);
  1476. }
  1477. #if (isset($opts['sum_items'])) $opts['sum_items'] = zt('@num Items', array('@num'=>$opts['sum_items']));
  1478. if (isset($opts['date_created'])) $opts['date_created'] = '<em>'.zina_date('F j, Y', $opts['date_created']).'</em>';
  1479. if (isset($opts['genre'])) $opts['genre'] = '<em>'.$opts['genre'].'</em>';
  1480. if (!empty($opts)) $output .= implode(' | ', $opts) .'<br/>';
  1481. if (isset($stats['sum_items'])) $stats['sum_items'] = zt('@num Items.', array('@num'=>$stats['sum_items']));
  1482. if (isset($stats['sum_views'])) $stats['sum_views'] = zt('@num Views.', array('@num'=>$stats['sum_views']));
  1483. if (isset($stats['sum_plays'])) $stats['sum_plays'] = zt('@num Plays.', array('@num'=>$stats['sum_plays']));
  1484. if (!empty($stats)) $output .= implode(' ', $stats);
  1485. return $output;
  1486. }
  1487. function ztheme_genre_hierarchy($genres, $next_id, $attr, $custom) {
  1488. zina_add_tabledrag('genres', 'match', 'parent', 'genre-pid', 'genre-pid', 'genre-id', TRUE, 8);
  1489. zina_set_css('file', 'extras/tabledrag.css');
  1490. zina_set_js('vars', 'var zinaNextGenreID='.$next_id.';');
  1491. $jq = 'function zinaAddTableRow(table){'.
  1492. 'var lastRow=$(table+\' tr:last\').clone();'.
  1493. "$('input.genre-id',lastRow).val(zinaNextGenreID);".
  1494. "$('input.genre-pid',lastRow).val(0);".
  1495. "$('select.genre-weight',lastRow).val(0);".
  1496. "$('input.genre',lastRow).val('');".
  1497. "$('span.genre-hidden',lastRow).css('display','block');".
  1498. "$('span.genre-title',lastRow).css('display','none');".
  1499. "$('span.genre-operations',lastRow).css('display','none');".
  1500. "$('input.genre',lastRow).attr('name','id:'+zinaNextGenreID+'\[genre\]');".
  1501. "$('input.genre-pid',lastRow).attr('name','id:'+zinaNextGenreID+'\[pid\]');".
  1502. "$('input.genre-id',lastRow).attr('name','id:'+zinaNextGenreID+'\[id\]');".
  1503. "$('select.genre-weight',lastRow).attr('name','id:'+zinaNextGenreID+'\[weight\]');".
  1504. "$(table).removeClass('tabledrag-processed');".
  1505. '$(table).append(lastRow);'.
  1506. "$('div.warning').remove();".
  1507. "$('a').remove('.tabledrag-handle');".
  1508. 'Drupal.behaviors.tableDrag();'.
  1509. 'zinaNextGenreID++;'.
  1510. 'return true;'.
  1511. '}';
  1512. zina_set_js('jquery', $jq);
  1513. #$delta = (int)(sizeof($genres)/2)+25;
  1514. $delta = 1;
  1515. $output = '';
  1516. if ($custom) {
  1517. $output .= '<p>'.zt('If you create a hierarchy here, it will be used when playing random songs via genres.').'</p>'.
  1518. '<ul><li><a href="#" onclick="zinaAddTableRow(\'#genres\'); return false;">'.zt('Add a genre').'</a></li></ul>';
  1519. }
  1520. $output .= '<table id="genres">'.
  1521. '<thead><tr><th>Genre</th><th>Operations</th></thead></tr><tbody>';
  1522. foreach($genres as $genre) {
  1523. $id = $genre['id'];
  1524. $row = '<tr class="draggable odd"><td>'.ztheme('indentation',substr_count($genre['path'],'/'));
  1525. $input = '<input type="text" name="id:'.$id.'[genre]" class="genre" value="'.htmlentities($genre['genre']).'">';
  1526. if ($genre['actual']) {
  1527. $row .= '<span class="genre-title">'.zl(htmlentities($genre['genre']),'',$genre['view_query']) .'</span><span style="display:none;" class="genre-hidden">'.$input.'</span>';
  1528. } else {
  1529. $row .= $input;
  1530. }
  1531. $row .= '</td>';
  1532. $row .= '<td style="display:none;"><select name="id:'.$id.'[weight]" class="genre-weight">'.
  1533. ztheme('delta',$delta, $genre['weight']).'</select>'.
  1534. '<input type="hidden" name="id:'.$id.'[pid]" value="'.$genre['pid'].'" class="genre-pid">'.
  1535. '<input type="hidden" name="id:'.$id.'[id]" value="'.$id.'" class="genre-id"></td>';
  1536. $row .= '<td><span class="genre-operations">';
  1537. if (!$genre['actual'])$row .= '<a href="'.$genre['delete_url'].'">'.zt('Delete').'</a>';
  1538. $row .= '</span></td>'.
  1539. '</tr>';
  1540. $output .= $row;
  1541. }
  1542. $output .= '</tbody></table>'.
  1543. '<input type="Submit" value="Save Settings">';
  1544. return ztheme('form',$attr, $output);
  1545. }
  1546. function ztheme_delta($delta, $item) {
  1547. $output = '';
  1548. for ($i = (-1 * $delta); $i <= $delta; $i++) {
  1549. $output .= '<option value="'.$i.'"'.(($item == $i) ? ' selected="selected"':'').'>'.$i.'</option>';
  1550. }
  1551. return $output;
  1552. }
  1553. function ztheme_year_form($display, $action, $years, $current, $title = false) {
  1554. return ztheme('genres_form', $display, $action, $years, $current, $title);
  1555. }
  1556. /*
  1557. * Genre search select
  1558. */
  1559. function ztheme_genres_form($display, $action, $genres, $current, $title = false) {
  1560. $output = '';
  1561. if ($display) {
  1562. $form_id = 'zinagenreform';
  1563. $output = '<form id="'.$form_id.'" method="post" action="'.$action.'"><div>'.
  1564. (($title) ? '<strong>'.zt($title).': </strong>' : '').
  1565. '<select name="pl" onchange="this.form.submit();">';
  1566. if (!empty($genres)) {
  1567. foreach($genres as $genre) {
  1568. $sel = ($genre == $current) ? ' selected="selected"' : '';
  1569. $output .= '<option value="'.htmlentities($genre).'"'.$sel.'>'.htmlentities($genre).'</option>';
  1570. }
  1571. }
  1572. $output .= '</select>&nbsp;'.zl(ztheme('icon','more.gif',zt('More')),'javascript:document.forms.'.$form_id.'.submit();').'</div></form>';
  1573. }
  1574. return $output;
  1575. }
  1576. /*
  1577. * Missing Images select
  1578. */
  1579. function ztheme_images_missing_form($dest, $missing, $current) {
  1580. $form_id = 'zinaimgmissing';
  1581. $output = '<form id="'.$form_id.'" method="GET" action="'.$dest['action'].'"><div>';
  1582. foreach($dest['queries'] as $key => $val) {
  1583. $output .= ztheme('form_hidden', $key, $val);
  1584. }
  1585. $output .= '<select name="p" onchange="this.form.submit();">';
  1586. if (!empty($missing)) {
  1587. foreach($missing as $path) {
  1588. $sel = ($path == $current) ? ' selected="selected"' : '';
  1589. $output .= '<option value="'.zrawurlencode($path).'"'.$sel.'>'.htmlentities($path).'</option>';
  1590. }
  1591. }
  1592. $output .= '</select>'.zl(ztheme('icon','more.gif',zt('More')),'javascript:document.forms.'.$form_id.'.submit();').'</div></form>';
  1593. return $output;
  1594. }
  1595. /*
  1596. * Search header sort options
  1597. */
  1598. function ztheme_search_header($type, $term, $action, $selected) {
  1599. $form_id = 'zinasearchheader';
  1600. $form_attr = 'id="'.$form_id.'" action="'.$action.'"';
  1601. if ($type != 'search') {
  1602. $opts['type'] = zina_search_opts_type($type);
  1603. }
  1604. $opts['sort'] = zina_search_opts_sort();
  1605. $opts['order'] = zina_search_opts_order();
  1606. $opts['per_page'] = zina_search_opts_per_page();
  1607. $output = '';
  1608. $output .= ztheme('form_hidden', 'searchterm', htmlentities($term));
  1609. foreach ($opts as $name => $opt) {
  1610. $output .= '<select name="'.$name.'" onchange="this.form.submit();">';
  1611. foreach($opt as $key => $val) {
  1612. $sel = ($key == $selected[$name]) ? ' selected="selected"' : '';
  1613. $output .= '<option value="'.$key.'"'.$sel.'>'.$val.'</option>';
  1614. }
  1615. $output .= '</select>';
  1616. }
  1617. $output .= '&nbsp;'.zl(ztheme('icon','more.gif',zt('More')),'javascript:document.forms.'.$form_id.'.submit();');
  1618. return ztheme('form', $form_attr, $output);
  1619. }
  1620. /*
  1621. * Playlists header sort options
  1622. */
  1623. #TODO: combine with search_header
  1624. function ztheme_playlist_header($action, $selected) {
  1625. $form_id = 'zinasearchheader';
  1626. $form_attr = 'id="'.$form_id.'" action="'.$action.'"';
  1627. if (isset($selected['all'])) $opts['all'] = zina_playlist_opts_all();
  1628. $opts['sort'] = zina_playlist_opts_sort();
  1629. $opts['order'] = zina_search_opts_order();
  1630. #$opts['per_page'] = zina_search_opts_per_page();
  1631. $output = '';
  1632. foreach ($opts as $name => $opt) {
  1633. $output .= '<select name="'.$name.'" onchange="this.form.submit();">';
  1634. foreach($opt as $key => $val) {
  1635. $sel = ($key == $selected[$name]) ? ' selected="selected"' : '';
  1636. $output .= '<option value="'.$key.'"'.$sel.'>'.$val.'</option>';
  1637. }
  1638. $output .= '</select>';
  1639. }
  1640. $output .= '&nbsp;'.zl(ztheme('icon','more.gif',zt('More')),'javascript:document.forms.'.$form_id.'.submit();');
  1641. return ztheme('form', $form_attr, $output);
  1642. }
  1643. /*
  1644. * Playlist form elements/options
  1645. */
  1646. function ztheme_playlist_form_elements($display, $form, $options, $opts_url, $playlists) {
  1647. $output = '';
  1648. if ($display) {
  1649. $output = '<div class="playlist-form-elements">';
  1650. $elements = array(
  1651. 'd'=>zl(ztheme('icon','delete.gif',zt('Delete')),$opts_url['d']),
  1652. 'a'=>zl(ztheme('icon','add.gif',zt('Add To')),$opts_url['a']),
  1653. 'v'=>zl(ztheme('icon','more.gif',zt('More')),$opts_url['v']),
  1654. 'p'=>zl(ztheme('icon','play.gif',zt('Play')),$opts_url['p']),
  1655. 'r'=>zl(ztheme('icon','play_rec_rand.gif',zt('Play Random')),$opts_url['r']),
  1656. 'q'=>zl(ztheme('icon','play_lofi.gif',zt('Play Low Fidelity')),$opts_url['q']),
  1657. 'l'=>zl(ztheme('icon','playlist.gif',zt('Playlists')),'',$opts_url['l']),
  1658. 'x'=>$playlists
  1659. );
  1660. foreach($options as $opt) {
  1661. $output .= $elements[$opt];
  1662. }
  1663. $output .= '</div>';
  1664. }
  1665. return $output;
  1666. }
  1667. function ztheme_playlist_form_select($name, $playlists, $current, $new, $session, $db = false) {
  1668. $output = '<select name="'.$name.'">';
  1669. if ($new) {
  1670. $output .= '<option value="new_zina_list"> - '.zt('New Playlist').' - </option>';
  1671. }
  1672. if ($session) {
  1673. $output .= '<option value="zina_session_playlist"> - '.zt('Session Playlist').' - </option>';
  1674. }
  1675. if (!empty($playlists)) {
  1676. if ($db) {
  1677. foreach($playlists as $playlist) {
  1678. $selected = ($playlist['title'] == $current) ? " selected='selected'" : '';
  1679. $output .= '<option value="'.$playlist['id'].'"'.$selected.'>'.ztheme('truncate', $playlist['title'],15).'</option>';
  1680. }
  1681. } else {
  1682. foreach($playlists as $playlist) {
  1683. $selected = ($playlist == $current) ? " selected='selected'" : '';
  1684. $output .= '<option value="'.$playlist.'"'.$selected.'>'.ztheme('truncate', $playlist,15).'</option>';
  1685. }
  1686. }
  1687. }
  1688. $output .= '</select>';
  1689. return $output;
  1690. }
  1691. function ztheme_admin_section_header($title, $anchor, $query = null) {
  1692. $output = '<a name="'.$anchor.'"></a><div class="cfg-cat"><span class="cfg-left">'.$title.'</span>';
  1693. if ($query) {
  1694. $output .= '<span class="cfg-right">'.zl(zt('Top'),'',$query,'top').'</span>';
  1695. }
  1696. $output .= '</div>';
  1697. return $output;
  1698. }
  1699. /*
  1700. * Random drop-down form
  1701. *
  1702. * array key numbers are critical (e.g. 4,5,11,12)
  1703. * todo: pass array keys?
  1704. * todo: but, pass less crap, wtf?
  1705. */
  1706. function ztheme_random($zc, $db, $genres, $action, $url_low, $url_play) {
  1707. #key == m=
  1708. $r_type = array(4=>zt('Albums'),5=>zt('Songs'));
  1709. if ($db && $zc['rating_random']) {
  1710. $r_type[11] = zt('Songs (via Rated Albums)');
  1711. $r_type[12] = zt('Songs (via Rated Artists)');
  1712. }
  1713. $all = $zc['cache'] ? '<option value="0">'.zt('All') : '';
  1714. $low = '';
  1715. if ($zc['low']) {
  1716. $low .= zl(ztheme('icon','play_lofi.gif',zt('Play Low Fidelity')),"javascript:SubmitForm('random','".$url_low."','play');");
  1717. }
  1718. $form_id = 'zinarandomform';
  1719. $form_attr = 'id="'.$form_id.'" action="'.$action.'"';
  1720. $output = '<span class="small">'.zt('Random').': </span><select name="n">';
  1721. foreach($zc['ran_opts'] as $option) {
  1722. $selected = '';
  1723. if ($option == $zc['ran_opts_def']) $selected = ' selected="selected"';
  1724. $output .= '<option value="'.$option.'"'.$selected.'>';
  1725. $output .= ($option != 0) ? $option : zt('All');
  1726. $output .= '</option>';
  1727. }
  1728. $output .= '</select><select name="m">';
  1729. foreach($r_type as $key=>$type) {
  1730. $selected = '';
  1731. if ($key == 5) $selected = ' selected="selected"';
  1732. $output .= '<option value="'.$key.'"'.$selected.'>'.$type.'</option>';
  1733. }
  1734. $output .= '</select>';
  1735. if (!empty($genres)) {
  1736. $output .= '<select name="playlist"><option value="zina" selected="selected">'.zt('All').'</option>';
  1737. foreach($genres as $genre) {
  1738. $output .= '<option value="'.htmlentities($genre).'">'.htmlentities(ztheme('truncate', $genre, 20)).'</option>';
  1739. }
  1740. $output .= '</select>';
  1741. }
  1742. if ($db && $zc['rating_random']) {
  1743. $opts = explode(',',$zc['rating_random_opts']);
  1744. $output .= '<select name="rating"><option value="zina" selected="selected">'.zt('All').'</option>';
  1745. foreach ($opts as $opt) $output .= '<option value="'.$opt.'">'.$opt.'</option>';
  1746. $output .= '</select>';
  1747. }
  1748. $output .= zl(ztheme('icon','play.gif',zt('Play')),"javascript:SubmitForm('$form_id','".$url_play."','play');").
  1749. $low;
  1750. return ztheme('form', $form_attr, $output);
  1751. }
  1752. /*
  1753. * Optional for statistic blocks
  1754. */
  1755. function ztheme_zina_block($items, $type) {
  1756. if (!empty($items)) {
  1757. $output = '<ul>';
  1758. foreach($items as $item) {
  1759. $output .= '<li>';
  1760. if ($type == 'f') {
  1761. $output .= (isset($item['url'])) ? '<a href="'.$item['url'].'">'.$item['filename'].'</a>' : $title;
  1762. } else {
  1763. $output .= $item['display'];
  1764. }
  1765. $output .= '</li>';
  1766. }
  1767. $output .= '</ul>';
  1768. } else {
  1769. $output = zt('No results');
  1770. }
  1771. return $output;
  1772. }
  1773. /*
  1774. * Following four functions for formating
  1775. */
  1776. function ztheme_artist_song($song, $artist = false) {
  1777. return ($artist) ? $artist.' - '.$song : $song;
  1778. }
  1779. function ztheme_title($title) {
  1780. return str_replace('_',' ',
  1781. preg_replace('/^[0-9]{0,4}[ ]?-[ ]?/i','',rtrim(zcheck_utf8($title),"\r\n"))
  1782. );
  1783. }
  1784. function ztheme_song_title($song, $tag = false) {
  1785. return ($tag) ? $song : str_replace('_',' ',
  1786. preg_replace('/^.*?[0-9][0-9][ ]?-[ ]?/i','',rtrim(zcheck_utf8($song),"\r\n"))
  1787. );
  1788. }
  1789. function ztheme_truncate($str, $length, $replace = '...') {
  1790. return (zina_strlen($str) > $length) ? zina_substr($str,0,$length).$replace : $str;
  1791. }
  1792. /*
  1793. * Sitemap
  1794. */
  1795. function ztheme_sitemap($items) {
  1796. $output = '<?xml version="1.0" encoding="UTF-8"?'.'>'."\n".
  1797. '<urlset xmlns="http://www.google.com/schemas/sitemap/0.84" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" '.
  1798. 'xsi:schemaLocation="http://www.google.com/schemas/sitemap/0.84 http://www.google.com/schemas/sitemap/0.84/sitemap.xsd">'."\n";
  1799. foreach($items as $item) {
  1800. $output .= "\t<url>\n".
  1801. "\t\t".str_replace('&', '&amp;', xml_field('loc', $item['url']))."\n".
  1802. "\t\t<lastmod>".date('c',$item['mtime'])."</lastmod>\n".
  1803. "\t\t<changefreq>".zina_sitemap_frequency(time() - $item['mtime'])."</changefreq>\n".
  1804. "\t\t<priority>".((isset($item['priority'])) ? $item['priority'] : .5 )."</priority>\n".
  1805. "\t</url>\n";
  1806. }
  1807. $output .= '</urlset>'."\n";
  1808. return $output;
  1809. }
  1810. function ztheme_admin_nav($nav) {
  1811. return implode(' | ', $nav);
  1812. }
  1813. /*
  1814. * RSS
  1815. */
  1816. function ztheme_rss($zina, $podcast = true) {
  1817. global $zc;
  1818. $xml = '<?xml version="1.0" encoding="UTF-8"?'.'>'."\n";
  1819. if ($podcast)
  1820. $xml .= '<rss xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" version="2.0">'."\n";
  1821. else
  1822. $xml .= '<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">'."\n";
  1823. #$xml .= xml_field('cssurl', zpath_to_theme().'/rss.css');
  1824. $xml .='<channel>'."\n".
  1825. xml_field('title', $zina['title']).
  1826. xml_field('link', $zina['page_url']);
  1827. if (isset($zina['desc'])) {
  1828. $feed_desc = strip_tags($zina['desc']);
  1829. $xml .= xml_field('description', $feed_desc);
  1830. if ($podcast) $xml .= xml_field('itunes:summary', $feed_desc);
  1831. }
  1832. if (isset($zina['image_url']) && $zina['image_url']) {
  1833. $xml .= '<image>'."\n".
  1834. xml_field('title', $zina['title']).
  1835. xml_field('link', $zina['page_url']).
  1836. xml_field('url', $zina['image_url']).
  1837. '</image>'."\n";
  1838. if ($podcast) $xml .= '<itunes:image href="'.zxml_encode($zina['image_url']).'" />'."\n";
  1839. }
  1840. if ($podcast) {
  1841. $xml .= '<itunes:category text="Music"/>'."\n";
  1842. } else {
  1843. $xml .= '<atom:link rel="self" href="'.zxml_encode($zina['link_url']).'" type="application/rss+xml" />'."\n";
  1844. }
  1845. $xml .= xml_field('language', $zina['lang_code']).
  1846. xml_field('lastBuildDate', date('r'));
  1847. if ($zina['items']) {
  1848. foreach ($zina['items'] as $item) {
  1849. $xml .= '<item>'."\n".
  1850. xml_field('title', $item['title']);
  1851. if (isset($item['url'])) $xml .= xml_field('link', $item['url']);
  1852. if ((isset($item['description']) && $item['description']) || isset($item['image_url'])) {
  1853. $item_desc = (isset($item['description'])) ? strip_tags($item['description']) : '';
  1854. if (isset($item['image_url'])) {
  1855. $xml .= '<description>'.zxml_encode($item['image_url'].'<br/>'.$item_desc).'</description>';
  1856. } else {
  1857. $xml .= xml_field('description', $item_desc);
  1858. }
  1859. if ($podcast) $xml .= xml_field('itunes:subtitle', $item_desc);
  1860. }
  1861. if (isset($item['url'])) $xml .= xml_field('guid', $item['url']);
  1862. if (isset($item['pub'])) $xml .= xml_field('pubDate', $item['pub']);
  1863. if ($podcast) {
  1864. $xml .= '<enclosure url="'.$item['url_enc'].'" length="'.$item['size'].'" type="'.$item['type'].'"/>'."\n";
  1865. if (isset($item['artist'])) $xml .= xml_field('itunes:author', $item['artist']);
  1866. if (isset($item['duration'])) $xml .= xml_field('itunes:duration', $item['duration']);
  1867. }
  1868. $xml .= '</item>'."\n";
  1869. }
  1870. }
  1871. $xml .= '</channel>'."\n".'</rss>';
  1872. return $xml;
  1873. }
  1874. function ztheme_artist_album($path, $rss = false) {
  1875. $x = explode('/', $path);
  1876. $len = sizeof($x);
  1877. return ($len == 2) ? ztheme('title',$x[0]).' - '.ztheme('title', $x[1]) : ztheme('title', $path);
  1878. }
  1879. function ztheme_indentation($size = 1) {
  1880. $output = '';
  1881. for ($n = 0; $n < $size; $n++) {
  1882. $output .= '<div class="indentation">&nbsp;</div>';
  1883. }
  1884. return $output;
  1885. }
  1886. function ztheme_page_zinamp($zina) {
  1887. $theme_path = $zina['theme_path'];
  1888. return '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'.
  1889. '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"><head><title>'.$zina['title'].'</title>'.
  1890. '<meta http-equiv="Content-Type" content="text/html; charset='.$zina['charset'].'" />'.
  1891. '<link rel="shortcut icon" href="'.$theme_path.'/zina.ico" type="image/x-icon" />'.
  1892. $zina['head_js'].'<style>body{margin:0;padding:0;;overflow-x:hidden;overflow-y:hidden;}</style></head>'.
  1893. '<body onload="setTimeout(\'window.document.zinamp.addPlaylist(window.opener.zinamp_playlist);\',500);zinampFocus();">'.$zina['content'].'</body>'.
  1894. '</html>';
  1895. }
  1896. function ztheme_zinamp_embed() {
  1897. global $zc;
  1898. if ($zc['zinamp'] != 1 && $zc['zinamp'] != 2) return '';
  1899. zina_set_js('file', 'extras/jquery.js');
  1900. zina_set_js('jquery',
  1901. "$('a.zinamp').click(function(){".
  1902. 'var href=this.href;'.
  1903. 'zinampWindow(href);'.
  1904. 'return false;'.
  1905. '});'
  1906. );
  1907. zina_set_js('inline',
  1908. 'function zinampSelect(form, url){'.
  1909. 'var href = url+"&"+jQuery(form).serialize();'.
  1910. 'zinampWindow(href);'.
  1911. '}'
  1912. );
  1913. zina_set_js('inline',
  1914. 'function zinampSelectPost(form, url){'.
  1915. 'jQuery.ajax({'.
  1916. 'type:"POST",'.
  1917. 'cache:false,'.
  1918. 'url:url+"&store",'.
  1919. 'data:jQuery(form).serialize(),'.
  1920. 'success:function(data,textStatus){'.
  1921. 'zinampWindow(data);'.
  1922. '}'.
  1923. '});'.
  1924. '}'
  1925. );
  1926. if ($zc['zinamp'] == 2) { # popup
  1927. $js =
  1928. 'function zinampWindow(href){'.
  1929. 'zinamp_playlist=encodeURIComponent(href);'.
  1930. 'if (window.zwin&&!zwin.closed){'.
  1931. 'zwin.document.zinamp.addPlaylist(encodeURIComponent(href));'.
  1932. '}else{'.
  1933. 'var winsize=(zina_cookie("zinamp_window"))?","+zina_cookie("zinamp_window"):"";'.
  1934. 'zwin=window.open("","zinamp","width='.$zc['zinamp_width'].',height='.$zc['zinamp_height'].',status=no,toolbar=no,scrollbars=no"+winsize);'.
  1935. 'zwin.location="'.$zc['zinamp_url'].'";'.
  1936. '}'.
  1937. '}';
  1938. zina_set_js('inline', $js);
  1939. } else {
  1940. zina_set_js('inline',
  1941. 'function zinampWindow(href){'.
  1942. 'window.document.zinamp.addPlaylist(encodeURIComponent(href));'.
  1943. '}'
  1944. );
  1945. return ztheme('zinamp');
  1946. }
  1947. }
  1948. function ztheme_jplayer_embed() {
  1949. global $zc;
  1950. if ($zc['zinamp']!=3) return '';
  1951. zina_set_js('file', 'extras/jquery.js');
  1952. zina_set_js('jquery',
  1953. "$('a.zinamp').click(function(){".
  1954. 'var href=this.href;'.
  1955. 'jplayerWindow(href);'.
  1956. 'return false;'.
  1957. '});'
  1958. );
  1959. # TODO: Figure out how to change the name from zinamp to jplayer without breaking the
  1960. # world.
  1961. zina_set_js('inline',
  1962. 'function zinampSelect(form, url){'.
  1963. 'var href = url+"&"+jQuery(form).serialize();'.
  1964. 'jplayerWindow(href);'.
  1965. '}'
  1966. );
  1967. zina_set_js('inline',
  1968. 'function zinampSelectPost(form, url){'.
  1969. 'jQuery.ajax({'.
  1970. 'type:"POST",'.
  1971. 'cache:false,'.
  1972. 'url:url+"&store",'.
  1973. 'data:jQuery(form).serialize(),'.
  1974. 'success:function(data,textStatus){'.
  1975. 'jplayerWindow(data);'.
  1976. '}'.
  1977. '});'.
  1978. '}'
  1979. );
  1980. if ($zc['zinamp'] == 3) { # popup
  1981. $js =
  1982. 'function jplayerWindow(href){'.
  1983. 'jplayer_playlist=encodeURIComponent(href);'.
  1984. 'if (window.zwin&&!zwin.closed){'.
  1985. 'zwin.close();'.
  1986. # 'zwin.document.jplayer.addPlaylist(encodeURIComponent(href));'.
  1987. '}'.
  1988. 'var winsize=(zina_cookie("jplayer_window"))?","+zina_cookie("jplayer_window"):"";'.
  1989. 'zwin=window.open("","jplayer","width=484,height=433,status=no,toolbar=no,scrollbars=no"+winsize);'.
  1990. 'zwin.location="'.$zc['jplayer_url'].'";'.
  1991. '}';
  1992. zina_set_js('inline', $js);
  1993. }
  1994. }
  1995. function ztheme_page_jplayer($zina) {
  1996. global $zc;
  1997. $theme_path = $zina['theme_path'];
  1998. $skin_dir = $zc['zina_dir_rel'].'/extras/jQuery.jPlayer.2.2.0/skins/';
  1999. $base_skin = 'zina.css';
  2000. $skin = 'midnight.black/jplayer.midnight.black.css';
  2001. return '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'.
  2002. '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"><head><title>'.$zina['title'].'</title>'.
  2003. '<meta http-equiv="Content-Type" content="text/html; charset='.$zina['charset'].'" />'.
  2004. '<link rel="shortcut icon" href="'.$theme_path.'/zina.ico" type="image/x-icon" />'.
  2005. $zina['head_js'].
  2006. '<link href="'.$skin_dir.$base_skin.'" rel = "stylesheet" type="text/css" />'.
  2007. '<link href="'.$skin_dir.$skin.'" rel="stylesheet" type="text/css" />'.
  2008. '</head>'.
  2009. '<body onload="setTimeout(\'window.document.jplayer.addPlaylist(window.opener.jplayer_playlist);\',500);jplayerFocus();" style="overflow:hidden">'.$zina['content'].'</body>'.
  2010. '</html>';
  2011. }
  2012. function ztheme_zinamp() {
  2013. global $zc;
  2014. $player = $zc['zina_dir_rel'].'/zinamp/zinamp.swf';
  2015. $express = $zc['zina_dir_rel'].'/zinamp/expressInstall.swf';
  2016. $skin = $zc['zina_dir_rel'].'/zinamp/skins/'.$zc['zinamp_skin'];
  2017. zina_set_js('file', 'zinamp/swfobject.js');
  2018. #todo: ready is for IE6/7
  2019. $output = 'swfobject.embedSWF("'.$player.'", "zinamp", "'.$zc['zinamp_width'].'", "'.$zc['zinamp_height'].'", "8.0.0", "'.$express.'", '.
  2020. '{skin_url:"'.$skin.
  2021. '",lang_loading:"'.zt('Loading...').
  2022. '",lang_missing:"'.zt('Missing Title').
  2023. '",lang_no_tracks:"'.zt('No tracks found in playlist').
  2024. '",lang_error:"'.zt('Error opening').
  2025. '",lang_nothing:"'.zt('Nothing to play').
  2026. '",lang_seek:"'.zt('Seek').
  2027. '",lang_volume:"'.zt('Volume').
  2028. '",lang_balance:"'.zt('Balance').
  2029. '",lang_not_found:"'.zt('File not found').
  2030. '"}, '.
  2031. '{wmode:"transparent", allowscriptaccess:"sameDomain", loop:"false", quality:"high"});'
  2032. ;
  2033. zina_set_js('inline', 'function zinampFocus(){document.getElementById("zinamp").focus();}');
  2034. zina_set_js('inline', 'function zinampUrl(url){if(window.opener){window.opener.location=url;}else{self.location=url;}stop;}');
  2035. return '<div id="zinamp"><p><a href="http://www.adobe.com/go/getflashplayer"><img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="'.zt('Get Adobe Flash player').'" /></a></p></div>'.
  2036. '<script type="text/javascript">'.$output.'</script>';
  2037. }
  2038. function ztheme_jplayer() {
  2039. global $zc;
  2040. $player = $zc['zina_dir_rel'].'/extras/jQuery.jPlayer.2.2.0/jquery.jplayer.min.js';
  2041. $playlist = $zc['zina_dir_rel'].'/extras/jQuery.jPlayer.2.2.0/add-on/jplayer.playlist.min.js';
  2042. $inspector = $zc['zina_dir_rel'].'/extras/jQuery.jPlayer.2.2.0/add-on/jquery.jplayer.inspector.js';
  2043. $swf_path = $zc['zina_dir_rel'].'/extras/jQuery.jPlayer.2.2.0/';
  2044. $output = '
  2045. <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8/jquery.min.js"></script>
  2046. <script type="text/javascript" src="'.$player.'"></script>
  2047. <script type="text/javascript" src="'.$playlist.'"></script>
  2048. <script type="text/javascript" src="'.$inspector.'"></script>
  2049. <script type="text/javascript">
  2050. var bPlaying = false;
  2051. var pl_data = [];
  2052. var pl;
  2053. var current_track_url;
  2054. $(document).ready(function(){
  2055. var playlist_url = window.opener.jplayer_playlist;
  2056. u = playlist_url.replace(/%3A/g, ":");
  2057. u = u.replace(/%2F/g, "/");
  2058. u = u.replace(/%3F/g, "?");
  2059. u = u.replace(/%3D/g, "=");
  2060. u = u.replace(/%26/g, "&");
  2061. $.ajax({
  2062. type: "GET",
  2063. url: u,
  2064. dataType: "xml",
  2065. success: function(xml) {
  2066. var i = 0;
  2067. $(xml).find(\'track\').each(function(){
  2068. mp3_url = $(this).find("link").text();
  2069. idx = mp3_url.indexOf("&l=54");
  2070. stripped_url = mp3_url.substr(0, idx);
  2071. var t = $(this).find("title").text();
  2072. pl.add({
  2073. title: t,
  2074. artist: $(this).find("creator").text(),
  2075. mp3: stripped_url
  2076. });
  2077. });
  2078. window.resizeTo(500,498);
  2079. pl.play();
  2080. },
  2081. error: function(xhr, textStatus, errorThrown){
  2082. alert(\'request failed->\'+textStatus);
  2083. }
  2084. });
  2085. // Push a dummy entry
  2086. pl_data.push({
  2087. title: "xxx",
  2088. mp3:"xxx",
  2089. });
  2090. // Firefox sucks and does not provide mp3 support, so we will
  2091. // force it to always use flash player and only mp3 for now
  2092. if(navigator.userAgent.toLowerCase().indexOf(\'firefox\') > -1) {
  2093. //Do Firefox-related activities
  2094. pl = new jPlayerPlaylist({
  2095. jPlayer: "#jquery_jplayer_1",
  2096. cssSelectorAncestor: "#jp_container_1"
  2097. }, pl_data, {
  2098. playlistOptions: {
  2099. autoplay: true,
  2100. enableRemoveControls: true
  2101. },
  2102. swfPath: "'.$swf_path.'",
  2103. supplied: "mp3",
  2104. wmode: "window",
  2105. });
  2106. }
  2107. else {
  2108. pl = new jPlayerPlaylist({
  2109. jPlayer: "#jquery_jplayer_1",
  2110. cssSelectorAncestor: "#jp_container_1"
  2111. }, pl_data, {
  2112. playlistOptions: {
  2113. autoplay: true,
  2114. enableRemoveControls: true
  2115. },
  2116. swfPath: "'.$swf_path.'",
  2117. supplied: "oga, mp3, mp4",
  2118. wmode: "window",
  2119. });
  2120. }
  2121. // Remove a dummy entry
  2122. pl.remove();
  2123. $("#jplayer_inspector_1").jPlayerInspector({jPlayer:$("#jquery_jplayer_1")});
  2124. $("#jquery_jplayer_1").bind($.jPlayer.event.ended, function(event) {
  2125. bPlaying = false;
  2126. current_track_url = event.jPlayer.status.media;
  2127. scrobble_url = current_track_url.mp3 + "&l=102&q=music";
  2128. $.ajax({
  2129. type: "GET",
  2130. url: scrobble_url,
  2131. dataType: "text",
  2132. error: function(xhr, textStatus, errorThrown){
  2133. alert(\'request failed->\'+textStatus);
  2134. }
  2135. });
  2136. });
  2137. $("#jquery_jplayer_1").bind($.jPlayer.event.loadstart, function(event) {
  2138. if (bPlaying) {
  2139. scrobble_url = current_track_url.mp3 + "&l=102&q=music";
  2140. $.ajax({
  2141. type: "GET",
  2142. url: scrobble_url,
  2143. dataType: "text",
  2144. error: function(xhr, textStatus, errorThrown){
  2145. alert(\'request failed->\'+textStatus);
  2146. }
  2147. });
  2148. }
  2149. bPlaying = true;
  2150. current_track_url = event.jPlayer.status.media;
  2151. scrobble_url = current_track_url.mp3 + "&l=101&q=music";
  2152. $.ajax({
  2153. url: scrobble_url,
  2154. dataType: "text",
  2155. error: function(xhr, textStatus, errorThrown){
  2156. alert(\'request failed->\'+textStatus);
  2157. }
  2158. });
  2159. });
  2160. });
  2161. $(window).unload(function() {
  2162. if (bPlaying) {
  2163. scrobble_url = current_track_url.mp3 + "&l=102&q=music";
  2164. $.ajax({
  2165. type: "GET",
  2166. url: scrobble_url,
  2167. dataType: "text",
  2168. async: false
  2169. });
  2170. }
  2171. });
  2172. </script>';
  2173. $output2 = '
  2174. <div id="content_main">
  2175. <div id="jquery_jplayer_1" class="jp-jplayer"></div>
  2176. <div id="jp_container_1" class="jp-audio">
  2177. <div class="jp-type-playlist">
  2178. <div class="jp-gui jp-interface">
  2179. <ul class="jp-controls">
  2180. <li><a href="javascript:;" class="jp-previous" tabindex="1">previous</a></li>
  2181. <li><a href="javascript:;" class="jp-play" tabindex="1">play</a></li>
  2182. <li><a href="javascript:;" class="jp-pause" tabindex="1">pause</a></li>
  2183. <li><a href="javascript:;" class="jp-next" tabindex="1">next</a></li>
  2184. <li><a href="javascript:;" class="jp-stop" tabindex="1">stop</a></li>
  2185. <li><a href="javascript:;" class="jp-mute" tabindex="1" title="mute">mute</a></li>
  2186. <li><a href="javascript:;" class="jp-unmute" tabindex="1" title="unmute">unmute</a></li>
  2187. <li><a href="javascript:;" class="jp-volume-max" tabindex="1" title="max volume">max volume</a></li>
  2188. </ul>
  2189. <div class="jp-progress">
  2190. <div class="jp-seek-bar">
  2191. <div class="jp-play-bar"></div>
  2192. </div>
  2193. </div>
  2194. <div class="jp-volume-bar">
  2195. <div class="jp-volume-bar-value"></div>
  2196. </div>
  2197. <div class="jp-current-time"></div>
  2198. <div class="jp-duration"></div>
  2199. <ul class="jp-toggles">
  2200. <li><a href="javascript:;" class="jp-shuffle" tabindex="1" title="shuffle">shuffle</a></li>
  2201. <li><a href="javascript:;" class="jp-shuffle-off" tabindex="1" title="shuffle off">shuffle off</a></li>
  2202. <li><a href="javascript:;" class="jp-repeat" tabindex="1" title="repeat">repeat</a></li>
  2203. <li><a href="javascript:;" class="jp-repeat-off" tabindex="1" title="repeat off">repeat off</a></li>
  2204. </ul>
  2205. </div>
  2206. <div class="jp-playlist" style="width:483px;height:363px;overflow: auto">
  2207. <ul>
  2208. <li></li>
  2209. </ul>
  2210. </div>
  2211. <div class="jp-no-solution">
  2212. <span>Update Required</span>
  2213. To play the media you will need to either update your browser to a recent version or update your <a href="http://get.adobe.com/flashplayer/" target="_blank">Flash plugin</a>.
  2214. </div>
  2215. </div>
  2216. </div>
  2217. </div>
  2218. ';
  2219. return $output.$output2;
  2220. }
  2221. function ztheme_zinamp_song_info($item) {
  2222. # css references here are defined in zinamp/skins/SKIN/style.css
  2223. $output = '';
  2224. $output .= '<div><span class="title">'.$item['title'].'</span>';
  2225. if (isset($item['time'])) $output .= '<span class="time"> ('.$item['time'].')</span>';
  2226. if (isset($item['album'])) {
  2227. $output .= '<br /><span class="album">"'.$item['album'].'"';
  2228. if (isset($item['year']) && !empty($item['year'])) $output .= ' ('.$item['year'].')';
  2229. $output .='</span>';
  2230. }
  2231. if (isset($item['artist'])) {
  2232. $output .= '<br /><span class="artist">'.$item['artist'].'</span>';
  2233. }
  2234. $output .='</div>';
  2235. return $output;
  2236. }
  2237. /*
  2238. * Generic Image Tag
  2239. */
  2240. function ztheme_image($src, $alt='', $title='', $attributes='') {
  2241. if (empty($title)) $title = $alt;
  2242. if (!empty($attributes)) $attributes = ' '.$attributes;
  2243. return '<img src="'.$src.'" alt="'.zcheck_utf8($alt).'" title="'.zcheck_utf8($title).'"'.$attributes.'/>';
  2244. }
  2245. /*
  2246. * Generic Icon
  2247. */
  2248. function ztheme_icon($file, $alt='', $title='', $attributes='') {
  2249. return ztheme('image', zpath_to_theme().'/icons/'.$file, $alt, $title, $attributes.' class="icon"');
  2250. }
  2251. /*
  2252. * Genre filename (path is THEME/images
  2253. */
  2254. function ztheme_image_genre($genre) {
  2255. return 'genre_'.strtolower($genre).'.jpg';
  2256. }
  2257. /*
  2258. * Keeps track of row number for alternating row colors on separate tables
  2259. */
  2260. function zevenodd($i=null) {
  2261. static $class = 0;
  2262. if (empty($i)) return $class;
  2263. $class = $i;
  2264. }
  2265. ?>