PageRenderTime 100ms CodeModel.GetById 3ms app.highlight 81ms RepoModel.GetById 1ms app.codeStats 1ms

/zina/theme.php

https://bitbucket.org/helmespc/zina2
PHP | 2627 lines | 2098 code | 335 blank | 194 comment | 409 complexity | 40374136df0ede9f79ec5558f4bcf280 MD5 | raw file

Large files files are truncated, but you can click here to view the full 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/*
  25 * YOU SHOULD NOT MODIFY THIS FILE...
  26 *
  27 * You should override all these functions in your own theme:
  28 *  1) Copy a theme folder
  29 *  2) in MYTHEME/index.php copy any function you want to
  30 *     override into that file
  31 *  3) rename that function to MYTHEME_function()
  32 *      - e.g. ztheme_icon -> MYTHEME_icon
  33 *  4) modify that function to suit your needs
  34 *  x) An easy way to see what a function is passing is zdbg($var);
  35 */
  36
  37/*
  38 * Complete Page (Standalone)
  39 */
  40function ztheme_page_complete($zina) {
  41	$theme_path = $zina['theme_path'];
  42
  43	$output = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'.
  44		'<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"><head><title>'.$zina['title'].'</title>'.
  45		'<meta http-equiv="Content-Type" content="text/html; charset='.$zina['charset'].'" />'.
  46		'<link rel="shortcut icon" href="'.$theme_path.'/zina.ico" type="image/x-icon" />'.
  47		'<link rel="stylesheet" href="'.$theme_path.'/index.css" type="text/css" />'.
  48		'<!--[if lt IE 7]><link type="text/css" rel="stylesheet" media="all" href="'.$theme_path.'/fix-ie.css" /><![endif]-->'.
  49		$zina['head_html'].$zina['head_css'].$zina['head_js'].'</head><body>';
  50
  51	$output .= '<div id="header-region" class="clear-block"></div>'.
  52		'<div id="wrapper"><div id="container" class="clear-block">'.
  53		'<div id="header"><h1>'.$zina['title'].'</h1>'.
  54		'<div class="header-right">';
  55
  56		if (isset($zina['dir_year']) || isset($zina['dir_genre'])) {
  57			$output .= '<span class="title_details">';
  58			if (isset($zina['dir_genre'])) $output .= $zina['dir_genre'];
  59			if (!empty($zina['dir_year'])) $output .= ' ('.$zina['dir_year'].')';
  60			$output .= '</span>';
  61		}
  62
  63	$output .= '</div></div>'.
  64      '<div id="center"><div class="right-corner"><div class="left-corner">'.
  65		'<div class="breadcrumb">'.ztheme('breadcrumb',$zina['breadcrumb']).'</div>'.
  66		'<div class="breadcrumb-right">';
  67
  68	if (isset($zina['admin_config'])) {
  69		$output .= zl(ztheme('icon','config.gif',zt('Settings')),$zina['admin_config']['path'],$zina['admin_config']['query']);
  70	}
  71	$lang['login'] = zt('Login');
  72	$lang['logout'] = zt('Logout');
  73	if (isset($zina['login'])) {
  74		$output .= zl(ztheme('icon',$zina['login']['type'].'.gif',$lang[$zina['login']['type']]), $zina['login']['path'], $zina['login']['query']);
  75	}
  76
  77	$output .= '</div><div id="zina" class="clear-block">';
  78	if (!isset($zina['popup'])) {
  79		$output .= '<div class="subheader clear-block"><div class="subheader-left">'.$zina['searchform'].'</div>'.
  80			'<div class="subheader-right">'.$zina['randomplayform'].'</div></div>';
  81		if (!empty($zina['zinamp']) && (!isset($zina['page_main']) || isset($zina['category']))) {
  82			$output .= '<div style="text-align:right;">'.$zina['zinamp'].'</div>';
  83		}
  84	}
  85
  86	$output .= '<div id="zina_messages">'.$zina['messages'].'</div>'.$zina['content'].ztheme('page_footer',$zina).
  87		'</div></div></div></div></div></div></body></html>';
  88
  89	return $output;
  90}
  91
  92function ztheme_page_main($zina) {
  93	$path = $zina['path'];
  94	$output = '';
  95
  96	$lang['dir'] = zt('Edit Text');
  97	$lang['dir_opts'] = zt('Options');
  98	$lang['podcast'] = zt('Edit Podcast');
  99	$lang['rename'] = zt('Rename');
 100	$lang['images'] = zt('Edit Images');
 101	$lang['tags'] = zt('Edit Tags');
 102
 103	if (isset($zina['category'])) {
 104		if (!empty($zina['description']) || isset($zina['dir_edit_opts'])) {
 105			$output .= '<table border="0" cellpadding="5" cellspacing="0" width="100%">'.
 106				'<tr><td valign="top" width="100%">';
 107			if (!empty($zina['description'])) $output .= '<p>'.$zina['description'].'</p>';
 108
 109			# todo: dup with below...
 110			if (isset($zina['dir_edit_opts'])) {
 111				$options = array();
 112				foreach ($zina['dir_edit_opts'] as $opt => $opts) {
 113					$options[] = zl($lang[$opt],$opts['path'], $opts['query']);
 114				}
 115				$output .= '<p class="small">';
 116				$output .= implode(' | ', $options);
 117				$output .= '</p>';
 118			}
 119			$output .= '</td></tr></table>';
 120		}
 121
 122		if (isset($zina['category']) && !empty($zina['category']['sort'])) {
 123			$output .= '<table width="100%"><tr><td class="quarterwidth">'.$zina['category']['sort'].'</td>';
 124			if (isset($zina['category']['navigation'])) {
 125				$output .= '<td class="halfwidth" align="center">'.$zina['category']['navigation'].'</td>'.
 126					'<td class="quarterwidth"></td>';
 127			}
 128			$output .= '</tr></table>';
 129		} else {
 130			if (isset($zina['category']['navigation'])) $output .= $zina['category']['navigation'];
 131		}
 132
 133		$output .= ''.$zina['category']['content'];
 134
 135		if (isset($zina['category']['navigation'])) $output .= $zina['category']['navigation'];
 136	} else {
 137		$output .= '<div class="section">';
 138		$subdirs = ($zina['subdir_num'] > 0);
 139		$altdirs = ($zina['alt_num'] > 0);
 140
 141		if (($subdirs && $zina['dir_list']) || $altdirs || isset($zina['alt_list_edit']) || !empty($zina['zinamp']) || $zina['pls_included']) {
 142			$output .= '<div class="directory_list">';
 143			if (!empty($zina['zinamp'])) $output .= '<div style="margin-bottom:5px;">'.$zina['zinamp'].'</div>';
 144			$form_content = '';
 145			if ($subdirs && $zina['dir_list']) $form_content .= ztheme('directory_list', $zina['subdirs'], $zina['subdir_truncate']);
 146
 147			if ($altdirs || isset($zina['alt_list_edit'])) {
 148				$form_content .= ztheme('directory_alt_list', $zina['alt_items'], $zina['subdir_truncate']);
 149				if (isset($zina['alt_list_edit'])) {
 150					$form_content .= '<div class="small">'.zl(zt('Edit "See Also"'),$path,$zina['alt_list_edit']['query']).'</div>';
 151				}
 152			}
 153
 154			if ($zina['pls_included']) {
 155				$form_content .= '<div style="margin:10px 0 10px 0">'.ztheme('playlists_block', $zina['pls_included']['items'], $zina['subdir_truncate']);
 156				if (isset($zina['pls_included']['more'])) {
 157					$form_content .= '<div class="small">'.zl(zt('More'),$zina['pls_included']['more']['path'],$zina['pls_included']['more']['query']).'</div>';
 158
 159				}
 160
 161				$form_content .= '</div>';
 162			}
 163
 164			$output .= (!empty($zina['list_form_opts'])) ? ztheme('form', $zina['list_form_opts'], $form_content.$zina['list_form']) : $form_content;
 165			if ($zina['amg']) {
 166				$output .= '<div class="amg">'.ztheme('amg',$zina).'</div>';
 167			}
 168			$output .= '</div>';
 169		}
 170		if (isset($zina['dir_image'])) $output .= '<div class="directory-image">'.$zina['dir_image'].'</div>';
 171		if (isset($zina['dir_opts'])) {
 172			$output .= '<p class="dir-opts">'.ztheme('dir_opts',$zina['dir_opts'],$zina['title_raw']).'</p>';
 173		}
 174
 175		$votes = (isset($zina['dir_rating']) && $zina['dir_rating']['sum_votes'] > 0);
 176		if ($votes || isset($zina['dir_rate'])) {
 177			$output .= '<p class="small">';
 178			if ($votes) {
 179				$output .= ztheme('rating_display', $zina['dir_rating']['sum_rating']).
 180					ztheme('votes_display',$zina['dir_rating']['sum_votes']);
 181				if (isset($zina['dir_rate'])) $output .= '&nbsp; | ';
 182			}
 183			if (isset($zina['dir_rate'])) $output .= zt('Rate').': '.$zina['dir_rate'];
 184			$output .= '</p>';
 185		}
 186
 187		if (isset($zina['description'])) $output .= $zina['description'];
 188		if (isset($zina['podcast'])) {
 189			$type = $zina['podcast']['type'];
 190			$icon_title = ($type == 'podcast') ? zt('Podcast') : zt('RSS Feed');
 191			$output .= '<p>'.zl(ztheme('icon',$type.'.gif', $icon_title),$zina['podcast']['url'],$zina['podcast']['query']).'</p>';
 192		}
 193
 194		$output .= ztheme('addthis', $zina, 'bookmark');
 195
 196		if (isset($zina['dir_edit_opts'])) {
 197			$options = array();
 198			foreach ($zina['dir_edit_opts'] as $opt => $opts) {
 199				$options[] = zl($lang[$opt],$opts['path'], $opts['query']);
 200			}
 201			$output .= '<p class="small">';
 202			$output .= implode(' | ', $options);
 203			$output .= '</p>';
 204		}
 205
 206		$output .= '</div>';
 207
 208		if ($subdirs && $zina['subdir_images']) {
 209			$output .= '<div class="section">'.ztheme('image_list', $zina['subdirs'], $zina['subdir_cols']).'</div>';
 210		}
 211
 212		if ($altdirs) {
 213			$output .= '<div class="section">'.ztheme('image_alt_list', $zina['alt_items'], $zina['subdir_cols']).'</div>';
 214		}
 215	}
 216
 217	if (isset($zina['songs'])) $output .= '<div class="section">'.$zina['songs'].'</div>';
 218
 219	if (isset($zina['multimedia'])) {
 220		$output .= '<div class="section">'.
 221			ztheme('multimedia_section', ztheme('multimedia_list', $zina['multimedia'])).
 222			'</div>';
 223	}
 224	return $output;
 225}
 226
 227#todo: try <ul>
 228function ztheme_category($dirs, $cols, $images = false, $truncate = 25, $full_page_split = false) {
 229	$output = '';
 230	if (!empty($dirs)) {
 231
 232		if ($images) {
 233			if ($full_page_split) {
 234				$output = '';
 235				foreach($dirs as $letter => $items) {
 236					if (strlen($letter) > 3) {
 237						$output .= '<h1 class="zina-cat-letter"><a name="'.strtolower($letter).'" href="'.zurl($letter).'" class="zina-cat-letter">'.$letter.'</a></h1>';
 238					} else {
 239						$letter = ($letter == 'zzz') ? zt('Other') : $letter;
 240						$output .= '<h1 class="zina-cat-letter">'.$letter.'<a name="'.strtolower($letter).'" class="zina-cat-letter" /></h1>';
 241					}
 242					$output .= '<br style="clear:both;"/>'.ztheme('image_list_category', $items, $cols);
 243				}
 244				return $output;
 245			} else {
 246				return ztheme('image_list_category', $dirs, $cols);
 247			}
 248		}
 249
 250		$columns = $i = $row = 0;
 251		$letter_height = 3;
 252		$items = ($full_page_split) ? $full_page_split + (count($dirs)*$letter_height) : count($dirs);
 253		$rows_in_col = ceil($items/$cols);
 254		if ($rows_in_col < $cols) $cols = ceil($items/$rows_in_col);
 255		$col_width = round(100/$cols);
 256		$img_new = ztheme('icon','new.gif',zt('New'));
 257
 258		zina_set_css('inline','.catcolwidth{width:'.$col_width.'%;}');
 259
 260		$output .= '<table width="100%" class="category"><tr>';
 261
 262		if ($full_page_split) {
 263			zina_set_css('inline', 'td.catcolwidth a{margin-left:5px;}');
 264			$first = true;
 265			foreach($dirs as $letter => $dir) {
 266				$count = count($dir) + $letter_height;
 267				$row += $count;
 268
 269				if (($first || $row > $rows_in_col + ($letter_height*2)) && $columns < $cols) {
 270					$row = $count;
 271					if (!$first) $output .= '</td>';
 272					$output .= '<td class="catcolwidth'.(($cols != ++$i) ? ' category_cols' : '').'" valign="top">';
 273					$first = false;
 274					$columns++;
 275				} else {
 276					$output .= "<br/>\n";
 277				}
 278
 279				if (strlen($letter) > 3) {
 280					$output .= '<h1 class="zina-cat-letter"><a name="'.strtolower($letter).'" href="'.zurl($letter).'" class="zina-cat-letter">'.$letter.'</a></h1>';
 281				} else {
 282					$letter = ($letter == 'zzz') ? zt('Other') : $letter;
 283					$output .= '<h1 class="zina-cat-letter">'.$letter.'<a name="'.strtolower($letter).'" class="zina-cat-letter" /></h1>';
 284				}
 285
 286				foreach($dir as $key => $opts) {
 287					$title = ztheme('truncate', $opts['title'], $truncate);
 288					$output .= zl($title,$opts['path'],$opts['query']);
 289					if ($opts['new']) $output .= '&nbsp;'.$img_new;
 290					$output .= ' <br/>'."\n";
 291				}
 292			}
 293			$output .= '</td>'."\n";
 294		} else {
 295			foreach ($dirs as $opts) {
 296				if ($row == 0) {
 297					$output .= '<td class="catcolwidth'.(($cols != ++$i) ? ' category_cols' : '').'" valign="top">';
 298				}
 299				$title = ztheme('truncate', $opts['title'], $truncate);
 300				$output .= zl($title,$opts['path'],$opts['query']);
 301				if ($opts['new']) $output .= '&nbsp;'.$img_new;
 302				$output .= '<br/>'."\n";
 303
 304				$row = ++$row % $rows_in_col;
 305				if ($row == 0) $output .= '</td>';
 306			}
 307			if ($row != 0) $output .= '</td>';
 308		}
 309		$output .= '</tr></table>';
 310	}
 311	return $output;
 312}
 313
 314/*
 315 * Category Pages Navigation
 316 *
 317 * e.g. Start - First - 1 - 2 - Next - Last
 318 */
 319function ztheme_category_pages($path, $current, $total, $query='') {
 320	$output = '';
 321	if ($total > 1) {
 322		$output .= '<div class="category_pages">';
 323		if ($current != 1) {
 324			$output .= zl(ztheme('icon','first.gif',zt('First')),$path,$query.'page=1');
 325			$output .= zl(ztheme('icon','back.gif',zt('Previous')),$path,$query.'page='.($current-1));
 326		} else {
 327			$output .= ztheme('icon','first_un.gif',zt('First'));
 328			$output .= ztheme('icon','back_un.gif',zt('Previous'));
 329		}
 330		$output .= '&nbsp;';
 331		for($i=1;$i<=$total;$i++) {
 332			$arr[] = ($current == $i) ? "<strong>$i</strong>" : zl($i,$path,$query.'page='.$i);
 333		}
 334		$output .= implode(' &middot; ',$arr);
 335		$output .= '&nbsp;';
 336		if ($current == $total) {
 337			$output .= ztheme('icon','forward_un.gif',zt('Next'));
 338			$output .= ztheme('icon','last_un.gif',zt('Last'));
 339		} else {
 340			$output .= zl(ztheme('icon','forward.gif',zt('Next')),$path,$query.'page='.($current+1));
 341			$output .= zl(ztheme('icon','last.gif',zt('Last')),$path,$query.'page='.$total);
 342		}
 343		$output .= '</div>';
 344	}
 345	return $output;
 346}
 347
 348/*
 349 * Category Alphabet Navigation
 350 *
 351 * e.g. A - B - C - D...
 352 */
 353function ztheme_category_alphabet($path, $current, $letters, $query='', $full_page = false) {
 354	$output = '<div class="category_pages">';
 355	if ($full_page) {
 356		foreach ($letters as $key) {
 357			$letter = ($key == 'zzz') ? zt('Other') : $key;
 358			$links[] = zl($letter,$path,$query,strtolower($letter));
 359		}
 360	} else {
 361		foreach ($letters as $key) {
 362			$letter = ($key == 'zzz') ? zt('Other') : $key;
 363			$links[] = ($current == $key) ? "<strong>$letter</strong>" : zl($letter,$path,$query.'page='.$key);
 364		}
 365	}
 366	$output .= implode(' &middot; ',$links);
 367	return $output.'</div>';
 368}
 369
 370/*
 371 * Category Split by Alphabet helper
 372 */
 373function ztheme_category_alphabet_split($dirs, $sort_ignore) {
 374	$splits = array();
 375	foreach ($dirs as $key=>$item) {
 376		$key = $item['title'];
 377		if ($item['person']) {
 378			if (($pos = strripos($key, ' ')) !== false) {
 379				$letter = zina_strtoupper(zcheck_utf8(zina_substr($key, $pos+1,1)));
 380			} else {
 381				$letter = zina_strtoupper(zcheck_utf8($key[0]));
 382			}
 383		} else if ($sort_ignore && preg_match('/^('.$sort_ignore.')\s/i',$key, $matches)) {
 384			# ignore certain thing like "the" and "a"
 385			$letter = zina_strtoupper(zina_substr($key, zina_strlen($matches[1])+1, 1));
 386		} elseif (preg_match('/^(\W|\d)/', $key, $matches)) {
 387			# non-alpha characters get grouped together...
 388			$letter = 'zzz';
 389		} else {
 390			# upper and lowercase are same
 391			$letter = zina_strtoupper(zcheck_utf8($key[0]));
 392		}
 393		$splits[$letter][$key] = $item;
 394	}
 395	ksort($splits);
 396	return $splits;
 397}
 398
 399/*
 400 * Category Sort Alpha/Date
 401 */
 402function ztheme_category_sort($path, $cat) {
 403	$lang['asc'] = zt('Sort Ascending');
 404	$lang['desc'] = zt('Sort Descending');
 405	return '<span class="small">'.zt('Sort').': '.
 406		zl(zt('Alpha'), $path, $cat['alpha']['query']).' '.
 407		zl(ztheme('icon','sort_'.$cat['alpha']['sort'].'.gif', $lang[$cat['alpha']['sort']]), $path,$cat['alpha']['query']).
 408		'&nbsp;'.
 409		zl(zt('Date'), $path, $cat['date']['query']).' '.
 410		zl(ztheme('icon','sort_'.$cat['date']['sort'].'.gif',$lang[$cat['date']['sort']]),$path,$cat['date']['query']).'</span>';
 411}
 412
 413function ztheme_playlists_block($playlists, $truncate=25) {
 414	$output='';
 415	if ($playlists) {
 416		$output .= '<h3>'.zt('Tracks Appear On').'</h3>';
 417		$output .= ztheme('directory_list_helper', $playlists, $truncate);
 418	}
 419	return $output;
 420}
 421
 422function ztheme_directory_list($dirs, $truncate=25) {
 423	$output='';
 424	if ($dirs) {
 425		$output .= '<h3>'.zt('Albums').'</h3>';
 426		$output .= ztheme('directory_list_helper', $dirs, $truncate);
 427	}
 428	return $output;
 429}
 430
 431function ztheme_directory_alt_list($dirs, $truncate=25) {
 432	$output='';
 433	$output .= '<h3>'.zt('See Also').'</h3>';
 434	if ($dirs) {
 435		$output .= ztheme('directory_list_helper', $dirs, $truncate);
 436	}
 437	return $output;
 438}
 439
 440function ztheme_directory_list_helper($dirs, $truncate=25) {
 441	global $zc;
 442
 443	$lang['play']      = zt('Play');
 444	$lang['play_lofi'] = zt('Play Low Fidelity');
 445	$lang['download']  = zt('Download');
 446	$lang['play_rec'] = zt('Play recursively');
 447	$lang['play_rec_rand'] = zt('Play recursively random');
 448
 449	$class = "zinamp";
 450
 451	$img_new = ztheme('icon','new.gif',zt('New'));
 452	$output = '<ul>';
 453	foreach ($dirs as $opts) {
 454		$output .= '<li>';
 455		if (isset($opts['opts'])) {
 456			foreach ($opts['opts'] as $type=>$opt) {
 457				$attr = (substr($type,0,4) == 'play') ? 'class="'.$class.'"' : '';
 458				//$attr = (substr($type,0,4) == 'play') ? 'class="zinamp"' : '';
 459				$output .= zl(ztheme('icon',$type.'.gif',$lang[$type]),$opt['path'],$opt['query'], null, false, $attr);
 460			}
 461		}
 462
 463		if (isset($opts['checkbox'])) $output .= ztheme('form_checkbox', $opts['checkbox']['name'], $opts['checkbox']['value'], $opts['checkbox']['checked']).'&nbsp;';
 464
 465		$title = ztheme('truncate', $opts['title'], $truncate);
 466
 467		$output .= zl($title,$opts['path'], isset($opts['query']) ? $opts['query'] : null);
 468		if (!empty($opts['info']->year)) $output .= ' ('.$opts['info']->year.')';
 469		if ($opts['new']) $output .= '&nbsp;'.$img_new;
 470		$output .= '</li>';
 471	}
 472	$output .= '</ul>';
 473	return $output;
 474}
 475
 476function ztheme_image_list($dirs, $cols) {
 477	return '<h3>'.zt('Albums').'</h3>'.ztheme('image_list_helper', $dirs, $cols);
 478}
 479
 480function ztheme_image_alt_list($dirs, $cols) {
 481	return '<h3>'.zt('See Also').'</h3>'.ztheme('image_list_helper', $dirs, $cols);
 482}
 483
 484function ztheme_image_list_helper($dirs, $cols) {
 485	$col = 0;
 486	$col_width = round(100/$cols).'%';
 487	zina_set_css('inline', 'td.zinaimgcolwidth{width:'.$col_width.';}');
 488
 489	$align[$cols - 1] = 'right';
 490	$align[0] = 'left';
 491	for($i=1; $i < $cols - 1; $i++) $align[$i] = 'center';
 492
 493	$first = 1;
 494	$output = '<table cellpadding="5" width="100%">';
 495	foreach($dirs as $dir => $opts) {
 496		if ($col==0) {
 497			if ($first) {
 498				$output .= '<tr>';
 499				$first = false;
 500			} else {
 501				$output .= '</tr><tr>';
 502			}
 503		}
 504		#$title = $opts['title'];
 505
 506		$output .= '<td class="zinaimgcolwidth" align="'.$align[$col].'" valign="top">'.$opts['image'].'</td>';
 507		/*
 508		 * outputs a play icon over album covers
 509		$output .= '<td class="zinaimgcolwidth" align="'.$align[$col].'" valign="top">'.
 510			$opts['image'].'<span class="image-inner">'.zl(ztheme('icon','play.gif',zt('Play')),$dir,'l=8&amp;m=0').'</span></td>';
 511		 */
 512
 513		if ($col==$cols) $output .= '</tr>';
 514		$col = ++$col % $cols;
 515	}
 516
 517	if ($col <> 0 ) {
 518		for ($i = $col; $i < $cols; $i++) $output .= '<td class="zinaimgcolwidth">&nbsp;</td>';
 519	}
 520	$output .= '</tr></table>';
 521
 522	return $output;
 523}
 524
 525function ztheme_image_list_category($dirs, $cols) {
 526	$col = 0;
 527	$col_width = round(100/$cols).'%';
 528	zina_set_css('inline','.imglistcatwidth{width:'.$col_width.';}');
 529
 530	$output = '<table cellpadding="0" cellspacing="0" width="100%" class="image-list-category">';
 531	foreach($dirs as $dir => $opts) {
 532		if ($col==0) { $row = $row1 = '<tr>'; }
 533		$row .= '<td class="imglistcatwidth" align="center">'.$opts['image'].'</td>';
 534		$row1 .= '<td class="imglistcatwidth" align="center" valign="top"><h3>'.zl($opts['title'], $opts['path'], $opts['query']).'</h3></td>';
 535
 536		if (++$col==$cols) { $output .= $row.'</tr>'."\n".$row1.'</tr>'."\n"; }
 537		$col = $col % $cols;
 538	}
 539
 540	if ($col <> 0 ) {
 541		for ($i = $col; $i < $cols; $i++) {
 542			$row .= '<td class="imglistcatwidth">&nbsp;</td>';
 543			$row1 .= '<td class="imglistcatwidth">&nbsp;</td>';
 544		}
 545		$output .= $row.'</tr>'.$row1.'</tr>';
 546	}
 547	$output .= '</table>';
 548	return $output;
 549}
 550
 551#TODO: rename? and then have song_list call "generic" func? use array for opts
 552function ztheme_song_list($songs, $various = false, $images = false, $stats = false, $reorder = false, $song_info = true, $checkbox = true) {
 553	global $zc;
 554	if (empty($songs)) return '';
 555
 556	$class = "zinamp";
 557
 558	if ($reorder){
 559		zina_add_tabledrag('table-playlist', 'order', 'sibling', 'order');
 560		zina_set_css('file', 'extras/tabledrag.css');
 561		$table_id = ' id="table-playlist"';
 562		$row_class = 'draggable ';
 563		$row_id = ' id="order"';
 564		$row_order = true;
 565	} else {
 566		$table_id = $row_class = $row_id = '';
 567		$row_order = false;
 568	}
 569	$img_new = ztheme('icon','new.gif',zt('New'));
 570	$lang['download']  = zt('Download');
 571	$lang['play']      = zt('Play');
 572	$lang['play_lofi'] = zt('Play Low Fidelity');
 573	$lang['edit']      = zt('Edit');
 574	$lang['more']      = zt('More');
 575	#remove next two - > used to be for playlists...test?
 576	$lang['rename']    = zt('Rename');
 577	$lang['delete']    = zt('Delete');
 578
 579	$lang['play_lofi'] = zt('Play low fidelity');
 580	$lang['play_lofi_custom'] = zt('Play custom low fidelity');
 581	$lang['play_rec'] = zt('Play recursively');
 582	$lang['play_rec_rand'] = zt('Play recursively random');
 583
 584	$i = $stat_prev = 0;
 585	$p = 1;
 586
 587	$output = '<table cellpadding="5" cellspacing="0" width="100%"'.$table_id.'>';
 588
 589	foreach($songs as $song) {
 590		#todo: $class = ++$i % 2 == 0 ? 'even' : 'odd';
 591		$v = (isset($song['description']) && !$images) ? ' valign="top"' : '';
 592		$output .= '<tr class="'.$row_class.'row'.$i.'"'.$v.$row_id.'>';
 593		if ($row_order) $output .= '<td></td><td style="display:none;"><input type="hidden" name="order[]" value="'.($p).'" size="2" class="order" /></td>';
 594		$output .= '<td class="song'.$i.' nowrap">';
 595
 596		if (isset($song['opts'])) {
 597			foreach ($song['opts'] as $type=>$opt) {
 598				$attr = (substr($type,0,4) == 'play') ? ' class="'.$class.'"' : '';
 599				$output .= zl(ztheme('icon',$type.'.gif',$lang[$type]),$opt['path'],$opt['query'], null, false, $attr);
 600			}
 601		}
 602		if (isset($song['extras'])) {
 603			foreach ($song['extras'] as $type=>$extra) {
 604				$output .= zl(ztheme('icon',$type.'.gif',$extra['text']),$extra['path'],$extra['query'],NULL,FALSE,$extra['attr']);
 605			}
 606		}
 607		$output .= '</td>';
 608
 609		if (isset($song['opts_edit']) || isset($song['extras_edit'])) {
 610			$output .= '<td class="song'.$i.' nowrap">';
 611			if (isset($song['opts_edit'])) {
 612				foreach ($song['opts_edit'] as $type=>$opt) {
 613					$output .= zl(ztheme('icon',$type.'.gif',$lang[$type]),$opt['path'],$opt['query']);
 614				}
 615			}
 616			if (isset($song['extras_edit'])) {
 617				foreach ($song['extras_edit'] as $type=>$extra) {
 618					$output .= zl(ztheme('icon',$type.'_edit.gif',$extra['text']),$extra['path'],$extra['query'],NULL,FALSE,$extra['attr']);
 619				}
 620			}
 621			if (isset($song['delete'])) {
 622				$type = 'delete';
 623				$output .= zl(ztheme('icon',$type.'.gif',$lang[$type], $lang[$type], " onclick='return(confirm(\"".zt('Delete file?')."\"));'"),$song['delete']['path'],$song['delete']['query']);
 624			}
 625			$output .= '</td>';
 626		}
 627		if ($checkbox) {
 628			$output .= '<td class="song'.$i.' nowrap">';
 629			if (isset($song['checkbox']) && $song['checkbox']) {
 630				$output .= ztheme('form_checkbox', $song['checkbox']['name'], $song['checkbox']['value'], $song['checkbox']['checked']);
 631			}
 632			$output .= '</td>';
 633		}
 634		#if (isset($song['track'])) $output .= '</td><td align="right" class="song'.$i.' nowrap">'. $song['track'];
 635
 636		if ($images) {
 637			$output .= '<td class="song'.$i.'"'.$v.'>';
 638			if (isset($song['image']) && !empty($song['image'])) {
 639				$output .= '<div class="search-results">';
 640				#if (isset($song['title_link'])) {
 641				#	$output .= zl($song['image'],$song['title_link']['path'],$song['title_link']['query']);
 642				if (isset($song['image_link'])) {
 643					$output .= zl($song['image'],$song['image_link']['path'],$song['image_link']['query']);
 644				} else {
 645					$output .= $song['image'];
 646				}
 647				$output .= '</div>';
 648			}
 649			$output .= '</td>';
 650		}
 651
 652		$td = '<td align="right" class="song_info'.$i.' nowrap"'.$v.'>';
 653
 654		if ($stats) {
 655			$output .= $td.(($stat_prev == $song['stat']) ? '' : $p.'.').'</td>';
 656			$stat_prev = $song['stat'];
 657		}
 658
 659		$output .= '<td class="song'.$i.' fullwidth"'.$v.'>';
 660		$title = $song['title'];
 661
 662		if ($various) {
 663			if (isset($song['info']->artist)) $title = $song['info']->artist.' - '.$title;
 664		}
 665		if (isset($song['title_link'])) {
 666			$output .= zl($title,$song['title_link']['path'],$song['title_link']['query'], null, false, isset($song['title_link']['attr']) ? $song['title_link']['attr'] : '');
 667		} else {
 668			$output .= '<span class="song_title">'.$title.'</span>';
 669		}
 670		if ($song['new']) $output .= $img_new;
 671		if (isset($song['description']) && !empty($song['description'])) {
 672			$output .= '<br/><span class="song_blurb'.$i.'">'.$song['description'].'</span>';
 673		}
 674		if (isset($song['options'])) {
 675			$output .= '<br/><span class="song_blurb'.$i.'"><small>'.implode(' | ', $song['options']).'</small></span>';
 676		}
 677		$output .= '</td>';
 678
 679		if ($stats) {
 680			if ($song['stat_type'] == 'votes' || $song['stat_type'] == 'rating') {
 681				$output .= $td.'<span class="zina-rating">'.ztheme('votes_display',$song['votes']).'</span></td>';
 682				$output .= '<td class="song_info'.$i.' nowrap"'.$v.'>'.ztheme('rating_display', $song['stat']).'</td>';
 683			} elseif ($song['stat_type'] == 'latest' || $song['stat_type'] == 'added') {
 684				$output .= $td.ztheme('stat_date', $song['stat']).'</td>';
 685			} else {
 686				$output .= $td.number_format($song['stat']).'</td>';
 687			}
 688		} else {
 689			if ($song['ratings']) {
 690				$output .= $td.'<span class="zina-rating">'.ztheme('votes_display',$song['sum_votes']).'</span></td>';
 691				$output .= '<td class="song_info'.$i.' nowrap"'.$v.'>'.
 692					'<div class="stars-song">'.ztheme('rating_display', $song['sum_rating']).'</div></td>';
 693
 694				if (isset($song['full_path']))
 695					$output .= $td.'<div class="stars-song">'.ztheme('vote', zina_get_vote_url($song['full_path']), $song['user_rating']).'</div></td>';
 696				else
 697					$output .= $td.'&nbsp;'.'</td>';
 698				/*
 699				 * If you are using statistics, there are also
 700				 * $song['sum_plays'] & $songs['sum_downloads']
 701				 */
 702			} else {
 703				$output .= $td.'&nbsp;'.'</td>';
 704				$output .= $td.'&nbsp;'.'</td>';
 705				$output .= $td.'&nbsp;'.'</td>';
 706			}
 707			if ($song_info) {
 708				if (isset($song['info']->info)) {
 709					$info = &$song['info'];
 710					$output .= $td.((isset($info->time) && !empty($info->time)) ? $info->time : '&nbsp;').'</td>';
 711					$output .= $td.((isset($info->bitrate) && !empty($info->bitrate)) ? $info->bitrate.' kbps' : '&nbsp;').'</td>';
 712					$output .= $td.((isset($info->frequency) && !empty($info->frequency)) ? round($info->frequency/1000,1).' kHz' : '&nbsp;').'</td>';
 713					$output .= $td.((isset($info->filesize) && !empty($info->filesize)) ? sprintf("%.2f", round($info->filesize/1000000,2)).' Mb' : '&nbsp;').'</td>';
 714				} else {
 715					$output .= $td.'</td>';
 716					$output .= $td.'</td>';
 717					$output .= $td.'</td>';
 718					$output .= $td.((isset($song['info']->filesize)) ? sprintf("%.2f", round($song['info']->filesize/1000000,2)).' Mb' : '&nbsp;').'</td>';
 719				}
 720			}
 721		}
 722		$output .= '</tr>'."\n";
 723		$i = ++$i % 2;
 724		$p++;
 725	}
 726	zevenodd($i);
 727	$output .= '</table>';
 728	return $output;
 729}
 730
 731function ztheme_stats_form_select($action, $selects) {
 732	$form = '<form id="sform" method="post" action="'.$action.'" class="z_small"><div>';
 733	$form .= '<strong>'.zt('Statistic').': </strong>';
 734
 735	foreach($selects as $name=>$select) {
 736		$form .= '<select class="z_form_select" name="'.$name.'" onchange=\'this.form.submit();\'>';
 737		foreach($select['options'] as $key=>$value) {
 738			$sel = ($key == $select['default']) ? ' selected="selected"' : '';
 739			$form .= '<option value="'.$key.'"'.$sel.'>'.$value.'</option>';
 740		}
 741		$form .= '</select>';
 742	}
 743	$form .= ' '.zl(ztheme('icon','more.gif',zt('More')),"javascript:document.forms.sform.submit();").'</div></form>';
 744	return $form;
 745}
 746
 747function ztheme_stats_list($items, $various = false, $images = false) {
 748	return ztheme_song_list($items, $various, $images, true);
 749}
 750
 751function ztheme_breadcrumb($links) {
 752	return (!empty($links)) ? implode(' &gt;&nbsp;',$links) : '';
 753}
 754
 755function ztheme_breadcrumb_home($links) {
 756	return implode(' / ', $links);
 757}
 758
 759function ztheme_page_title($links) {
 760	#return implode(' &#8226; ',$links);
 761	return  implode(' &middot; ',$links);
 762}
 763
 764function ztheme_search_song_titles($titles) {
 765	return implode(' / ', $titles);
 766}
 767
 768/*
 769 * Theme file to use for missing image
 770 * $type is 'dir' or 'sub'
 771 */
 772function ztheme_missing_image($type) {
 773	return 'missing_'.$type.'.jpg';
 774}
 775
 776/*
 777 * Theme for rating (currently "stars")
 778 * $rating is float with one decimal place, e.g. 4.5
 779 */
 780function ztheme_rating_display($rating) {
 781	$output='';
 782	if ($rating > 0) {
 783		$output .= '<span class="stars">';
 784		$star = ztheme('icon','star.gif','*');
 785		$rating = number_format($rating,1);
 786		$arr = explode('.',$rating);
 787		$output .= str_repeat($star, $arr[0]);
 788		if ($arr[1] >= 5) $output .= ztheme('icon','star-half.gif','�');
 789		$output .= '</span>';
 790	}
 791	return $output;
 792}
 793
 794/*
 795 * Theme for voting
 796 *
 797 * currently "stars" and utilizes ajax
 798 */
 799function ztheme_vote($url, $user_rating = 0) {
 800	static $num = 0;
 801	if ($num == 0) zina_set_js('vars', ztheme('vote_js').'var zv=new Array();');
 802	$pr = 'zv'.$num;
 803
 804	zina_set_js('vars', 'zv['.$num.']=\''.$url.'\';');
 805	$remove = '';
 806	if ($user_rating > 0) {
 807		$remove = zl(ztheme('icon','delete.gif',zt('Remove Vote')),'javascript: void 0;', null, null, null, ' onclick="ajax(zv['.$num.']+\'0\',\'span'.$pr.'\');"');
 808	}
 809
 810	$output = '<span id="span'.$pr.'">'.$remove.ztheme('icon','stars-0.gif',NULL,NULL,'id="'.$pr.'" height="14" width="70" usemap="#'.$pr.'map"').
 811		'</span>'.
 812		'<map name="'.$pr.'map" id="'.$pr.'map">';
 813	for($i=1;$i<=5;$i++) {
 814		$output .= '<area coords="'.(($i-1)*14).',0,'.($i*14).',14" onmouseover="imgOn(\''.$pr.'\','.$i.
 815			');" onmouseout="imgOff(\''.$pr.'\');" title="'.$i.'" alt="'.$i.'" '.
 816			'href="javascript: void 0;" onclick="vote(\''.$pr.'\','.$i.');ajax('.
 817			'zv['.$num.']+\''.$i.'\',\'span'.$pr.'\');" />';
 818	}
 819	$output .= '</map>';
 820	if ($user_rating > 0) $output .= '<script type="text/javascript">vote(\''.$pr.'\','.$user_rating.');</script>';
 821	$num++;
 822	return $output;
 823}
 824
 825/*
 826 * Star voting javascript
 827 *
 828 * gets put in html head
 829 */
 830function ztheme_vote_js() {
 831	$theme = zpath_to_theme().'/icons/stars-';
 832	$output = '';
 833
 834	for($i=0;$i<=5;$i++) {
 835		$output .= "onImgArr[$i]=new Image(70,14);onImgArr[$i].src=zImgBase+'$i.gif';";
 836	}
 837
 838	return 'var onImgArr=new Array();var zImgBase=\''.$theme.'\';'.
 839		$output.'var aVote=new Array();'.
 840		'function imgOn(img,i){if(aVote[img]==null)document.getElementById(img).src=onImgArr[i].src;}'.
 841		'function imgOff(img){if(aVote[img]==null)document.getElementById(img).src=zImgBase+\'0.gif\';}'.
 842		'function vote(img,i){aVote[img]=null;imgOn(img,i);aVote[img]=i;}';
 843}
 844/*
 845 * Voting plurality
 846 *
 847 * "(1 vote)" or "(2 votes)"
 848 */
 849function ztheme_votes_display($votes) {
 850	if (!empty($votes)) {
 851		return ' ('.$votes.' '.(($votes == 1) ? zt('vote') : zt('votes')) .')';
 852	}
 853	return '';
 854}
 855
 856function ztheme_genres($dirs, $cols, $images, $truncate, $zina, $navigation = false, $full_page_split = false) {
 857	$output = '';
 858	if (!empty($zina['messages'])) $output .= '<div id="zina_messages">'.$zina['messages'].'</div>';
 859	if ($navigation) $output .= $navigation;
 860
 861	$output .= ztheme('category', $dirs, $cols, $images, $truncate, $full_page_split);
 862	return $output;
 863}
 864
 865function ztheme_multimedia_section($list) {
 866	return '<h3>'.zt('Multimedia').'</h3>'.$list;
 867}
 868
 869function ztheme_image_missing_nav($select, $close) {
 870	return zt('Directories with no image:').$select.zl(zt('Close'), $close['path'], $close['query']).'<br/><br/>';
 871}
 872
 873function ztheme_edit_images_page($title, $images, $new, $missing_navigation = '') {
 874	$output = '';
 875
 876	if (!empty($missing_navigation)) $output .= $missing_navigation;
 877
 878	if (!empty($images)) {
 879		$output .= '<div class="section">'.
 880			'<h3>'.zt('Current Images').'</h3>'.
 881			ztheme('image_list_helper', $images, 3).
 882			'</div>';
 883	}
 884
 885	if (!empty($new)) {
 886		$output .= '<div class="section"><h3>'.zt('Remote Images').'</h3>';
 887		foreach($new as $opt) {
 888			$output .= $opt['image'];
 889		}
 890	}
 891
 892	return $output;
 893}
 894
 895function ztheme_addthis($zina, $type = 'bookmark') {
 896	global $zc;
 897	static $first = true;
 898
 899	$output = '';
 900	if ($zina['addthis']) {
 901		if ($first) {
 902			$output .= '<script type="text/javascript" src="http://s7.addthis.com/js/250/addthis_widget.js"></script>';
 903			zina_set_js('vars', 'var addthis_pub = "'.$zina['addthis_id'].'";');
 904			if (!empty($zina['site_name'])) zina_set_js('vars', 'var addthis_brand = "'.$zina['site_name'].'";');
 905			$first = false;
 906		}
 907
 908		$source = zurl($zina['addthis_path'], $zina['addthis_query'], null, true);
 909
 910		if ($type == 'feed') {
 911			$output .= ' <a href="http://www.addthis.com/feed.php" '.
 912     			'onclick="return addthis_open(this, \'feed\', \''.$source.'\')">' .
 913     			'<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>';
 914		} else { # bookmark
 915			$output .= '<p><a href="http://www.addthis.com/bookmark.php" '.
 916				'onmouseover="return addthis_open(this,\'\',\''.$source.'\',\''.$zina['title'].'\');" '.
 917				'onmouseout="addthis_close();" '.
 918				'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>';
 919		}
 920	}
 921
 922	return $output;
 923}
 924
 925function ztheme_stats_page($form_attr, $stats, $stat_opts, $zina) {
 926	$output = '';
 927
 928	$output .= '<div class="clear-block" style="margin-bottom:20px;">'.$zina['statsformselect'].'</div>';
 929	if (empty($stats)) {
 930		$output .= '<h3>'.zt('No data found for this period.').'</h3>';
 931	} else {
 932		$output .= ztheme('form', $form_attr, $stats.'<div class="section">'.$stat_opts.'</div>');
 933	}
 934	return $output;
 935}
 936
 937function ztheme_stats_section($title, $list, $type, $zina, $rss_title = '', $rss_path = false) {
 938	if ($rss_path) {
 939		$rss_icon = ($type == 'song') ? 'podcast.gif' : 'rss.png';
 940
 941		$zina['addthis_path'] = $rss_path;
 942		$zina['addthis_query'] = null;
 943
 944		$addthis = ztheme('addthis', $zina, 'feed');
 945
 946		return '<div class="section"><div class="stats">'.
 947			'<div class="stats-left"><h3>'.$title.'</h3></div>'.
 948			'<div class="stats-right">'.zl(ztheme('icon', $rss_icon, $rss_title),$rss_path).$addthis.'</div></div>'.
 949			$list.'</div>';
 950
 951	} else {
 952		return '<div class="section"><h3>'.$title.'</h3>'.$list.'</div>';
 953	}
 954}
 955
 956function ztheme_stat_date($time) {
 957	return date("M j, Y g:i a", $time);
 958}
 959
 960/*
 961 * NEXT THREE FUNCTIONS:
 962 * Take an array, expect an array back
 963 *  - unset ones you don't want
 964 *  - reorder, change text, etc.
 965 */
 966function ztheme_stats_pages($pages) { return $pages; }
 967function ztheme_stats_periods($periods) { return $periods; }
 968function ztheme_stats_types($types) { return $types; }
 969
 970function ztheme_stats_list_opts($items, $form) {
 971	return ztheme('song_list_opts',$items, $form);
 972}
 973
 974function ztheme_search_list($items, $images = false) {
 975	return ztheme('song_list',$items, false, $images);
 976}
 977
 978function ztheme_playlist_list($items, $images = false, $reorder = false) {
 979	return ztheme('song_list',$items, false, $images, false, $reorder, false);
 980}
 981
 982function ztheme_playlists_list_db($items, $count, $navigation, $action, $form_attr, $list_opts, $selected = false, $checkbox = false) {
 983	$output = '';
 984
 985	if ($count > 0) {
 986		if ($navigation) $output .= $navigation;
 987		$output .= '<table class="search-header"><tr><td align="left">'.
 988			'<em>'.zt('@total Playlists', array('@total'=>$count)).'</em></td>';
 989		if ($selected) $output .= '<td align="right" style="text-align:right;">'.ztheme('playlist_header', $action, $selected).'</td>';
 990		$output .= '</tr></table>';
 991	}
 992	$list = ztheme('song_list',$items, false, true, false, false, false, $checkbox);
 993	return $output.ztheme('form', $form_attr, $list.$list_opts);
 994
 995	#return $output.ztheme('song_list',$items, false, true, false, false, false, $checkbox);
 996}
 997
 998function ztheme_playlists_list($items, $zina, $reorder = false) {
 999	global $zc;
1000	if (empty($items)) return '';
1001
1002	if ($reorder) {
1003		zina_add_tabledrag('table-playlist', 'order', 'sibling', 'order');
1004		zina_set_css('file', 'extras/tabledrag.css');
1005	}
1006
1007	$class = "zinamp";
1008
1009	$songs = &$items;
1010	zina_set_css('inline', '.zinaplswidthA{width:90px;}.zinaplswidthB{width:20px}');
1011
1012	$lang['download']  = zt('Download');
1013	$lang['play']      = zt('Play');
1014	$lang['more']      = zt('More');
1015	$lang['rename']    = zt('Rename');
1016	$lang['delete']    = zt('Delete');
1017	$lang['play_rec_rand'] = zt('Play random');
1018
1019	$i = 0;
1020	$j = 1;
1021	$output = '';
1022	$output .= '<table cellpadding="5" cellspacing="0" id="table-playlist">';
1023	foreach($songs as $song) {
1024		$v = (isset($song['description'])) ? ' valign="top"' : '';
1025		$output .= '<tr class="draggable row'.$i.'"'.$v.' id="order'.($j).'"><td class="song'.$i.' zinaplswidthA nowrap">';
1026		if (isset($song['opts'])) {
1027			foreach ($song['opts'] as $type=>$opt) {
1028				$attr = (substr($type,0,4) == 'play') ? "class='$class'" : '';
1029				$output .= zl(ztheme('icon',$type.'.gif',$lang[$type]),$opt['path'],$opt['query'], null, false, $attr);
1030			}
1031		}
1032
1033		if (isset($song['checkbox'])) {
1034			$output .= '</td><td class="song'.$i.' zinaplswidthB nowrap">'.
1035				ztheme('form_checkbox', $song['checkbox']['name'], $song['checkbox']['value'], $song['checkbox']['checked']).'</td>'.
1036				'<td style="display:none;"><input type="hidden" name="order[]" value="'.($j).'" size="2" class="order" />';
1037		}
1038		$output .= '</td><td class="song'.$i.'"'.$v.'>';
1039
1040		$title = $song['title'];
1041
1042		if (isset($song['title_link'])) {
1043			$output .= zl($title,$song['title_link']['path'],$song['title_link']['query']);
1044		} else {
1045			$output .= $title;
1046		}
1047		if (isset($song['description'])) $output.= '<br/>'.$song['description'];
1048		$output .= '</td>';
1049		$output .= '</tr>';
1050		$i = ++$i % 2;
1051		$j++;
1052	}
1053	zevenodd($i);
1054	$output .= '</table>';
1055
1056	return $output;
1057}
1058
1059function ztheme_form_checkbox($name, $value, $check = false) {
1060	$checked = ($check) ? ' checked="checked"' : '';
1061	return '<input type="checkbox" name="'.$name.'" value="'.$value.'"'.$checked.'/>';
1062}
1063
1064function ztheme_form_hidden($name, $value) {
1065	return '<input type="hidden" name="'.$name.'" value="'.$value.'"/>';
1066}
1067
1068function ztheme_multimedia_list($items) {
1069	if (empty($items)) return '';
1070	$img_new = ztheme('icon','new.gif',zt('New'));
1071	$lang['edit'] = zt('Edit');
1072
1073	$i = 0;
1074	$output = '<table cellpadding="5" cellspacing="0" width="100%">';
1075	foreach($items as $song) {
1076		$v = (isset($song['description'])) ? ' valign="top"' : '';
1077		$output .= '<tr class="row'.$i.'"'.$v.'><td class="song'.$i.' nowrap">';
1078		if (isset($song['opts'])) {
1079			if (isset($song['opts']['play']) && $song['opts']['play']['local']) {
1080				$output .= zl(ztheme('icon','mm/'.$song['ext'].'.gif',zt('Play')),$song['opts']['play']['path'],$song['opts']['play']['query']);
1081			}
1082			if (isset($song['opts']['download'])) {
1083				$icon = (isset($song['opts']['play']) && $song['opts']['play']['local']) ? 'download' : 'mm/'.$song['ext'];
1084				$output .= zl(ztheme('icon',$icon.'.gif',zt('Download')),$song['opts']['download']['path'],$song['opts']['download']['query']);
1085			}
1086		}
1087
1088		if (isset($song['opts_edit'])) {
1089			$output .= '</td><td class="song'.$i.' nowrap">';
1090			foreach ($song['opts_edit'] as $type=>$opt) {
1091				$output .= zl(ztheme('icon',$type.'.gif',$lang[$type]),$opt['path'],$opt['query']);
1092			}
1093		}
1094
1095		$output .= '</td><td class="song'.$i.' fullwidth"'.$v.'>';
1096		$title = $song['title'];
1097
1098		if (isset($song['title_link'])) {
1099			$output .= zl($title,$song['title_link']['path'],$song['title_link']['query']);
1100		} else {
1101			$output .= $title;
1102		}
1103		if ($song['new']) $output .= $img_new;
1104		if (isset($song['description'])) {
1105			$output .= '<br/><span class="song_blurb'.$i.'">'.$song['description'].'</span>';
1106		}
1107		$output .= '</td>';
1108		$output .= '</tr>';
1109		$i = ++$i % 2;
1110	}
1111	zevenodd($i);
1112	$output .= '</table>';
1113	return $output;
1114}
1115
1116function ztheme_playlists_section($page,$form_attr,$list,$list_opts, $opts = array()) {
1117
1118	$lang['play'] = zt('Play');
1119	$lang['playlist'] = zt('View Playlists');
1120	$lang['rename'] = zt('Rename');
1121	$lang['delete'] = zt('Delete');
1122	$output = '';
1123
1124	$output .= '<div class="genre-page clear-block">';
1125	if ($page['image']) $output .= $page['image'];
1126
1127	if ($opts['user']) {
1128		$lang['download']  = zt('Download');
1129		$lang['play']      = zt('Play');
1130		$lang['play_lofi'] = zt('Play Low Fidelity');
1131		$lang['play_rec_rand'] = zt('Play random');
1132
1133		$output .= '<p>';
1134		$items = &$opts['user'];
1135		foreach($items as $type=>$opt) {
1136			$output.= zl(ztheme('icon',$type.'.gif',$lang[$type]),$items[$type]['path'],$items[$type]['query'],NULL,FALSE,$items[$type]['attr']);
1137		}
1138		$output .= zl(zt('Play @pls Playlist', array('@pls'=>$page['title'])),$items['play']['path'], $items['play']['query'], null, false, $items['play']['attr']).
1139			'</p>';
1140	}
1141
1142	$votes = (isset($page['pls_ratings']) && $page['sum_votes'] > 0);
1143	if ($votes || isset($page['pls_rate_output'])) {
1144		$output .= '<p class="small">';
1145		if ($votes) {
1146			$output .= ztheme('rating_display', $page['sum_rating']).
1147				ztheme('votes_display',$page['sum_votes']);
1148			if (isset($page['pls_rate_output'])) $output .= '&nbsp; | ';
1149		}
1150		if (isset($page['pls_rate_output'])) $output .= zt('Rate').': '.$page['pls_rate_output'];
1151		$output .= '</p>';
1152	}
1153
1154	if (isset($page['description']) && !empty($page['description'])) {
1155		$output .= '<p>'.$page['description'].'</p>';
1156	}
1157
1158	if (isset($page['podcast'])) {
1159		$type = $page['podcast']['type'];
1160		$icon_title = ($type == 'podcast') ? zt('Podcast') : zt('RSS Feed');
1161		$output .= '<p>'.zl(ztheme('icon',$type.'.gif', $icon_title),$page['podcast']['url'],$page['podcast']['query']).'</p>';
1162	}
1163
1164	$output .= ztheme('addthis', $page, 'bookmark');
1165
1166	$date = (!empty($page['date_created'])) ? zina_date('F j, Y', $page['date_created']) : null;
1167
1168	$output .= '<p class="small">';
1169	if (isset($page['username'])) {
1170		$name = (isset($page['profile_url'])) ? '<a href="'.$page['profile_url'].'">'.$page['username'].'</a>' : $page['username'];
1171		if (!empty($date)) {
1172			$output.= zt('Created by !name on @date.', array('!name'=>$name, '@date'=>$date));
1173		}
1174	} else {
1175		if (!empty($date)) {
1176			$output.= zt('Created on @date.', array('@date'=>$date));
1177		}
1178	}
1179	if (isset($page['sum_views'])) $output .= ' '.zt('Viewed @num times.', array('@num'=>$page['sum_views']));
1180	if (isset($page['sum_plays'])) $output .= ' '.zt('Played @num times.', array('@num'=>$page['sum_plays']));
1181	$output .= '</p>';
1182
1183	$admin = &$opts['admin'];
1184	if ($admin['edit'] || $admin['delete']) {
1185		$output .= '<p class="small">';
1186		if ($admin['edit']) $output .= zl(zt('Edit Playlist'),$admin['edit']['path'], $admin['edit']['query']).' | ';
1187		if ($admin['delete']) $output .= zl(zt('Delete Playlist'),$admin['delete']['path'], $admin['delete']['query']);
1188		$output .= '</p>';
1189	}
1190	$output .= '</div>';
1191
1192	if ($page['count'] > 0) {
1193		$output .= '<table class="search-header"><tr><td align="left">'.
1194			'<em>'.zt('@total Items', array('@total'=>$page['count'])).'</em></td>';
1195		#if ($selected) $output .= '<td align="right">'.ztheme('search_header', 'XXX', $genre, $action, $selected).'</td>';
1196		$output .= '</tr></table>';
1197	}
1198
1199	$output .= ztheme('form', $form_attr, $list.$list_opts);
1200	return $output;
1201}
1202
1203function ztheme_form($attr, $content, $method = 'post') {
1204	return '<form method="'.$method.'" '.$attr.'><div>'.$content.zina_get_form_token().'</div></form>';
1205}
1206
1207function ztheme_song_section($form_attr,$song_list,$song_list_opts) {
1208	return '<h3>'.zt('Songs').'</h3>'.ztheme('form', $form_attr, $song_list.$song_list_opts);
1209}
1210
1211function ztheme_search_page($term, $results, $total, $navigation, $form_attr, $list, $list_opts, $action, $selected, $zina) {
1212	$output = '';
1213	$output .= '<h3>'.zt('Search Results').'</h3>';
1214	if (empty($results)) {
1215		$output .= '<p><em>'.zt('0 total items found').'</em></p>';
1216	} else {
1217		if ($navigation) $output .= $navigation;
1218		$output .= '<table class="search-header"><tr><td align="left">';
1219		$output .= '<em>'.zt('@total items found', array('@total'=>$total)).'</em>';
1220		$output .= '</td>';
1221		if ($selected) $output .= '<td align="right">'.ztheme('search_header', 'search', $term, $action, $selected).'</td>';
1222		$output .= '</tr></table>';
1223
1224		$output .= ztheme('form', $form_attr, $list.$list_opts);
1225	}
1226	return $output;
1227}
1228
1229function ztheme_year_page($term, $results, $total, $search_navigation, $navigation, $form_attr, $list, $list_opts, $opts, $action, $selected, $zina) {
1230	return ztheme('genres_page',$term, $results, $total, $search_navigation, $navigation, $form_attr, $list, $list_opts, $opts, $action, $selected, $zina);
1231}
1232
1233function ztheme_genres_page($genre, $results, $total, $navigation, $genre_navigation, $form_attr, $list, $list_opts, $opts, $action, $selected, $zina) {
1234	global $zc;
1235
1236	$class="zinamp";
1237
1238	$output = '';
1239	if (!empty($zina['messages'])) $output .= '<div id="zina_messages">'.$zina['messages'].'</div>';
1240
1241	$output .= '<div class="genre-page clear-block">';
1242	if ($opts['image']) $output .= ztheme('image', zina_get_genre_image_path($genre), $genre, null, 'class="genre-image"');
1243	if ($genre_navigation) $output .= '<div class="genre-select">'.$genre_navigation.'</div>';
1244	$output .= '<p>'.
1245		zl(ztheme('icon','play.gif',zt('Play')),'',$opts['play_query'], null, false, "class='$class'").
1246		zl(zt('Play @genre', array('@genre'=>$genre)),'', $opts['play_query'], null, false, "class='$class'").
1247		'</p>';
1248
1249	if ($opts['description'] && !empty($opts['description'])) {
1250		$output .= '<p>'.$opts['description'].'</p>';
1251	}
1252	if ($opts['genre_edit']) {
1253		$output .= '<p class="small">'.zl(zt('Edit Genre'),$opts['genre_edit']['path'], $opts['genre_edit']['query']).'</p>';
1254	}
1255
1256	$output .= '</div>';
1257
1258	if (isset($zina['subgenres'])) {
1259		$output .= '<table class="search-header"><tr><td align="left"><h3>'.zt('Genre Family').'</h3></td></tr></table>';
1260		$output .= $zina['subgenres'];
1261	}
1262
1263	$output .= '<table class="search-header"><tr><td align="left" width="30%">';
1264	$output .= '<em>'.zt('@total items found', array('@total'=>$total)).'</em>';
1265	$output .= '</td><td>'.(($navigation) ? $navigation : '').'</td>';
1266	$output .= '<td align="right" width="30%">';
1267	if ($selected) $output .= ztheme('search_header', $zina['search_page_type'], $genre, $action, $selected);
1268	$output .= '</td></tr></table>';
1269
1270	if (empty($results) || $selected['type'] == 'artist') $list_opts = '';
1271
1272	$output .= ztheme('form', $form_attr, $list.$list_opts);
1273	return $output;
1274}
1275
1276function ztheme_playlist_list_opts($items, $form) {
1277	if (empty($items)) return '';
1278	if (empty($items['submit']) && empty($items['checkbox']) && !isset($items['playlist_form_elements'])) return '';
1279	$submit = ($items['submit']) ?  '<input type="submit" value="'.zt('Update Playlist').'"/>' : '';
1280	if ($items['checkbox']) {
1281		$checkbox = ' '.zt('Check').': &nbsp;'.
1282		zl(zt('All'),'javascript: void 0;',NULL,NULL,FALSE,' onclick="CheckBoxes(\''.$form.'\',true);"').' | '.
1283		zl(zt('None'),'javascript:void 0;',NULL,NULL,FALSE,' onclick="CheckBoxes(\''.$form.'\',false);"');
1284	} else {
1285		$checkbox = '';
1286	}
1287
1288	$output = '<table cellpadding="5" cellspacing="0" width="100%"><tr class="row'.zevenodd().'">';
1289	$output .= '<td>'.$submit.$checkbox.'</td>';
1290	$output .= '<td align="right">'.((isset($items['playlist_form_elements'])) ? $items['playlist_form_elements'] : '&nbsp;').'</td>';
1291	$output .= '</tr></table>';
1292
1293	return $output;
1294}
1295
1296function ztheme_search_list_opts($items, $form) {
1297	return ztheme('song_list_opts',$items, $form);
1298}
1299
1300function ztheme_song_list_opts($items, $form) {
1301	if (empty($items)) return '';
1302
1303	$output = '<table cellpadding="5" cellspacing="0" width="100%"><tr class="row'.zevenodd().'">';
1304	if (isset($items['checkboxes'])) {
1305		$submit = '';
1306		if (isset($items['submit'])) {
1307			$val = ($items['submit']['exists']) ? zt('Update custom playlist') : zt('Create custom playlist');
1308			$submit = '<input type="submit" value="'.$val.'" onclick="'.$items['submit']['js'].'"/>&nbsp;';
1309		}
1310		$output .= '<td>'.$submit.zt('Check').': &nbsp;'.
1311			zl(zt('All'),'javascript: void 0;',NULL,NULL,FALSE,' onclick="CheckBoxes(\''.$form.'\',true);"').' | '.
1312			zl(zt('None'),'javascript:void 0;',NULL,NULL,FALSE,' onclick="CheckBoxes(\''.$form.'\',false);"').'</td>';
1313	}
1314
1315	if (isset($items['opts'])) {
1316		$lang['download'] = zt('Download');
1317		$lang['play'] = zt('Play');
1318		$lang['play_lofi'] = zt('Play Low Fidelity');
1319		$lang['play_rec_rand'] = zt('Play random');
1320
1321		$output .= '<td >'.zt('Selected').': ';
1322		foreach($items['opts'] as $type=>$opt) {
1323			$output.= zl(ztheme('icon',$type.'.gif',$lang[$type]),$opt['path'],$opt['query'],NULL,FALSE,$opt['attr']);
1324		}
1325		$output .= '</td>';
1326	}
1327	$output .= '<td align="right">'.((isset($items['playlist_form_elements'])) ? $items['playlist_form_elements'] : '&nbsp;').'</td>';
1328	$output .= '</tr></table>';
1329	return $output;
1330}
1331
1332function ztheme_song_extra($type, $title, $content, $url = false) {
1333	if ($url) {
1334		$content = zt('Loading...');
1335		zina_set_js('jquery', '$("p#zina-'.$type.'").load("'.$url.'");');
1336

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