From 65663a24f14bf544c8391c169239d0811eed4ffb Mon Sep 17 00:00:00 2001 From: Karl 'vollmerk' Vollmer Date: Mon, 27 Jun 2005 08:40:23 +0000 Subject: move and break, move and break --- lib/album.lib.php | 31 + lib/album.php | 31 - lib/archive.lib.php | 778 ++++++++++++++++++ lib/archive.php | 778 ------------------ lib/artist.lib.php | 122 +++ lib/artist.php | 122 --- lib/batch.lib.php | 66 ++ lib/batch.php | 63 -- lib/class/access.php | 189 +++++ lib/class/album.php | 463 +++++++++++ lib/class/artist.php | 205 +++++ lib/class/catalog.php | 1934 +++++++++++++++++++++++++++++++++++++++++++++ lib/class/error.php | 94 +++ lib/class/genre.class.php | 45 ++ lib/class/playlist.php | 366 +++++++++ lib/class/song.php | 658 +++++++++++++++ lib/class/stream.php | 294 +++++++ lib/class/update.php | 931 ++++++++++++++++++++++ lib/class/user.php | 632 +++++++++++++++ lib/class/view.php | 229 ++++++ lib/general.lib.php | 703 ++++++++++++++++ lib/general.php | 703 ---------------- lib/ui.lib.php | 254 +++--- 23 files changed, 7887 insertions(+), 1804 deletions(-) create mode 100644 lib/album.lib.php delete mode 100644 lib/album.php create mode 100644 lib/archive.lib.php delete mode 100644 lib/archive.php create mode 100644 lib/artist.lib.php delete mode 100644 lib/artist.php create mode 100644 lib/batch.lib.php delete mode 100644 lib/batch.php create mode 100644 lib/class/access.php create mode 100644 lib/class/album.php create mode 100644 lib/class/artist.php create mode 100644 lib/class/catalog.php create mode 100644 lib/class/error.php create mode 100644 lib/class/genre.class.php create mode 100644 lib/class/playlist.php create mode 100644 lib/class/song.php create mode 100644 lib/class/stream.php create mode 100644 lib/class/update.php create mode 100644 lib/class/user.php create mode 100644 lib/class/view.php create mode 100644 lib/general.lib.php delete mode 100644 lib/general.php (limited to 'lib') diff --git a/lib/album.lib.php b/lib/album.lib.php new file mode 100644 index 00000000..7d518ff8 --- /dev/null +++ b/lib/album.lib.php @@ -0,0 +1,31 @@ +format_album(); + $albums[] = $album; + } + + return $albums; + + +} // get_albums + + + + + +?> diff --git a/lib/album.php b/lib/album.php deleted file mode 100644 index 7d518ff8..00000000 --- a/lib/album.php +++ /dev/null @@ -1,31 +0,0 @@ -format_album(); - $albums[] = $album; - } - - return $albums; - - -} // get_albums - - - - - -?> diff --git a/lib/archive.lib.php b/lib/archive.lib.php new file mode 100644 index 00000000..1a605f10 --- /dev/null +++ b/lib/archive.lib.php @@ -0,0 +1,778 @@ +options = array( + 'basedir'=>".", + 'name'=>$name, + 'prepend'=>"", + 'inmemory'=>0, + 'overwrite'=>0, + 'recurse'=>1, + 'storepaths'=>1, + 'level'=>3, + 'method'=>1, + 'sfx'=>"", + 'type'=>"", + 'comment'=>"" + ); + $this->files = array(); + $this->exclude = array(); + $this->storeonly = array(); + $this->error = array(); + } + + function set_options($options) + { + foreach($options as $key => $value) + { + $this->options[$key] = $value; + } + if(!empty($this->options['basedir'])) + { + $this->options['basedir'] = str_replace("\\","/",$this->options['basedir']); + $this->options['basedir'] = preg_replace("/\/+/","/",$this->options['basedir']); + $this->options['basedir'] = preg_replace("/\/$/","",$this->options['basedir']); + } + if(!empty($this->options['name'])) + { + $this->options['name'] = str_replace("\\","/",$this->options['name']); + $this->options['name'] = preg_replace("/\/+/","/",$this->options['name']); + } + if(!empty($this->options['prepend'])) + { + $this->options['prepend'] = str_replace("\\","/",$this->options['prepend']); + $this->options['prepend'] = preg_replace("/^(\.*\/+)+/","",$this->options['prepend']); + $this->options['prepend'] = preg_replace("/\/+/","/",$this->options['prepend']); + $this->options['prepend'] = preg_replace("/\/$/","",$this->options['prepend']) . "/"; + } + } + + function create_archive() + { + $this->make_list(); + + if($this->options['inmemory'] == 0) + { + $pwd = getcwd(); + chdir($this->options['basedir']); + if($this->options['overwrite'] == 0 && file_exists($this->options['name'] . ($this->options['type'] == "gzip" || $this->options['type'] == "bzip"? ".tmp" : ""))) + { + $this->error[] = "File {$this->options['name']} already exists."; + chdir($pwd); + return 0; + } + else if($this->archive = @fopen($this->options['name'] . ($this->options['type'] == "gzip" || $this->options['type'] == "bzip"? ".tmp" : ""),"wb+")) + { + chdir($pwd); + } + else + { + $this->error[] = "Could not open {$this->options['name']} for writing."; + chdir($pwd); + return 0; + } + } + else + { + $this->archive = ""; + } + + switch($this->options['type']) + { + case "zip": + if(!$this->create_zip()) + { + $this->error[] = "Could not create zip file."; + return 0; + } + break; + case "bzip": + if(!$this->create_tar()) + { + $this->error[] = "Could not create tar file."; + return 0; + } + if(!$this->create_bzip()) + { + $this->error[] = "Could not create bzip2 file."; + return 0; + } + break; + case "gzip": + if(!$this->create_tar()) + { + $this->error[] = "Could not create tar file."; + return 0; + } + if(!$this->create_gzip()) + { + $this->error[] = "Could not create gzip file."; + return 0; + } + break; + case "tar": + if(!$this->create_tar()) + { + $this->error[] = "Could not create tar file."; + return 0; + } + } + + if($this->options['inmemory'] == 0) + { + fclose($this->archive); + if($this->options['type'] == "gzip" || $this->options['type'] == "bzip") + { + unlink($this->options['basedir'] . "/" . $this->options['name'] . ".tmp"); + } + } + } + + function add_data($data) + { + if($this->options['inmemory'] == 0) + { + fwrite($this->archive,$data); + } + else + { + $this->archive .= $data; + } + } + + function make_list() + { + if(!empty($this->exclude)) + { + foreach($this->files as $key => $value) + { + foreach($this->exclude as $current) + { + if($value['name'] == $current['name']) + { + unset($this->files[$key]); + } + } + } + } + if(!empty($this->storeonly)) + { + foreach($this->files as $key => $value) + { + foreach($this->storeonly as $current) + { + if($value['name'] == $current['name']) + { + $this->files[$key]['method'] = 0; + } + } + } + } + unset($this->exclude,$this->storeonly); + } + + function add_files($list) + { + $temp = $this->list_files($list); + foreach($temp as $current) + { + $this->files[] = $current; + } + } + + function exclude_files($list) + { + $temp = $this->list_files($list); + foreach($temp as $current) + { + $this->exclude[] = $current; + } + } + + function store_files($list) + { + $temp = $this->list_files($list); + foreach($temp as $current) + { + $this->storeonly[] = $current; + } + } + + function list_files($list) + { + if(!is_array($list)) + { + $temp = $list; + $list = array($temp); + unset($temp); + } + + $files = array(); + + $pwd = getcwd(); + chdir($this->options['basedir']); + + foreach($list as $current) + { + $current = str_replace("\\","/",$current); + $current = preg_replace("/\/+/","/",$current); + $current = preg_replace("/\/$/","",$current); + if(strstr($current,"*")) + { + $regex = preg_replace("/([\\\^\$\.\[\]\|\(\)\?\+\{\}\/])/","\\\\\\1",$current); + $regex = str_replace("*",".*",$regex); + $dir = strstr($current,"/")? substr($current,0,strrpos($current,"/")) : "."; + $temp = $this->parse_dir($dir); + foreach($temp as $current2) + { + if(preg_match("/^{$regex}$/i",$current2['name'])) + { + $files[] = $current2; + } + } + unset($regex,$dir,$temp,$current); + } + else if(@is_dir($current)) + { + $temp = $this->parse_dir($current); + foreach($temp as $file) + { + $files[] = $file; + } + unset($temp,$file); + } + else if(@file_exists($current)) + { + $files[] = array('name'=>$current,'name2'=>$this->options['prepend'] . + preg_replace("/(\.+\/+)+/","",($this->options['storepaths'] == 0 && strstr($current,"/"))? + substr($current,strrpos($current,"/") + 1) : $current),'type'=>0, + 'ext'=>substr($current,strrpos($current,".")),'stat'=>stat($current)); + } + } + + chdir($pwd); + + unset($current,$pwd); + + usort($files,array("archive","sort_files")); + + return $files; + } + + function parse_dir($dirname) + { + if($this->options['storepaths'] == 1 && !preg_match("/^(\.+\/*)+$/",$dirname)) + { + $files = array(array('name'=>$dirname,'name2'=>$this->options['prepend'] . + preg_replace("/(\.+\/+)+/","",($this->options['storepaths'] == 0 && strstr($dirname,"/"))? + substr($dirname,strrpos($dirname,"/") + 1) : $dirname),'type'=>5,'stat'=>stat($dirname))); + } + else + { + $files = array(); + } + $dir = @opendir($dirname); + + while($file = @readdir($dir)) + { + if($file == "." || $file == "..") + { + continue; + } + else if(@is_dir($dirname."/".$file)) + { + if(empty($this->options['recurse'])) + { + continue; + } + $temp = $this->parse_dir($dirname."/".$file); + foreach($temp as $file2) + { + $files[] = $file2; + } + } + else if(@file_exists($dirname."/".$file)) + { + $files[] = array('name'=>$dirname."/".$file,'name2'=>$this->options['prepend'] . + preg_replace("/(\.+\/+)+/","",($this->options['storepaths'] == 0 && strstr($dirname."/".$file,"/"))? + substr($dirname."/".$file,strrpos($dirname."/".$file,"/") + 1) : $dirname."/".$file),'type'=>0, + 'ext'=>substr($file,strrpos($file,".")),'stat'=>stat($dirname."/".$file)); + } + } + + @closedir($dir); + + return $files; + } + + function sort_files($a,$b) + { + if($a['type'] != $b['type']) + { + return $a['type'] > $b['type']? -1 : 1; + } + else if($a['type'] == 5) + { + return strcmp(strtolower($a['name']),strtolower($b['name'])); + } + else + { + if($a['ext'] != $b['ext']) + { + return strcmp($a['ext'],$b['ext']); + } + else if($a['stat'][7] != $b['stat'][7]) + { + return $a['stat'][7] > $b['stat'][7]? -1 : 1; + } + else + { + return strcmp(strtolower($a['name']),strtolower($b['name'])); + } + } + return 0; + } + + function download_file() + { + if($this->options['inmemory'] == 0) + { + $this->error[] = "Can only use download_file() if archive is in memory. Redirect to file otherwise, it is faster."; + return; + } + switch($this->options['type']) + { + case "zip": + header("Content-type:application/zip"); + break; + case "bzip": + header("Content-type:application/x-compressed"); + break; + case "gzip": + header("Content-type:application/x-compressed"); + break; + case "tar": + header("Content-type:application/x-tar"); + } + $header = "Content-disposition: attachment; filename=\""; + $header .= strstr($this->options['name'],"/")? substr($this->options['name'],strrpos($this->options['name'],"/") + 1) : $this->options['name']; + $header .= "\""; + header($header); + header("Content-length: " . strlen($this->archive)); + header("Content-transfer-encoding: binary"); + header("Pragma: no-cache"); + header("Expires: 0"); + print($this->archive); + } +} + +class tar_file extends archive +{ + function tar_file($name) + { + $this->archive($name); + $this->options['type'] = "tar"; + } + + function create_tar() + { + $pwd = getcwd(); + chdir($this->options['basedir']); + + foreach($this->files as $current) + { + if($current['name'] == $this->options['name']) + { + continue; + } + if(strlen($current['name2']) > 99) + { + $path = substr($current['name2'],0,strpos($current['name2'],"/",strlen($current['name2']) - 100) + 1); + $current['name2'] = substr($current['name2'],strlen($path)); + if(strlen($path) > 154 || strlen($current['name2']) > 99) + { + $this->error[] = "Could not add {$path}{$current['name2']} to archive because the filename is too long."; + continue; + } + } + $block = pack("a100a8a8a8a12a12a8a1a100a6a2a32a32a8a8a155a12",$current['name2'],decoct($current['stat'][2]), + sprintf("%6s ",decoct($current['stat'][4])),sprintf("%6s ",decoct($current['stat'][5])), + sprintf("%11s ",decoct($current['stat'][7])),sprintf("%11s ",decoct($current['stat'][9])), + " ",$current['type'],"","ustar","00","Unknown","Unknown","","",!empty($path)? $path : "",""); + + $checksum = 0; + for($i = 0; $i < 512; $i++) + { + $checksum += ord(substr($block,$i,1)); + } + $checksum = pack("a8",sprintf("%6s ",decoct($checksum))); + $block = substr_replace($block,$checksum,148,8); + + if($current['stat'][7] == 0) + { + $this->add_data($block); + } + else if($fp = @fopen($current['name'],"rb")) + { + $this->add_data($block); + while($temp = fread($fp,1048576)) + { + $this->add_data($temp); + } + if($current['stat'][7] % 512 > 0) + { + $temp = ""; + for($i = 0; $i < 512 - $current['stat'][7] % 512; $i++) + { + $temp .= "\0"; + } + $this->add_data($temp); + } + fclose($fp); + } + else + { + $this->error[] = "Could not open file {$current['name']} for reading. It was not added."; + } + } + + $this->add_data(pack("a512","")); + + chdir($pwd); + + return 1; + } + + function extract_files() + { + $pwd = getcwd(); + chdir($this->options['basedir']); + + if($fp = $this->open_archive()) + { + if($this->options['inmemory'] == 1) + { + $this->files = array(); + } + + while($block = fread($fp,512)) + { + $temp = unpack("a100name/a8mode/a8uid/a8gid/a12size/a12mtime/a8checksum/a1type/a100temp/a6magic/a2temp/a32temp/a32temp/a8temp/a8temp/a155prefix/a12temp",$block); + $file = array( + 'name'=>$temp['prefix'] . $temp['name'], + 'stat'=>array( + 2=>$temp['mode'], + 4=>octdec($temp['uid']), + 5=>octdec($temp['gid']), + 7=>octdec($temp['size']), + 9=>octdec($temp['mtime']), + ), + 'checksum'=>octdec($temp['checksum']), + 'type'=>$temp['type'], + 'magic'=>$temp['magic'], + ); + if($file['checksum'] == 0x00000000) + { + break; + } + else if($file['magic'] != "ustar") + { + $this->error[] = "This script does not support extracting this type of tar file."; + break; + } + $block = substr_replace($block," ",148,8); + $checksum = 0; + for($i = 0; $i < 512; $i++) + { + $checksum += ord(substr($block,$i,1)); + } + if($file['checksum'] != $checksum) + { + $this->error[] = "Could not extract from {$this->options['name']}, it is corrupt."; + } + + if($this->options['inmemory'] == 1) + { + $file['data'] = fread($fp,$file['stat'][7]); + fread($fp,(512 - $file['stat'][7] % 512) == 512? 0 : (512 - $file['stat'][7] % 512)); + unset($file['checksum'],$file['magic']); + $this->files[] = $file; + } + else + { + if($file['type'] == 5) + { + if(!is_dir($file['name'])) + { + mkdir($file['name'],$file['stat'][2]); + chown($file['name'],$file['stat'][4]); + chgrp($file['name'],$file['stat'][5]); + } + } + else if($this->options['overwrite'] == 0 && file_exists($file['name'])) + { + $this->error[] = "{$file['name']} already exists."; + } + else if($new = @fopen($file['name'],"wb")) + { + fwrite($new,fread($fp,$file['stat'][7])); + fread($fp,(512 - $file['stat'][7] % 512) == 512? 0 : (512 - $file['stat'][7] % 512)); + fclose($new); + chmod($file['name'],$file['stat'][2]); + chown($file['name'],$file['stat'][4]); + chgrp($file['name'],$file['stat'][5]); + } + else + { + $this->error[] = "Could not open {$file['name']} for writing."; + } + } + unset($file); + } + } + else + { + $this->error[] = "Could not open file {$this->options['name']}"; + } + + chdir($pwd); + } + + function open_archive() + { + return @fopen($this->options['name'],"rb"); + } +} + +class gzip_file extends tar_file +{ + function gzip_file($name) + { + $this->tar_file($name); + $this->options['type'] = "gzip"; + } + + function create_gzip() + { + if($this->options['inmemory'] == 0) + { + $pwd = getcwd(); + chdir($this->options['basedir']); + if($fp = gzopen($this->options['name'],"wb{$this->options['level']}")) + { + fseek($this->archive,0); + while($temp = fread($this->archive,1048576)) + { + gzwrite($fp,$temp); + } + gzclose($fp); + chdir($pwd); + } + else + { + $this->error[] = "Could not open {$this->options['name']} for writing."; + chdir($pwd); + return 0; + } + } + else + { + $this->archive = gzencode($this->archive,$this->options['level']); + } + + return 1; + } + + function open_archive() + { + return @gzopen($this->options['name'],"rb"); + } +} + +class bzip_file extends tar_file +{ + function bzip_file($name) + { + $this->tar_file($name); + $this->options['type'] = "bzip"; + } + + function create_bzip() + { + if($this->options['inmemory'] == 0) + { + $pwd = getcwd(); + chdir($this->options['basedir']); + if($fp = bzopen($this->options['name'],"wb")) + { + fseek($this->archive,0); + while($temp = fread($this->archive,1048576)) + { + bzwrite($fp,$temp); + } + bzclose($fp); + chdir($pwd); + } + else + { + $this->error[] = "Could not open {$this->options['name']} for writing."; + chdir($pwd); + return 0; + } + } + else + { + $this->archive = bzcompress($this->archive,$this->options['level']); + } + + return 1; + } + + function open_archive() + { + return @bzopen($this->options['name'],"rb"); + } +} + +class zip_file extends archive +{ + function zip_file($name) + { + $this->archive($name); + $this->options['type'] = "zip"; + } + + function create_zip() + { + $files = 0; + $offset = 0; + $central = ""; + + if(!empty($this->options['sfx'])) + { + if($fp = @fopen($this->options['sfx'],"rb")) + { + $temp = fread($fp,filesize($this->options['sfx'])); + fclose($fp); + $this->add_data($temp); + $offset += strlen($temp); + unset($temp); + } + else + { + $this->error[] = "Could not open sfx module from {$this->options['sfx']}."; + } + } + + $pwd = getcwd(); + chdir($this->options['basedir']); + + foreach($this->files as $current) + { + if($current['name'] == $this->options['name']) + { + continue; + } + + $translate = array('Ç'=>pack("C",128),'ü'=>pack("C",129),'é'=>pack("C",130),'â'=>pack("C",131),'ä'=>pack("C",132), + 'à'=>pack("C",133),'å'=>pack("C",134),'ç'=>pack("C",135),'ê'=>pack("C",136),'ë'=>pack("C",137), + 'è'=>pack("C",138),'ï'=>pack("C",139),'î'=>pack("C",140),'ì'=>pack("C",141),'Ä'=>pack("C",142), + 'Å'=>pack("C",143),'É'=>pack("C",144),'æ'=>pack("C",145),'Æ'=>pack("C",146),'ô'=>pack("C",147), + 'ö'=>pack("C",148),'ò'=>pack("C",149),'û'=>pack("C",150),'ù'=>pack("C",151),'Ö'=>pack("C",153), + 'Ü'=>pack("C",154),'£'=>pack("C",156),'¥'=>pack("C",157),'ƒ'=>pack("C",159),'á'=>pack("C",160), + 'í'=>pack("C",161),'ó'=>pack("C",162),'ú'=>pack("C",163),'ñ'=>pack("C",164),'Ñ'=>pack("C",165)); + $current['name2'] = strtr($current['name2'],$translate); + + $timedate = explode(" ",date("Y n j G i s",$current['stat'][9])); + $timedate = ($timedate[0] - 1980 << 25) | ($timedate[1] << 21) | ($timedate[2] << 16) | + ($timedate[3] << 11) | ($timedate[4] << 5) | ($timedate[5]); + + $block = pack("VvvvV",0x04034b50,0x000A,0x0000,(isset($current['method']) || $this->options['method'] == 0)? 0x0000 : 0x0008,$timedate); + + if($current['stat'][7] == 0 && $current['type'] == 5) + { + $block .= pack("VVVvv",0x00000000,0x00000000,0x00000000,strlen($current['name2']) + 1,0x0000); + $block .= $current['name2'] . "/"; + $this->add_data($block); + $central .= pack("VvvvvVVVVvvvvvVV",0x02014b50,0x0014,$this->options['method'] == 0? 0x0000 : 0x000A,0x0000, + (isset($current['method']) || $this->options['method'] == 0)? 0x0000 : 0x0008,$timedate, + 0x00000000,0x00000000,0x00000000,strlen($current['name2']) + 1,0x0000,0x0000,0x0000,0x0000,$current['type'] == 5? 0x00000010 : 0x00000000,$offset); + $central .= $current['name2'] . "/"; + $files++; + $offset += (31 + strlen($current['name2'])); + } + else if($current['stat'][7] == 0) + { + $block .= pack("VVVvv",0x00000000,0x00000000,0x00000000,strlen($current['name2']),0x0000); + $block .= $current['name2']; + $this->add_data($block); + $central .= pack("VvvvvVVVVvvvvvVV",0x02014b50,0x0014,$this->options['method'] == 0? 0x0000 : 0x000A,0x0000, + (isset($current['method']) || $this->options['method'] == 0)? 0x0000 : 0x0008,$timedate, + 0x00000000,0x00000000,0x00000000,strlen($current['name2']),0x0000,0x0000,0x0000,0x0000,$current['type'] == 5? 0x00000010 : 0x00000000,$offset); + $central .= $current['name2']; + $files++; + $offset += (30 + strlen($current['name2'])); + } + else if($fp = @fopen($current['name'],"rb")) + { + $temp = fread($fp,$current['stat'][7]); + fclose($fp); + $crc32 = crc32($temp); + if(!isset($current['method']) && $this->options['method'] == 1) + { + $temp = gzcompress($temp,$this->options['level']); + $size = strlen($temp) - 6; + $temp = substr($temp,2,$size); + } + else + { + $size = strlen($temp); + } + $block .= pack("VVVvv",$crc32,$size,$current['stat'][7],strlen($current['name2']),0x0000); + $block .= $current['name2']; + $this->add_data($block); + $this->add_data($temp); + unset($temp); + $central .= pack("VvvvvVVVVvvvvvVV",0x02014b50,0x0014,$this->options['method'] == 0? 0x0000 : 0x000A,0x0000, + (isset($current['method']) || $this->options['method'] == 0)? 0x0000 : 0x0008,$timedate, + $crc32,$size,$current['stat'][7],strlen($current['name2']),0x0000,0x0000,0x0000,0x0000,0x00000000,$offset); + $central .= $current['name2']; + $files++; + $offset += (30 + strlen($current['name2']) + $size); + } + else + { + $this->error[] = "Could not open file {$current['name']} for reading. It was not added."; + } + } + + $this->add_data($central); + + $this->add_data(pack("VvvvvVVv",0x06054b50,0x0000,0x0000,$files,$files,strlen($central),$offset, + !empty($this->options['comment'])? strlen($this->options['comment']) : 0x0000)); + + if(!empty($this->options['comment'])) + { + $this->add_data($this->options['comment']); + } + + chdir($pwd); + + return 1; + } +} ?> \ No newline at end of file diff --git a/lib/archive.php b/lib/archive.php deleted file mode 100644 index 1a605f10..00000000 --- a/lib/archive.php +++ /dev/null @@ -1,778 +0,0 @@ -options = array( - 'basedir'=>".", - 'name'=>$name, - 'prepend'=>"", - 'inmemory'=>0, - 'overwrite'=>0, - 'recurse'=>1, - 'storepaths'=>1, - 'level'=>3, - 'method'=>1, - 'sfx'=>"", - 'type'=>"", - 'comment'=>"" - ); - $this->files = array(); - $this->exclude = array(); - $this->storeonly = array(); - $this->error = array(); - } - - function set_options($options) - { - foreach($options as $key => $value) - { - $this->options[$key] = $value; - } - if(!empty($this->options['basedir'])) - { - $this->options['basedir'] = str_replace("\\","/",$this->options['basedir']); - $this->options['basedir'] = preg_replace("/\/+/","/",$this->options['basedir']); - $this->options['basedir'] = preg_replace("/\/$/","",$this->options['basedir']); - } - if(!empty($this->options['name'])) - { - $this->options['name'] = str_replace("\\","/",$this->options['name']); - $this->options['name'] = preg_replace("/\/+/","/",$this->options['name']); - } - if(!empty($this->options['prepend'])) - { - $this->options['prepend'] = str_replace("\\","/",$this->options['prepend']); - $this->options['prepend'] = preg_replace("/^(\.*\/+)+/","",$this->options['prepend']); - $this->options['prepend'] = preg_replace("/\/+/","/",$this->options['prepend']); - $this->options['prepend'] = preg_replace("/\/$/","",$this->options['prepend']) . "/"; - } - } - - function create_archive() - { - $this->make_list(); - - if($this->options['inmemory'] == 0) - { - $pwd = getcwd(); - chdir($this->options['basedir']); - if($this->options['overwrite'] == 0 && file_exists($this->options['name'] . ($this->options['type'] == "gzip" || $this->options['type'] == "bzip"? ".tmp" : ""))) - { - $this->error[] = "File {$this->options['name']} already exists."; - chdir($pwd); - return 0; - } - else if($this->archive = @fopen($this->options['name'] . ($this->options['type'] == "gzip" || $this->options['type'] == "bzip"? ".tmp" : ""),"wb+")) - { - chdir($pwd); - } - else - { - $this->error[] = "Could not open {$this->options['name']} for writing."; - chdir($pwd); - return 0; - } - } - else - { - $this->archive = ""; - } - - switch($this->options['type']) - { - case "zip": - if(!$this->create_zip()) - { - $this->error[] = "Could not create zip file."; - return 0; - } - break; - case "bzip": - if(!$this->create_tar()) - { - $this->error[] = "Could not create tar file."; - return 0; - } - if(!$this->create_bzip()) - { - $this->error[] = "Could not create bzip2 file."; - return 0; - } - break; - case "gzip": - if(!$this->create_tar()) - { - $this->error[] = "Could not create tar file."; - return 0; - } - if(!$this->create_gzip()) - { - $this->error[] = "Could not create gzip file."; - return 0; - } - break; - case "tar": - if(!$this->create_tar()) - { - $this->error[] = "Could not create tar file."; - return 0; - } - } - - if($this->options['inmemory'] == 0) - { - fclose($this->archive); - if($this->options['type'] == "gzip" || $this->options['type'] == "bzip") - { - unlink($this->options['basedir'] . "/" . $this->options['name'] . ".tmp"); - } - } - } - - function add_data($data) - { - if($this->options['inmemory'] == 0) - { - fwrite($this->archive,$data); - } - else - { - $this->archive .= $data; - } - } - - function make_list() - { - if(!empty($this->exclude)) - { - foreach($this->files as $key => $value) - { - foreach($this->exclude as $current) - { - if($value['name'] == $current['name']) - { - unset($this->files[$key]); - } - } - } - } - if(!empty($this->storeonly)) - { - foreach($this->files as $key => $value) - { - foreach($this->storeonly as $current) - { - if($value['name'] == $current['name']) - { - $this->files[$key]['method'] = 0; - } - } - } - } - unset($this->exclude,$this->storeonly); - } - - function add_files($list) - { - $temp = $this->list_files($list); - foreach($temp as $current) - { - $this->files[] = $current; - } - } - - function exclude_files($list) - { - $temp = $this->list_files($list); - foreach($temp as $current) - { - $this->exclude[] = $current; - } - } - - function store_files($list) - { - $temp = $this->list_files($list); - foreach($temp as $current) - { - $this->storeonly[] = $current; - } - } - - function list_files($list) - { - if(!is_array($list)) - { - $temp = $list; - $list = array($temp); - unset($temp); - } - - $files = array(); - - $pwd = getcwd(); - chdir($this->options['basedir']); - - foreach($list as $current) - { - $current = str_replace("\\","/",$current); - $current = preg_replace("/\/+/","/",$current); - $current = preg_replace("/\/$/","",$current); - if(strstr($current,"*")) - { - $regex = preg_replace("/([\\\^\$\.\[\]\|\(\)\?\+\{\}\/])/","\\\\\\1",$current); - $regex = str_replace("*",".*",$regex); - $dir = strstr($current,"/")? substr($current,0,strrpos($current,"/")) : "."; - $temp = $this->parse_dir($dir); - foreach($temp as $current2) - { - if(preg_match("/^{$regex}$/i",$current2['name'])) - { - $files[] = $current2; - } - } - unset($regex,$dir,$temp,$current); - } - else if(@is_dir($current)) - { - $temp = $this->parse_dir($current); - foreach($temp as $file) - { - $files[] = $file; - } - unset($temp,$file); - } - else if(@file_exists($current)) - { - $files[] = array('name'=>$current,'name2'=>$this->options['prepend'] . - preg_replace("/(\.+\/+)+/","",($this->options['storepaths'] == 0 && strstr($current,"/"))? - substr($current,strrpos($current,"/") + 1) : $current),'type'=>0, - 'ext'=>substr($current,strrpos($current,".")),'stat'=>stat($current)); - } - } - - chdir($pwd); - - unset($current,$pwd); - - usort($files,array("archive","sort_files")); - - return $files; - } - - function parse_dir($dirname) - { - if($this->options['storepaths'] == 1 && !preg_match("/^(\.+\/*)+$/",$dirname)) - { - $files = array(array('name'=>$dirname,'name2'=>$this->options['prepend'] . - preg_replace("/(\.+\/+)+/","",($this->options['storepaths'] == 0 && strstr($dirname,"/"))? - substr($dirname,strrpos($dirname,"/") + 1) : $dirname),'type'=>5,'stat'=>stat($dirname))); - } - else - { - $files = array(); - } - $dir = @opendir($dirname); - - while($file = @readdir($dir)) - { - if($file == "." || $file == "..") - { - continue; - } - else if(@is_dir($dirname."/".$file)) - { - if(empty($this->options['recurse'])) - { - continue; - } - $temp = $this->parse_dir($dirname."/".$file); - foreach($temp as $file2) - { - $files[] = $file2; - } - } - else if(@file_exists($dirname."/".$file)) - { - $files[] = array('name'=>$dirname."/".$file,'name2'=>$this->options['prepend'] . - preg_replace("/(\.+\/+)+/","",($this->options['storepaths'] == 0 && strstr($dirname."/".$file,"/"))? - substr($dirname."/".$file,strrpos($dirname."/".$file,"/") + 1) : $dirname."/".$file),'type'=>0, - 'ext'=>substr($file,strrpos($file,".")),'stat'=>stat($dirname."/".$file)); - } - } - - @closedir($dir); - - return $files; - } - - function sort_files($a,$b) - { - if($a['type'] != $b['type']) - { - return $a['type'] > $b['type']? -1 : 1; - } - else if($a['type'] == 5) - { - return strcmp(strtolower($a['name']),strtolower($b['name'])); - } - else - { - if($a['ext'] != $b['ext']) - { - return strcmp($a['ext'],$b['ext']); - } - else if($a['stat'][7] != $b['stat'][7]) - { - return $a['stat'][7] > $b['stat'][7]? -1 : 1; - } - else - { - return strcmp(strtolower($a['name']),strtolower($b['name'])); - } - } - return 0; - } - - function download_file() - { - if($this->options['inmemory'] == 0) - { - $this->error[] = "Can only use download_file() if archive is in memory. Redirect to file otherwise, it is faster."; - return; - } - switch($this->options['type']) - { - case "zip": - header("Content-type:application/zip"); - break; - case "bzip": - header("Content-type:application/x-compressed"); - break; - case "gzip": - header("Content-type:application/x-compressed"); - break; - case "tar": - header("Content-type:application/x-tar"); - } - $header = "Content-disposition: attachment; filename=\""; - $header .= strstr($this->options['name'],"/")? substr($this->options['name'],strrpos($this->options['name'],"/") + 1) : $this->options['name']; - $header .= "\""; - header($header); - header("Content-length: " . strlen($this->archive)); - header("Content-transfer-encoding: binary"); - header("Pragma: no-cache"); - header("Expires: 0"); - print($this->archive); - } -} - -class tar_file extends archive -{ - function tar_file($name) - { - $this->archive($name); - $this->options['type'] = "tar"; - } - - function create_tar() - { - $pwd = getcwd(); - chdir($this->options['basedir']); - - foreach($this->files as $current) - { - if($current['name'] == $this->options['name']) - { - continue; - } - if(strlen($current['name2']) > 99) - { - $path = substr($current['name2'],0,strpos($current['name2'],"/",strlen($current['name2']) - 100) + 1); - $current['name2'] = substr($current['name2'],strlen($path)); - if(strlen($path) > 154 || strlen($current['name2']) > 99) - { - $this->error[] = "Could not add {$path}{$current['name2']} to archive because the filename is too long."; - continue; - } - } - $block = pack("a100a8a8a8a12a12a8a1a100a6a2a32a32a8a8a155a12",$current['name2'],decoct($current['stat'][2]), - sprintf("%6s ",decoct($current['stat'][4])),sprintf("%6s ",decoct($current['stat'][5])), - sprintf("%11s ",decoct($current['stat'][7])),sprintf("%11s ",decoct($current['stat'][9])), - " ",$current['type'],"","ustar","00","Unknown","Unknown","","",!empty($path)? $path : "",""); - - $checksum = 0; - for($i = 0; $i < 512; $i++) - { - $checksum += ord(substr($block,$i,1)); - } - $checksum = pack("a8",sprintf("%6s ",decoct($checksum))); - $block = substr_replace($block,$checksum,148,8); - - if($current['stat'][7] == 0) - { - $this->add_data($block); - } - else if($fp = @fopen($current['name'],"rb")) - { - $this->add_data($block); - while($temp = fread($fp,1048576)) - { - $this->add_data($temp); - } - if($current['stat'][7] % 512 > 0) - { - $temp = ""; - for($i = 0; $i < 512 - $current['stat'][7] % 512; $i++) - { - $temp .= "\0"; - } - $this->add_data($temp); - } - fclose($fp); - } - else - { - $this->error[] = "Could not open file {$current['name']} for reading. It was not added."; - } - } - - $this->add_data(pack("a512","")); - - chdir($pwd); - - return 1; - } - - function extract_files() - { - $pwd = getcwd(); - chdir($this->options['basedir']); - - if($fp = $this->open_archive()) - { - if($this->options['inmemory'] == 1) - { - $this->files = array(); - } - - while($block = fread($fp,512)) - { - $temp = unpack("a100name/a8mode/a8uid/a8gid/a12size/a12mtime/a8checksum/a1type/a100temp/a6magic/a2temp/a32temp/a32temp/a8temp/a8temp/a155prefix/a12temp",$block); - $file = array( - 'name'=>$temp['prefix'] . $temp['name'], - 'stat'=>array( - 2=>$temp['mode'], - 4=>octdec($temp['uid']), - 5=>octdec($temp['gid']), - 7=>octdec($temp['size']), - 9=>octdec($temp['mtime']), - ), - 'checksum'=>octdec($temp['checksum']), - 'type'=>$temp['type'], - 'magic'=>$temp['magic'], - ); - if($file['checksum'] == 0x00000000) - { - break; - } - else if($file['magic'] != "ustar") - { - $this->error[] = "This script does not support extracting this type of tar file."; - break; - } - $block = substr_replace($block," ",148,8); - $checksum = 0; - for($i = 0; $i < 512; $i++) - { - $checksum += ord(substr($block,$i,1)); - } - if($file['checksum'] != $checksum) - { - $this->error[] = "Could not extract from {$this->options['name']}, it is corrupt."; - } - - if($this->options['inmemory'] == 1) - { - $file['data'] = fread($fp,$file['stat'][7]); - fread($fp,(512 - $file['stat'][7] % 512) == 512? 0 : (512 - $file['stat'][7] % 512)); - unset($file['checksum'],$file['magic']); - $this->files[] = $file; - } - else - { - if($file['type'] == 5) - { - if(!is_dir($file['name'])) - { - mkdir($file['name'],$file['stat'][2]); - chown($file['name'],$file['stat'][4]); - chgrp($file['name'],$file['stat'][5]); - } - } - else if($this->options['overwrite'] == 0 && file_exists($file['name'])) - { - $this->error[] = "{$file['name']} already exists."; - } - else if($new = @fopen($file['name'],"wb")) - { - fwrite($new,fread($fp,$file['stat'][7])); - fread($fp,(512 - $file['stat'][7] % 512) == 512? 0 : (512 - $file['stat'][7] % 512)); - fclose($new); - chmod($file['name'],$file['stat'][2]); - chown($file['name'],$file['stat'][4]); - chgrp($file['name'],$file['stat'][5]); - } - else - { - $this->error[] = "Could not open {$file['name']} for writing."; - } - } - unset($file); - } - } - else - { - $this->error[] = "Could not open file {$this->options['name']}"; - } - - chdir($pwd); - } - - function open_archive() - { - return @fopen($this->options['name'],"rb"); - } -} - -class gzip_file extends tar_file -{ - function gzip_file($name) - { - $this->tar_file($name); - $this->options['type'] = "gzip"; - } - - function create_gzip() - { - if($this->options['inmemory'] == 0) - { - $pwd = getcwd(); - chdir($this->options['basedir']); - if($fp = gzopen($this->options['name'],"wb{$this->options['level']}")) - { - fseek($this->archive,0); - while($temp = fread($this->archive,1048576)) - { - gzwrite($fp,$temp); - } - gzclose($fp); - chdir($pwd); - } - else - { - $this->error[] = "Could not open {$this->options['name']} for writing."; - chdir($pwd); - return 0; - } - } - else - { - $this->archive = gzencode($this->archive,$this->options['level']); - } - - return 1; - } - - function open_archive() - { - return @gzopen($this->options['name'],"rb"); - } -} - -class bzip_file extends tar_file -{ - function bzip_file($name) - { - $this->tar_file($name); - $this->options['type'] = "bzip"; - } - - function create_bzip() - { - if($this->options['inmemory'] == 0) - { - $pwd = getcwd(); - chdir($this->options['basedir']); - if($fp = bzopen($this->options['name'],"wb")) - { - fseek($this->archive,0); - while($temp = fread($this->archive,1048576)) - { - bzwrite($fp,$temp); - } - bzclose($fp); - chdir($pwd); - } - else - { - $this->error[] = "Could not open {$this->options['name']} for writing."; - chdir($pwd); - return 0; - } - } - else - { - $this->archive = bzcompress($this->archive,$this->options['level']); - } - - return 1; - } - - function open_archive() - { - return @bzopen($this->options['name'],"rb"); - } -} - -class zip_file extends archive -{ - function zip_file($name) - { - $this->archive($name); - $this->options['type'] = "zip"; - } - - function create_zip() - { - $files = 0; - $offset = 0; - $central = ""; - - if(!empty($this->options['sfx'])) - { - if($fp = @fopen($this->options['sfx'],"rb")) - { - $temp = fread($fp,filesize($this->options['sfx'])); - fclose($fp); - $this->add_data($temp); - $offset += strlen($temp); - unset($temp); - } - else - { - $this->error[] = "Could not open sfx module from {$this->options['sfx']}."; - } - } - - $pwd = getcwd(); - chdir($this->options['basedir']); - - foreach($this->files as $current) - { - if($current['name'] == $this->options['name']) - { - continue; - } - - $translate = array('Ç'=>pack("C",128),'ü'=>pack("C",129),'é'=>pack("C",130),'â'=>pack("C",131),'ä'=>pack("C",132), - 'à'=>pack("C",133),'å'=>pack("C",134),'ç'=>pack("C",135),'ê'=>pack("C",136),'ë'=>pack("C",137), - 'è'=>pack("C",138),'ï'=>pack("C",139),'î'=>pack("C",140),'ì'=>pack("C",141),'Ä'=>pack("C",142), - 'Å'=>pack("C",143),'É'=>pack("C",144),'æ'=>pack("C",145),'Æ'=>pack("C",146),'ô'=>pack("C",147), - 'ö'=>pack("C",148),'ò'=>pack("C",149),'û'=>pack("C",150),'ù'=>pack("C",151),'Ö'=>pack("C",153), - 'Ü'=>pack("C",154),'£'=>pack("C",156),'¥'=>pack("C",157),'ƒ'=>pack("C",159),'á'=>pack("C",160), - 'í'=>pack("C",161),'ó'=>pack("C",162),'ú'=>pack("C",163),'ñ'=>pack("C",164),'Ñ'=>pack("C",165)); - $current['name2'] = strtr($current['name2'],$translate); - - $timedate = explode(" ",date("Y n j G i s",$current['stat'][9])); - $timedate = ($timedate[0] - 1980 << 25) | ($timedate[1] << 21) | ($timedate[2] << 16) | - ($timedate[3] << 11) | ($timedate[4] << 5) | ($timedate[5]); - - $block = pack("VvvvV",0x04034b50,0x000A,0x0000,(isset($current['method']) || $this->options['method'] == 0)? 0x0000 : 0x0008,$timedate); - - if($current['stat'][7] == 0 && $current['type'] == 5) - { - $block .= pack("VVVvv",0x00000000,0x00000000,0x00000000,strlen($current['name2']) + 1,0x0000); - $block .= $current['name2'] . "/"; - $this->add_data($block); - $central .= pack("VvvvvVVVVvvvvvVV",0x02014b50,0x0014,$this->options['method'] == 0? 0x0000 : 0x000A,0x0000, - (isset($current['method']) || $this->options['method'] == 0)? 0x0000 : 0x0008,$timedate, - 0x00000000,0x00000000,0x00000000,strlen($current['name2']) + 1,0x0000,0x0000,0x0000,0x0000,$current['type'] == 5? 0x00000010 : 0x00000000,$offset); - $central .= $current['name2'] . "/"; - $files++; - $offset += (31 + strlen($current['name2'])); - } - else if($current['stat'][7] == 0) - { - $block .= pack("VVVvv",0x00000000,0x00000000,0x00000000,strlen($current['name2']),0x0000); - $block .= $current['name2']; - $this->add_data($block); - $central .= pack("VvvvvVVVVvvvvvVV",0x02014b50,0x0014,$this->options['method'] == 0? 0x0000 : 0x000A,0x0000, - (isset($current['method']) || $this->options['method'] == 0)? 0x0000 : 0x0008,$timedate, - 0x00000000,0x00000000,0x00000000,strlen($current['name2']),0x0000,0x0000,0x0000,0x0000,$current['type'] == 5? 0x00000010 : 0x00000000,$offset); - $central .= $current['name2']; - $files++; - $offset += (30 + strlen($current['name2'])); - } - else if($fp = @fopen($current['name'],"rb")) - { - $temp = fread($fp,$current['stat'][7]); - fclose($fp); - $crc32 = crc32($temp); - if(!isset($current['method']) && $this->options['method'] == 1) - { - $temp = gzcompress($temp,$this->options['level']); - $size = strlen($temp) - 6; - $temp = substr($temp,2,$size); - } - else - { - $size = strlen($temp); - } - $block .= pack("VVVvv",$crc32,$size,$current['stat'][7],strlen($current['name2']),0x0000); - $block .= $current['name2']; - $this->add_data($block); - $this->add_data($temp); - unset($temp); - $central .= pack("VvvvvVVVVvvvvvVV",0x02014b50,0x0014,$this->options['method'] == 0? 0x0000 : 0x000A,0x0000, - (isset($current['method']) || $this->options['method'] == 0)? 0x0000 : 0x0008,$timedate, - $crc32,$size,$current['stat'][7],strlen($current['name2']),0x0000,0x0000,0x0000,0x0000,0x00000000,$offset); - $central .= $current['name2']; - $files++; - $offset += (30 + strlen($current['name2']) + $size); - } - else - { - $this->error[] = "Could not open file {$current['name']} for reading. It was not added."; - } - } - - $this->add_data($central); - - $this->add_data(pack("VvvvvVVv",0x06054b50,0x0000,0x0000,$files,$files,strlen($central),$offset, - !empty($this->options['comment'])? strlen($this->options['comment']) : 0x0000)); - - if(!empty($this->options['comment'])) - { - $this->add_data($this->options['comment']); - } - - chdir($pwd); - - return 1; - } -} ?> \ No newline at end of file diff --git a/lib/artist.lib.php b/lib/artist.lib.php new file mode 100644 index 00000000..38a93c75 --- /dev/null +++ b/lib/artist.lib.php @@ -0,0 +1,122 @@ +" . htmlspecialchars($artist['prefix']) . " " . htmlspecialchars($artist['name']) . ""; + + return $artist; + +} // format_artist + +/*! + @function show_artists + @discussion takes a match and accounts for the possiblity of a view + then displays _many_ artists +*/ +function show_artists ($match = '') { + + global $settings; + $dbh = dbh(); + + $view = new View(); + $view->import_session_view(); + + // Check for the view object... + if ($_REQUEST['keep_view']) { + $view->initialize(); + } + + // If there isn't a view object we need to create a new one.. + else { + if ( isset($match) && $match != '' ) { + $query = "SELECT id,name FROM artist " . + " WHERE name LIKE '$match%' "; + } + else { + $query = "SELECT id FROM artist "; + } + + $db_results = mysql_query($query, $dbh); + $total_items = mysql_num_rows($db_results); + if ($_REQUEST['match'] === "Show_all") { + $offset_limit = 999999; + } + else { + $offset_limit = $_SESSION['userdata']['offset_limit']; + } + $view = new View($query,'artists.php','name',$total_items,$offset_limit); + } // end if creating view object + + if (is_array($match)) { + $artists = $match; + $_SESSION['view_script'] = false; + } + + $db_results = mysql_query($view->sql, $dbh); + while ($r = @mysql_fetch_array($db_results)) { + $artist_info = get_artist_info($r[0]); + $artist = format_artist($artist_info); + // Only Add this artist if there is information to go along with it + if ($artist_info) { + $artists[] = $artist; + } + } + + if (count($artists)) { + require ( conf('prefix') . "/templates/show_artists.inc"); + } + +} // show_artists + + + + +?> diff --git a/lib/artist.php b/lib/artist.php deleted file mode 100644 index 38a93c75..00000000 --- a/lib/artist.php +++ /dev/null @@ -1,122 +0,0 @@ -" . htmlspecialchars($artist['prefix']) . " " . htmlspecialchars($artist['name']) . ""; - - return $artist; - -} // format_artist - -/*! - @function show_artists - @discussion takes a match and accounts for the possiblity of a view - then displays _many_ artists -*/ -function show_artists ($match = '') { - - global $settings; - $dbh = dbh(); - - $view = new View(); - $view->import_session_view(); - - // Check for the view object... - if ($_REQUEST['keep_view']) { - $view->initialize(); - } - - // If there isn't a view object we need to create a new one.. - else { - if ( isset($match) && $match != '' ) { - $query = "SELECT id,name FROM artist " . - " WHERE name LIKE '$match%' "; - } - else { - $query = "SELECT id FROM artist "; - } - - $db_results = mysql_query($query, $dbh); - $total_items = mysql_num_rows($db_results); - if ($_REQUEST['match'] === "Show_all") { - $offset_limit = 999999; - } - else { - $offset_limit = $_SESSION['userdata']['offset_limit']; - } - $view = new View($query,'artists.php','name',$total_items,$offset_limit); - } // end if creating view object - - if (is_array($match)) { - $artists = $match; - $_SESSION['view_script'] = false; - } - - $db_results = mysql_query($view->sql, $dbh); - while ($r = @mysql_fetch_array($db_results)) { - $artist_info = get_artist_info($r[0]); - $artist = format_artist($artist_info); - // Only Add this artist if there is information to go along with it - if ($artist_info) { - $artists[] = $artist; - } - } - - if (count($artists)) { - require ( conf('prefix') . "/templates/show_artists.inc"); - } - -} // show_artists - - - - -?> diff --git a/lib/batch.lib.php b/lib/batch.lib.php new file mode 100644 index 00000000..f30f6f16 --- /dev/null +++ b/lib/batch.lib.php @@ -0,0 +1,66 @@ +status != 'disabled') { + $user->update_stats( $song_id ); + $total_size += sprintf("%.2f",($song->size/1048576)); + array_push( $song_files, $song->file ); + } // if song isn't disabled + } + return array($song_files,$total_size); +} //get_song_files + + +/** + * send_zip + * takes array of full paths to songs + * zips them and sends them + * @param $name name of the zip file to be created + * @param $song_files array of full paths to songs to zip create w/ call to get_song_files + */ +function send_zip( $name, $song_files ) { + + /* Require needed library */ + require_once(conf('prefix') . '/lib/archive.lib.php' ); + $arc = new zip_file( $name . ".zip" ); + $options = array( + 'inmemory' => 1, // create archive in memory + 'storepaths' => 0, // only store file name, not full path + 'level' => 0 // no compression + ); + $arc->set_options( $options ); + $arc->add_files( $song_files ); + $arc->create_archive(); + $arc->download_file(); + +} // send_zip +?> diff --git a/lib/batch.php b/lib/batch.php deleted file mode 100644 index 508564c1..00000000 --- a/lib/batch.php +++ /dev/null @@ -1,63 +0,0 @@ -status != 'disabled') { - $user->update_stats( $song_id ); - $total_size += sprintf("%.2f",($song->size/1048576)); - array_push( $song_files, $song->file ); - } // if song isn't disabled - } - return array($song_files,$total_size); -} //get_song_files - - -/*! - @function send_zip - @discussion takes array of full paths to songs - zips them and sends them - @param $song_files array of full paths to songs to zip - create w/ call to get_song_files -*/ -function send_zip( $name, $song_files ) { - require_once(conf('prefix') . '/lib/archive.php' ); - $arc = new zip_file( $name . ".zip" ); - $options = array( - 'inmemory' => 1, // create archive in memory - 'storepaths' => 0, // only store file name, not full path - 'level' => 0 // no compression - ); - $arc->set_options( $options ); - $arc->add_files( $song_files ); - $arc->create_archive(); - $arc->download_file(); -} -?> diff --git a/lib/class/access.php b/lib/class/access.php new file mode 100644 index 00000000..6e6afbf2 --- /dev/null +++ b/lib/class/access.php @@ -0,0 +1,189 @@ +id = $access_id; + + /* Get the information from the db */ + if ($info = $this->get_info()) { + + /* Assign Vars */ + $this->name = $info->name; + $this->start = $info->start; + $this->end = $info->end; + $this->level = $info->level; + } // if info + + } // if access_id + + } //constructor + + /*! + @function get_info + @discussion get's the vars for $this out of the database + @param $this->id Taken from the object + */ + function get_info() { + + /* Grab the basic information from the catalog and return it */ + $sql = "SELECT * FROM access_list WHERE id='$this->id'"; + $db_results = mysql_query($sql, dbh()); + + $results = mysql_fetch_object($db_results); + + return $results; + + } //get_info + + /*! + @function create + @discussion creates a new entry + */ + function create($name,$start,$end,$level) { + + $start = ip2int($start); + $end = ip2int($end); + $name = sql_escape($name); + $level = intval($level); + + $sql = "INSERT INTO access_list (`name`,`level`,`start`,`end`) VALUES ". + "('$name','$level','$start','$end')"; + $db_results = mysql_query($sql, dbh()); + + } // create + + /*! + @function delete + @discussion deletes $this access_list entry + */ + function delete($access_id=0) { + + if (!$access_id) { + $access_id = $this->id; + } + + $sql = "DELETE FROM access_list WHERE id='$access_id'"; + $db_results = mysql_query($sql, dbh()); + + } // delete + + /*! + @function check + @discussion check to see if they have rights + */ + function check($needed, $ip) { + + // They aren't using access control + // lets just keep on trucking + if (!conf('access_control')) { + return true; + } + + $ip = ip2int($ip); + + $sql = "SELECT id FROM access_list WHERE start<='$ip' AND end>='$ip' AND level>='$needed'"; + $db_results = mysql_query($sql, dbh()); + + // Yah they have access they can use the mojo + if (mysql_fetch_row($db_results)) { + return true; + } + + // No Access Sucks to be them. + else { + return false; + } + + } // check + + /*! + @function get_access_list + @discussion returns a full listing of all access + rules on this server + */ + function get_access_list() { + + $sql = "SELECT * FROM access_list"; + $db_results = mysql_query($sql, dbh()); + + + while ($r = mysql_fetch_object($db_results)) { + $obj = new Access(); + $obj->id = $r->id; + $obj->start = $r->start; + $obj->end = $r->end; + $obj->name = $r->name; + $obj->level = $r->level; + $results[] = $obj; + } // end while access list mojo + + return $results; + + } // get_access_list + + + /*! + @function get_level_name + @discussion take the int level and return a + named level + */ + function get_level_name() { + + if ($this->level == '75') { + return "Full Access"; + } + if ($this->level == '5') { + return "Demo"; + } + if ($this->level == '25') { + return "Stream"; + } + if ($this->level == '50') { + return "Stream/Download"; + } + + + } // get_level_name + +} //end of access class + +?> diff --git a/lib/class/album.php b/lib/class/album.php new file mode 100644 index 00000000..17befbd9 --- /dev/null +++ b/lib/class/album.php @@ -0,0 +1,463 @@ +id = $album_id; + + /* Get the information from the db */ + if ($info = $this->get_info()) { + + /* Assign Vars */ + $this->name = trim($info->prefix . " " . $info->album_name); + $this->songs = $info->song_count; + $this->artist_count = $info->artist_count; + $this->year = $info->year; + $this->artist = trim($info->artist_prefix . " " . $info->artist_name); + $this->artist_id = $info->art_id; + $this->album = $info->album_name; + + $this->prefix = $info->prefix; + } // if info + + } // if album_id + + } //constructor + + + /*! + @function get_info + @discussion get's the vars for $this out of the database + @param $this->id Taken from the object + */ + function get_info() { + + /* Grab the basic information from the catalog and return it */ + $sql = "SELECT COUNT(DISTINCT(song.artist)) as artist_count,album.prefix,album.year,album.name AS album_name,COUNT(song.id) AS song_count," . + "artist.name AS artist_name,artist.id AS art_id,artist.prefix AS artist_prefix ". + "FROM song,artist,album WHERE album.id='$this->id' AND song.album=album.id AND song.artist=artist.id GROUP BY song.album"; + + $db_results = mysql_query($sql, dbh()); + + $results = mysql_fetch_object($db_results); + + return $results; + + } //get_info + + /*! + @function get_songs + @discussion gets the songs for this album + */ + function get_songs($limit = 0) { + + $results = array(); + + $sql = "SELECT id FROM song WHERE album='$this->id' ORDER BY track, title"; + if ($limit) { $sql .= " LIMIT $limit"; } + $db_results = mysql_query($sql, dbh()); + + while ($r = mysql_fetch_object($db_results)) { + $results[] = new Song($r->id); + } + + return $results; + + } // get_songs + + + /*! + @function format_album + @dicussion reformats this object with f_name, f_songs and f_artist + that contain links etc... + */ + function format_album() { + + $web_path = conf('web_path'); + + /* Truncate the string if it's to long */ + $name = htmlspecialchars(truncate_with_ellipse($this->name,conf('ellipse_threshold_album'))); + $artist = htmlspecialchars($this->artist); + $this->f_name = "id . "\" title=\"" . $name . "\">" . $name . ""; + $this->f_songs = "
" . $this->songs . "
"; + if ($this->artist_count == '1') { + $this->f_artist = "artist_id . "\">" . $artist . ""; + } + else { + $this->f_artist = _("Various"); + } + + if ($this->year == '0') { + $this->year = "N/A"; + } + + } // format_album + + /*! + @function get_art + @discussion get art wrapper function + */ + function get_art($fast = 0) { + + /* Check DB first */ + if ($image = $this->get_db_art()) { + return $image; + } + + /* Stop here if we are doing the fast art */ + if ($fast) { return false; } + + /* Create Base Vars */ + $album_art_order = array(); + + /* Attempt to retrive the album art order */ + $config_value = conf('album_art_order'); + $class_methods = get_class_methods('Album'); + + /* If it's not set */ + if (empty($config_value)) { + $album_art_order = array('id3','folder','amazon'); + } + elseif (!is_array($config_value)) { + $album_art_order = array_push($album_art_order,$config_value); + } + else { + $album_art_order = array_merge($album_art_order, conf('album_art_order')); + } + + foreach ($album_art_order AS $method) { + + $method_name = "get_" . $method . "_art"; + + if (in_array($method_name,$class_methods)) { + if ($this->{$method_name}()) { + return $this->get_db_art(); + } // if method finds the art + } // if the method exists + + } // end foreach + + return false; + + } // get_art + + /*! + @function get_id3_art + @discussion looks for art from the id3 tags + */ + function get_id3_art() { + + $songs = $this->get_songs(); + + // Foreach songs in this album + foreach ($songs as $song) { + // If we find a good one, stop looking + $getID3 = new getID3(); + $id3 = $getID3->analyze($song->file); + + if ($id3['format_name'] == "WMA") { + $image = $id3['asf']['extended_content_description_object']['content_descriptors']['13']; + } + else { + $image = $id3['id3v2']['APIC']['0']; + } + if ($image) { + $art = $image['data']; + $mime = $image['mime']; + + // Stick it in the db for next time + $sql = "UPDATE album SET art = '" . sql_escape($art) . "'," . + " art_mime = '" . sql_escape($mime) . "'" . + " WHERE id = '" . $this->id . "'"; + $db_result = mysql_query($sql, dbh()); + + return true; + } // end if image + } // end foreach + + return false; + + } // get_id3_art + + /*! + @function get_folder_art() + @discussion returns the album art from the folder of the mp3s + */ + function get_folder_art() { + + $songs = $this->get_songs(); + + /* See if we are looking for a specific filename */ + $preferred_filename = conf('album_art_preferred_filename'); + + /* Thanks to dromio for origional code */ + /* Added search for any .jpg, png or .gif - Vollmer */ + foreach($songs as $song) { + $dir = dirname($song->file); + + /* Open up the directory */ + $handle = @opendir($dir); + + if (!is_resource($handle)) { + echo "" . _("Error: Unable to open") . " $dir
\n"; + if (conf('debug')) { log_event($GLOBALS['user']->username,' read ',"Error: Unable to open $dir for album art read"); } + } + + /* Recurse through this dir and create the files array */ + while ( FALSE !== ($file = @readdir($handle)) ) { + $extension = substr($file,strlen($file)-3,4); + + /* If it's an image file */ + if ($extension == "jpg" || $extension == "gif" || $extension == "png" || $extension == "jp2") { + + if ($file == $preferred_filename) { + $found = 1; + $album_art_filename = array('file' => $file, 'ext' => $extension); + break; + } + elseif (!$preferred_filename) { + $found = 1; + $album_art_filename = array('file' => $file, 'ext' => $extension); + break; + } + else { + $found = 1; + $album_art_filename = array('file' => $file, 'ext' => $extension); + } + + } // end if it's an image + + } // end while reading dir + @closedir($handle); + + if ($found) { + $handle = fopen($dir."/".$album_art_filename['file'], "rb"); + $mime = "image/" . $album_art_filename['ext']; + $art = ''; + while(!feof($handle)) { + $art .= fread($handle, 1024); + } + fclose($handle); + $sql = "UPDATE album SET art = '" . sql_escape($art) . "'," . + " art_mime = '" . sql_escape($mime) . "'" . + " WHERE id = '$this->id'"; + $db_results = mysql_query($sql, dbh()); + return true; + } // if found + } // end foreach songs + + return false; + + } // get_folder_art() + + /*! + @function get_db_art() + @discussion returns the album art from the db + */ + function get_db_art() { + + $sql = "SELECT art,art_mime FROM album WHERE id='$this->id' AND art_mime IS NOT NULL"; + $db_results = mysql_query($sql, dbh()); + + $results = mysql_fetch_object($db_results); + + return $results; + + } // get_db_art + + + /*! + @function get_amazon_art + @discussion searches amazon for the + album art + */ + function get_amazon_art() { + + return $this->find_art(); + + } // get_amazon_art + + /*! + @function get_random_songs + @discussion gets a random number, and + a random assortment of songs from this + album + */ + function get_random_songs() { + + $results = array(); + + $sql = "SELECT id FROM song WHERE album='$this->id' ORDER BY RAND() LIMIT " . rand(1,$this->songs); + $db_results = mysql_query($sql, dbh()); + + while ($r = mysql_fetch_array($db_results)) { + $results[] = $r[0]; + } + + return $results; + + } // get_random_songs + + /*! + @function clear_art + @discussion clears the album art from the DB + */ + function clear_art() { + + $sql = "UPDATE album SET art=NULL, art_mime=NULL WHERE id='$this->id'"; + $db_results = mysql_query($sql, dbh()); + + } // clear_art + + /*! + @function find_art + @discussion searches amazon or a url + for the album art + //FIXME: Rename this POS + */ + function find_art($coverurl = '') { + + // No coverurl specified search amazon + if (empty($coverurl)) { + $amazon = new AmazonSearch(conf('amazon_developer_key')); + // Prevent the script from timing out + set_time_limit(0); + $search_term = $this->artist . " " . $this->name; + $amazon->search(array('artist' => $this->artist, 'album' => $this->name, 'keywords' => $serch_term)); + // Only do the second search if the first actually returns something + if (count($amazon->results)) { + $amazon->lookup($amazon->results); + } + + /* Log this if we're doin debug */ + if (conf('debug')) { + log_event($_SESSION['userdata']['username'],' amazon-xml ',"Searched using $search_term with " . conf('amazon_developer_key') . " as key " . count($amazon->results) . " results found"); + } + + //FIXME: For now just pull the first one we find + foreach ($amazon->results as $key=>$value) { + $results = $value; + break; + } //FIXME: + + } // if no cover + // If we've specified a coverurl, create a fake Amazon array with it + else { + $results = array('LargeImage' => $coverurl); + } + + // If we have results of some kind + if (is_array($results)) { + + /* Recurse through the images found */ + $possible_keys = array("LargeImage","MediumImage","SmallImage"); + + foreach ($possible_keys as $key) { + if (strlen($results[$key])) { + break; + } + + + } // foreach + + // Rudimentary image type detection, only JPG and GIF allowed. + if (substr($results[$key], -4 == ".jpg")) { + $mime = "image/jpg"; + } + elseif (substr($results[$key], -4 == ".gif")) { + $mime = "image/gif"; + } + else { + return false; + } + + /* Create Snoopy Object and pull info */ + $snoopy = new Snoopy; + $snoopy->fetch($results[$key]); + $art = $snoopy->results; + + // Skip 1x1 size images + if (function_exists('ImageCreateFromString')) { + $im = @ImageCreateFromString($art); + if (@imagesx($im) == 1 || @imagesy($im) == 1 && $im) { + return false; + } + } + + // Push the image into the database + $sql = "UPDATE album SET art = '" . sql_escape($art) . "'," . + " art_mime = '" . sql_escape($mime) . "'" . + " WHERE id = '$this->id'"; + $db_results = mysql_query($sql, dbh()); + + return true; + + } // if we've got something + + /* Default to false */ + return false; + + } // find_art + + /*! + @function get_song_ids + @discussion returns a list of song_ids on the album + get_songs returns a list of song objects + */ + + // it seems get_songs really should call this, + // but I don't feel comfortable imposing that - RCR + function get_song_ids( $limit = 0 ) { + $results = array(); + $sql = "SELECT id FROM song WHERE album='$this->id' ORDER BY track, title"; + if ($limit) { $sql .= " LIMIT $limit"; } + $db_results = mysql_query($sql, dbh()); + + while ($r = mysql_fetch_object($db_results)) { + $results[] = $r->id; + } + return( $results ); + } // get_song_ids + +} //end of album class + +?> diff --git a/lib/class/artist.php b/lib/class/artist.php new file mode 100644 index 00000000..2a6e3308 --- /dev/null +++ b/lib/class/artist.php @@ -0,0 +1,205 @@ +id = $song_id; + + /* Get the information from the db */ + if ($info = $this->get_info()) { + + /* Assign Vars */ + $this->name = $info->name; + $this->prefix = $info->prefix; + } // if info + + } // if song_id + + } //constructor + + + /*! + @function get_info + @discussion get's the vars for $this out of the database + @param $this->id Taken from the object + */ + function get_info() { + + /* Grab the basic information from the catalog and return it */ + $sql = "SELECT * FROM artist WHERE id='$this->id'"; + $db_results = mysql_query($sql, dbh()); + + $results = mysql_fetch_object($db_results); + + return $results; + + } //get_info + + /*! + @function get_albums + @discussion gets the albums for this artist + */ + function get_albums() { + + $results = array(); + + $sql = "SELECT DISTINCT(album.id) FROM song,album WHERE song.album=album.id AND song.artist='$this->id' ORDER BY album.name"; + $db_results = mysql_query($sql, dbh()); + + while ($r = mysql_fetch_object($db_results)) { + $results[] = new Album($r->id); + } + + return $results; + + } // get_albums + + /*! + @function get_songs + @discussion gets the songs for this artist + */ + function get_songs() { + + $sql = "SELECT song.id FROM song WHERE song.artist='$this->id'"; + $db_results = mysql_query($sql, dbh()); + + while ($r = mysql_fetch_object($db_results)) { + $results[] = new Song($r->id); + } + + return $results; + + } // get_songs + + /*! + @function get_random_songs + @discussion gets a random number, and + a random assortment of songs from this + album + */ + function get_random_songs() { + + $results = array(); + + $sql = "SELECT id FROM song WHERE artist='$this->id' ORDER BY RAND() LIMIT " . rand(1,$this->songs); + $db_results = mysql_query($sql, dbh()); + + while ($r = mysql_fetch_array($db_results)) { + $results[] = $r[0]; + } + + return $results; + + } // get_random_songs + + /*! + @function get_count + @discussion gets the album and song count of + this artist + */ + function get_count() { + + /* Define vars */ + $songs = 0; + $albums = 0; + + $sql = "SELECT COUNT(song.id) FROM song WHERE song.artist='$this->id' GROUP BY song.album"; + $db_results = mysql_query($sql, dbh()); + + while ($r = mysql_fetch_array($db_results)) { + $songs += $r[0]; + $albums++; + } + + /* Set Object Vars */ + $this->songs = $songs; + $this->albums = $albums; + + return true; + + } // get_count + + /*! + @function format_artist + @discussion this function takes an array of artist + information and reformats the relevent values + so they can be displayed in a table for example + it changes the title into a full link. + */ + function format_artist() { + + /* Combine prefix and name, trim then add ... if needed */ + $name = htmlspecialchars(truncate_with_ellipse(trim($this->prefix . " " . $this->name))); + $this->f_name = $this->name; + $this->full_name = htmlspecialchars(trim($this->prefix . " " . $this->name)); + //FIXME: This shouldn't be set like this, f_name should be like this + $this->link = "id . "\" title=\"" . $this->full_name . "\">" . $name . ""; + $this->name = $this->link; + return $artist; + + } // format_artist + + + /*! + @function show_albums + @discussion displays the show albums by artist page + */ + function show_albums() { + + /* Set Vars */ + $web_path = conf('web_path'); + + + $albums = $this->get_albums(); + $this->format_artist(); + $artist = $this; + + require (conf('prefix') . "/templates/show_artist.inc"); + + } // show_albums + + +} //end of artist class + +?> diff --git a/lib/class/catalog.php b/lib/class/catalog.php new file mode 100644 index 00000000..9affc95a --- /dev/null +++ b/lib/class/catalog.php @@ -0,0 +1,1934 @@ +id = $catalog_id; + + /* Get the information from the db */ + $info = $this->get_info(); + + /* Assign Vars */ + $this->path = $info->path; + $this->name = $info->name; + $this->last_update = $info->last_update; + $this->last_add = $info->last_add; + $this->id3_set_command = $info->id3_set_command; + $this->rename_pattern = $info->rename_pattern; + $this->sort_pattern = $info->sort_pattern; + $this->catalog_type = $info->catalog_type; + } //catalog_id + + } //constructor + + + /*! + @function get_info + @discussion get's the vars for $this out of the database + @param $this->id Taken from the object + */ + function get_info() { + + /* Grab the basic information from the catalog and return it */ + $sql = "SELECT * FROM catalog WHERE id='$this->id'"; + $db_results = mysql_query($sql, dbh()); + + $results = mysql_fetch_object($db_results); + + return $results; + + } //get_info + + + /*! + @function get_catalogs + @discussion Pull all the current catalogs + */ + function get_catalogs() { + + $sql = "SELECT id FROM catalog"; + $db_results = mysql_query($sql, dbh()); + + while ($r = mysql_fetch_object($db_results)) { + $results[] = new Catalog($r->id); + } + + return $results; + + } // get_catalogs + + + /*! + @function get_catalog_stats + @discussion Pulls information about number of songs etc for a specifc catalog, or all catalogs + calls many other internal functions, returns an object containing results + @param $catalog_id If set tells us to pull from a single catalog, rather than all catalogs + */ + function get_catalog_stats($catalog_id=0) { + + $results->songs = $this->count_songs($catalog_id); + $results->albums = $this->count_albums($catalog_id); + $results->artists = $this->count_artists($catalog_id); + $results->size = $this->get_song_size($catalog_id); + $results->time = $this->get_song_time($catalog_id); + + } // get_catalog_stats + + + /*! + @function get_song_time + @discussion Get the total amount of time (song wise) in all or specific catalog + @param $catalog_id If set tells ut to pick a specific catalog + */ + function get_song_time($catalog_id=0) { + + $sql = "SELECT SUM(song.time) FROM song"; + if ($catalog_id) { + $sql .= " WHERE catalog='$catalog_id'"; + } + + $db_results = mysql_query($sql, dbh()); + + $results = mysql_fetch_field($db_results); + + /* Do some conversion to get Hours Min Sec */ + + + return $results; + + } // get_song_time + + + /*! + @function get_song_size + @discussion Get the total size of songs in all or a specific catalog + @param $catalog_id If set tells us to pick a specific catalog + */ + function get_song_size($catalog_id=0) { + + $sql = "SELECT SUM(song.size) FROM song"; + if ($catalog_id) { + $sql .= " WHERE catalog='$catalog_id'"; + } + + $db_results = mysql_query($sql, dbh()); + + $results = mysql_fetch_field($db_results); + + /* Convert it into MB */ + $results = ($results / 1048576); + + return $results; + + } // get_song_size + + + /*! + @function count_artists + @discussion Count the number of artists in all catalogs or in a specific one + @param $catalog_id If set tells us to pick a specific catalog + */ + function count_artists($catalog_id=0) { + + $sql = "SELECT DISTINCT(song.artist) FROM song"; + if ($catalog_id) { + $sql .= " WHERE catalog='$catalog_id'"; + } + + $db_results = mysql_query($sql,dbh()); + + $results = mysql_num_rows($db_results); + + return $results; + + } // count_artists + + + /*! + @function count_albums + @discussion Count the number of albums in all catalogs or in a specific one + @param $catalog_id If set tells us to pick a specific catalog + */ + function count_albums($catalog_id=0) { + + $sql = "SELECT DISTINCT(song.album) FROM song"; + if ($catalog_id) { + $sql .=" WHERE catalog='$catalog_id'"; + } + + $db_results = mysql_query($sql, dbh()); + + $results = mysql_num_rows($db_results); + + return $results; + + } // count_albums + + + /*! + @function count_songs + @discussion Count the number of songs in all catalogs, or a specific one + @param $catalog_id If set tells us to pick a specific catalog + */ + function count_songs($catalog_id=0) { + + $sql = "SELECT count(*) FROM song"; + if ($catalog_id) { + $sql .= " WHERE catalog='$catalog_id'"; + } + + $db_results = mysql_query($sql, dbh()); + $results = mysql_fetch_field($db_results); + + return $results; + + } // count_songs + + /*! + @function add_file + @discussion adds a single file + */ + function add_file($filename) { + + $file_size = @filesize($filename); + $pattern = "/\.[" . conf('catalog_file_pattern') . "]$/i"; + + if ( preg_match($pattern ,$filename) && ($file_size > 0) && (!preg_match('/\.AppleDouble/', $filename)) ) { + if(!$this->check_local_mp3($filename,$gather_type)) { + $this->insert_local_song($filename,$file_size); + } + } // if valid file + + + } // add_file + + + /*! + @function add_files + @discussion Recurses throught $this->path and pulls out all mp3s and returns the full + path in an array. Passes gather_type to determin if we need to check id3 + information against the db. + @param $path The root path you want to start grabing files from + @param $gather_type=0 Determins if we need to check the id3 tags of the file or not + */ + function add_files($path,$gather_type=0,$parse_m3u=0) { + /* Strip existing escape slashes and then add them again + This is done because we keep adding to the dir (slashed) + (non slashed) + and a double addslashes would pooch things + */ + + /* Open up the directory */ + $handle = opendir(stripslashes($path)); + + if (!is_resource($handle)) { + if (conf('debug')) { log_event($_SESSION['userdata']['username'],'read',"Unable to Open $path",'ampache-catalog'); } + echo "" . _("Error: Unable to open") . " $path
\n"; + } + + /* Recurse through this dir and create the files array */ + while ( false !== ( $file = readdir($handle) ) ) { + + // Fix Found by Naund + // Needed to protect from ' in filenames + $file = sql_escape($file); + + // Prevent the script from timing out + set_time_limit(0); + + /* if not .. or . */ + if ($file != "." AND $file != "..") { + + if (conf('debug')) { + log_event($_SESSION['userdata']['username'],'read',"Starting work on $file inside $path",'ampache-catalog'); + } + + /* Change the dir so is_dir works correctly */ + if (!@chdir(stripslashes($path))) { + if (conf('debug')) { log_event($_SESSION['userdata']['username'],'read',"Unable to chdir $path",'ampache-catalog'); } + echo "" . _("Error: Unable to change to directory") . " $path
\n"; + } + + /* Create the new path */ + $full_file = stripslashes($path."/".$file); + $full_file = str_replace("//","/",$full_file); + + if (conf('no_symlinks')) { + if (is_link($full_file)) { $failed_check = 1; } + } + + /* If it's a dir run this function again! */ + if (is_dir($full_file) AND !$failed_check) { + $this->add_files($full_file,$gather_type,$parse_m3u); + unset($failed_check); + } //it's a directory + + /* If it's not a dir let's roll with it */ + else { + /* Get the file information */ + $file_size = @filesize($full_file); + + if (!$file_size && $file_size != '0') { + echo "" . _("Error: Unable to get filesize for") . " $full_file
"; + if (conf('debug')) { log_event($GLOBALS['user']->username,' read ',"Error: Unable to get filesize for $full_file",'ampache-catalog'); } + } // if no filesize + + $pattern = "/\.(" . conf('catalog_file_pattern'); + if ($parse_m3u) { + $pattern .= "|m3u)$/i"; + } + else { + $pattern .= ")$/i"; + } + + /* see if this is an mp3 file and if it is greater than 0 bytes */ + if ( preg_match($pattern ,$file) && ($file_size > 0) && (!preg_match('/\.AppleDouble/', $file)) ) { + + if (is_readable($full_file)) { + + if (substr($file,-3,3) == 'm3u') { + if ($this->import_m3u($full_file)) { + echo "   " . _("Added Playlist From") . " $file . . . .
\n"; + flush(); + } + } // if it's an m3u + + else { + + /* see if the current song is in the catalog */ + $found = $this->check_local_mp3($full_file,$gather_type); + + /* If not found then insert, gets id3 information + * and then inserts it into the database + */ + if (!$found) { + $this->insert_local_song($full_file,$file_size); + + /* Stupid little cutesie thing */ + $this->count++; + if ( !($this->count%conf('catalog_echo_count')) ) { + echo _("Added") . " $this->count. . . .
\n"; + flush(); + } //echos song count + + } // not found + + } // if it's not an m3u + + } // is readable + else { + // not readable, warn user + if (conf('debug')) { log_event($_SESSION['userdata']['username'],'read',"$full_file is not readable by ampache",'ampache-catalog'); } + echo "$full_file " . _("is not readable by ampache") . ".
\n"; + + } + + } //if it's a mp3 and is greater than 0 bytes + + else { + if (conf('debug')) { + log_event($_SESSION['userdata']['username'],'read',"$full_file ignored, non audio file or 0 bytes",'ampache-catalog'); + } + } // else not an audio file or 0 size + + } //else it's not a directory + + } //end if not . or .. + + } //end while + + if (conf('debug')) { + log_event($_SESSION['userdata']['username'],' closedir ',"Finished reading $path closing handle",'ampache-catalog'); + } + + /* Close the dir handle */ + @closedir($handle); + + } //add_files + + /*! + @function get_albums + @discussion This gets albums for all songs passed in an array + */ + function get_albums($songs=array()) { + + foreach ($songs as $song_id) { + $sql = "SELECT album FROM song WHERE id='$song_id'"; + $db_results = mysql_query($sql, dbh()); + $results = mysql_fetch_array($db_results); + $albums[] = new Album($results[0]); + } // files + + return $albums; + + } // get_albums + + /*! + @function get_album_art + @discussion This runs through all of the albums and trys to find the + art for them from the mp3s + //FIXME: Make the display a table so it all lines up + */ + function get_album_art($catalog_id=0,$methods=array()) { + + if (!$catalog_id) { $catalog_id = $this->id; } + + // Get all of the albums in this catalog + $albums = $this->get_catalog_albums($catalog_id); + + // Run through them an get the art! + foreach ($albums as $album) { + flush(); + if ($debug) { echo "    " . $album->name . " -- "; } + + if ($methods['id3']) { + $found = $album->get_id3_art(); + if ($found && $debug) { echo _("Found in ID3") . "
\n"; } + } + if ($methods['amazon'] && !$found) { + $found = $album->get_amazon_art(); + if ($found && $debug) { echo _("Found on Amazon") . "
\n"; } + } + if ($methods['folder'] && !$found) { + $found = $album->get_folder_art(); + if ($found && $debug) { echo _("Found in Folder") . "
\n"; } + } + if (count($methods) == '0' && !$found) { + $found = $album->get_art(); + if ($found && $debug) { echo _("Found") . "
\n"; } + } + + if (!$found && $debug) { echo "" . _("Not Found") . "
\n"; } + + if ($found) { $art_found++; } + + + /* Stupid little cutesie thing */ + $search_count++; + if ( !($search_count%conf('catalog_echo_count')) ) { + echo _("Searched") . " $search_count. . . .
\n"; + flush(); + } //echos song count + + + // Prevent the script from timing out + set_time_limit(0); + + unset($found); + + } // foreach albums + + echo "$art_found album's with art. . .
\n"; + flush(); + + } // get_album_art + + /*! + @function get_catalog_albums() + @discussion Returns an array of the albums from a catalog + */ + function get_catalog_albums($catalog_id=0) { + + $results = array(); + + /* Use $this->id if nothing is passed */ + if (!$catalog_id) { $catalog_id = $this->id; } + + $sql = "SELECT DISTINCT(album.id) FROM album,song WHERE song.catalog='$catalog_id' AND song.album=album.id"; + $db_results = mysql_query($sql, dbh()); + + while ($r = mysql_fetch_object($db_results)) { + $results[] = new Album($r->id); + } + + return $results; + + } // get_catalog_albums + + + /*! + @function get_catalog_files + @discussion Returns an array of song objects from a catalog + @param $catalog_id=0 Specify the catalog ID you want to get the files of + */ + function get_catalog_files($catalog_id=0) { + + $results = array(); + + /* Use $this->id if nothing passed */ + if (!$catalog_id) { $catalog_id = $this->id; } + + $sql = "SELECT id FROM song WHERE catalog='$catalog_id' AND status='enabled'"; + $db_results = mysql_query($sql, dbh()); + + $results = array(); // return an emty array instead of nothing if no objects + while ($r = mysql_fetch_object($db_results)) { + $results[] = new Song($r->id); + } //end while + + return $results; + + } //get_catalog_files + + + /*! + @function get_disabled + @discussion Gets an array of the disabled songs for all catalogs + and returns full song objects with them + */ + function get_disabled() { + global $conf; + + $results = array(); + + $sql = "SELECT id FROM song WHERE status='disabled'"; + $db_results = mysql_query($sql, dbh()); + + while ($r = mysql_fetch_array($db_results)) { + $results[] = new Song($r['id']); + } + + return $results; + + } // get_disabled + + + /*! + @function get_files + @discussion Get's an array of .mp3s and returns the filenames + @param $path Get files starting at root $path + */ + function get_files($path) { + + /* Set it as an empty array */ + $files = array(); + + $path = stripslashes($path); + + /* Open up the directory */ + $handle = @opendir($path); + + if (!is_resource($handle)) { echo "" . _("Error: Unable to open") . " $path
\n"; } + + /* Change dir so we can tell if it's a directory */ + if (!@chdir($path)) { + echo "Error: Unable to change to $path directory
\n"; + } + + /* Recurse through this dir and create the files array */ + while ( FALSE !== ($file = @readdir($handle)) ) { + + $full_file = stripslashes($path . "/" . $file); + $full_file = str_replace("//","/",$full_file); + + if (conf('no_symlinks')) { + if (is_link($full_file)) { $failed_check = true; } + } + + /* It's a dir */ + if (is_dir($full_file) AND $file != "." AND $file != ".." AND !$failed_check) { + /* Merge the results of the get_files with the current results */ + $files = array_merge($files,$this->get_files($full_file)); + } //isdir + + /* Get the file information */ + $file_info = filesize($full_file); + + $pattern = "/\.[" . conf('catalog_file_pattern') . "]$/i"; + + if ( preg_match($pattern ,$file) && ($file_info > 0) && (!preg_match("/\.AppleDouble/", $file)) ) { + $files[] = $full_file; + } //is mp3 of at least some size + + } //end while + + /* Close the dir handle */ + @closedir($handle); + + /* Return the files array */ + return $files; + + } //get_files + + /*! + @function dump_album_art (Added by Cucumber 20050216) + @discussion This runs through all of the albums and trys to dump the + art for them into the 'folder.jpg' file in the appropriate dir + */ + function dump_album_art($catalog_id=0,$methods=array()) { + if (!$catalog_id) { $catalog_id = $this->id; } + + // Get all of the albums in this catalog + $albums = $this->get_catalog_albums($catalog_id); + + echo "
" . _("Starting Dump Album Art") . ". . .

\n"; + + // Run through them an get the art! + foreach ($albums as $album) { + flush(); + if ($image = $album->get_db_art()) { + /* Get the first song in the album */ + $songs = $album->get_songs(1); + $song = $songs[0]; + $dir = dirname($song->file); + $extension = substr($image->art_mime,strlen($image->art_mime)-3,3); + + $preferred_filename = conf('album_art_preferred_filename'); + if (!$preferred_filename) { $preferred_filename = "folder.$extension"; } + + $file = "$dir/$preferred_filename"; + if ($file_handle = @fopen($file,"w")) { + if (fwrite($file_handle, $image->art)) { + $i++; + if ( !($i%conf('catalog_echo_count')) ) { + echo _("Written") . " $i. . .
\n"; + flush(); + } //echos song count + if (conf('debug')) { log_event($_SESSION['userdata']['username'],'art_write',"$album->name Art written to $file"); } + } + fclose($file_handle); + } // end if fopen + else { + if (conf('debug')) { log_event($_SESSION['userdata']['username'],'art_write',"Unable to open $file for writting"); } + echo "" . _("Error unable to open file for writting") . " [$file]
\n"; + } + + } // end if image + + } // end foreach + + echo "
" . _("Album Art Dump Complete") . "   "; + echo "[" . _("Return") . "]"; + + flush(); + + } // dump_album_art + + /*! + @function update_last_update + @discussion updates the last_update of the catalog + */ + function update_last_update() { + + $date = time(); + $sql = "UPDATE catalog SET last_update='$date' WHERE id='$this->id'"; + $db_results = mysql_query($sql, dbh()); + + } // update_last_update + + + /*! + @function update_last_add + @discussion updates the last_add of the catalog + */ + function update_last_add() { + + $date = time(); + $sql = "UPDATE catalog SET last_add='$date' WHERE id='$this->id'"; + $db_results = mysql_query($sql, dbh()); + + } // update_last_add + + + /*! + @function new_catalog + @discussion The Main array for making a new catalog calls many other child functions within this class + @param $path Root path to start from for catalog + @param $name Name of the new catalog + */ + function new_catalog($path,$name, $id3cmd=0, $ren=0, $sort=0, $type=0,$gather_art=0,$parse_m3u=0,$art=array()) { + + /* Record the time.. time the catalog gen */ + $start_time = time(); + + /* Flush anything that has happened so they don't think it's locked */ + flush(); + + /* + * Step one Add this to the catalog table if it's not + * already there returns the new catalog_id + */ + $catalog_id = $this->check_catalog($path); + + if (!$catalog_id) { + $catalog_id = $this->create_catalog_entry($path,$name,$id3cmd, $ren, $sort, $type); + } + + /* Setup the $this with the new information */ + $this->id = $catalog_id; + $this->path = $path; + $this->name = $name; + $this->id3_set_command = ($id3cmd)?$id3cmd:''; + $this->rename_pattern = ($ren)?$ren:''; + $this->sort_pattern = ($sort)?$sort:''; + $this->catalog_type = $type; + + /* Fluf */ + echo _("Starting Catalog Build") . " [$name]
\n"; + flush(); + + + if ($this->catalog_type == 'remote') { + echo _("Running Remote Sync") . ". . .

"; + flush(); + $this->get_remote_catalog($type=0); + return true; + } + /* Get the songs and then insert them into the db */ + $this->add_files($this->path,$type,$parse_m3u); + + /* Now Adding Album Art? */ + if ($gather_art) { + echo "
\n" . _("Starting Album Art Search") . ". . .
\n"; + flush(); + $this->get_album_art(0,$art); + } // if we want to gather album art + + /* Do a little stats mojo here */ + $current_time = time(); + + $time_diff = $current_time - $start_time; + if ($time_diff) { $song_per_sec = intval($this->count/$time_diff); } + echo _("Catalog Finished") . ". . . " . _("Total Time") . " [" . date("i:s",$time_diff) . "] " . _("Total Songs") . " [" . $this->count . "] " . + _("Songs Per Seconds") . " [" . $song_per_sec . "]
\n"; + + return $catalog_id; + + } //new_catalog + + /*! + @function update_single_item + @discussion updates a single album,artist,song + */ + function update_single_item($type,$id) { + + $songs = array(); + + switch ($type) { + case 'album': + $album = new Album($id); + $songs = $album->get_songs(); + break; + case 'artist': + $artist = new Artist($id); + $songs = $artist->get_songs(); + break; + case 'song': + $songs[0] = new Song($id); + break; + } // end switch type + + foreach($songs as $song) { + + $info = $this->update_song_from_tags($song); + + if ($info['change']) { + echo "
\n\t
  • "; + echo "$song->file " . _("Updated") . "\n"; + echo $info['text']; + echo "\t
  • \n

    "; + flush(); + } // if change + else { + echo"
    \n\t
  • "; + echo "$song->file
    " . _("No Update Needed") . "\n"; + echo "\t
  • \n

    "; + flush(); + } + } // foreach songs + + } // update_single_item + + /*! + @function update_song_from_tags + @discussion updates the song info based on tags + */ + function update_song_from_tags($song) { + + $info = new Audioinfo(); + $results = $info->Info($song->file); + + /* Find the correct key */ + $key = get_tag_type($results); + + /* Fill Missing Information */ + $results = $song->fill_info($results,$this->sort_pattern . "/" . $this->rename_pattern, $this->id, $key); + + /* Clean up the tags */ + $results = clean_tag_info($results,$key,$song->file); + + /* Setup the vars */ + $new_song = new Song(); + $new_song->file = $results['file']; + $new_song->title = $results['title']; + $new_song->year = $results['year']; + $new_song->comment = $results['comment']; + $new_song->bitrate = $results['bitrate']; + $new_song->rate = $results['rate']; + $new_song->mode = $results['mode']; + $new_song->size = $results['size']; + $new_song->time = $results['time']; + $new_song->track = $results['track']; + $artist = $results['artist']; + $album = $results['album']; + $genre = $results['genre']; + + /* Clean up Old Vars */ + unset($results,$key,$info); + + /* + * We have the artist/genre/album name need to check it in the tables + * If found then add & return id, else return id + */ + $new_song->artist = $this->check_artist($artist); + $new_song->f_artist = $artist; + $new_song->genre = $this->check_genre($genre); + $new_song->f_genre = $genre; + $new_song->album = $this->check_album($album,$new_song->year); + $new_song->f_album = $album . " - " . $new_song->year; + $new_song->title = $this->check_title($new_song->title,$new_song->file); + + $info = $song->compare_song_information($song,$new_song); + + if ($info['change']) { + $song->update_song($song->id,$new_song); + } + + return $info; + + } // update_song_from_tags + + /*! + @function add_to_catalog + @discussion this function adds new files to an + existing catalog + */ + function add_to_catalog($type=0) { + + echo _("Starting New Song Search on") . " [$this->name] " . _("catalog") . "

    \n"; + flush(); + + if ($this->catalog_type == 'remote') { + echo _("Running Remote Update") . ". . .

    "; + flush(); + $this->get_remote_catalog($type=0); + return true; + } + + /* Set the Start time */ + $start_time = time(); + + /* Get the songs and then insert them into the db */ + $this->add_files($this->path,$type); + + /* Do a little stats mojo here */ + $current_time = time(); + + if ($type != "fast_add") { + echo "" . _("Starting Album Art Search") . ". . .
    \n"; + flush(); + $this->get_album_art(); + } + + /* Update the Catalog last_update */ + $this->update_last_add(); + + $time_diff = $current_time - $start_time; + if ($time_diff) { + $song_per_sec = intval($this->count/$time_diff); + } + if (!$song_per_sec) { + $song_per_sec = "N/A"; + } + if (!$this->count) { + $this->count = 0; + } + + echo "\n
    " . _("Catalog Update Finished") . "... " . _("Total Time") . " [" . date("i:s",$time_diff) . "] " . + _("Total Songs") . " [" . $this->count . "] " . _("Songs Per Seconds") . " [" . $song_per_sec . "]

    "; + + } // add_to_catalog + + + /*! + @function get_remote_catalog + @discussion get a remote catalog and runs update if needed + */ + function get_remote_catalog($type=0) { + + if (!class_exists('xmlrpc_client')) { + if (conf('debug')) { log_event($_SESSION['userdata']['username'],'xmlrpc',"Unable to load XMLRPC library"); } + echo "" . _("Error") . ": " . _("Unable to load XMLRPC library, make sure XML-RPC is enabled") . "
    \n"; + return false; + } + + // first, glean out the information from the path about the server and remote path + preg_match("/http:\/\/([^\/]+)\/*(.*)/", $this->path, $match); + $server = $match[1]; + $path = $match[2]; + + if ( ! $path ) { + $client = new xmlrpc_client("/server.php", $server, 80); + } + else { + $client = new xmlrpc_client("/$path/server.php", $server, 80); + } + + $f = new xmlrpcmsg('remote_server_query', array(new xmlrpcval( conf('web_path'), "string")) ); + //if (conf('debug')) { $client->setDebug(1); } + $response = $client->send($f); + $value = $response->value(); + + if ( !$response->faultCode() ) { + $data = old_xmlrpc_decode($value); + + // Print out the catalogs we are going to sync + //FIXME: We should add catalog level access control + foreach ($data as $vars) { + $catalog_name = $vars[0]; + print("Reading Remote Catalog: $catalog_name [$this->path]
    \n"); + } + } + else { + $error_msg = _("Error connecting to") . " " . $server . " " . _("Code") . ": " . $response->faultCode() . " " . _("Reason") . ": " . $response->faultString(); + log_event($_SESSION['userdata']['username'],'xmlrpc',$error_msg); + echo "

    $error_msg

    "; + return; + } + + $f = new xmlrpcmsg('remote_song_query', array(new xmlrpcval( 'song', "string")) ); + $response = $client->send($f); + $value = $response->value(); + + if ( !$response->faultCode() ) { + $data = old_xmlrpc_decode($value); + $this->update_remote_catalog($data,$this->path); + } + else { + $error_msg = _("Error connecting to") . " " . $server . " " . _("Code") . ": " . $response->faultCode() . " " . _("Reason") . ": " . $response->faultString(); + log_event($_SESSION['userdata']['username'],'xmlrpc',$error_msg); + echo "

    $error_msg

    "; + } + + echo "

    " . _("Completed updating remote catalog(s)") . ".


    \n"; + + + } // get_remote_catalog + + /*! + @function update_remote_catalog + @discussion actually updates from the remote data + */ + function update_remote_catalog($songs,$root_path) { + global $settings, $dbh, $artists; + + + /* + We need to check the incomming songs + to see which ones need to be added + */ + foreach ($songs as $song) { + + // Prevent a timeout + set_time_limit(0); + + $song = base64_decode($song); + + $data = explode("::", $song); + + $new_song->artist = $this->check_artist($data[0]); + $new_song->album = $this->check_album($data[1],$data[4]); + $new_song->title = $data[2]; + $new_song->comment = $data[3]; + $new_song->year = $data[4]; + $new_song->bitrate = $data[5]; + $new_song->rate = $data[6]; + $new_song->mode = $data[7]; + $new_song->size = $data[8]; + $new_song->time = $data[9]; + $new_song->track = $data[10]; + $new_song->genre = $this->check_genre($data[11]); + $new_song->file = $root_path . "/play/index.php?song=" . $data[12] . "uid=$md5_ip"; + $new_song->catalog = $this->id; + + if (!$song_id = $this->check_remote_song($new_song->file)) { + $this->insert_remote_song($new_song); + } + + } // foreach new Songs + + //FIXME: Delete Songs that were not updated (gone) + + // now delete invalid entries + $this->clean_albums(); + $this->clean_stats(); + $this->clean_artists(); + $this->clean_flagged(); + + } // update_remote_catalog + + + /*! + @function clean_catalog + @discussion Cleans the Catalog of files that no longer exist grabs from $this->id or $id passed + Doesn't actually delete anything, disables errored files, and returns them in an array + @param $catalog_id=0 Take the ID of the catalog you want to clean + @param $action=0 Delete/Disable, default is disable + */ + function clean_catalog($catalog_id=0,$action=0) { + + /* Define the Arrays we will need */ + $dead_files = array(); + + if (!$catalog_id) { $catalog_id = $this->id; } + + echo "Cleaning the [" . $this->name . "] Catalog...

    "; + flush(); + + /* Get all songs in this catalog */ + $sql = "SELECT id,file FROM song WHERE catalog='$catalog_id' AND status='enabled'"; + $db_results = mysql_query($sql, dbh()); + + /* Recurse through files, put @ to prevent errors poping up */ + while ($results = mysql_fetch_object($db_results)) { + + /* Remove slashes while we are checking for its existance */ + $results->file = stripslashes($results->file); + + /* Stupid little cutesie thing */ + $this->count++; + if ( !($this->count%conf('catalog_echo_count')) ) { + echo _("Checking") . " $this->count. . . .
    \n"; + flush(); + } //echos song count + + /* Also check the file information */ + $file_info = @filesize($results->file); + + /* If it errors somethings splated, or the files empty */ + if (!file_exists($results->file) OR $file_info < 1) { + + /* Add Error */ + echo "Error File Not Found or 0 Bytes: " . $results->file . "
    "; + flush(); + + /* Add this file to the list for removal from the db */ + $dead_files[] = $results; + } //if error + + } //while gettings songs + + /* Incase there's been a snafo with a mount point on something + * don't actually delete from DB here, simply disable and list + */ + if (count($dead_files)) { + foreach ($dead_files as $data) { + + //FIXME: Until I fix the form, assume delete + //if ($action === 'delete_dead') { + $sql = "DELETE FROM song WHERE id='$data->id'"; + //} + // + //else { + // $sql = "UPDATE song SET status='disabled' WHERE id='$data->id'"; + //} + + $db_results = mysql_query($sql, dbh()); + + /* DB Error occured */ + if (!$db_results) { + /* Add Error */ + } //if error + + } //end foreach + + } // end if dead files + + /* Step two find orphaned Arists/Albums + * This finds artists and albums that no + * longer have any songs associated with them + */ + $this->clean_albums(); + $this->clean_artists(); + $this->clean_stats(); + $this->clean_playlists(); + $this->clean_flagged(); + + /* Return dead files, so they can be listed */ + echo "" . _("Catalog Clean Done") . " [" . count($dead_files) . "] " . _("files removed") . "
    \n"; + flush(); + return $dead_files; + + } //clean_catalog + + + /*! + @function clean_albums + @discussion This function cleans out unused albums + @param $this->id Depends on the current object + */ + function clean_albums() { + + /* Mysql 3.23 doesn't support our cool query so we have to do it a different way */ + if (preg_match("/^3\./",mysql_get_server_info())) { + $sql = "SELECT album.id FROM album LEFT JOIN song ON song.album = album.id WHERE song.id IS NULL"; + $db_results = mysql_query($sql, dbh()); + + $results = array(); + + while ($r = mysql_fetch_row($db_results)) { + $results[] = $r; + } + + foreach ($results as $dead) { + + $sql = "DELETE FROM album WHERE id='$dead[0]'"; + $db_results = mysql_query($sql,dbh()); + } + return true; + } + + /* Do a complex delete to get albums where there are no songs */ + $sql = "DELETE FROM album USING album LEFT JOIN song ON song.album = album.id WHERE song.id IS NULL"; + $db_results = mysql_query($sql, dbh()); + + } //clean_albums + + /*! + @function clean_flagged + @discussion This functions cleans ou unused flagged items + */ + function clean_flagged() { + + /* Mysql 3.23 doesn't support our cool query so we have to do it a different way */ + if (preg_match("/^3\./",mysql_get_server_info())) { + $sql = "SELECT flagged.id FROM flagged LEFT JOIN song ON song.id=flagged.song WHERE song.id IS NULL"; + $db_results = mysql_query($sql, dbh()); + + $results = array(); + + while ($r = mysql_fetch_row($db_results)) { + $results[] = $r; + } + + foreach ($results as $dead) { + $sql = "DELETE FROM flagged WHERE id='$dead[0]'"; + $db_results = mysql_query($sql, dbh()); + } + return true; + } + + /* Do a complex delete to get flagged items where the songs are now gone */ + $sql = "DELETE FROM flagged USING flagged LEFT JOIN song ON song.id = flagged.song WHERE song.id IS NULL"; + $db_results = mysql_query($sql, dbh()); + + } // clean_flagged + + + /*! + @function clean_artists + @discussion This function cleans out unused artists + @param $this->id Depends on the current object + */ + function clean_artists() { + + /* Mysql 3.23 doesn't support our cool query so we have to do it a different way */ + if (preg_match("/^3\./",mysql_get_server_info())) { + $sql = "SELECT artist.id FROM artist LEFT JOIN song ON song.artist = artist.id WHERE song.id IS NULL"; + $db_results = mysql_query($sql, dbh()); + + $results = array(); + + while ($r = mysql_fetch_row($db_results)) { + $results[] = $r; + } + + foreach ($results as $dead) { + + $sql = "DELETE FROM artist WHERE id='$dead[0]'"; + $db_results = mysql_query($sql,dbh()); + } + return true; + } + + + /* Do a complex delete to get artists where there are no songs */ + $sql = "DELETE FROM artist USING artist LEFT JOIN song ON song.artist = artist.id WHERE song.id IS NULL"; + $db_results = mysql_query($sql, dbh()); + + } //clean_artists + + /* + @function clean_playlists + @discussion cleans out dead files from playlists + @param $this->id depends on the current object + */ + function clean_playlists() { + + /* Mysql 3.23 doesn't support our cool query so we have to do it a different way */ + if (preg_match("/^3\./",mysql_get_server_infO())) { + $sql = "SELECT playlist_data.song FROM playlist_data LEFT JOIN song ON song.id = playlist_data.song WHERE song.file IS NULL"; + $db_results = mysql_query($sql, dbh()); + + $results = array(); + + while ($r = mysql_fetch_row($db_results)) { + $results[] = $r; + } + + foreach ($results as $dead) { + $sql = "DELETE FROM playlist_data WHERE song='$dead[0]'"; + $db_results = mysql_query($sql, dbh()); + } + return true; + } + + /* Do a complex delete to get playlist songs where there are no songs */ + $sql = "DELETE FROM playlist_data USING playlist_data LEFT JOIN song ON song.id = playlist_data.song WHERE song.file IS NULL"; + $db_results = mysql_query($sql, dbh()); + + } // clean_playlists + + /*! + @function clean_stats + @discussion This functions removes stats for songs/albums that no longer exist + @param $catalog_id The ID of the catalog to clean + */ + function clean_stats() { + + $version = mysql_get_server_info(); + + /* Mysql 3.23 doesn't support our cool query so we have to do it a different way */ + if (preg_match("/^3\./",$version)) { + $sql = "SELECT object_count.id FROM object_count LEFT JOIN song ON song.id = object_count.object_id WHERE object_type='song' AND song.id IS NULL"; + $db_results = mysql_query($sql, dbh()); + + $results = array(); + + while ($r = mysql_fetch_row($db_results)) { + $results[] = $r; + } + + foreach ($results as $dead) { + + $sql = "DELETE FROM object_count WHERE id='$dead[0]'"; + $db_results = mysql_query($sql,dbh()); + } + + } + // We assume this will be 4.0+ + else { + /* Crazy SQL Mojo to remove stats where there are no songs */ + $sql = "DELETE FROM object_count USING object_count LEFT JOIN song ON song.id=object_count.object_id WHERE object_type='song' AND song.id IS NULL"; + $db_results = mysql_query($sql, dbh()); + } + + /* Mysql 3.23 doesn't support our cool query so we have to do it a different way */ + if (preg_match("/^3\./",$version)) { + $sql = "SELECT object_count.id FROM object_count LEFT JOIN album ON album.id = object_count.object_id WHERE object_type='album' AND album.id IS NULL"; + $db_results = mysql_query($sql, dbh()); + + $results = array(); + + while ($r = mysql_fetch_row($db_results)) { + $results[] = $r; + } + + foreach ($results as $dead) { + + $sql = "DELETE FROM object_count WHERE id='$dead[0]'"; + $db_results = mysql_query($sql,dbh()); + } + } + // We assume 4.0+ Here + else { + /* Crazy SQL Mojo to remove stats where there are no albums */ + $sql = "DELETE FROM object_count USING object_count LEFT JOIN album ON album.id=object_count.object_id WHERE object_type='album' AND album.id IS NULL"; + $db_results = mysql_query($sql, dbh()); + } + + /* Mysql 3.23 doesn't support our cool query so we have to do it a different way */ + if (preg_match("/^3\./",$version)) { + $sql = "SELECT object_count.id FROM object_count LEFT JOIN artist ON artist.id = object_count.object_id WHERE object_type='artist' AND artist.id IS NULL"; + $db_results = mysql_query($sql, dbh()); + + $results = array(); + + while ($r = mysql_fetch_row($db_results)) { + $results[] = $r; + } + + foreach ($results as $dead) { + + $sql = "DELETE FROM object_count WHERE id='$dead[0]'"; + $db_results = mysql_query($sql,dbh()); + } + } + // We assume 4.0+ here + else { + /* Crazy SQL Mojo to remove stats where ther are no artists */ + $sql = "DELETE FROM object_count USING object_count LEFT JOIN artist ON artist.id=object_count.object_id WHERE object_type='artist' AND artist.id IS NULL"; + $db_results = mysql_query($sql, dbh()); + } + + + } // clean_stats + + + /*! + @function verify_catalog + @discussion This function compares the DB's information with the ID3 tags + @param $catalog_id The ID of the catalog to compare + */ + function verify_catalog($catalog_id=0,$gather_type=0) { + + /* Create and empty song for us to use */ + $total_updated = 0; + + /* Set it to this if they don't pass anything */ + if (!$catalog_id) { + $catalog_id = $this->id; + } + + /* First get the filenames for the catalog */ + $sql = "SELECT id FROM song WHERE catalog='$catalog_id' ORDER BY id"; + $db_results = mysql_query($sql, dbh()); + $number = mysql_num_rows($db_results); + + echo _("Updating the") . " [ $this->name ] " . _("Catalog") . "
    \n"; + echo $number . " " . _("songs found checking tag information.") . "

    \n\n"; + flush(); + + /* Magical Fix so we don't run out of time */ + set_time_limit(0); + + /* Recurse through this catalogs files + * and get the id3 tage information, + * if it's not blank, and different in + * in the file then update! + */ + while ($results = mysql_fetch_object($db_results)) { + + $song = new Song($results->id); + + if (is_readable($song->file)) { + unset($skip); + + /* If they have specified fast_update check the file + filemtime to make sure the file has actually + changed + */ + if ($gather_type === "fast_update") { + $file_date = filemtime($song->file); + if ($file_date < $this->last_update) { $skip = true; } + } // if gather_type + + if ($song->update_time >= $this->last_update) { + $skip = true; + $song->update_utime($song->id,time()+86400); + } + + // if the file hasn't been modified since the last_update + if (!$skip) { + + $info = $this->update_song_from_tags($song); + $album_id = $song->album; + if ($info['change']) { + echo "
    \n\t
  • "; + echo "$song->file " . _("Updated") . "\n"; + echo $info['text']; + /* If we aren't doing a fast update re-gather album art */ + if ($gather_type !== "fast_update" AND !isset($searched_albums[$album_id])) { + $album = new Album($song->album); + $searched_albums[$album_id] = 1; + $found = $album->get_art(); + unset($album); + if ($found) { $is_found = _(" FOUND"); } + echo "
    " . _("Searching for new Album Art") . ". . .$is_found
    \n"; + unset($found,$is_found); + } + elseif (isset($searched_albums[$album_id])) { + echo "
    " . _("Album Art Already Found") . ". . .
    \n"; + } + echo "\t
  • \n
    \n
    \n"; + flush(); + $total_updated++; + } + + unset($info); + + } // end skip + + /* Stupid little cutesie thing */ + $this->count++; + if ( !($this->count%conf('catalog_echo_count')) ) { + echo "Checked $this->count. . . .
    \n"; + flush(); + } //echos song count + + } // end if file exists + + else { + echo "
    \n
  • "; + echo "$song->file does not exist or is not readable\n"; + echo "
  • \n
    \n
    \n"; + // Should we remove it from catalog? + } + + + } //end foreach + + + /* After we have updated all the songs with the new information clear any empty albums/artists */ + $this->clean_albums(); + $this->clean_artists(); + $this->clean_stats(); + $this->clean_flagged(); + + // Update the last_update + $this->update_last_update(); + + echo "Update Finished. Checked $this->count. $total_updated songs updated.

    "; + + } //verify_catalog + + + /*! + @function create_catalog_entry + @discussion Creates a new catalog from path and type + @param $path The root path for this catalog + @param $name The name of the new catalog + */ + function create_catalog_entry($path,$name,$id3cmd=0,$ren=0,$sort=0, $type='local') { + + // Current time + $date = time(); + + $path = sql_escape($path); + $name = sql_escape($name); + + if($id3cmd && $ren && $sort) { + $sql = "INSERT INTO catalog (path,name,last_update,id3_set_command,rename_pattern,sort_pattern,catalog_type) " . + " VALUES ('$path','$name','$date', '$id3cmd', '$ren', '$sort','$type')"; + } + else { + $sql = "INSERT INTO catalog (path,name,last_update) VALUES ('$path','$name','$date')"; + } + + $db_results = mysql_query($sql, dbh()); + $catalog_id = mysql_insert_id(dbh()); + + return $catalog_id; + + } //create_catalog_entry + + + /*! + @function check_catalog + @discussion Checks for the $path already in the catalog table + @param $path The root path for the catalog we are checking + */ + function check_catalog($path) { + + $path = sql_escape($path); + + $sql = "SELECT id FROM catalog WHERE path='$path'"; + $db_results = mysql_query($sql, dbh()); + + $results = mysql_fetch_object($db_results); + + return $results->id; + + } //check_catalog + + + /*! + @function check_artist + @discussion Takes $artist checks if there then return id else insert and return id + @param $artist The name of the artist + */ + function check_artist($artist) { + + // Only get the var ones.. less func calls + $cache_limit = conf('artist_cache_limit'); + + /* Clean up the artist */ + $artist = trim($artist); + $artist = sql_escape($artist); + + + /* Ohh no the artist has lost it's mojo! */ + if (!$artist) { + $artist = "Unknown (Orphaned)"; + } + + // Remove the prefix so we can sort it correctly + preg_match("/^(The\s|An\s|A\s)(.*)/i",$artist,$matches); + + if (count($matches)) { + $artist = $matches[2]; + $prefix = $matches[1]; + } + + // Check to see if we've seen this artist before + if (isset($this->artists[$artist])) { + return $this->artists[$artist]; + } // if we've seen this artist before + + /* Setup the checking sql statement */ + $sql = "SELECT id FROM artist WHERE name LIKE '$artist' "; + $db_results = mysql_query($sql, dbh()); + + /* If it's found */ + if ($r = mysql_fetch_object($db_results)) { + $artist_id = $r->id; + } //if found + + /* If not found create */ + else { + + $sql = "INSERT INTO artist (name, prefix) VALUES ('$artist', '$prefix')"; + $db_results = mysql_query($sql, dbh()); + $artist_id = mysql_insert_id(dbh()); + + + if (!$db_results) { + echo "Error Inserting Artist:$artist
    "; + flush(); + } + + } //not found + + if ($cache_limit) { + + $artist_count = count($this->artists); + if ($artist_count == $cache_limit) { + $this->artists = array_slice($this->artists,1); + } + if (conf('debug')) { log_event($_SESSION['userdata']['username'],'cache',"Adding $artist with $artist_id to Cache",'ampache-catalog'); } + $array = array($artist => $artist_id); + $this->artists = array_merge($this->artists, $array); + unset($array); + + } // if cache limit is on.. + + return $artist_id; + + } //check_artist + + + /*! + @function check_album + @disucssion Takes $album and checks if there then return id else insert and return id + @param $album The name of the album + */ + function check_album($album,$album_year=0) { + + /* Clean up the album name */ + $album = trim($album); + $album = sql_escape($album); + $album_year = intval($album_year); + + // Set it once to reduce function calls + $cache_limit = conf('album_cache_limit'); + + /* Ohh no the album has lost it's mojo */ + if (!$album) { + $album = "Unknown (Orphaned)"; + } + + // Remove the prefix so we can sort it correctly + preg_match("/^(The\s|An\s|A\s)(.*)/i",$album,$matches); + + if (count($matches)) { + $album = $matches[2]; + $prefix = $matches[1]; + } + + // Check to see if we've seen this album before + if (isset($this->albums[$album])) { + return $this->albums[$album]; + } + + /* Setup the Query */ + $sql = "SELECT id FROM album WHERE name LIKE '$album'"; + if ($album_year) { $sql .= " AND year='$album_year'"; } + $db_results = mysql_query($sql, dbh()); + + /* If it's found */ + if ($r = mysql_fetch_object($db_results)) { + $album_id = $r->id; + + } //if found + + /* If not found create */ + else { + + $sql = "INSERT INTO album (name, prefix,year) VALUES ('$album', '$prefix','$album_year')"; + $db_results = mysql_query($sql, dbh()); + $album_id = mysql_insert_id(dbh()); + + if (!$db_results) { + echo "Error Inserting Album:$album
    "; + flush(); + } + + } //not found + + if ($cache_limit > 0) { + + $albums_count = count($this->albums); + + if ($albums_count == $cache_limit) { + $this->albums = array_slice($this->albums,1); + } + $array = array($album => $album_id); + $this->albums = array_merge($this->albums,$array); + unset($array); + + } // if cache limit is on.. + + return $album_id; + + } //check_album + + + /*! + @function check_genre + @discussion Finds the Genre_id from the text name + @param $genre The name of the genre + */ + function check_genre($genre) { + + if (!$genre) { + return false; + } + + if ($this->genres[$genre]) { + return $this->genres[$genre]; + } + + /* Look in the genre table */ + $genre = sql_escape($genre); + $sql = "SELECT id FROM genre WHERE name LIKE '$genre'"; + $db_results = mysql_query($sql, dbh()); + + $results = mysql_fetch_object($db_results); + + if (!$results->id) { + $sql = "INSERT INTO genre (name) VALUES ('$genre')"; + $db_results = mysql_query($sql, dbh()); + $results->id = mysql_insert_id(dbh()); + } + + $this->genres[$genre] = $results->id; + + return $results->id; + + } //check_genre + + + /*! + @function check_title + @discussion this checks to make sure something is + set on the title, if it isn't it looks at the + filename and trys to set the title based on that + */ + function check_title($title,$file=0) { + + if (strlen(trim($title)) < 1) { + preg_match("/.+\/(.*)\.....?$/",$file,$matches); + $title = sql_escape($matches[1]); + } + + return $title; + + + } //check_title + + + /*! + @function insert_local_song + @discussion Insert a song that isn't already in the database this + function is in here so we don't have to create a song object + @param $file The file name we are adding (full path) + @param $file_info The information of the file, size etc taken from stat() + */ + function insert_local_song($file,$file_info) { + + /* Create the Audioinfo object and get info */ + $audio_info = new Audioinfo(); + $song_obj = new Song(); + $results = $audio_info->Info($file); + $results['file'] = $file; + + $key = get_tag_type($results); + + /* Fill Empty info from filename/path */ + $results = $song_obj->fill_info($results,$this->sort_pattern . "/" . $this->rename_pattern,$this->id,$key); + + /* Clean Up the tags */ + $results = clean_tag_info($results,$key,$file); + + /* Set the vars here... so we don't have to do the '" . $blah['asd'] . "' */ + $title = sql_escape($results['title']); + $artist = $results['artist']; + $album = $results['album']; + $genre = $results['genre']; + $bitrate = $results['bitrate']; + $rate = $results['rate']; + $mode = $results['mode']; + $size = $results['size']; + $song_time = $results['time']; + $track = $results['track']; + $year = $results['year']; + $comment = $results['comment']; + $current_time = time(); + + /* + * We have the artist/genre/album name need to check it in the tables + * If found then add & return id, else return id + */ + $artist_id = $this->check_artist($artist); + $genre_id = $this->check_genre($genre); + $album_id = $this->check_album($album,$year); + $title = $this->check_title($title,$file); + $add_file = sql_escape($results['file']); + + $sql = "INSERT INTO song (file,catalog,album,artist,title,bitrate,rate,mode,size,time,track,genre,addition_time,year,comment)" . + " VALUES ('$add_file','$this->id','$album_id','$artist_id','$title','$bitrate','$rate','$mode','$size','$song_time','$track','$genre_id','$current_time','$year','$comment')"; + + $db_results = mysql_query($sql, dbh()); + + if (!$db_results) { + if (conf('debug')) { log_event($_SESSION['userdata']['username'],'insert',"Unable to insert $file -- $sql",'ampache-catalog'); } + echo "Error Adding $file
    $sql
    "; + flush(); + } + + /* Clear Variables */ + unset($results,$audio_info,$song_obj); + + } // insert_local_song + + /*! + @function insert_remote_song + @discussion takes the information gotten from XML-RPC and + inserts it into the local database. The filename + ends up being the url. + */ + function insert_remote_song($song) { + + $url = sql_escape($song->file); + $title = $this->check_title($song->title); + $title = sql_escape($title); + $comment = sql_escape($song->comment); + $current_time = time(); + + $sql = "INSERT INTO song (file,catalog,album,artist,title,bitrate,rate,mode,size,time,track,genre,addition_time,year,comment)" . + " VALUES ('$url','$song->catalog','$song->album','$song->artist','$title','$song->bitrate','$song->rate','$song->mode','$song->size','$song->time','$song->track','$song->genre','$current_time','$song->year','$comment')"; + $db_results = mysql_query($sql, dbh()); + + if (!$db_results) { + if (conf('debug')) { log_event($_SESSION['userdata']['username'],'insert',"Unable to Add Remote $url -- $sql",'ampache-catalog'); } + echo "Error Adding Remote $url
    $sql
    \n"; + flush(); + } + + } // insert_remote_song + + + /*! + @function check_remote_song + @discussion checks to see if a remote song exists in the database or not + if it find a song it returns the UID + */ + function check_remote_song($url) { + + $url = sql_escape($url); + + $sql = "SELECT id FROM song WHERE file='$url'"; + $db_results = mysql_query($sql, dbh()); + + if ($r = mysql_fetch_object($db_results)) { + return $r->id; + } + + return false; + + } // check_remote_song + + + /*! + @function check_local_mp3 + @discussion Checks the song to see if it's there already returns true if found, false if not + @param $full_file The full file name that we are checking + @param $gather_type=0 If we need to check id3 tags or not + */ + function check_local_mp3($full_file, $gather_type=0) { + + if ($gather_type == 'fast_add') { + $file_date = filemtime($full_file); + if ($file_date < $this->last_add) { + return true; + } + } + + $full_file = sql_escape($full_file); + + $sql = "SELECT id FROM song WHERE file = '$full_file'"; + $db_results = mysql_query($sql, dbh()); + + //If it's found then return true + if (@mysql_fetch_row($db_results)) { + return true; + } + + return false; + + } //check_local_mp3 + + /*! + @function import_m3u + @discussion this takes m3u filename and then attempts + to create a Public Playlist based on the filenames + listed in the m3u + */ + function import_m3u($filename) { + + $m3u_handle = @fopen($filename,'r'); + + $data = @fread($m3u_handle,filesize($filename)); + + $results = explode("\n",$data); + + foreach ($results as $value) { + // Remove extra whitespace + $value = trim($value); + if (preg_match("/\.[A-Za-z0-9]{3}$/",$value)) { + $file[0] = str_replace("/","\\",$value); + $file[1] = str_replace("\\","/",$value); + /* Search for this filename, cause it's a audio file */ + $sql = "SELECT id FROM song WHERE file LIKE '%" . sql_escape($file[0]) . "' OR file LIKE '%" . sql_escape($file[1]) . "'"; + $db_results = mysql_query($sql, dbh()); + $song_id = mysql_result($db_results,'id'); + if ($song_id) { $songs[] = $song_id; } + } // if it's a file + + } // end foreach line + + if (conf('debug')) { log_event($GLOBALS['user']->username,' m3u_parse ',"Parsing $filename - Found: " . count($songs) . " Songs"); } + + if (count($songs)) { + $playlist = new Playlist(); + $playlist_name = "M3U - " . basename($filename); + $playlist->create_playlist($playlist_name,$GLOBALS['user']->id,'public'); + $playlist->add_songs($songs); + return true; + } + + return false; + + } // import_m3u + + /*! + @function delete_catalog + @discussion Deletes the catalog and everything assoicated with it + assumes $this + */ + function delete_catalog() { + + // Do some crazyness to delete all the songs in this catalog + // from playlists... + $sql = "SELECT playlist_data.song FROM song,playlist_data,catalog WHERE catalog.id=song.catalog AND playlist_data.song=song.id AND catalog.id='$this->id'"; + $db_results = mysql_query($sql, dbh()); + + $results = array(); + + while ($r = mysql_fetch_object($db_results)) { + $results[] = $r; + } + + foreach ($results as $r) { + // Clear Playlist Data + $sql = "DELETE FROM playlist_data WHERE song='$r->song'"; + $db_results = mysql_query($sql, dbh()); + + } // End Foreach + + // First remove the songs in this catalog + $sql = "DELETE FROM song WHERE catalog = '$this->id'"; + $db_results = mysql_query($sql, dbh()); + + // Next Remove the Catalog Entry it's self + $sql = "DELETE FROM catalog WHERE id = '$this->id'"; + $db_results = mysql_query($sql, dbh()); + + // Run the Aritst/Album Cleaners... + $this->clean_albums(); + $this->clean_artists(); + $this->clean_stats(); + $this->clean_playlists(); + $this->clean_flagged(); + + } // delete_catalog + + + /*! + @function remove_songs + @discussion removes all songs sent in $songs array from the + database, it doesn't actually delete them... + */ + function remove_songs($songs) { + + foreach($songs as $song) { + $sql = "DELETE FROM song WHERE id = '$song'"; + $db_results = mysql_query($sql, dbh()); + } + + } // remove_songs + +} //end of catalog class + +?> diff --git a/lib/class/error.php b/lib/class/error.php new file mode 100644 index 00000000..9283e29d --- /dev/null +++ b/lib/class/error.php @@ -0,0 +1,94 @@ +$description); + + error_results($array); + $this->error_state = 1; + + return true; + + } // add_error + + + /*! + @function has_error + @discussion returns true if the name given has an error, + false if it doesn't + */ + function has_error($name) { + + $results = error_results($name); + + if (!empty($results)) { + return true; + } + + return false; + + } // has_error + + /*! + @function print_error + @discussion prints out the error for a name if it exists + */ + function print_error($name) { + + if ($this->has_error($name)) { + echo "
    " . error_results($name) . "
    \n"; + } + + } // print_error + +} //end error class +?> diff --git a/lib/class/genre.class.php b/lib/class/genre.class.php new file mode 100644 index 00000000..9d5e4d4e --- /dev/null +++ b/lib/class/genre.class.php @@ -0,0 +1,45 @@ + diff --git a/lib/class/playlist.php b/lib/class/playlist.php new file mode 100644 index 00000000..130537af --- /dev/null +++ b/lib/class/playlist.php @@ -0,0 +1,366 @@ +id = $playlist_id; + + // Get the information from the db + $this->refresh_object(); + } + + } + + + + /*! + @function refresh_object + @discussion Reads playlist information from the db and updates the Playlist object with it + */ + function refresh_object() { + + $dbh = dbh(); + + if ($this->id) { + $sql = "SELECT name, owner, type, date FROM playlist" . + " WHERE id = '$this->id'"; + $db_results = mysql_query($sql, $dbh); + + if ($r = mysql_fetch_object($db_results)) { + $this->name = $r->name; + $this->owner = $r->owner; + $this->type = $r->type; + $this->time = $r->date; + $this->items = array(); + + // Fetch playlist items + $sql = "SELECT song, track FROM playlist_data" . + " WHERE playlist = '$this->id'" . + " ORDER BY track"; + $db_results = mysql_query($sql, $dbh); + + while ($r = mysql_fetch_object($db_results)) { + $this->items[] = array("song_id" => $r->song, "track" => $r->track); + } + } + + return TRUE; + } + + return FALSE; + + } + + + /*! + @function create_playlist + @discussion Creates an empty playlist, given a name, owner_id, and type. + */ + function create_playlist($name, $owner_id, $type) { + + $dbh = dbh(); + + if (isset($name) && isset($owner_id) && isset($type) && $this->check_type($type)) { + $name = sql_escape($name); + $sql = "INSERT INTO playlist" . + " (name, owner, type)" . + " VALUES ('$name', '$owner_id', '$type')"; + $db_results = mysql_query($sql, $dbh); + if ($this->id = mysql_insert_id($dbh)) { + $this->refresh_object(); + return TRUE; + } + } + + return FALSE; + + } + + + /*! + @function delete + @discussion Deletes the playlist. + */ + function delete() { + + $dbh = dbh(); + + if ($this->id) { + $sql = "DELETE FROM playlist_data" . + " WHERE playlist = '$this->id'"; + $db_results = mysql_query($sql, $dbh); + + $sql = "DELETE FROM playlist" . + " WHERE id = '$this->id'"; + $db_results = mysql_query($sql, $dbh); + + // Clean up this object + foreach (get_object_vars($this) as $var) { + unset($var); + } + + return TRUE; + } + + return FALSE; + + } + + + /*! + @function update_track_numbers + @discussion Reads an array of song_ids and track numbers to update + */ + function update_track_numbers($changes) { + + $dbh = dbh(); + + if ($this->id && isset($changes) && is_array($changes)) { + foreach ($changes as $change) { + // Check for valid song_id + $sql = "SELECT count(*) FROM song WHERE id = '" . $change['song_id'] . "'"; + $db_results = mysql_query($sql, $dbh); + $r = mysql_fetch_row($db_results); + if ($r[0] == 1) { + $sql = "UPDATE playlist_data SET" . + " track = '" . $change['track'] . "'" . + " WHERE playlist = '$this->id'". + " AND song = '" . $change['song_id'] . "'"; + $db_results = mysql_query($sql, $dbh); + } + } + + // Refresh the playlist object + $this->refresh_object(); + + return TRUE; + } + + return FALSE; + + } + + + /*! + @function add_songs + @discussion Reads an array of song_ids to add to the playlist + */ + function add_songs($song_ids) { + + $dbh = dbh(); + + if ($this->id && isset($song_ids) && is_array($song_ids)) { + foreach ($song_ids as $song_id) { + $song = new Song($song_id); + if (isset($song->id)) { + $sql = "INSERT INTO playlist_data" . + " (playlist, song, track)" . + " VALUES ('$this->id', '$song->id', '$song->track')"; + $db_results = mysql_query($sql, $dbh); + } + } + + // Refresh the playlist object + $this->refresh_object(); + + return TRUE; + } + + return FALSE; + + } + + + /*! + @function remove_songs + @discussion Reads an array of song_ids to remove from the playlist + */ + function remove_songs($song_ids) { + + $dbh = dbh(); + + if ($this->id && isset($song_ids) && is_array($song_ids)) { + foreach ($song_ids as $song_id) { + $sql = "DELETE FROM playlist_data" . + " WHERE song = '$song_id'" . + " AND playlist = '$this->id'"; + $db_results = mysql_query($sql, $dbh); + } + + // Refresh the playlist object + $this->refresh_object(); + + return TRUE; + } + + return FALSE; + + } + + + /*! + @function check_type + @discussion Checks for a valid playlist type + */ + function check_type($type) { + + if (isset($type)) { + if ($type === 'public' || $type === 'private') { + return TRUE; + } + } + + return FALSE; + + } + + + /*! + @function update_type + @discussion Updates the playlist type + */ + function update_type($type) { + + $dbh = dbh(); + + if ($this->id && isset($type) && $this->check_type($type)) { + $sql = "UPDATE playlist SET type = '$type'" . + " WHERE id = '$this->id'"; + $db_results = mysql_query($sql, $dbh); + + // Refresh the playlist object + $this->refresh_object(); + + return TRUE; + } + + return FALSE; + + } + + + /*! + @function update_name + @discussion Updates the playlist name + */ + function update_name($name) { + + $dbh = dbh(); + + if ($this->id && isset($name)) { + $name = sql_escape($name); + $sql = "UPDATE playlist SET name = '$name'" . + " WHERE id = '$this->id'"; + $db_results = mysql_query($sql, $dbh); + + // Refresh the playlist object + $this->refresh_object(); + + return TRUE; + } + + return FALSE; + + } + + + /*! + @function get_songs + @discussion Returns an array of song_ids for the playlist + */ + function get_songs() { + + $song_ids = array(); + + if ($this->id && is_array($this->items)) { + foreach ($this->items as $item) { + $song_ids[] = $item['song_id']; + } + } + + return $song_ids; + + } // get_songs + + /*! + @function get_random_songs + @discussion gets a random set of the songs in this + playlist + */ + function get_random_songs() { + + $sql = "SELECT COUNT(song) FROM playlist_data WHERE playlist = '$this->id'"; + $db_results = mysql_query($sql, dbh()); + + $total_songs = mysql_fetch_row($db_results); + + $limit = rand(1,$total_songs[0]); + + // Fetch playlist items + $sql = "SELECT song, track FROM playlist_data" . + " WHERE playlist = '$this->id'" . + " ORDER BY RAND() LIMIT $limit"; + $db_results = mysql_query($sql, dbh()); + while ($r = mysql_fetch_object($db_results)) { + $song_ids[] = $r->song; + } + + return $song_ids; + } // get_random_songs + + /*! + @function show_import + @discussion shows the import from file template + */ + function show_import() { + + require (conf('prefix') . "/templates/show_import_playlist.inc.php"); + + } // show_import + + +} //end of playlist class + +?> diff --git a/lib/class/song.php b/lib/class/song.php new file mode 100644 index 00000000..47600ee5 --- /dev/null +++ b/lib/class/song.php @@ -0,0 +1,658 @@ +id = $song_id; + + /* Get the information from the db */ + if ($info = $this->get_info()) { + + /* Assign Vars */ + $this->file = $info->file; + $this->album = $info->album; + $this->artist = $info->artist; + $this->title = $info->title; + $this->comment = $info->comment; + $this->year = $info->year; + $this->bitrate = $info->bitrate; + $this->rate = $info->rate; + $this->mode = $info->mode; + $this->size = $info->size; + $this->time = $info->time; + $this->track = $info->track; + $this->genre = $info->genre; + $this->addition_time = $info->addition_time; + $this->catalog = $info->catalog; + $this->played = $info->played; + $this->update_time = $info->update_time; + $this->flagid = $info->flagid; + $this->flaguser = $info->flaguser; + $this->flagtype = $info->flagtype; + $this->flagcomment = $info->flagcomment; + $this->status = $info->status; + + // Format the Type of the song + $this->format_type(); + } + + } + + } //constructor + + + /*! + @function get_info + @discussion get's the vars for $this out of the database + @param $this->id Taken from the object + */ + function get_info() { + + /* Grab the basic information from the catalog and return it */ + $sql = "SELECT song.id,file,catalog,album,song.comment,year,artist,". + "title,bitrate,rate,mode,size,time,track,genre,played,status,update_time,". + "addition_time,flagged.id as flagid,flagged.user as flaguser,flagged.type ". + "as flagtype,flagged.date as flagdate,flagged.comment as flagcomment FROM ". + "song LEFT JOIN flagged ON song.id = flagged.song WHERE song.id = '$this->id'"; + $db_results = mysql_query($sql, dbh()); + + $results = mysql_fetch_object($db_results); + + return $results; + + } //get_info + + /*! + @function format_type + @discussion gets the type of song we are trying to + play, used to set mime headers and to trick + players into playing them correctly + */ + function format_type() { + + preg_match('/\.([A-Za-z0-9]+)$/', $this->file,$results); + + $this->type = $results[1]; + + switch ($this->type) { + case "spx": + case "ogg": + $this->mime = "application/x-ogg"; + break; + case "wma": + case "WMA": + case "asf": + $this->mime = "audio/x-ms-wma"; + break; + case "mp3": + case "mpeg3": + $this->mime = "audio/mpeg"; + break; + case "rm": + $this->mime = "audio/x-realaudio"; + break; + case "flac"; + $this->mime = "audio/x-flac"; + break; + case 'aac': + case 'mp4': + case 'm4a': + $this->mime = "audio/mp4"; + break; + case 'mpc': + $this->mime = "audio/x-musepack"; + break; + default: + $this->mime = "audio/mpeg"; + break; + } + + } // get_type + /*! + @function get_album_songs + @discussion gets an array of song objects based on album + */ + function get_album_songs($album_id) { + + $sql = "SELECT id FROM song WHERE album='$album_id'"; + $db_results = mysql_query($sql, libglue_param(libglue_param('dbh_name'))); + + while ($r = mysql_fetch_object($db_results)) { + $results[] = new Song($r->id); + } + + return $results; + + } // get_album_songs + + /*! + @function get_album_name + @discussion gets the name of $this->album + */ + function get_album_name() { + + $sql = "SELECT name,prefix FROM album WHERE id='$this->album'"; + $db_results = mysql_query($sql, dbh()); + + $results = mysql_fetch_array($db_results); + + if ($results['prefix']) { + return $results['prefix'] . " " .$results['name']; + } + else { + return $results['name']; + } + + } // get_album_name + + /*! + @function get_artist_name + @discussion gets the name of $this->artist + */ + function get_artist_name() { + + $sql = "SELECT name,prefix FROM artist WHERE id='$this->artist'"; + $db_results = mysql_query($sql, dbh()); + + $results = mysql_fetch_array($db_results); + + if ($results['prefix']) { + return $results['prefix'] . " " . $results['name']; + } + else { + return $results['name']; + } + + } // get_album_name + + /*! + @function get_genre_name + @discussion gets the name of the genre + */ + function get_genre_name() { + + $sql = "SELECT name FROM genre WHERE id='$this->genre'"; + $db_results = mysql_query($sql, dbh()); + + $results = mysql_fetch_array($db_results); + + return $results['name']; + + } // get_genre_name + /*! + @function compare_song_information + @discussion this compares the new ID3 tags of a file against + the ones in the database to see if they have changed + it returns false if nothing has changes, or the true + if they have. + @param $song The origional song object + @param $new_song The new version of the song + */ + function compare_song_information($song,$new_song) { + + if ($song->title == "No Title Found") { $song->title = false; } + + + if (trim($song->title) != trim($new_song->title) && strlen($new_song->title) > 0) { + $array['change'] = true; + $array['text'] .= "
    " . _("Title") . " [$song->title] " . _("updated to") . " [$new_song->title]\n"; + } // if title + if ($song->bitrate != $new_song->bitrate) { + $array['change'] = true; + $array['text'] .= "
    " . _("Bitrate") . " [$song->bitrate] " . _("updated to") . " [$new_song->bitrate]\n"; + } // if bitrate + if ($song->rate != $new_song->rate) { + $array['change'] = true; + $array['text'] .= "
    " . _("Rate") . " [$song->rate] " . _("updated to") . " [$new_song->rate]\n"; + } // if rate + if ($song->mode != $new_song->mode) { + $array['change'] = true; + $array['text'] .= "
    " . _("Mode") . " [$song->mode] " . _("updated to") . " [$new_song->mode]\n"; + } // if mode + if ($song->time != $new_song->time) { + $array['change'] = true; + $array['text'] .= "
    " . _("Time") . " [$song->time] " . _("updated to") . " [$new_song->time]\n"; + } // if time + if ($song->track != $new_song->track) { + $array['change'] = true; + $array['text'] .= "
    " . _("Track") . " [$song->track] " . _("updated to") . " [$new_song->track]\n"; + } // if track + if ($song->size != $new_song->size) { + $array['change'] = true; + $array['text'] .= "
    " . _("Filesize") . " [$song->size] " . _("updated to") . " [$new_song->size]\n"; + } // if artist + if ($song->artist != $new_song->artist) { + $array['change'] = true; + $name = $song->get_artist_name(); + $array['text'] .= "
    " . _("Artist") . " [$name] " . _("updated to") . " [$new_song->f_artist]\n"; + } // if artist + if ($song->album != $new_song->album) { + $array['change'] = true; + $name = $song->get_album_name() . " - " . $song->year; + $array['text'] .= "
    " . _("Album") . " [$name] " . _("updated to") . " [$new_song->f_album]\n"; + } // if album + if ($song->year != $new_song->year) { + $array['change'] = true; + $array['text'] .= "
    " . _("Year") . " [$song->year] " . _("updated to") . " [$new_song->year]\n"; + } // if year + if (trim($song->comment) != trim($new_song->comment)) { + $array['change'] = true; + $array['text'] .= "
    " . _("Comment") . " [$song->comment] " . _("updated to") . " [$new_song->comment]\n"; + } // if comment + if ($song->genre != $new_song->genre) { + $array['change'] = true; + $name = $song->get_genre_name(); + $array['text'] .= "
    " . _("Genre") . " [$name] " . _("updated to") . " [$new_song->f_genre]\n"; + } // if genre + + return $array; + + } // compare_song_information + + /*! + @function update_song + @discussion this is the main updater for a song it actually + calls a whole bunch of mini functions to update + each little part of the song... lastly it updates + the "update_time" of the song + @param $song_id The id of the song we are updating + @param $new_song A object with the new song params + */ + function update_song($song_id, $new_song) { + + $this->update_title($new_song->title,$song_id); + $this->update_bitrate($new_song->bitrate,$song_id); + $this->update_rate($new_song->rate,$song_id); + $this->update_mode($new_song->mode,$song_id); + $this->update_size($new_song->size,$song_id); + $this->update_time($new_song->time,$song_id); + $this->update_track($new_song->track,$song_id); + $this->update_artist($new_song->artist,$song_id); + $this->update_genre($new_song->genre,$song_id); + $this->update_album($new_song->album,$song_id); + $this->update_year($new_song->year,$song_id); + $this->update_comment($new_song->comment,$song_id); + $this->update_played('false',$song_id); + $this->update_utime($song_id); + + } // update_song + + /*! + @function update_year + @discussion update the year tag + */ + function update_year($new_year,$song_id=0) { + + if ($_SESSION['userdata']['access'] === 'admin') { + $this->update_item('year',$new_year,$song_id); + } + } // update_year + + /*! + @function update_comment + @discussion updates the comment field + */ + function update_comment($new_comment,$song_id=0) { + + if ($_SESSION['userdata']['access'] === 'admin') { + $this->update_item('comment',$new_comment,$song_id); + } + } // update_comment + + /*! + @function update_title + @discussion updates the title field + */ + function update_title($new_title,$song_id=0) { + + if ($_SESSION['userdata']['access'] === 'admin') { + $this->update_item('title',$new_title,$song_id); + } + } // update_title + + /*! + @function update_bitrate + @discussion updates the bitrate field + */ + function update_bitrate($new_bitrate,$song_id=0) { + + if ($_SESSION['userdata']['access'] === 'admin') { + $this->update_item('bitrate',$new_bitrate,$song_id); + } + + } // update_bitrate + + /*! + @function update_rate + @discussion updates the rate field + */ + function update_rate($new_rate,$song_id=0) { + + if ($_SESSION['userdata']['access'] === 'admin') { + $this->update_item('rate',$new_rate,$song_id); + } + + } // update_rate + + /*! + @function update_mode + @discussion updates the mode field + */ + function update_mode($new_mode,$song_id=0) { + + if ($_SESSION['userdata']['access'] === 'admin') { + $this->update_item('mode',$new_mode,$song_id); + } + + } // update_mode + + /*! + @function update_size + @discussion updates the size field + */ + function update_size($new_size,$song_id=0) { + + if ($_SESSION['userdata']['access'] === 'admin') { + $this->update_item('size',$new_size,$song_id); + } + + } // update_size + + /*! + @function update_time + @discussion updates the time field + */ + function update_time($new_time,$song_id=0) { + + if ($_SESSION['userdata']['access'] === 'admin') { + $this->update_item('time',$new_time,$song_id); + } + + } // update_time + + /*! + @function update_track + @discussion this updates the track field + */ + function update_track($new_track,$song_id=0) { + + if ($_SESSION['userdata']['access'] === 'admin') { + $this->update_item('track',$new_track,$song_id); + } + + } // update_track + + /*! + @function update_artist + @discussion updates the artist field + */ + function update_artist($new_artist,$song_id=0) { + + if ($_SESSION['userdata']['access'] === 'admin') { + $this->update_item('artist',$new_artist,$song_id); + } + + } // update_artist + + /*! + @function update_genre + @discussion updates the genre field + */ + function update_genre($new_genre,$song_id=0) { + + if ($_SESSION['userdata']['access'] === 'admin') { + $this->update_item('genre',$new_genre,$song_id); + } + + } // update_genre + + /*! + @function update_album + @discussion updates the album field + */ + function update_album($new_album,$song_id=0) { + + if ($_SESSION['userdata']['access'] === 'admin') { + $this->update_item('album',$new_album,$song_id); + } + + } // update_album + + /*! + @function update_utime + @discussion sets a new update time + */ + function update_utime($song_id=0,$time=0) { + + if (!$time) { $time = time(); } + + if ($_SESSION['userdata']['access'] === 'admin') { + $this->update_item('update_time',$time,$song_id); + } + + } // update_utime + + /*! + @function update_played + @discussion sets the played flag + */ + function update_played($new_played,$song_id=0) { + + $this->update_item('played',$new_played,$song_id); + + } // update_played + + + /*! + @function update_enabled + @discussion sets the enabled flag + */ + function update_enabled($new_enabled,$song_id=0) { + + if ($_SESSION['userdata']['access'] === 'admin' || $_SESSION['userdata']['access'] === '100') { + $this->update_item('status',$new_enabled,$song_id); + } + + } // update_enabled + + /*! + @function update_item + @discussion this is a generic function that is called + by all the other update functions... + @param $field The field we are updating + @param $value The new value for said field + @param $song_id ID of the song, uses $this->id by default + */ + function update_item($field,$value,$song_id=0) { + + if (!$song_id) { $song_id = $this->id; } + + $value = sql_escape($value); + + $sql = "UPDATE song SET $field='$value' WHERE id='$song_id'"; + $db_results = mysql_query($sql, dbh()); + + $this->{$field} = $value; + + } //update_item + + + /*! + @function format_song + @discussion this takes a song object + and formats it for display + and returns the object cleaned up + */ + function format_song() { + + // Format the filename + preg_match("/^.*\/(.*?)$/",$this->file, $short); + $this->f_file = htmlspecialchars($short[1]); + + // Format the album name + $this->f_album_full = $this->get_album_name(); + $this->f_album = truncate_with_ellipse($this->f_album_full,conf('ellipse_threshold_album')); + + // Format the artist name + $this->f_artist_full = $this->get_artist_name(); + $this->f_artist = truncate_with_ellipse($this->f_artist_full,conf('ellipse_threshold_artist')); + + // Format the title + $this->f_title = truncate_with_ellipse($this->title,conf('ellipse_threshold_title')); + + // Create A link inclduing the title + $this->f_link = "id . "\">$this->f_title"; + + // Format the Bitrate + $this->f_bitrate = intval($this->bitrate/1000) . "-" . strtoupper($this->mode); + + // Format Genre + $this->f_genre = $this->get_genre_name(); + + // Format the Time + $min = floor($this->time/60); + $sec = sprintf("%02d", ($this->time%60) ); + $this->f_time = $min . ":" . $sec; + + // Format the size + $this->f_size = sprintf("%.2f",($this->size/1048576)); + + // Set style + if (preg_match("/id3/", $this->flagtype)) { $this->f_style = "style=\"color: #33c;\""; } + elseif (preg_match("/(mp3|del|sort|ren)/", $this->flagtype)) { $this->f_style = "style=\"color: #C00;\""; } + if ($this->status === 'disabled') { $this->f_style = "style=\"text-decoration: line-through;\""; } + + return true; + + } // format_song + + /*! + * @function get_rel_path + * @discussion returns the path of the song file stripped of the catalog path + * used for mpd playback + */ + function get_rel_path($file_path=0,$catalog_id=0) { + + if (!$file_path) { + $info = $this->get_info( ); + $file_path = $info->file; + } + if (!$catalog_id) { + $catalog_id = $info->catalog; + } + $catalog = new Catalog( $catalog_id ); + $info = $catalog->get_info( ); + $catalog_path = $info->path; + $catalog_path = rtrim($catalog_path, "/"); + return( str_replace( $catalog_path . "/", "", $file_path ) ); + + } // get_rel_path + + + /*! + @function fill_info + @discussion this takes the $results from getid3 and attempts to fill + as much information as possible from the file name using the + pattern set in the current catalog + */ + function fill_info($results,$pattern,$catalog_id,$key) { + + $filename = $this->get_rel_path($results['file'],$catalog_id); + + if (!strlen($results[$key]['title'])) { + $results[$key]['title'] = $this->get_info_from_filename($filename,$pattern,"%t"); + } + if (!strlen($results[$key]['track'])) { + $results[$key]['track'] = $this->get_info_from_filename($filename,$pattern,"%T"); + } + if (!strlen($results[$key]['year'])) { + $results[$key]['year'] = $this->get_info_from_filename($filename,$pattern,"%y"); + } + if (!strlen($results[$key]['album'])) { + $results[$key]['album'] = $this->get_info_from_filename($filename,$pattern,"%A"); + } + if (!strlen($results[$key]['artist'])) { + $results[$key]['artist'] = $this->get_info_from_filename($filename,$pattern,"%a"); + } + if (!strlen($results[$key]['genre'])) { + $results[$key]['genre'] = $this->get_info_from_filename($filename,$pattern,"%g"); + } + + return $results; + + } // fill_info + + /*! + @function get_info_from_filename + @discussion get information from a filename based on pattern + */ + function get_info_from_filename($file,$pattern,$tag) { + + $preg_pattern = preg_replace("/$tag/","(.+)",$pattern); + $preg_pattern = preg_replace("/\%\w/",".+",$preg_pattern); + $preg_pattern = "/" . str_replace("/","\/",$preg_pattern) . "\..+/"; + + preg_match($preg_pattern,$file,$matches); + + return stripslashes($matches[1]); + + } // get_info_from_filename + +} //end of song class + +?> diff --git a/lib/class/stream.php b/lib/class/stream.php new file mode 100644 index 00000000..999dcbca --- /dev/null +++ b/lib/class/stream.php @@ -0,0 +1,294 @@ +type = $type; + $this->songs = $song_ids; + $this->web_path = conf('web_path'); + + if (conf('force_http_play')) { + $port = conf('http_port'); + $this->web_path = preg_replace("/https/", "http",$this->web_path); + $this->web_path = preg_replace("/:\d+/",":$port",$this->web_path); + } + + $this->sess = session_id(); + $this->user_id = $_SESSION['userdata']['id']; + + } //constructor + + /*! + @function start + @discussion runs this and depending on the type passed it will + call the correct function + */ + function start() { + + $methods = get_class_methods('Stream'); + $create_function = "create_" . $this->type; + if (in_array($create_function,$methods)) { + $this->{$create_function}(); + } + // Assume M3u incase they've pooched the type + else { + $this->create_m3u(); + } + + } // start + + /*! + @function create_simplem3u + @discussion this creates a simple m3u + without any of the extended information + */ + function create_simple_m3u() { + + header("Cache-control: public"); + header("Content-Disposition: filename=playlist.m3u"); + header("Content-Type: audio/x-mpegurl;"); + foreach ($this->songs as $song_id) { + $song = new Song($song_id); + if ($song->type == ".flac") { $song->type = ".ogg"; } + if($GLOBALS['user']->prefs['play_type'] == 'downsample') { + $ds = $GLOBALS['user']->prefs['sample_rate']; + } + echo "$this->web_path/play/index.php?song=$song_id&uid=$this->user_id&sid=$this->sess&ds=$ds&stupidwinamp=." . $song->type . "\n"; + } // end foreach + + } // simple_m3u + + /*! + @function create_m3u + @discussion creates an m3u file + */ + function create_m3u() { + + // Send the client an m3u playlist + header("Cache-control: public"); + header("Content-Disposition: filename=playlist.m3u"); + header("Content-Type: audio/x-mpegurl;"); + echo "#EXTM3U\n"; + foreach($this->songs as $song_id) { + $song = new Song($song_id); + $song->format_song(); + if ($song->type == ".flac") { $song->type = ".ogg"; } + $song_name = $song->f_artist_full . " - " . $song->title . "." . $song->type; + echo "#EXTINF:$song->time,$song_name\n"; + $sess = $_COOKIE[libglue_param('sess_name')]; + if($GLOBALS['user']->prefs['play_type'] == 'downsample') { + $ds = $GLOBALS['user']->prefs['sample_rate']; + } + echo "$this->web_path/play/index.php?song=$song_id&uid=$this->user_id&sid=$this->sess&ds=$ds&name=/" . rawurlencode($song_name) . "\n"; + } // end foreach + + } // create_m3u + + /*! + @function create_pls + @discussion creates a pls file + */ + function create_pls() { + + // Send the client a pls playlist + header("Cache-control: public"); + header("Content-Disposition: filename=playlist.pls"); + header("Content-Type: audio/x-scpls;"); + echo "[Playlist]\n"; + echo "NumberOfEntries=" . count($this->songs) . "\n"; + foreach ($this->songs as $song_id) { + $i++; + $song = new Song($song_id); + $song->format_song(); + if ($song->type == ".flac") { $song->type = ".ogg"; } + $song_name = $song->f_artist_full . " - " . $song->title . "." . $song->type; + if($GLOBALS['user']->prefs['play_type'] == 'downsample') { + $ds = $GLOBALS['user']->prefs['sample_rate']; + } + $song_url = $this->web_path . "/play/index.php?song=$song_id&uid=$this->user_id&sid=$this->sess&ds=$ds&stupidwinamp=." . $song->type; + echo "File" . $i . "=$song_url\n"; + echo "Title" . $i . "=$song_name\n"; + echo "Length" . $i . "=-1\n"; + } // end foreach songs + echo "Version=2\n"; + + } // create_pls + + /*! + @function create_asx + @discussion creates an ASZ playlist (Thx Samir Kuthiala) + */ + function create_asx() { + + header("Cache-control: public"); + header("Content-Disposition: filename=playlist.asx"); + header("Content-Type: video/x-ms-asf;"); + + echo "\n"; + echo "Ampache ASX Playlist"; + + foreach ($this->songs as $song_id) { + $song = new Song($song_id); + $song->format_song(); + $song_name = $song->f_artist_full . " - " . $song->title . "." . $song->type; + echo "\n"; + echo "".$song->f_album_full ." - ". $song->f_artist_full ." - ". $song->title ."\n"; + echo "".$song->f_artist_full."\n"; + $sess = $_COOKIE[libglue_param('sess_name')]; + if ($GLOBALS['user']->prefs['play_type'] == 'downsample') { + $ds = $GLOBALS['user']->prefs['sample_rate']; + } + echo "user_id&sid=$sess&ds=$ds&name=/" . rawurlencode($song_name) . "\" />\n"; + echo "\n"; + + } // end foreach + + echo "\n"; + + } // create_asx + + /*! + @function create_icecast2 + @discussion pushes an icecast stream + */ + function create_icecast2() { + + echo "ICECAST2
    \n"; + + // Play the song locally using local play configuration + if (count($this->songs) > 0) { + echo "ICECAST2
    \n"; + exec("killall ices"); + $filename = conf('icecast_tracklist'); + echo "$filename " . _("Opened for writting") . "
    \n"; + + /* Open the file for writting */ + if (!$handle = @fopen($filename, "w")) { + log_event($_SESSION['userdata']['username'],"icecast","Fopen: $filename Failed"); + echo _("Error, cannot write") . " $filename
    \n"; + exit; + } + + /* Foreach through songs */ + foreach($this->songs as $song_id) { + $song = new Song($song_id); + echo "$song->file
    \n"; + $line = "$song->file\n"; + if (!fwrite($handle, $line)) { + log_event($_SESSION['userdata']['username'],"icecast","Fwrite: Unabled to write $line into $filename"); + echo _("Error, cannot write song in file") . " $song->file --> $filename"; + exit; + } // if write fails + + } // foreach songs + + echo $filename . " " . _("Closed after write") . "
    \n"; + fclose($handle); + $cmd = conf('icecast_command'); + $cmd = str_replace("%FILE%", $filename, $cmd); + if (conf('debug')) { + log_event($_SESSION['userdata']['username'],"icecast","Exec: $cmd"); + } + exec($cmd); + exit; + + } // if songs + + + } // create_icecast2 + + /*! + @function create_local_play + @discussion pushes out localplay mojo + */ + function create_local_play() { + + foreach($this->songs as $song_id) { + $song = new Song($song_id); + $song->format_song(); + $song_name = $song->f_artist_full . " - " . $song->title . "." . $song->type; + $url = escapeshellarg("$this->web_path/play/?song=$song_id&uid=$this->user_id&sid=$this->sess&name=" . rawurlencode($song_name)); + $localplay_add = conf('localplay_add'); + $localplay_add = str_replace("%URL%", $url, $localplay_add); + if (conf('debug')) { + log_event($_SESSION['userdata']['username'],"localplay","Exec: $localplay_add"); + } + exec($localplay_add); + header("Location: " . conf('web_path') . "/index.php"); + } + + } // create_localplay + + /*! + @function create_mpd + @discussion function that passes information to + MPD + */ + function create_mpd() { + + /* Create the MPD object */ + $myMpd = @new mpd(conf('mpd_host'),conf('mpd_port'),conf('mpd_pass')); + + /* Add the files to the MPD playlist */ + addToPlaylist($myMpd,$this->songs); + + /* If we've added songs we should start playing */ + $myMpd->Play(); + + header ("Location: " . return_referer()); + + } // create_mpd + + + /*! + @function create_slim + @discussion this function passes the correct mojo to the slim + class which is in turn passed to the slimserver + */ + function create_slim() { + + + + + + } // create_slim + + +} //end of stream class + +?> diff --git a/lib/class/update.php b/lib/class/update.php new file mode 100644 index 00000000..b006b8e7 --- /dev/null +++ b/lib/class/update.php @@ -0,0 +1,931 @@ +get_info(); + $this->key = $key; + $this->value = $info->value; + $this->versions = $this->populate_version(); + } + + } // constructor + + /*! + @function get_info + @discussion gets the information for the zone + */ + function get_info() { + global $conf; + + $sql = "SELECT * FROM update_info WHERE key='$this->key'"; + $db_results = mysql_query($sql, dbh()); + + return mysql_fetch_object($db_results); + + } //get_info + + /*! + @function get_version + @discussion this checks to see what version you are currently running + because we may not have the update_info table we have to check + for it's existance first. + */ + function get_version() { + + + /* Make sure that update_info exits */ + $sql = "SHOW TABLES LIKE 'update_info'"; + $db_results = mysql_query($sql, dbh()); + // If no table + if (!mysql_num_rows($db_results)) { + + $version = '310000'; + + } // if table isn't found + + else { + // If we've found the update_info table, let's get the version from it + $sql = "SELECT * FROM update_info WHERE `key`='db_version'"; + $db_results = mysql_query($sql, dbh()); + $results = mysql_fetch_object($db_results); + $version = $results->value; + } + + return $version; + + } // get_version + + /*! + @function format_version + @discussion make the version number pretty + */ + function format_version($data) { + + $new_version = substr($data,0,strlen($data) - 5) . "." . substr($data,strlen($data)-5,1) . " Build:" . + substr($data,strlen($data)-4,strlen($data)); + + return $new_version; + + } // format_version + + /*! + @function need_update + @discussion checks to see if we need to update + maintain at all + */ + function need_update() { + + $current_version = $this->get_version(); + + if (!is_array($this->versions)) { + $this->versions = $this->populate_version(); + } + + /* + Go through the versions we have and see if + we need to apply any updates + */ + foreach ($this->versions as $update) { + if ($update['version'] > $current_version) { + return true; + } + + } // end foreach version + + return false; + + } // need_update + + + /*! + @function populate_version + @discussion just sets an array the current differences + that require an update + */ + function populate_version() { + + /* Define the array */ + $version = array(); + + /* Version 3.2 Build 0001 */ + $update_string = "- Add update_info table to the database
    " . + "- Add Now Playing Table
    " . + "- Add album art columns to album table
    " . + "- Compleatly Changed Preferences table
    " . + "- Added Upload table
    "; + $version[] = array('version' => '320001', 'description' => $update_string); + + $update_string = "- Add back in catalog_type for XML-RPC Mojo
    " . + "- Add level to access list to allow for play/download/xml-rpc share permissions
    " . + "- Changed access_list table to allow start-end (so we can set full ip ranges)
    " . + "- Add default_play to preferences to allow quicktime/localplay/stream
    " . + "- Switched Artist ID from 10 --> 11 to match other tables
    "; + $version[] = array('version' => '320002', 'description' => $update_string); + + $update_string = "- Added a last_seen field user table to track users
    " . + "- Made preferences table key/value based
    "; + + $version[] = array('version' => '320003', 'description' => $update_string); + + $update_string = "- Added play_type to preferences table
    " . + "- Removed multicast,downsample,localplay from preferences table
    " . + "- Dropped old config table which was no longer needed
    "; + + $version[] = array('version' => '320004', 'description' => $update_string); + + $update_string = "- Added type to preferences to allow for site/user preferences
    "; + + $version[] = array('version' => '330000', 'description' => $update_string); + + $update_string = "- Added Year to album table
    " . + "- Increased length of password field in User table
    "; + + $version[] = array('version' => '330001', 'description' => $update_string); + + $update_string = "- Changed user.access to varchar from enum for more flexibility
    " . + "- Added catalog.private for future catalog access control
    " . + "- Added user_catalog table for future catalog access control
    "; + + + $version[] = array('version' => '330002', 'description' => $update_string); + + $update_string = "- Added user_preferences table to once and for all fix preferences.
    " . + "- Moved Contents of preferences into new table, and modifies old preferences table.
    "; + + $version[] = array('version' => '330003', 'description' => $update_string); + + $update_string = "- Changed song comment from varchar255 in order to handle comments longer than 255 chr.
    " . + "- Added Language and Playlist Type as a per user preference.
    " . + "- Added Level to Catalog_User table for future use.
    " . + "- Added gather_types to Catalog table for future use.
    "; + + + $version[] = array('version' => '330004', 'description' => $update_string); + + $update_string = "- Added Theme config option.
    "; + + $version[] = array('version' => '331000', 'description' => $update_string); + + $update_string = "- Added Elipse Threshold Preferences.
    "; + + $version[] = array('version' => '331001', 'description' => $update_string); + + $update_string = "- Added Show bottom menu option.
    "; + $version[] = array('version' => '331002', 'description' => $update_string); + + $update_string = "- Cleaned up user management.
    "; + + $version[] = array('version' => '331003', 'description' => $update_string); + + + return $version; + + } // populate_version + + /*! + @function display_update + @discussion This displays a list of the needed + updates to the database. This will actually + echo out the list... + */ + function display_update() { + + $current_version = $this->get_version(); + if (!is_array($this->versions)) { + $this->versions = $this->populate_version(); + } + + echo "
      \n"; + + foreach ($this->versions as $version) { + + if ($version['version'] > $current_version) { + $updated = true; + echo "Version: " . $this->format_version($version['version']) . "
      "; + echo $version['description'] . "
      \n"; + } // if newer + + } // foreach versions + + echo "
    \n"; + + if (!$updated) { echo "

    No Updates Needed [Return]

    "; } + } // display_update + + /*! + @function run_update + @discussion This function actually updates the db. + it goes through versions and finds the ones + that need to be run. Checking to make sure + the function exists first. + */ + function run_update() { + + /* Nuke All Active session before we start the mojo */ + $sql = "DELETE * FROM session"; + $db_results = mysql_query($sql, dbh()); + + + $methods = array(); + + $current_version = $this->get_version(); + + $methods = get_class_methods('Update'); + + if (!is_array($this->versions)) { + $this->versions = $this->populate_version(); + } + + foreach ($this->versions as $version) { + + + // If it's newer than our current version + // let's see if a function exists and run the + // bugger + if ($version['version'] > $current_version) { + $update_function = "update_" . $version['version']; + if (in_array($update_function,$methods)) { + $this->{$update_function}(); + } + + } + + } // end foreach version + + } // run_update + + /*! + @function set_version + @discussion sets a new version takes + a key and value + */ + function set_version($key,$value) { + + $sql = "UPDATE update_info SET value='$value' WHERE `key`='$key'"; + $db_results = mysql_query($sql, dbh()); + + } //set_version + + /*! + @function update_320001 + @discussion Migration function for 3.2 Build 0001 + */ + function update_320001() { + + // Add the update_info table to the database + $sql = "CREATE TABLE `update_info` (`key` VARCHAR( 128 ) NOT NULL ,`value` VARCHAR( 255 ) NOT NULL ,INDEX ( `key` ) )"; + $db_results = mysql_query($sql, dbh()); + + // Insert the first version info + $sql = "INSERT INTO update_info (`key`,`value`) VALUES ('db_version','320001')"; + $db_results = mysql_query($sql, dbh()); + + // Add now_playing table to database + $sql = "CREATE TABLE now_playing (" . + "id int(11) unsigned NOT NULL auto_increment, " . + "song_id int(11) unsigned NOT NULL default '0', " . + "user_id int(11) unsigned default NULL, " . + "start_time int(11) unsigned NOT NULL default '0', " . + "PRIMARY KEY (id) " . + ") TYPE=MyISAM"; + $db_results = mysql_query($sql, dbh()); + + // Add the upload table to the database + $sql = "CREATE TABLE upload ( id int(11) unsigned NOT NULL auto_increment, `user` int(11) unsigned NOT NULL," . + "`file` varchar(255) NOT NULL , `comment` varchar(255) NOT NULL , action enum('add','quarantine','delete') NOT NULL default 'quarantine', " . + "addition_time int(11) unsigned default '0', PRIMARY KEY (id), KEY action (`action`), KEY user (`user`) )"; + $db_results = mysql_query($sql, dbh()); + + /* + Ok we need to compleatly tweak the preferences table + first things first, nuke the damn thing so we can + setup our new mojo + */ + $sql = "DROP TABLE `preferences`"; + $db_results = mysql_query($sql, dbh()); + + $sql = "CREATE TABLE `preferences` (`id` INT( 11 ) UNSIGNED NOT NULL AUTO_INCREMENT , `user` INT( 11 ) UNSIGNED NOT NULL ," . + "`download` ENUM( 'true', 'false' ) DEFAULT 'false' NOT NULL , `upload` ENUM( 'disabled', 'html', 'gui' ) DEFAULT 'disabled' NOT NULL ," . + "`downsample` ENUM( 'true', 'false' ) DEFAULT 'false' NOT NULL , `local_play` ENUM( 'true', 'false' ) DEFAULT 'false' NOT NULL ," . + "`multicast` ENUM( 'true', 'false' ) DEFAULT 'false' NOT NULL , `quarantine` ENUM( 'true', 'false' ) DEFAULT 'true' NOT NULL ," . + "`popular_threshold` INT( 11 ) UNSIGNED DEFAULT '10' NOT NULL , `font` VARCHAR( 255 ) DEFAULT 'Verdana, Helvetica, sans-serif' NOT NULL ," . + "`bg_color1` VARCHAR( 32 ) DEFAULT '#ffffff' NOT NULL , `bg_color2` VARCHAR( 32 ) DEFAULT '#000000' NOT NULL , `base_color1` VARCHAR( 32 ) DEFAULT '#bbbbbb' NOT NULL , " . + "`base_color2` VARCHAR( 32 ) DEFAULT '#dddddd' NOT NULL , `font_color1` VARCHAR( 32 ) DEFAULT '#222222' NOT NULL , " . + "`font_color2` VARCHAR( 32 ) DEFAULT '#000000' NOT NULL , `font_color3` VARCHAR( 32 ) DEFAULT '#ffffff' NOT NULL , " . + "`row_color1` VARCHAR( 32 ) DEFAULT '#cccccc' NOT NULL , `row_color2` VARCHAR( 32 ) DEFAULT '#bbbbbb' NOT NULL , " . + "`row_color3` VARCHAR( 32 ) DEFAULT '#dddddd' NOT NULL , `error_color` VARCHAR( 32 ) DEFAULT '#990033' NOT NULL , " . + "`font_size` INT( 11 ) UNSIGNED DEFAULT '10' NOT NULL , `upload_dir` VARCHAR( 255 ) NOT NULL , " . + "`sample_rate` INT( 11 ) UNSIGNED DEFAULT '32' NOT NULL , PRIMARY KEY ( `id` ), KEY user (`user`) )"; + $db_results = mysql_query($sql, dbh()); + + $sql = "INSERT INTO preferences (`user`,`font_size`) VALUES ('0','12')"; + $db_results = mysql_query($sql, dbh()); + + // Now we need to give everyone some preferences + $sql = "SELECT * FROM user"; + $db_results = mysql_query($sql, dbh()); + + while ($r = mysql_fetch_object($db_results)) { + $users[] = $r; + } + + foreach ($users as $user) { + $sql = "INSERT INTO preferences (`user`) VALUES ('$user->id')"; + $db_results = mysql_query($sql, dbh()); + } + + // Add album art columns to album table + $sql = "ALTER TABLE album ADD art MEDIUMBLOB, ADD art_mime VARCHAR(128)"; + $db_result = mysql_query($sql, dbh()); + + } // update_320001 + + /*! + @function update_320002 + @discussion update to alpha 2 + */ + function update_320002() { + + /* Add catalog_type back in for XML-RPC */ + $sql = "ALTER TABLE `catalog` ADD `catalog_type` ENUM( 'local', 'remote' ) DEFAULT 'local' NOT NULL AFTER `path`"; + $db_results = mysql_query($sql, dbh()); + + /* Add default_play to pick between stream/localplay/quicktime */ + $sql = "ALTER TABLE `preferences` ADD `default_play` VARCHAR( 128 ) DEFAULT 'stream' NOT NULL AFTER `popular_threshold`"; + $db_results = mysql_query($sql, dbh()); + + /* Should be INT(11) Why not eah? */ + $sql = "ALTER TABLE `artist` CHANGE `id` `id` INT( 11 ) UNSIGNED NOT NULL AUTO_INCREMENT"; + $db_results = mysql_query($sql, dbh()); + + /* Add level to access_list so we can limit playback/download/xml-rpc share */ + $sql = "ALTER TABLE `access_list` ADD `level` SMALLINT( 3 ) UNSIGNED DEFAULT '5' NOT NULL"; + $db_results = mysql_query($sql, dbh()); + + /* Shouldn't be zero fill... not needed */ + $sql = "ALTER TABLE `user` CHANGE `offset_limit` `offset_limit` INT( 5 ) UNSIGNED DEFAULT '00050' NOT NULL"; + $db_results = mysql_query($sql, dbh()); + + /* Let's knock it up a notch 11.. BAM */ + $sql = "ALTER TABLE `user` CHANGE `id` `id` INT( 11 ) UNSIGNED NOT NULL AUTO_INCREMENT"; + $db_results = mysql_query($sql, dbh()); + + /* Change IP --> Start */ + $sql = "ALTER TABLE `access_list` CHANGE `ip` `start` INT( 11 ) UNSIGNED NOT NULL"; + $db_results = mysql_query($sql, dbh()); + + /* Add End */ + $sql = "ALTER TABLE `access_list` ADD `end` INT( 11 ) UNSIGNED NOT NULL AFTER `start`"; + $db_results = mysql_query($sql, dbh()); + + /* Update Version */ + $this->set_version('db_version', '320002'); + + } // update_320002 + + + /*! + @function update_320003 + @discussion updates to the alpha 3 of 3.2 + */ + function update_320003() { + + /* Add last_seen to user table */ + $sql = "ALTER TABLE `user` ADD `last_seen` INT( 11 ) UNSIGNED NOT NULL"; + $db_results = mysql_query($sql, dbh()); + + /* + Load the preferences table into an array + so we can migrate it to the new format + */ + $sql = "SELECT * FROM preferences"; + $db_results = mysql_query($sql, dbh()); + + $results = array(); + + while ($r = mysql_fetch_object($db_results)) { + $results[$r->user]['download'] = $r->download; + $results[$r->user]['upload'] = $r->upload; + $results[$r->user]['downsample'] = $r->downsample; + $results[$r->user]['local_play'] = $r->local_play; + $results[$r->user]['multicast'] = $r->multicast; + $results[$r->user]['quarantine'] = $r->quarantine; + $results[$r->user]['popular_threshold'] = $r->popular_threshold; + $results[$r->user]['default_play'] = $r->default_play; + $results[$r->user]['font'] = $r->font; + $results[$r->user]['bg_color1'] = $r->bg_color1; + $results[$r->user]['bg_color2'] = $r->bg_color2; + $results[$r->user]['base_color1'] = $r->base_color1; + $results[$r->user]['base_color2'] = $r->base_color2; + $results[$r->user]['font_color1'] = $r->font_color1; + $results[$r->user]['font_color2'] = $r->font_color2; + $results[$r->user]['font_color3'] = $r->font_color3; + $results[$r->user]['row_color1'] = $r->row_color1; + $results[$r->user]['row_color2'] = $r->row_color2; + $results[$r->user]['row_color3'] = $r->row_color3; + $results[$r->user]['error_color'] = $r->error_color; + $results[$r->user]['font_size'] = $r->font_size; + $results[$r->user]['upload_dir'] = $r->upload_dir; + $results[$r->user]['sample_rate'] = $r->sample_rate; + + } // while preferences + + /* Drop the preferences table so we can start over */ + $sql = "DROP TABLE `preferences`"; + $db_results = mysql_query($sql, dbh()) or die('Query failed: ' . mysql_error()); + + /* Create the new preferences table */ + $sql = "CREATE TABLE `preferences` (`key` VARCHAR( 255 ) NOT NULL , `value` VARCHAR( 255 ) NOT NULL , `user` INT( 11 ) UNSIGNED NOT NULL)"; + $db_results = mysql_query($sql, dbh()); + + $sql = "ALTER TABLE `preferences` ADD INDEX ( `key` )"; + $db_results = mysql_query($sql, dbh()); + + $sql = "ALTER TABLE `preferences` ADD INDEX ( `user` )"; + $db_results = mysql_query($sql, dbh()); + + + $user = new User(); + + /* Populate the mofo! */ + foreach ($results as $key => $data) { + + $user->add_preference('download',$results[$key]['download'],$key); + $user->add_preference('upload',$results[$key]['upload'], $key); + $user->add_preference('downsample',$results[$key]['downsample'], $key); + $user->add_preference('local_play', $results[$key]['local_play'], $key); + $user->add_preference('multicast', $results[$key]['multicast'], $key); + $user->add_preference('quarantine', $results[$key]['quarantine'], $key); + $user->add_preference('popular_threshold',$results[$key]['popular_threshold'], $key); + $user->add_preference('font', $results[$key]['font'], $key); + $user->add_preference('bg_color1',$results[$key]['bg_color1'], $key); + $user->add_preference('bg_color2',$results[$key]['bg_color2'], $key); + $user->add_preference('base_color1',$results[$key]['base_color1'], $key); + $user->add_preference('base_color2',$results[$key]['base_color2'], $key); + $user->add_preference('font_color1',$results[$key]['font_color1'], $key); + $user->add_preference('font_color2',$results[$key]['font_color2'], $key); + $user->add_preference('font_color3',$results[$key]['font_color3'], $key); + $user->add_preference('row_color1',$results[$key]['row_color1'], $key); + $user->add_preference('row_color2',$results[$key]['row_color2'], $key); + $user->add_preference('row_color3',$results[$key]['row_color3'], $key); + $user->add_preference('error_color', $results[$key]['error_color'], $key); + $user->add_preference('font_size', $results[$key]['font_size'], $key); + $user->add_preference('upload_dir', $results[$key]['upload_dir'], $key); + $user->add_preference('sample_rate', $results[$key]['sample_rate'], $key); + + } // foreach preferences + + /* Update Version */ + $this->set_version('db_version', '320003'); + + } // update_320003 + + /*! + @function update_320004 + @discussion updates to the 320004 + version of the db + */ + function update_320004() { + + $results = array(); + + $sql = "SELECT * FROM preferences WHERE `key`='local_play' AND `value`='true'"; + $db_results = mysql_query($sql, dbh()); + + while ($r = mysql_fetch_object($db_results)) { + $results[$r->user] = 'local_play'; + } + + $sql = "SELECT * FROM preferences WHERE `key`='downsample' AND `value`='true'"; + $db_results = mysql_query($sql, dbh()); + + while ($r = mysql_fetch_object($db_results)) { + $results[$r->user] = 'downsample'; + } + + $sql = "SELECT * FROM preferences WHERE `key`='multicast' AND `value`='true'"; + $db_results = mysql_query($sql, dbh()); + + while ($r = mysql_fetch_object($db_results)) { + $results[$r->user] = 'multicast'; + } + + $sql = "SELECT DISTINCT(user) FROM preferences"; + $db_results = mysql_query($sql, dbh()); + + while ($r = mysql_fetch_object($db_results)) { + if (!isset($results[$r->user])) { + $results[$r->user] = 'normal'; + } + } + + foreach ($results as $key => $value) { + $sql = "INSERT INTO preferences (`key`,`value`,`user`) VALUES ('play_type','$value','$key')"; + $db_results = mysql_query($sql, dbh()); + } + + $sql = "DELETE FROM preferences WHERE `key`='downsample'"; + $db_results = mysql_query($sql, dbh()); + + $sql = "DELETE FROM preferences WHERE `key`='local_play'"; + $db_results = mysql_query($sql, dbh()); + + $sql = "DELETE FROM preferences WHERE `key`='multicast'"; + $db_results = mysql_query($sql, dbh()); + + $sql = "DROP TABLE `config`"; + $db_results = mysql_query($sql, dbh()); + + /* Update Version */ + $this->set_version('db_version', '320004'); + + } // update_320004 + + /*! + @function update_330000 + @discussion updates to 3.3 Build 0 + */ + function update_330000() { + + /* Add Type to preferences */ + $sql = "ALTER TABLE `preferences` ADD `type` VARCHAR( 128 ) NOT NULL"; + $db_results = mysql_query($sql, dbh()); + + /* Set Type on current preferences */ + $sql = "UPDATE `preferences` SET type='user'"; + $db_results = mysql_query($sql, dbh()); + + /* Add New Preferences */ + $new_prefs[] = array('key' => 'local_length', 'value' => libglue_param('local_length')); + $new_prefs[] = array('key' => 'site_title', 'value' => conf('site_title')); + $new_prefs[] = array('key' => 'access_control', 'value' => conf('access_control')); + $new_prefs[] = array('key' => 'xml_rpc', 'value' => conf('xml_rpc')); + $new_prefs[] = array('key' => 'lock_songs', 'value' => conf('lock_songs')); + $new_prefs[] = array('key' => 'force_http_play', 'value' => conf('force_http_play')); + $new_prefs[] = array('key' => 'http_port', 'value' => conf('http_port')); + $new_prefs[] = array('key' => 'do_mp3_md5', 'value' => conf('do_mp3_md5')); + $new_prefs[] = array('key' => 'catalog_echo_count', 'value' => conf('catalog_echo_count')); + $new_prefs[] = array('key' => 'no_symlinks', 'value' => conf('no_symlinks')); + $new_prefs[] = array('key' => 'album_cache_limit', 'value' => conf('album_cache_limit')); + $new_prefs[] = array('key' => 'artist_cache_limit', 'value' => conf('artist_cache_limit')); + $new_prefs[] = array('key' => 'memory_limit', 'value' => conf('memory_limit')); + $new_prefs[] = array('key' => 'refresh_limit', 'value' => conf('refresh_interval')); + + foreach ($new_prefs as $pref) { + $sql = "INSERT INTO `preferences` (`key`,`value`,`type`) VALUES ('".$pref['key']."','".$pref['value']."','system')"; + $db_results = mysql_query($sql, dbh()); + } + + + /* Update Version */ + $this->set_version('db_version','330000'); + + + } // update_330000 + + + /*! + @function update_330001 + @discussion adds year to album and tweaks + the password field in session + */ + function update_330001() { + + /* Add Year to Album Table */ + $sql = "ALTER TABLE `album` ADD `year` INT( 4 ) UNSIGNED NOT NULL AFTER `prefix`"; + $db_results = mysql_query($sql, dbh()); + + /* Alter Password Field */ + $sql = "ALTER TABLE `user` CHANGE `password` `password` VARCHAR( 64 ) NOT NULL"; + $db_results = mysql_query($sql, dbh()); + + /* Update Version */ + $this->set_version('db_version', '330001'); + + } // update_330001 + + /*! + @function update_330002 + @discussion changes user.access from enum to a + varchr field + */ + function update_330002() { + + /* Alter user table */ + $sql = "ALTER TABLE `user` CHANGE `access` `access` VARCHAR( 64 ) NOT NULL"; + $db_results = mysql_query($sql, dbh()); + + /* Add private option to catalog */ + $sql = "ALTER TABLE `catalog` ADD `private` INT( 1 ) UNSIGNED DEFAULT '0' NOT NULL AFTER `enabled`"; + $db_results = mysql_query($sql, dbh()); + + /* Add new user_catalog table */ + $sql = "CREATE TABLE `user_catalog` ( `user` INT( 11 ) UNSIGNED NOT NULL , `catalog` INT( 11 ) UNSIGNED NOT NULL )"; + $db_results = mysql_query($sql, dbh()); + + /* Update Version */ + $this->set_version('db_version', '330002'); + + } // update_330002 + + /*! + @function update_330003 + @discussion adds user_preference and modifies the + existing preferences table + */ + function update_330003() { + + /* Add new user_preference table */ + $sql = "CREATE TABLE `user_preference` ( `user` INT( 11 ) UNSIGNED NOT NULL , `preference` INT( 11 ) UNSIGNED NOT NULL, `value` VARCHAR( 255 ) NOT NULL )"; + $db_results = mysql_query($sql, dbh()); + + /* Add indexes */ + $sql = "ALTER TABLE `user_preference` ADD INDEX ( `user` )"; + $db_results = mysql_query($sql, dbh()); + + $sql = "ALTER TABLE `user_preference` ADD INDEX ( `preference` )"; + $db_results = mysql_query($sql, dbh()); + + /* Pull and store all preference information */ + $sql = "SELECT * FROM preferences"; + $db_results = mysql_query($sql, dbh()); + + $results = array(); + + while ($r = mysql_fetch_object($db_results)) { + $results[] = $r; + } + + + /* Re-combobulate preferences table */ + + /* Drop the preferences table so we can start over */ + $sql = "DROP TABLE `preferences`"; + $db_results = mysql_query($sql, dbh()) or die('Query failed: ' . mysql_error()); + + /* Insert new preference table */ + $sql = "CREATE TABLE `preferences` ( `id` INT ( 11 ) UNSIGNED NOT NULL AUTO_INCREMENT, `name` VARCHAR ( 128 ) NOT NULL, `value` VARCHAR ( 255 ) NOT NULL," . + " `description` VARCHAR ( 255 ) NOT NULL, `level` INT ( 11 ) UNSIGNED NOT NULL DEFAULT '100', `type` VARCHAR ( 128 ) NOT NULL, `locked` SMALLINT ( 1 ) NOT NULL Default '1'" . + ", PRIMARY KEY ( `id` ) )"; + $db_results = mysql_query($sql, dbh()) or die("Query failed: " . mysql_error()); + + /* Create Array of Preferences */ + $new_prefs = array(); + + $new_prefs[] = array('name' => 'download', 'value' => '0', 'description' => 'Allow Downloads', 'level' => '100', 'locked' => '0', 'type' => 'user'); + $new_prefs[] = array('name' => 'upload', 'value' => '0', 'description' => 'Allow Uploads', 'level' => '100', 'locked' => '0', 'type' => 'user'); + $new_prefs[] = array('name' => 'quarantine', 'value' => '1', 'description' => 'Quarantine All Uploads', 'level' => '100', 'locked' => '0', 'type' => 'user'); + $new_prefs[] = array('name' => 'popular_threshold', 'value' => '10', 'description' => 'Popular Threshold', 'level' => '25', 'locked' => '0', 'type' => 'user'); + $new_prefs[] = array('name' => 'font', 'value' => 'Verdana, Helvetica, sans-serif', 'description' => 'Interface Font', 'level' => '25', 'locked' => '0', 'type' => 'user'); + $new_prefs[] = array('name' => 'bg_color1', 'value' => '#ffffff', 'description' => 'Background Color 1', 'level' => '25', 'locked' => '0', 'type' => 'user'); + $new_prefs[] = array('name' => 'bg_color2', 'value' => '#000000', 'description' => 'Background Color 2', 'level' => '25', 'locked' => '0', 'type' => 'user'); + $new_prefs[] = array('name' => 'base_color1', 'value' => '#bbbbbb', 'description' => 'Base Color 1', 'level' => '25', 'locked' => '0', 'type' => 'user'); + $new_prefs[] = array('name' => 'base_color2', 'value' => '#dddddd', 'description' => 'Base Color 2', 'level' => '25', 'locked' => '0', 'type' => 'user'); + $new_prefs[] = array('name' => 'font_color1', 'value' => '#222222', 'description' => 'Font Color 1', 'level' => '25', 'locked' => '0', 'type' => 'user'); + $new_prefs[] = array('name' => 'font_color2', 'value' => '#000000', 'description' => 'Font Color 2', 'level' => '25', 'locked' => '0', 'type' => 'user'); + $new_prefs[] = array('name' => 'font_color3', 'value' => '#ffffff', 'description' => 'Font Color 3', 'level' => '25', 'locked' => '0', 'type' => 'user'); + $new_prefs[] = array('name' => 'row_color1', 'value' => '#cccccc', 'description' => 'Row Color 1', 'level' => '25', 'locked' => '0', 'type' => 'user'); + $new_prefs[] = array('name' => 'row_color2', 'value' => '#bbbbbb', 'description' => 'Row Color 2', 'level' => '25', 'locked' => '0', 'type' => 'user'); + $new_prefs[] = array('name' => 'row_color3', 'value' => '#dddddd', 'description' => 'Row Color 3', 'level' => '25', 'locked' => '0', 'type' => 'user'); + $new_prefs[] = array('name' => 'error_color', 'value' => '#990033', 'description' => 'Error Color', 'level' => '25', 'locked' => '0', 'type' => 'user'); + $new_prefs[] = array('name' => 'font_size', 'value' => '10', 'description' => 'Font Size', 'level' => '25', 'locked' => '0', 'type' => 'user'); + $new_prefs[] = array('name' => 'upload_dir', 'value' => '/tmp', 'description' => 'Upload Directory', 'level' => '25', 'locked' => '0', 'type' => 'user'); + $new_prefs[] = array('name' => 'sample_rate', 'value' => '32', 'description' => 'Downsample Bitrate', 'level' => '25', 'locked' => '0', 'type' => 'user'); + $new_prefs[] = array('name' => 'refresh_limit', 'value' => '0', 'description' => 'Refresh Rate for Homepage', 'level' => '100', 'locked' => '0', 'type' => 'system'); + $new_prefs[] = array('name' => 'local_length', 'value' => '900', 'description' => 'Session Expire in Seconds', 'level' => '100', 'locked' => '0', 'type' => 'system'); + $new_prefs[] = array('name' => 'site_title', 'value' => 'For The Love of Music', 'description' => 'Website Title', 'level' => '100', 'locked' => '0', 'type' => 'system'); + $new_prefs[] = array('name' => 'lock_songs', 'value' => '0', 'description' => 'Lock Songs', 'level' => '100', 'locked' => '1', 'type' => 'system'); + $new_prefs[] = array('name' => 'force_http_play', 'value' => '1', 'description' => 'Forces Http play regardless of port', 'level' => '100', 'locked' => '1', 'type' => 'system'); + $new_prefs[] = array('name' => 'http_port', 'value' => '80', 'description' => 'Non-Standard Http Port', 'level' => '100', 'locked' => '1', 'type' => 'system'); + $new_prefs[] = array('name' => 'catalog_echo_count', 'value' => '100', 'description' => 'Catalog Echo Interval', 'level' => '100', 'locked' => '0', 'type' => 'system'); + $new_prefs[] = array('name' => 'no_symlinks', 'value' => '0', 'description' => 'Don\'t Follow Symlinks', 'level' => '100', 'locked' => '0', 'type' => 'system'); + $new_prefs[] = array('name' => 'album_cache_limit', 'value' => '25', 'description' => 'Album Cache Limit', 'level' => '100', 'locked' => '0', 'type' => 'system'); + $new_prefs[] = array('name' => 'artist_cache_limit', 'value' => '50', 'description' => 'Artist Cache Limit', 'level' => '100', 'locked' => '0', 'type' => 'system'); + $new_prefs[] = array('name' => 'play_type', 'value' => 'stream', 'description' => 'Type of Playback', 'level' => '25', 'locked' => '0', 'type' => 'user'); + $new_prefs[] = array('name' => 'direct_link', 'value' => '1', 'description' => 'Allow Direct Links', 'level' => '100', 'locked' => '0', 'type' => 'user'); + + foreach ($new_prefs as $prefs) { + + $sql = "INSERT INTO preferences (`name`,`value`,`description`,`level`,`locked`,`type`) VALUES ('" . $prefs['name'] . "','" . $prefs['value'] ."','". $prefs['description'] ."','" . $prefs['level'] ."','". $prefs['locked'] ."','" . $prefs['type'] . "')"; + $db_results = mysql_query($sql, dbh()); + + } // foreach prefs + + + /* Re-insert Data into preferences table */ + + $user = new User(); + $users = array(); + + foreach ($results as $old_pref) { + // This makes sure that true/false yes no get turned into 0/1 + $temp_array = fix_preferences(array('old' => $old_pref->value)); + $old_pref->value = $temp_array['old']; + $user->add_preference($old_pref->key,$old_pref->value,$old_pref->user); + $users[$old_pref->user] = 1; + } // end foreach old preferences + + /* Fix missing preferences */ + foreach ($users as $userid => $data) { + $user->fix_preferences($userid); + } // end foreach user + + /* Update Version */ + $this->set_version('db_version', '330003'); + + } // update_330003 + + /*! + @function update_330004 + @discussion changes comment from varchar to text + and also adds a few preferences options and + adds the per db art functions + */ + function update_330004() { + + /* Change comment field in song */ + $sql = "ALTER TABLE `song` CHANGE `comment` `comment` TEXT NOT NULL"; + $db_results = mysql_query($sql, dbh()); + + /* Add Extra Preferences */ + $sql = "INSERT INTO `preferences` ( `id` , `name` , `value` , `description` , `level` , `type` , `locked` ) VALUES ('', 'lang', 'en_US', 'Language', '100', 'user', '0')"; + $db_results = mysql_query($sql, dbh()); + + $sql = "INSERT INTO `preferences` ( `id` , `name` , `value` , `description` , `level` , `type` , `locked` ) VALUES ('', 'playlist_type','m3u','Playlist Type','100','user','0')"; + $db_results = mysql_query($sql, dbh()); + + /* Add Gathertype to Catalog for future use */ + $sql = "ALTER TABLE `catalog` ADD `gather_types` VARCHAR( 255 ) NOT NULL AFTER `sort_pattern`"; + $db_results = mysql_query($sql, dbh()); + + /* Add level to user_catalog for future use */ + $sql = "ALTER TABLE `user_catalog` ADD `level` SMALLINT( 3 ) DEFAULT '25' NOT NULL AFTER `catalog`"; + $db_results = mysql_query($sql, dbh()); + + /* Fix existing preferences */ + $sql = "SELECT id FROM user"; + $db_results = mysql_query($sql, dbh()); + + $user = new User(0); + + while ($results = mysql_fetch_array($db_results)) { + $user->fix_preferences($results[0]); + } + + /* Update Version */ + $this->set_version('db_version', '330004'); + + } // update_330004 + + /*! + @function update_331000 + @discussion this updates is for 3.3.1 it adds + the theme preference. + */ + function update_331000() { + + + /* Add new preference */ + $sql = "INSERT INTO `preferences` (`id`,`name`,`value`,`description`,`level`,`type`,`locked`) VALUES ('','theme_name','classic','Theme','0','user','0')"; + $db_results = mysql_query($sql, dbh()); + + /* Fix existing preferecnes */ + $sql = "SELECT DISTINCT(user) FROM user_preference"; + $db_results = mysql_query($sql, dbh()); + + $user = new User(0); + + while ($results = mysql_fetch_array($db_results)) { + $user->fix_preferences($results[0]); + } + + /* Update Version */ + $this->set_version('db_version','331000'); + + } // update_331000 + + /*! + @function update_331001 + @discussion this adds a few more user preferences + */ + function update_331001() { + + /* Add new preference */ + $sql = "INSERT INTO `preferences` (`id`,`name`,`value`,`description`,`level`,`type`,`locked`) VALUES ('','ellipse_threshold_album','27','Album Ellipse Threshold','0','user','0')"; + $db_results = mysql_query($sql, dbh()); + + $sql = "INSERT INTO `preferences` (`id`,`name`,`value`,`description`,`level`,`type`,`locked`) VALUES ('','ellipse_threshold_artist','27','Artist Ellipse Threshold','0','user','0')"; + $db_results = mysql_query($sql, dbh()); + + $sql = "INSERT INTO `preferences` (`id`,`name`,`value`,`description`,`level`,`type`,`locked`) VALUES ('','ellipse_threshold_title','27','Title Ellipse Threshold','0','user','0')"; + $db_results = mysql_query($sql, dbh()); + + /* Fix existing preferecnes */ + $sql = "SELECT DISTINCT(user) FROM user_preference"; + $db_results = mysql_query($sql, dbh()); + + $user = new User(0); + + while ($results = mysql_fetch_array($db_results)) { + $user->fix_preferences($results[0]); + } + + /* Update Version */ + $this->set_version('db_version','331001'); + + } // update_331001 + + + function update_331002() { + + /* Add new preference */ + $sql = "INSERT INTO `preferences` (`id`,`name`,`value`,`description`,`level`,`type`,`locked`) VALUES ('','display_menu','1','Show Bottom Menu','0','user','0')"; + $db_results = mysql_query($sql, dbh()); + /* Fix existing preferecnes */ + $sql = "SELECT DISTINCT(user) FROM user_preference"; + $db_results = mysql_query($sql, dbh()); + + $user = new User(0); + + while ($results = mysql_fetch_array($db_results)) { + $user->fix_preferences($results[0]); + } + + /* Update Version */ + $this->set_version('db_version','331002'); + + } // update_331002 + + function update_331003() { + + /* Add `disabled` column to user table */ + $sql = "ALTER TABLE `user` ADD `disabled` TINYINT( 1 ) NOT NULL DEFAULT '0' AFTER `access`"; + $db_results = mysql_query($sql, dbh()); + + /* Set `disabled` to '1' to all users that have an access level of 'disabled', + * then change their access level to 'user' because an access level of 'disabled' + * is now going to cause problems. + */ + $sql = "UPDATE `user` SET `disabled`='1',`access`='user' WHERE `access`='disabled'"; + $db_results = mysql_query($sql, dbh()); + + $this->set_version('db_version','331003'); + + } //update 331003 + + function update_332001() { + + $sql = "ALTER TABLE `object_count` CHANGE `object_type` `object_type` ENUM( 'album', 'artist', 'song', 'playlist', 'genre', 'catalog' ) NOT NULL DEFAULT 'song'"; + $sql = "ALTER TABLE `session` CHANGE `type` `type` ENUM( 'sso', 'mysql', 'ldap', 'http' ) NOT NULL DEFAULT 'mysql'"; + + } // update_332001 + +} // end update class +?> diff --git a/lib/class/user.php b/lib/class/user.php new file mode 100644 index 00000000..8f45cfed --- /dev/null +++ b/lib/class/user.php @@ -0,0 +1,632 @@ +username = $username; + $this->id = $uid; + $info = $this->get_info(); + $this->username = $info->username; + $this->id = $info->id; + $this->id = $info->id; + $this->fullname = $info->fullname; + $this->access = $info->access; + $this->disabled = $info->disabled; + $this->offset_limit = $info->offset_limit; + $this->email = $info->email; + $this->last_seen = $info->last_seen; + $this->set_preferences(); + + // Make sure the Full name is always filled + if (strlen($this->fullname) < 1) { $this->fullname = $this->username; } + + } // User + + + /*! + @function get_info + @dicussion gets the info! + */ + function get_info() { + + if ($this->username) { + $sql = "SELECT * FROM user WHERE username='$this->username'"; + } + else { + $sql = "SELECT * FROM user WHERE id='$this->id'"; + } + $db_results = mysql_query($sql, dbh()); + + return mysql_fetch_object($db_results); + + } // get_info + + /*! + @function get_preferences + @discussion gets the prefs for this specific + user and returns them as an array + */ + function get_preferences() { + + $sql = "SELECT preferences.name, preferences.description, preferences.type, user_preference.value FROM preferences,user_preference WHERE user_preference.user='$this->id' AND user_preference.preference=preferences.id AND preferences.type='user'"; + $db_results = mysql_query($sql, dbh()); + + while ($r = mysql_fetch_object($db_results)) { + $results[] = $r; + } + + return $results; + + } // get_preferences + + /*! + @function set_preferences + @discussion sets the prefs for this specific + user + */ + function set_preferences() { + + $sql = "SELECT preferences.name,user_preference.value FROM preferences,user_preference WHERE user_preference.user='$this->id' " . + "AND user_preference.preference=preferences.id AND preferences.type='user'"; + $db_results = mysql_query($sql, dbh()); + + while ($r = mysql_fetch_object($db_results)) { + $this->prefs[$r->name] = $r->value; + } + } // get_preferences + + /*! + @function get_favorites + @discussion returns an array of your $type + favorites + */ + function get_favorites($type) { + + $sql = "SELECT * FROM object_count" . + " WHERE count > 0" . + " AND object_type = '$type'" . + " AND userid = '" . $this->id . "'" . + " ORDER BY count DESC LIMIT " . conf('popular_threshold'); + $db_result = mysql_query($sql, dbh()); + + $items = array(); + $web_path = conf('web_path'); + + while ($r = @mysql_fetch_object($db_result) ) { + /* If its a song */ + if ($type == 'song') { + $data = new Song($r->object_id); + $data->count = $r->count; + $data->format_song(); + $data->f_name = $data->f_link; + $items[] = $data; + } + /* If its an album */ + elseif ($type == 'album') { + $data = new Album($r->object_id); + $data->count = $r->count; + $data->format_album(); + $items[] = $data; + } + /* If its an artist */ + elseif ($type == 'artist') { + $data = new Artist($r->object_id); + $data->count = $r->count; + $data->format_artist(); + $data->f_name = $data->link; + $items[] = $data; + } + + } // end while + + return $items; + + } // get_favorites + + /*! + @function is_xmlrpc + @discussion checks to see if this is a valid + xmlrpc user + */ + function is_xmlrpc() { + + /* If we aren't using XML-RPC return true */ + if (!conf('xml_rpc')) { + return false; + } + + //FIXME: Ok really what we will do is check the MD5 of the HTTP_REFERER + //FIXME: combined with the song title to make sure that the REFERER + //FIXME: is in the access list with full rights + return true; + + } // is_xmlrpc + + /*! + @function is_logged_in + @discussion checks to see if $this user is logged in + */ + function is_logged_in() { + + $sql = "SELECT id FROM session WHERE username='$this->id'" . + " AND expire > ". time(); + $db_results = mysql_query($sql,dbh()); + + if (mysql_num_rows($db_results)) { + return true; + } + + return false; + + } // is_logged_in + + /*! + @function has_access + @discussion this function checkes to see if this user has access + to the passed action (pass a level requirement) + */ + function has_access($needed_level) { + + if ($this->access == "admin") { $level = 100; } + elseif ($this->access == "user") { $level = 25; } + else { $level = $this->access; } + + if (!conf('use_auth') || conf('demo_mode')) { return true; } + + if ($level >= $needed_level) { return true; } + + return false; + + } // has_access + + /*! + @function update_preference + @discussion updates a single preference if the query fails + it attempts to insert the preference instead + */ + function update_preference($preference_id, $value, $id=0) { + + if (!$id) { + $id = $this->id; + } + + $value = sql_escape($value); + //FIXME: + // Do a has_access check here... + + $sql = "UPDATE user_preference SET value='$value' WHERE user='$id' AND preference='$preference_id'"; + $db_results = @mysql_query($sql, dbh()); + + } // update_preference + + /*! + @function add_preference + @discussion adds a new preference + @param $key preference name + @param $value preference value + @param $id user is + */ + function add_preference($preference_id, $value, $id=0) { + + if (!$id) { + $id = $this->id; + } + + $value = sql_escape($value); + + if (!is_numeric($preference_id)) { + $sql = "SELECT id FROM preferences WHERE `name`='$preference_id'"; + $db_results = mysql_query($sql, dbh()); + $r = mysql_fetch_array($db_results); + $preference_id = $r[0]; + } // end if it's not numeric + + $sql = "INSERT user_preference SET `user`='$id' , `value`='$value' , `preference`='$preference_id'"; + $db_results = mysql_query($sql, dbh()); + + } // add_preference + + /*! + @function update_username + @discussion updates their username + */ + function update_username($new_username) { + + $new_username = sql_escape($new_username); + $sql = "UPDATE user SET username='$new_username' WHERE id='$this->id'"; + $db_results = mysql_query($sql, dbh()); + + } // update_username + + /*! + @function update_fullname + @discussion updates their fullname + */ + function update_fullname($new_fullname) { + + $new_fullname = sql_escape($new_fullname); + $sql = "UPDATE user SET fullname='$new_fullname' WHERE id='$this->id'"; + $db_results = mysql_query($sql, dbh()); + + } // update_username + + /*! + @function update_email + @discussion updates their email address + */ + function update_email($new_email) { + + $new_email = sql_escape($new_email); + $sql = "UPDATE user SET email='$new_email' WHERE id='$this->id'"; + $db_results = mysql_query($sql, dbh()); + + } // update_email + + /*! + @function update_offset + @discussion this updates the users offset_limit + */ + function update_offset($new_offset) { + + $new_offset = sql_escape($new_offset); + $sql = "UPDATE user SET offset_limit='$new_offset' WHERE id='$this->id'"; + $db_results = mysql_query($sql, dbh()); + + } // update_offset + + /*! + @function update_access + @discussion updates their access level + */ + function update_access($new_access) { + + /* Check for all disable */ + if ($new_access == 'disabled') { + $sql = "SELECT id FROM user WHERE disabled != '1' AND id != '$this->id'"; + $db_results = mysql_query($sql,dbh()); + if (!mysql_num_rows($db_results)) { return false; } + } + + /* Prevent Only User accounts */ + if ($new_access == 'user') { + $sql = "SELECT id FROM user WHERE (access='admin' OR access='100') AND id != '$this->id'"; + $db_results = mysql_query($sql, dbh()); + if (!mysql_num_rows($db_results)) { return false; } + } + + if ($new_access == 'enabled') { + $new_access = sql_escape($new_access); + $sql = "UPDATE user SET disabled='0' WHERE id='$this->id'"; + $db_results = mysql_query($sql, dbh()); + } elseif ($new_access == 'disabled') { + $new_access = sql_escape($new_access); + $sql = "UPDATE user SET disabled='1' WHERE id='$this->id'"; + $db_results = mysql_query($sql, dbh()); + $sql = "DELETE FROM session WHERE username='" . sql_escape($this->username) . "'"; + $db_results = mysql_query($sql, dbh()); + } else { + $new_access = sql_escape($new_access); + $sql = "UPDATE user SET access='$new_access' WHERE id='$this->id'"; + $db_results = mysql_query($sql, dbh()); + } + + } // update_access + + /*! + @function update_last_seen + @discussion updates the last seen data for this user + */ + function update_last_seen() { + + $sql = "UPDATE user SET last_seen='" . time() . "' WHERE id='$this->id'"; + $db_results = mysql_query($sql, dbh()); + + } // update_last_seen + + /*! + @function update_user_stats + @discussion updates the playcount mojo for this + specific user + */ + function update_stats($song_id) { + + $song_info = new Song($song_id); + $user = $this->id; + $dbh = dbh(); + + if (!$song_info->file) { return false; } + + $time = time(); + + // Play count for this song + $sql = "UPDATE object_count" . + " SET date = '$time', count=count+1" . + " WHERE object_type = 'song'" . + " AND object_id = '$song_id' AND userid = '$user'"; + $db_result = mysql_query($sql, $dbh); + + $rows = mysql_affected_rows(); + if (!$rows) { + $sql = "INSERT INTO object_count (object_type,object_id,date,count,userid)" . + " VALUES ('song','$song_id','$time','1','$user')"; + $db_result = mysql_query($sql, $dbh); + } + + // Play count for this artist + $sql = "UPDATE object_count" . + " SET date = '$time', count=count+1" . + " WHERE object_type = 'artist'" . + " AND object_id = '" . $song_info->artist . "' AND userid = '$user'"; + $db_result = mysql_query($sql, $dbh); + + $rows = mysql_affected_rows(); + if (!$rows) { + $sql = "INSERT INTO object_count (object_type,object_id,date,count,userid)" . + " VALUES ('artist','".$song_info->artist."','$time','1','$user')"; + $db_result = mysql_query($sql, $dbh); + } + + // Play count for this album + $sql = "UPDATE object_count" . + " SET date = '$time', count=count+1" . + " WHERE object_type = 'album'" . + " AND object_id = '".$song_info->album."' AND userid = '$user'"; + $db_result = mysql_query($sql, $dbh); + + $rows = mysql_affected_rows(); + if (!$rows) { + $sql = "INSERT INTO object_count (object_type,object_id,date,count,userid)" . + "VALUES ('album','".$song_info->album."','$time','1','$user')"; + $db_result = mysql_query($sql, $dbh); + } + + // Play count for this genre + $sql = "UPDATE object_count" . + " SET date = '$time', count=count+1" . + " WHERE object_type = 'genre'" . + " AND object_id = '" . $song_info->genre."' AND userid='$user'"; + $db_results = mysql_query($sql, $dbh); + + $rows = mysql_affected_rows(); + if (!$rows) { + $sql = "INSERT INTO object_count (`object_type`,`object_id`,`date`,`count`,`userid`)" . + "VALUES ('genre','" . $song_info->genre."','$time','1'1,'$user')"; + $db_results = mysql_query($sql, $dbh); + } + + + } // update_stats + + /*! + @function create + @discussion inserts a new user into ampache + */ + function create($username, $fullname, $email, $password, $access) { + + /* Lets clean up the fields... */ + $username = sql_escape($username); + $fullname = sql_escape($fullname); + $email = sql_escape($email); + + /* Now Insert this new user */ + $sql = "INSERT INTO user (username, fullname, email, password, access) VALUES" . + " ('$username','$fullname','$email',PASSWORD('$password'),'$access')"; + $db_results = mysql_query($sql, dbh()); + if (!$db_results) { return false; } + $user_id = mysql_insert_id(dbh()); + + /* Populates any missing preferences, in this case all of them */ + $this->fix_preferences($user_id); + + return $user_id; + + } // new + + /*! + @function update_password + @discussion updates a users password + */ + function update_password($new_password) { + + $sql = "UPDATE user SET password=PASSWORD('$new_password') WHERE id='$this->id'"; + $db_results = mysql_query($sql, dbh()); + + return true; + } // update_password + + + /*! + @function format_favorites + @discussion takes an array of objects and formats them corrrectly + and returns a simply array with just count); + + // Go through the favs + foreach ($items as $data) { + + // Make all number lengths equal + $len = strlen($data->count); + while ($len < $maxlen) { + $data->count = "0" . $data->count; + $len++; + } + + $results[] = "
  • [$data->count] - $data->f_name
  • \n"; + + } // end foreach items + + return $results; + + } // format_favorites + + /*! + @function fix_preferences + @discussion this makes sure that the specified user + has all the correct preferences. This function + should be run whenever a system preference is run + it's a cop out... FIXME! + */ + function fix_preferences($user_id = 0) { + + if (!$user_id) { + $user_id = $this->id; + } + + /* Get All Preferences */ + $sql = "SELECT * FROM user_preference WHERE user='$user_id'"; + $db_results = mysql_query($sql, dbh()); + + while ($r = mysql_fetch_object($db_results)) { + /* Check for duplicates */ + if (isset($results[$r->preference])) { + $r->value = sql_escape($r->value); + $sql = "DELETE FROM user_preference WHERE user='$user_id' AND preference='$r->preference' AND value='$r->value'"; + $delete_results = mysql_query($sql, dbh()); + } // duplicate + else { + $results[$r->preference] = $r; + } + } // while results + + /* + If we aren't the 0 user before we continue then grab the + 0 user's values + */ + if ($user_id != '0') { + $sql = "SELECT user_preference.preference,user_preference.value FROM user_preference,preferences " . + "WHERE user_preference.preference = preferences.id AND user_preference.user='0' AND preferences.type='user'"; + $db_results = mysql_query($sql, dbh()); + while ($r = mysql_fetch_object($db_results)) { + $zero_results[$r->preference] = $r->value; + } + } // if not user 0 + + + $sql = "SELECT * FROM preferences"; + if ($user_id != '0') { + $sql .= " WHERE type='user'"; + } + $db_results = mysql_query($sql, dbh()); + + + while ($r = mysql_fetch_object($db_results)) { + + /* Check if this preference is set */ + if (!isset($results[$r->id])) { + if (isset($zero_results[$r->id])) { + $r->value = $zero_results[$r->id]; + } + $sql = "INSERT INTO user_preference (`user`,`preference`,`value`) VALUES ('$user_id','$r->id','$r->value')"; + $insert_db = mysql_query($sql, dbh()); + } + } // while preferences + + } // fix_preferences + + + /*! + @function delete_stats + @discussion deletes the stats for this user + */ + function delete_stats() { + + $sql = "DELETE FROM object_count WHERE userid='" . $this->id . "'"; + $db_results = mysql_query($sql, dbh()); + + } // delete_stats + + /*! + @function delete + @discussion deletes this user and everything assoicated with it + */ + function delete() { + + /* + Before we do anything make sure that they aren't the last + admin + */ + if ($this->has_access(100)) { + $sql = "SELECT * FROM user WHERE (level='admin' OR level='100') AND id!='" . $this->id . "'"; + $db_results = mysql_query($sql, dbh()); + if (!mysql_num_rows($db_results)) { + return false; + } + } // if this is an admin check for others + + // Delete their playlists + $sql = "DELETE FROM playlist WHERE owner='$this->id'"; + $db_results = mysql_query($sql, dbh()); + + // Delete any stats they have + $sql = "DELETE FROM object_count WHERE userid='$this->id'"; + $db_results = mysql_query($sql, dbh()); + + // Delete their preferences + $sql = "DELETE FROM preferences WHERE user='$this->id'"; + $db_results = mysql_query($sql, dbh()); + + // Delete the user itself + $sql = "DELETE FROM user WHERE id='$this->id'"; + $db_results = mysql_query($sql, dbh()); + + return true; + + } // delete + + /*! + @function is_online + @parameter delay how long since last_seen in seconds default of 20 min + @description calcs difference between now and last_seen + if less than delay, we consider them still online + */ + function is_online( $delay = 1200 ) { + return time() - $this->last_seen <= $delay; + } + +} //end class +?> diff --git a/lib/class/view.php b/lib/class/view.php new file mode 100644 index 00000000..f9de4ee6 --- /dev/null +++ b/lib/class/view.php @@ -0,0 +1,229 @@ +base_sql = $base_sql; + if ($offset_limit) { $this->offset_limit = $offset_limit; } + else { $this->offset_limit = $_SESSION['offset_limit']; } + if ($this->offset_limit < '1') { $this->offset_limit = '50'; } + $this->script = $script; + $this->sort_type = $sort_type; + $this->sort_order = "ASC"; + $this->offset = 0; + $this->total_items = $total_items; + + // Set the session + $_SESSION['view_offset_limit'] = $this->offset_limit; + $_SESSION['view_sort_type'] = $this->sort_type; + $_SESSION['view_offset'] = $this->offset; + $_SESSION['view_base_sql'] = $this->base_sql; + $_SESSION['view_sort_order'] = $this->sort_order; + $_SESSION['view_script'] = $this->script; + $_SESSION['view_total_items'] = $this->total_items; + $this->sql = $this->generate_sql(); + + } //constructor + + //takes all the parts and makes a full blown sql statement + function generate_sql() { + global $conf; + + $sql = $this->base_sql . " ORDER BY " . $this->sort_type ." ". $this->sort_order ." LIMIT " . $this->offset . "," . $this->offset_limit; + + return $sql; + + } //generate_sql + + //change the sort order from asc to desc or vise versa + function change_sort($new_sort=0) { + global $conf; + + if ($new_sort) { + $this->sort_order = $new_sort; + } + elseif ($this->sort_order == "DESC") { + $this->sort_order = "ASC"; + } + else { + $this->sort_order = "DESC"; + } + + $_SESSION['view_sort_order'] = $this->sort_order; + + $this->sql = $this->generate_sql(); + + return; + + } //change_sort + + //change the base sql + function change_sql($base_sql) { + global $conf; + + //Convert all 's into "s + $base_sql = str_replace("'",'"',$base_sql); + + $this->base_sql = $base_sql; + + $_SESSION['view_base_sql'] = $this->base_sql; + + $this->sql = $this->generate_sql(); + + } //change_sql + + //change offset + function change_offset($offset=0) { + global $conf; + + if (isset($offset)) { + $this->offset = $offset; + } + else { + $this->offset = $this->offset + $this->offset_limit; + } + + $_SESSION['view_offset'] = $this->offset; + + $this->sql = $this->generate_sql(); + + } //change_offset + + //change sort_type + function change_sort_type($sort_type) { + + $this->sort_type = $sort_type; + + $_SESSION['view_sort_type'] = $this->sort_type; + + $this->sql = $this->generate_sql(); + + } //change_sort_type + + /*! + @function change_offset_limit + @discussion changes the offset limit, sets the session + var and generates the sql statement + */ + function change_offset_limit($offset_limit) { + + $this->offset_limit = $offset_limit; + + $_SESSION['view_offset_limit'] = $this->offset_limit; + + $this->sql = $this->generate_sql(); + + } // change_offset_limit + + /*! + @function initialize + @discussion initializes the view object, checks $_REQUEST + for changes to the view object + */ + function initialize() { + + if ($_REQUEST['sort_type']) { + $this->change_sort_type($_REQUEST['sort_type']); + } + + if (isset($_REQUEST['offset'])) { + $this->change_offset($_REQUEST['offset']); + } + + if ($_REQUEST['base_sql']) { + $this->change_sql($_REQUEST['base_sql']); + } + + if (isset($_REQUEST['sort_order'])) { + $this->change_sort($_REQUEST['sort_order']); + } + + if ($_REQUEST['offset_limit']) { + $this->change_offset_limit($_REQUEST['offset_limit']); + } + + } // initialize + + + /*! + @function import_session_view + @discussion this imports the view from the session for use.. + this keeps us from having to globalize anything + wohoo! + */ + function import_session_view() { + + $this->sort_type = $_SESSION['view_sort_type']; + $this->offset = $_SESSION['view_offset']; + $this->base_sql = $_SESSION['view_base_sql']; + $this->sort_order = $_SESSION['view_sort_order']; + $this->script = $_SESSION['view_script']; + $this->total_items = $_SESSION['view_total_items']; + + + if ($_SESSION['view_offset_limit']) { + $this->offset_limit = $_SESSION['view_offset_limit']; + } + else { + $this->offset_limit = $_SESSION['offset_limit']; + } + + + $this->sql = $this->generate_sql(); + + } // import_session_view + + + +} //end class +?> diff --git a/lib/general.lib.php b/lib/general.lib.php new file mode 100644 index 00000000..83bf2bfc --- /dev/null +++ b/lib/general.lib.php @@ -0,0 +1,703 @@ +"; + + $count = 0; + + foreach($data as $value) { + $count++; + + $value = trim($value); + + if (preg_match("/^\[([A-Za-z]+)\]$/",$value,$matches)) { + // If we have previous data put it into $results... + if (isset($config_name) && isset(${$config_name}) && count(${$config_name})) { + $results[$config_name] = ${$config_name}; + } + + $config_name = $matches[1]; + + } // if it is a [section] name + + + elseif (isset($config_name)) { + + // if it's not a comment + if (preg_match("/^([\w\d]+)\s+=\s+[\"]{1}(.*?)[\"]{1}$/",$value,$matches) + || preg_match("/^([\w\d]+)\s+=\s+[\']{1}(.*?)[\']{1}$/", $value, $matches) + || preg_match("/^([\w\d]+)\s+=\s+[\'\"]{0}(.*)[\'\"]{0}$/",$value,$matches)) { + + if (isset(${$config_name}[$matches[1]]) && is_array(${$config_name}[$matches[1]]) && isset($matches[2]) ) { + if($debug) echo "Adding value $matches[2] to existing key $matches[1]\n"; + array_push(${$config_name}[$matches[1]], $matches[2]); + } + + elseif (isset(${$config_name}[$matches[1]]) && isset($matches[2]) ) { + if($debug) echo "Adding value $matches[2] to existing key $matches[1]\n"; + ${$config_name}[$matches[1]] = array(${$config_name}[$matches[1]],$matches[2]); + } + + elseif ($matches[2] !== "") { + if($debug) echo "Adding value $matches[2] for key $matches[1]\n"; + ${$config_name}[$matches[1]] = $matches[2]; + } + + // if there is something there and it's not a comment + elseif ($value{0} !== "#" AND strlen(trim($value)) > 0 AND !$test AND strlen($matches[2]) > 0) { + echo "Error Invalid Config Entry --> Line:$count"; return false; + } // elseif it's not a comment and there is something there + + else { + if($debug) echo "Key $matches[1] defined, but no value set\n"; + } + } // end if it's not a comment + + } // elseif no config_name + + + elseif (preg_match("/^([\w\d]+)\s+=\s+[\"]{1}(.*?)[\"]{1}$/",$value,$matches) + || preg_match("/^([\w\d]+)\s+=\s+[\']{1}(.*?)[\']{1}$/", $value, $matches) + || preg_match("/^([\w\d]+)\s+=\s+[\'\"]{0}(.*)[\'\"]{0}$/",$value,$matches)) { + + + if (is_array($results[$matches[1]]) && isset($matches[2]) ) { + if($debug) echo "Adding value $matches[2] to existing key $matches[1]\n"; + array_push($results[$matches[1]], $matches[2]); + } + + elseif (isset($results[$matches[1]]) && isset($matches[2]) ) { + if($debug) echo "Adding value $matches[2] to existing key $matches[1]\n"; + $results[$matches[1]] = array($results[$matches[1]],$matches[2]); + } + + elseif ($matches[2] !== "") { + if($debug) echo "Adding value $matches[2] for key $matches[1]\n"; + $results[$matches[1]] = $matches[2]; + } + + // if there is something there and it's not a comment + elseif ($value{0} !== "#" AND strlen(trim($value)) > 0 AND !$test AND strlen($matches[2]) > 0) { + echo "Error Invalid Config Entry --> Line:$count"; return false; + } // elseif it's not a comment and there is something there + + else { + if($debug) echo "Key $matches[1] defined, but no value set\n"; + } + + } // end else + + } // foreach + + if (isset($config_name) && isset(${$config_name}) && count(${$config_name})) { + $results[$config_name] = ${$config_name}; + } + + if($debug) echo ""; + + return $results; + + +} // read_config + +/* + * Conf function by Robert Hopson + * call it with a $parm name to retrieve + * a var, pass it a array to set them + * to reset a var pass the array plus + * Clobber! replaces global $conf; +*/ +function conf($param,$clobber=0) +{ + static $params = array(); + + if(is_array($param)) + //meaning we are setting values + { + foreach ($param as $key=>$val) + { + if(!$clobber && isset($params[$key])) + { + echo "Error: attempting to clobber $key = $val\n"; + exit(); + } + $params[$key] = $val; + } + return true; + } + else + //meaning we are trying to retrieve a parameter + { + if($params[$param]) return $params[$param]; + else return; + } +} //conf + +function libglue_param($param,$clobber=0) +{ + static $params = array(); + if(is_array($param)) + //meaning we are setting values + { + foreach ($param as $key=>$val) + { + if(!$clobber && isset($params[$key])) + { + echo "Error: attempting to clobber $key = $val\n"; + exit(); + } + $params[$key] = $val; + } + return true; + } + else + //meaning we are trying to retrieve a parameter + { + if(isset($params[$param])) return $params[$param]; + else return false; + } +} + +function error_results($param,$clobber=0) +{ + static $params = array(); + + if(is_array($param)) + //meaning we are setting values + { + foreach ($param as $key=>$val) + { + if(!$clobber && isset($params[$key])) + { + echo "Error: attempting to clobber $key = $val\n"; + exit(); + } + $params[$key] = $val; + } + return true; + } + else + //meaning we are trying to retrieve a parameter + { + if($params[$param]) return $params[$param]; + else return; + } +} //error_results + + +/*! + @function dbh + @discussion retrieves the DBH +*/ +function dbh() { return check_sess_db('local'); } + +/*! + @function fix_preferences + @discussion cleans up the preferences +*/ +function fix_preferences($results) { + + foreach ($results as $key=>$data) { + if (strcasecmp($data, "yes") == "0") { $data = 1; } + if (strcasecmp($data,"true") == "0") { $data = 1; } + if (strcasecmp($data,"enabled") == "0") { $data = 1; } + if (strcasecmp($data,"disabled") == "0") { $data = 0; } + if (strcasecmp($data,"false") == "0") { $data = 0; } + if (strcasecmp($data,"no") == "0") { $data = 0; } + $results[$key] = $data; + } + + return $results; + +} // fix_preferences + +/*! + @function session_exists + @discussion checks to make sure they've specified a + valid session +*/ +function session_exists($sid) { + + $sql = "SELECT * FROM session WHERE id = '$sid'"; + $db_results = mysql_query($sql, dbh()); + + if (!mysql_num_rows($db_results)) { + return false; + } + + return true; + +} // session_exists + +/*! + @function extend_session + @discussion just update the expire time +*/ +function extend_session($sid) { + + $new_time = time() + conf('local_length'); + + if ($_COOKIE['amp_longsess'] == '1') { $new_time = time() + 86400*364; } + + $sql = "UPDATE session SET expire='$new_time' WHERE id='$sid'"; + $db_results = mysql_query($sql, dbh()); + +} // extend_session + +/*! + @function get_tag_type + @discussion finds out what tag the audioinfo + results returned +*/ +function get_tag_type($results) { + + // Check and see if we are dealing with an ogg + // If so order will be a little different + if ($results['ogg']) { + $order[0] = 'ogg'; + } // end if ogg + elseif ($results['rm']) { + $order[0] = 'rm'; + } + elseif ($results['flac']) { + $order[0] = 'flac'; + } + elseif ($results['asf']) { + $order[0] = 'asf'; + } + elseif ($results['m4a']) { + $order[0] = 'm4a'; + } + elseif ($results['mpc']) { + $order[0] = 'mpc'; + } + else { + $order = conf('id3tag_order'); + } // end else + + if (!is_array($order)) { + $order = array($order); + } + + // set the $key to the first found tag style (according to their prefs) + foreach($order as $key) { + if ($results[$key]) { + break; + } + } + + return $key; + +} // get_tag_type + + +/*! + @function clean_tag_info + @discussion cleans up the tag information +*/ +function clean_tag_info($results,$key,$filename) { + + $info = array(); + + $clean_array = array("\n","\t","\r","\0"); + $wipe_array = array("","","",""); + + $info['file'] = $filename; + $info['title'] = stripslashes(trim($results[$key]['title'])); + $info['year'] = intval($results[$key]['year']); + $info['comment'] = sql_escape(str_replace($clean_array,$wipe_array,$results[$key]['comment'])); + $info['bitrate'] = intval($results['avg_bit_rate']); + $info['rate'] = intval($results['sample_rate']); + $info['mode'] = $results['bitrate_mode']; + $info['size'] = filesize($filename); + $info['time'] = intval($results['playing_time']); + $info['track'] = intval($results[$key]['track']); + + /* These are used to generate the correct ID's later */ + $info['artist'] = trim($results[$key]['artist']); + $info['album'] = trim($results[$key]['album']); + $info['genre'] = trim($results[$key]['genre']); + + return $info; + +} // clean_tag_info + +/*! + @function scrub_in() + @discussion Run on inputs, stuff that might get stuck in our db +*/ +function scrub_in($str) { + + if (!is_array($str)) { + return stripslashes( htmlspecialchars( strip_tags($str) ) ); + } + else { + $ret = array(); + foreach($str as $string) $ret[] = scrub_in($string); + return $ret; + } +} // scrub_in + +/*! + @function batch_ok() + @discussion return boolean if user can batch download +*/ +function batch_ok( ) { + global $user; + // i check this before showing any link + // should make it easy to tie to a new pref if you choose to add it + if (conf('allow_zip_download')) { + return( $user->prefs['download'] ); + } // if allowed zip downloads + + return false; + +} // batch_ok + +/*! + @function set_memory_limit + @discussion this function attempts to change the + php memory limit using init_set but it will + never reduce it +*/ +function set_memory_limit($new_limit) { + + /* Check their PHP Vars to make sure we're cool here */ + // Up the memory + $current_memory = ini_get('memory_limit'); + $current_memory = substr($current_memory,0,strlen($current_memory)-1); + if ($current_memory < $new_limit) { + $php_memory = $new_limit . "M"; + ini_set (memory_limit, "$php_memory"); + unset($php_memory); + } + +} // set_memory_limit + +/*! + @function get_random_songs + @discussion Returns a random set of songs/albums or artists + matchlist is an array of the WHERE mojo and options + defines special unplayed,album,artist,limit info +*/ +function get_random_songs( $options, $matchlist) { + + $dbh = dbh(); + + /* Define the options */ + $limit = $options['limit']; + $unplayed = $options['unplayed']; + + /* If they've passed -1 as limit then don't get everything */ + if ($options['limit'] == "-1") { unset($options['limit']); } + else { $options['limit'] = "LIMIT " . $limit; } + + + $where = "1=1 "; + if(is_array($matchlist)) + foreach ($matchlist as $type => $value) { + if (is_array($value)) { + foreach ($value as $v) { + $v = sql_escape($v); + if ($v != $value[0]) { $where .= " OR $type='$v' "; } + else { $where .= " AND ( $type='$v'"; } + } + $where .= " ) "; + } + else { + $value = sql_escape($value); + $where .= " AND $type='$value' "; + } + } + + + + if ($options['full_album'] == 1) { + $query = "SELECT album.id FROM song,album WHERE song.album=album.id AND $where GROUP BY song.album ORDER BY RAND() " . $options['limit']; + $db_results = mysql_query($query, $dbh); + while ($data = mysql_fetch_row($db_results)) { + $albums_where .= " OR song.album=" . $data[0]; + } + $albums_where = ltrim($albums_where," OR"); + $query = "SELECT song.id FROM song WHERE $albums_where ORDER BY song.track ASC"; + } + elseif ($options['full_artist'] == 1) { + $query = "SELECT artist.id FROM song,artist WHERE song.artist=artist.id AND $where GROUP BY song.artist ORDER BY RAND() " . $options['limit']; + $db_results = mysql_query($query, $dbh); + while ($data = mysql_fetch_row($db_results)) { + $artists_where .= " OR song.artist=" . $data[0]; + } + $artists_where = ltrim($artists_where," OR"); + $query = "SELECT song.id FROM song WHERE $artists_where ORDER BY RAND()"; + } + elseif ($options['unplayed'] == 1) { + $uid = $_SESSION['userdata']['id']; + $query = "SELECT song.id FROM song LEFT JOIN object_count ON song.id = object_count.object_id " . + "WHERE ($where) AND ((object_count.object_type='song' AND userid = '$uid') OR object_count.count IS NULL ) " . + "ORDER BY CASE WHEN object_count.count IS NULL THEN RAND() WHEN object_count.count > 4 THEN RAND()*RAND()*object_count.count " . + "ELSE RAND()*object_count.count END " . $options['limit']; + } // If unplayed + else { + $query = "SELECT id FROM song WHERE $where ORDER BY RAND() " . $options['limit']; + } + $db_result = mysql_query($query, $dbh); + + $songs = array(); + + while ( $r = mysql_fetch_array($db_result) ) { + $songs[] = $r[0]; + } + + return ($songs); + +} // get_random_songs + +/** + * cleanup_and_exit + * used specificly for the play/index.php file + * this functions nukes now playing and then exits + * @package Streaming + * @catagory Clean + */ +function cleanup_and_exit($playing_id) { + + /* Clear now playing */ + // 900 = 15 min + $expire = time() - 900; + $sql = "DELETE FROM now_playing WHERE now_playing.id='$lastid' OR now_playing.start_time < $expire"; + + $db_results = @mysql_query($sql, dbh()); + + exit(); + +} // cleanup_and_exit + +/** + * get_global_popular + * this function gets the current globally popular items + * from the object_count table, depending on type passed + * @package Web Interface + * @catagory Get + */ +function get_global_popular($type) { + + $dbh = dbh(); + + $sql = "SELECT object_id, SUM(count) as count FROM object_count" . + " WHERE object_type = '$type'" . + " GROUP BY object_id" . + " ORDER BY count DESC LIMIT " . conf('popular_threshold'); + $db_result = mysql_query($sql, $dbh); + + $items = array(); + $web_path = conf('web_path'); + + while ( $r = @mysql_fetch_object($db_result) ) { + /* If Songs */ + if ( $type == 'song' ) { + $song = new Song($r->object_id); + $artist = $song->get_artist_name(); + $text = "$artist - $song->title"; + /* Add to array */ + $items[] = "
  • id\" title=\"". htmlspecialchars($text) ."\">" . + htmlspecialchars(truncate_with_ellipse($text, conf('ellipse_threshold_title')+3)) . " ($r->count)
  • "; + } // if it's a song + + /* If Artist */ + elseif ( $type == 'artist' ) { + $artist = get_artist_name($r->object_id); + $items[] = "
  • object_id\" title=\"". htmlspecialchars($artist) ."\">" . + htmlspecialchars(truncate_with_ellipse($artist, conf('ellipse_threshold_artist')+3)) . " ($r->count)
  • "; + } // if type isn't artist + + /* If Album */ + elseif ( $type == 'album' ) { + $album = new Album($r->object_id); + $items[] = "
  • object_id\" title=\"". htmlspecialchars($album->name) ."\">" . + htmlspecialchars(truncate_with_ellipse($album->name,conf('ellipse_threshold_album')+3)) . " ($r->count)
  • "; + } // else not album + + elseif ($type == 'genre') { + $genre = new Genre($r->object_id); + $items[] = "
  • object_id\" title=\"" . htmlspecialchars($genre->name) . "\">" . + htmlspecialchars(truncate_with_ellipse($genre->name,conf('ellipse_threshold_title')+3)) . " ($r->count)
  • "; + } // end if genre + } // end while + + if (count($items) == 0) { + $items[] = "" . _("Not Enough Data") . "\n"; + } + + return $items; + +} // get_global_popular + +/** + * gen_newest + * Get a list of newest $type (which can then be handed to show_info_box + * @package Web Interface + * @catagory Get + * @todo Add Genre + */ +function get_newest ($type = 'artist') { + + $dbh = dbh(); + + if (conf('popular_threshold') < 1) { conf(array('popular_threshold'=>'10'),1); } + + $sql = "SELECT DISTINCT $type FROM song ORDER BY addition_time " . + "DESC LIMIT " . conf('popular_threshold'); + $db_result = mysql_query($sql, $dbh); + + $items = array(); + $web_path = conf('web_path'); + + while ( $item = mysql_fetch_row($db_result) ) { + if ( $type == 'artist' ) { + $artist = new Artist($item[0]); + $artist->format_artist(); + $items[] = "
  • " . $artist->link . "
  • \n"; + } + elseif ( $type == 'album' ) { + $album = new Album($item[0]); + $album->format_album(); + $items[] = "
  • " . $album->f_name . "
  • "; + } + } + return $items; +} // get_newest + +/** + * show_info_box + * This shows the basic box that popular and newest stuff goes into + * @package Web Interface + * @catagory Display + * @todo make this use a template + */ +function show_info_box ($title, $type, $items) { + + $web_path = conf('web_path'); + $popular_threshold = conf('popular_threshold'); + + echo ""; + echo " "; + + + if ($type == 'your_song') { + echo "\n"; + } + elseif ($type == 'song') { + echo "\n"; + } + else { + echo "\n"; + } + + print << + + + +
    $title - Play$title - Play$title
    +
      + +ECHO; + + foreach ($items as $item) { + echo "$item\n"; + } + + print << +
    + +ECHO; + +} // show_info_box + + + +?> diff --git a/lib/general.php b/lib/general.php deleted file mode 100644 index 83bf2bfc..00000000 --- a/lib/general.php +++ /dev/null @@ -1,703 +0,0 @@ -"; - - $count = 0; - - foreach($data as $value) { - $count++; - - $value = trim($value); - - if (preg_match("/^\[([A-Za-z]+)\]$/",$value,$matches)) { - // If we have previous data put it into $results... - if (isset($config_name) && isset(${$config_name}) && count(${$config_name})) { - $results[$config_name] = ${$config_name}; - } - - $config_name = $matches[1]; - - } // if it is a [section] name - - - elseif (isset($config_name)) { - - // if it's not a comment - if (preg_match("/^([\w\d]+)\s+=\s+[\"]{1}(.*?)[\"]{1}$/",$value,$matches) - || preg_match("/^([\w\d]+)\s+=\s+[\']{1}(.*?)[\']{1}$/", $value, $matches) - || preg_match("/^([\w\d]+)\s+=\s+[\'\"]{0}(.*)[\'\"]{0}$/",$value,$matches)) { - - if (isset(${$config_name}[$matches[1]]) && is_array(${$config_name}[$matches[1]]) && isset($matches[2]) ) { - if($debug) echo "Adding value $matches[2] to existing key $matches[1]\n"; - array_push(${$config_name}[$matches[1]], $matches[2]); - } - - elseif (isset(${$config_name}[$matches[1]]) && isset($matches[2]) ) { - if($debug) echo "Adding value $matches[2] to existing key $matches[1]\n"; - ${$config_name}[$matches[1]] = array(${$config_name}[$matches[1]],$matches[2]); - } - - elseif ($matches[2] !== "") { - if($debug) echo "Adding value $matches[2] for key $matches[1]\n"; - ${$config_name}[$matches[1]] = $matches[2]; - } - - // if there is something there and it's not a comment - elseif ($value{0} !== "#" AND strlen(trim($value)) > 0 AND !$test AND strlen($matches[2]) > 0) { - echo "Error Invalid Config Entry --> Line:$count"; return false; - } // elseif it's not a comment and there is something there - - else { - if($debug) echo "Key $matches[1] defined, but no value set\n"; - } - } // end if it's not a comment - - } // elseif no config_name - - - elseif (preg_match("/^([\w\d]+)\s+=\s+[\"]{1}(.*?)[\"]{1}$/",$value,$matches) - || preg_match("/^([\w\d]+)\s+=\s+[\']{1}(.*?)[\']{1}$/", $value, $matches) - || preg_match("/^([\w\d]+)\s+=\s+[\'\"]{0}(.*)[\'\"]{0}$/",$value,$matches)) { - - - if (is_array($results[$matches[1]]) && isset($matches[2]) ) { - if($debug) echo "Adding value $matches[2] to existing key $matches[1]\n"; - array_push($results[$matches[1]], $matches[2]); - } - - elseif (isset($results[$matches[1]]) && isset($matches[2]) ) { - if($debug) echo "Adding value $matches[2] to existing key $matches[1]\n"; - $results[$matches[1]] = array($results[$matches[1]],$matches[2]); - } - - elseif ($matches[2] !== "") { - if($debug) echo "Adding value $matches[2] for key $matches[1]\n"; - $results[$matches[1]] = $matches[2]; - } - - // if there is something there and it's not a comment - elseif ($value{0} !== "#" AND strlen(trim($value)) > 0 AND !$test AND strlen($matches[2]) > 0) { - echo "Error Invalid Config Entry --> Line:$count"; return false; - } // elseif it's not a comment and there is something there - - else { - if($debug) echo "Key $matches[1] defined, but no value set\n"; - } - - } // end else - - } // foreach - - if (isset($config_name) && isset(${$config_name}) && count(${$config_name})) { - $results[$config_name] = ${$config_name}; - } - - if($debug) echo ""; - - return $results; - - -} // read_config - -/* - * Conf function by Robert Hopson - * call it with a $parm name to retrieve - * a var, pass it a array to set them - * to reset a var pass the array plus - * Clobber! replaces global $conf; -*/ -function conf($param,$clobber=0) -{ - static $params = array(); - - if(is_array($param)) - //meaning we are setting values - { - foreach ($param as $key=>$val) - { - if(!$clobber && isset($params[$key])) - { - echo "Error: attempting to clobber $key = $val\n"; - exit(); - } - $params[$key] = $val; - } - return true; - } - else - //meaning we are trying to retrieve a parameter - { - if($params[$param]) return $params[$param]; - else return; - } -} //conf - -function libglue_param($param,$clobber=0) -{ - static $params = array(); - if(is_array($param)) - //meaning we are setting values - { - foreach ($param as $key=>$val) - { - if(!$clobber && isset($params[$key])) - { - echo "Error: attempting to clobber $key = $val\n"; - exit(); - } - $params[$key] = $val; - } - return true; - } - else - //meaning we are trying to retrieve a parameter - { - if(isset($params[$param])) return $params[$param]; - else return false; - } -} - -function error_results($param,$clobber=0) -{ - static $params = array(); - - if(is_array($param)) - //meaning we are setting values - { - foreach ($param as $key=>$val) - { - if(!$clobber && isset($params[$key])) - { - echo "Error: attempting to clobber $key = $val\n"; - exit(); - } - $params[$key] = $val; - } - return true; - } - else - //meaning we are trying to retrieve a parameter - { - if($params[$param]) return $params[$param]; - else return; - } -} //error_results - - -/*! - @function dbh - @discussion retrieves the DBH -*/ -function dbh() { return check_sess_db('local'); } - -/*! - @function fix_preferences - @discussion cleans up the preferences -*/ -function fix_preferences($results) { - - foreach ($results as $key=>$data) { - if (strcasecmp($data, "yes") == "0") { $data = 1; } - if (strcasecmp($data,"true") == "0") { $data = 1; } - if (strcasecmp($data,"enabled") == "0") { $data = 1; } - if (strcasecmp($data,"disabled") == "0") { $data = 0; } - if (strcasecmp($data,"false") == "0") { $data = 0; } - if (strcasecmp($data,"no") == "0") { $data = 0; } - $results[$key] = $data; - } - - return $results; - -} // fix_preferences - -/*! - @function session_exists - @discussion checks to make sure they've specified a - valid session -*/ -function session_exists($sid) { - - $sql = "SELECT * FROM session WHERE id = '$sid'"; - $db_results = mysql_query($sql, dbh()); - - if (!mysql_num_rows($db_results)) { - return false; - } - - return true; - -} // session_exists - -/*! - @function extend_session - @discussion just update the expire time -*/ -function extend_session($sid) { - - $new_time = time() + conf('local_length'); - - if ($_COOKIE['amp_longsess'] == '1') { $new_time = time() + 86400*364; } - - $sql = "UPDATE session SET expire='$new_time' WHERE id='$sid'"; - $db_results = mysql_query($sql, dbh()); - -} // extend_session - -/*! - @function get_tag_type - @discussion finds out what tag the audioinfo - results returned -*/ -function get_tag_type($results) { - - // Check and see if we are dealing with an ogg - // If so order will be a little different - if ($results['ogg']) { - $order[0] = 'ogg'; - } // end if ogg - elseif ($results['rm']) { - $order[0] = 'rm'; - } - elseif ($results['flac']) { - $order[0] = 'flac'; - } - elseif ($results['asf']) { - $order[0] = 'asf'; - } - elseif ($results['m4a']) { - $order[0] = 'm4a'; - } - elseif ($results['mpc']) { - $order[0] = 'mpc'; - } - else { - $order = conf('id3tag_order'); - } // end else - - if (!is_array($order)) { - $order = array($order); - } - - // set the $key to the first found tag style (according to their prefs) - foreach($order as $key) { - if ($results[$key]) { - break; - } - } - - return $key; - -} // get_tag_type - - -/*! - @function clean_tag_info - @discussion cleans up the tag information -*/ -function clean_tag_info($results,$key,$filename) { - - $info = array(); - - $clean_array = array("\n","\t","\r","\0"); - $wipe_array = array("","","",""); - - $info['file'] = $filename; - $info['title'] = stripslashes(trim($results[$key]['title'])); - $info['year'] = intval($results[$key]['year']); - $info['comment'] = sql_escape(str_replace($clean_array,$wipe_array,$results[$key]['comment'])); - $info['bitrate'] = intval($results['avg_bit_rate']); - $info['rate'] = intval($results['sample_rate']); - $info['mode'] = $results['bitrate_mode']; - $info['size'] = filesize($filename); - $info['time'] = intval($results['playing_time']); - $info['track'] = intval($results[$key]['track']); - - /* These are used to generate the correct ID's later */ - $info['artist'] = trim($results[$key]['artist']); - $info['album'] = trim($results[$key]['album']); - $info['genre'] = trim($results[$key]['genre']); - - return $info; - -} // clean_tag_info - -/*! - @function scrub_in() - @discussion Run on inputs, stuff that might get stuck in our db -*/ -function scrub_in($str) { - - if (!is_array($str)) { - return stripslashes( htmlspecialchars( strip_tags($str) ) ); - } - else { - $ret = array(); - foreach($str as $string) $ret[] = scrub_in($string); - return $ret; - } -} // scrub_in - -/*! - @function batch_ok() - @discussion return boolean if user can batch download -*/ -function batch_ok( ) { - global $user; - // i check this before showing any link - // should make it easy to tie to a new pref if you choose to add it - if (conf('allow_zip_download')) { - return( $user->prefs['download'] ); - } // if allowed zip downloads - - return false; - -} // batch_ok - -/*! - @function set_memory_limit - @discussion this function attempts to change the - php memory limit using init_set but it will - never reduce it -*/ -function set_memory_limit($new_limit) { - - /* Check their PHP Vars to make sure we're cool here */ - // Up the memory - $current_memory = ini_get('memory_limit'); - $current_memory = substr($current_memory,0,strlen($current_memory)-1); - if ($current_memory < $new_limit) { - $php_memory = $new_limit . "M"; - ini_set (memory_limit, "$php_memory"); - unset($php_memory); - } - -} // set_memory_limit - -/*! - @function get_random_songs - @discussion Returns a random set of songs/albums or artists - matchlist is an array of the WHERE mojo and options - defines special unplayed,album,artist,limit info -*/ -function get_random_songs( $options, $matchlist) { - - $dbh = dbh(); - - /* Define the options */ - $limit = $options['limit']; - $unplayed = $options['unplayed']; - - /* If they've passed -1 as limit then don't get everything */ - if ($options['limit'] == "-1") { unset($options['limit']); } - else { $options['limit'] = "LIMIT " . $limit; } - - - $where = "1=1 "; - if(is_array($matchlist)) - foreach ($matchlist as $type => $value) { - if (is_array($value)) { - foreach ($value as $v) { - $v = sql_escape($v); - if ($v != $value[0]) { $where .= " OR $type='$v' "; } - else { $where .= " AND ( $type='$v'"; } - } - $where .= " ) "; - } - else { - $value = sql_escape($value); - $where .= " AND $type='$value' "; - } - } - - - - if ($options['full_album'] == 1) { - $query = "SELECT album.id FROM song,album WHERE song.album=album.id AND $where GROUP BY song.album ORDER BY RAND() " . $options['limit']; - $db_results = mysql_query($query, $dbh); - while ($data = mysql_fetch_row($db_results)) { - $albums_where .= " OR song.album=" . $data[0]; - } - $albums_where = ltrim($albums_where," OR"); - $query = "SELECT song.id FROM song WHERE $albums_where ORDER BY song.track ASC"; - } - elseif ($options['full_artist'] == 1) { - $query = "SELECT artist.id FROM song,artist WHERE song.artist=artist.id AND $where GROUP BY song.artist ORDER BY RAND() " . $options['limit']; - $db_results = mysql_query($query, $dbh); - while ($data = mysql_fetch_row($db_results)) { - $artists_where .= " OR song.artist=" . $data[0]; - } - $artists_where = ltrim($artists_where," OR"); - $query = "SELECT song.id FROM song WHERE $artists_where ORDER BY RAND()"; - } - elseif ($options['unplayed'] == 1) { - $uid = $_SESSION['userdata']['id']; - $query = "SELECT song.id FROM song LEFT JOIN object_count ON song.id = object_count.object_id " . - "WHERE ($where) AND ((object_count.object_type='song' AND userid = '$uid') OR object_count.count IS NULL ) " . - "ORDER BY CASE WHEN object_count.count IS NULL THEN RAND() WHEN object_count.count > 4 THEN RAND()*RAND()*object_count.count " . - "ELSE RAND()*object_count.count END " . $options['limit']; - } // If unplayed - else { - $query = "SELECT id FROM song WHERE $where ORDER BY RAND() " . $options['limit']; - } - $db_result = mysql_query($query, $dbh); - - $songs = array(); - - while ( $r = mysql_fetch_array($db_result) ) { - $songs[] = $r[0]; - } - - return ($songs); - -} // get_random_songs - -/** - * cleanup_and_exit - * used specificly for the play/index.php file - * this functions nukes now playing and then exits - * @package Streaming - * @catagory Clean - */ -function cleanup_and_exit($playing_id) { - - /* Clear now playing */ - // 900 = 15 min - $expire = time() - 900; - $sql = "DELETE FROM now_playing WHERE now_playing.id='$lastid' OR now_playing.start_time < $expire"; - - $db_results = @mysql_query($sql, dbh()); - - exit(); - -} // cleanup_and_exit - -/** - * get_global_popular - * this function gets the current globally popular items - * from the object_count table, depending on type passed - * @package Web Interface - * @catagory Get - */ -function get_global_popular($type) { - - $dbh = dbh(); - - $sql = "SELECT object_id, SUM(count) as count FROM object_count" . - " WHERE object_type = '$type'" . - " GROUP BY object_id" . - " ORDER BY count DESC LIMIT " . conf('popular_threshold'); - $db_result = mysql_query($sql, $dbh); - - $items = array(); - $web_path = conf('web_path'); - - while ( $r = @mysql_fetch_object($db_result) ) { - /* If Songs */ - if ( $type == 'song' ) { - $song = new Song($r->object_id); - $artist = $song->get_artist_name(); - $text = "$artist - $song->title"; - /* Add to array */ - $items[] = "
  • id\" title=\"". htmlspecialchars($text) ."\">" . - htmlspecialchars(truncate_with_ellipse($text, conf('ellipse_threshold_title')+3)) . " ($r->count)
  • "; - } // if it's a song - - /* If Artist */ - elseif ( $type == 'artist' ) { - $artist = get_artist_name($r->object_id); - $items[] = "
  • object_id\" title=\"". htmlspecialchars($artist) ."\">" . - htmlspecialchars(truncate_with_ellipse($artist, conf('ellipse_threshold_artist')+3)) . " ($r->count)
  • "; - } // if type isn't artist - - /* If Album */ - elseif ( $type == 'album' ) { - $album = new Album($r->object_id); - $items[] = "
  • object_id\" title=\"". htmlspecialchars($album->name) ."\">" . - htmlspecialchars(truncate_with_ellipse($album->name,conf('ellipse_threshold_album')+3)) . " ($r->count)
  • "; - } // else not album - - elseif ($type == 'genre') { - $genre = new Genre($r->object_id); - $items[] = "
  • object_id\" title=\"" . htmlspecialchars($genre->name) . "\">" . - htmlspecialchars(truncate_with_ellipse($genre->name,conf('ellipse_threshold_title')+3)) . " ($r->count)
  • "; - } // end if genre - } // end while - - if (count($items) == 0) { - $items[] = "" . _("Not Enough Data") . "\n"; - } - - return $items; - -} // get_global_popular - -/** - * gen_newest - * Get a list of newest $type (which can then be handed to show_info_box - * @package Web Interface - * @catagory Get - * @todo Add Genre - */ -function get_newest ($type = 'artist') { - - $dbh = dbh(); - - if (conf('popular_threshold') < 1) { conf(array('popular_threshold'=>'10'),1); } - - $sql = "SELECT DISTINCT $type FROM song ORDER BY addition_time " . - "DESC LIMIT " . conf('popular_threshold'); - $db_result = mysql_query($sql, $dbh); - - $items = array(); - $web_path = conf('web_path'); - - while ( $item = mysql_fetch_row($db_result) ) { - if ( $type == 'artist' ) { - $artist = new Artist($item[0]); - $artist->format_artist(); - $items[] = "
  • " . $artist->link . "
  • \n"; - } - elseif ( $type == 'album' ) { - $album = new Album($item[0]); - $album->format_album(); - $items[] = "
  • " . $album->f_name . "
  • "; - } - } - return $items; -} // get_newest - -/** - * show_info_box - * This shows the basic box that popular and newest stuff goes into - * @package Web Interface - * @catagory Display - * @todo make this use a template - */ -function show_info_box ($title, $type, $items) { - - $web_path = conf('web_path'); - $popular_threshold = conf('popular_threshold'); - - echo ""; - echo " "; - - - if ($type == 'your_song') { - echo "\n"; - } - elseif ($type == 'song') { - echo "\n"; - } - else { - echo "\n"; - } - - print << - - - -
    $title - Play$title - Play$title
    -
      - -ECHO; - - foreach ($items as $item) { - echo "$item\n"; - } - - print << -
    - -ECHO; - -} // show_info_box - - - -?> diff --git a/lib/ui.lib.php b/lib/ui.lib.php index 6faa0897..ddbdbcd5 100644 --- a/lib/ui.lib.php +++ b/lib/ui.lib.php @@ -29,12 +29,12 @@ */ /** - @function show_confirmation - @discussion shows a confirmation of an action - @param $next_url Where to go next - @param $title The Title of the message - @param $text The details of the message -*/ + * show_confirmation + * shows a confirmation of an action + * @param $next_url Where to go next + * @param $title The Title of the message + * @param $text The details of the message + */ function show_confirmation($title,$text,$next_url) { if (substr_count($next_url,conf('web_path'))) { @@ -49,10 +49,11 @@ function show_confirmation($title,$text,$next_url) { } // show_confirmation /** - @function set_preferences - @discussion legacy function... - //FIXME: Remove References -*/ + * set_preferences + * legacy function... + * @todo Remove References + * @deprecated + */ function set_preferences() { get_preferences(); @@ -61,9 +62,9 @@ function set_preferences() { } // set_preferences /** - @function get_preferences - @discussion reads this users preferences -*/ + * get_preferences + * reads this users preferences + */ function get_preferences($username=0) { /* Get System Preferences first */ @@ -98,11 +99,11 @@ function get_preferences($username=0) { } // get_preferences /** - @function flip_class - @discussion takes an array of 2 class names - and flips them back and forth and - then echo's out [0] -*/ + * flip_class + * takes an array of 2 class names + * and flips them back and forth and + * then echo's out [0] + */ function flip_class($array=0) { static $classes = array(); @@ -118,10 +119,10 @@ function flip_class($array=0) { } // flip_class /** - @function clear_now_playing - @discussion Clears the now playing information incase something has - gotten stuck in there -*/ + * clear_now_playing + * Clears the now playing information incase something has + * gotten stuck in there + */ function clear_now_playing() { $sql = "DELETE FROM now_playing"; @@ -132,9 +133,9 @@ function clear_now_playing() { } // clear_now_playing /** - @function show_tool_box - @discussion shows the toolbox -*/ + * show_tool_box + * shows the toolbox + */ function show_tool_box ($title, $items) { include(conf('prefix') . "/templates/tool_box.inc"); @@ -142,9 +143,9 @@ function show_tool_box ($title, $items) { }// show_tool_box /** - @function show_box - @discussion shows a generic box -*/ + * show_box + * shows a generic box + */ function show_box($title,$items) { include(conf('prefix') . "/templates/show_box.inc"); @@ -152,20 +153,33 @@ function show_box($title,$items) { } // show_box /** - @function show_menu_items - @discussion shows menu items -*/ + * show_menu_items + * shows menu items + */ function show_menu_items ($high) { include(conf('prefix') . "/templates/menu.inc"); } // show_menu_items +/** + * Show Browse Menu + * Shows the menu used by the browse page + * @package Web Interface + * @cataogry Menu + * @author Karl Vollmer + */ +function show_browse_menu($highlight) { + + include(conf('prefix'). "/templates/show_browse_menu.inc"); + +} // show_browse_menu + /** - @function _ - @discussion checks to see if the alias _ is defined - if it isn't it defines it as a simple return -*/ + * _ + * checks to see if the alias _ is defined + * if it isn't it defines it as a simple return + */ if (!function_exists('_')) { function _($string) { @@ -175,9 +189,9 @@ if (!function_exists('_')) { } // if _ isn't defined /** - @function show_playlist_menu - @discussion playlist functions -*/ + * show_playlist_menu + * playlist functions + */ function show_playlist_menu () { echo "
    " . _("Playlist Actions") . ": " . _("New") ." | "; @@ -188,18 +202,18 @@ function show_playlist_menu () { } // show_playlist_menu /** - @function show_admin_menu - @discussion shows the admin menu -*/ + * show_admin_menu + * shows the admin menu + */ function show_admin_menu ($admin_highlight) { include(conf('prefix') . "/templates/admin_menu.inc"); } // show_admin_menu /** - @function access_denied - @discussion throws an error if they try to do something - that they aren't allowed to -*/ + * access_denied + * throws an error if they try to do something + * that they aren't allowed to + */ function access_denied() { show_template('style'); @@ -212,9 +226,9 @@ function access_denied() { } // access_denied /** - @function show_users - @discussion shows all users (admin function) -*/ + * show_users + * shows all users (admin function) + */ function show_users () { $dbh = dbh(); @@ -244,11 +258,11 @@ function show_users () { /** - @function return_referer - @discussion returns the script part of the - referer address passed by the web browser - this is not %100 accurate -*/ + * return_referer + * returns the script part of the + * referer address passed by the web browser + * this is not %100 accurate + */ function return_referer() { $web_path = substr(conf('web_path'),0,strlen(conf('web_path'))-1-strlen($_SERVER['SERVER_PORT'])) . "/"; @@ -265,10 +279,10 @@ function return_referer() { } // return_referer /** - @function show_alphabet_list - @discussion shows the A-Z,0-9 lists for - albums and artist pages -*/ + * show_alphabet_list + * shows the A-Z,0-9 lists for + * albums and artist pages + */ function show_alphabet_list ($type,$script="artist.php",$selected="false") { $list = array(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,1,2,3,4,5,6,7,8,9,"0"); @@ -293,10 +307,10 @@ function show_alphabet_list ($type,$script="artist.php",$selected="false") { } // show_alphabet_list /** - @function show_local_control - @discussion shows the controls - for localplay -*/ + * show_local_control + * shows the controls + * for localplay + */ function show_local_control () { require_once(conf('prefix') . "/templates/show_localplay.inc"); @@ -304,46 +318,66 @@ function show_local_control () { } // show_local_control /** - @function truncate_with_ellipse - @discussion truncates a text file to specified length by adding - thre dots (ellipse) to the end - (Thx Nedko Arnaudov) -*/ + * truncate_with_ellipse + * truncates a text file to specified length by adding + * thre dots (ellipse) to the end + * (Thx Nedko Arnaudov) + * @todo Fix Spelling! + * @depreciated + */ function truncate_with_ellipse($text, $max=27) { - /* If we want it to be shorter than three, just throw it back */ - if ($max > 3) { - /* Make sure the functions exist before doing the iconv mojo */ - if (function_exists('iconv') && function_exists('iconv_substr') && function_exists('iconv_strlen')) { - if (iconv_strlen($text, conf('site_charset')) > $max) { - $text = iconv_substr($text, 0, $max-3, conf('site_charset')); - $text .= iconv("ISO-8859-1", conf('site_charset'), "..."); - } + /* Run the function with the correct spelling */ + return truncate_with_ellipsis($text,$max); + +} // truncate_with_ellipse + +/** + * truncate_with_ellipsis + * Correct Spelling function that truncates text to a specific lenght + * and appends three dots, or an ellipsis to the end + * @package Web Interface + * @catagory General + * @author Nedko Arnaudov + */ +function truncate_with_ellipsis($text, $max=27) { + + /* If we want it to be shorter than three, just throw it back */ + if ($max > 3) { + + /* Make sure the functions exist before doing the iconv mojo */ + if (function_exists('iconv') && function_exists('iconv_substr') && function_exists('iconv_strlen')) { + if (iconv_strlen($text, conf('site_charset')) > $max) { + $text = iconv_substr($text, 0, $max-3, conf('site_charset')); + $text .= iconv("ISO-8859-1", conf('site_charset'), "..."); + } } - /* Do normal substr if we don't have iconv */ + + /* Do normal substr if we don't have iconv */ else { if (strlen($text) > $max) { $text = substr($text,0,$max-3)."..."; } } // else no iconv } // else greater than 3 - + return $text; -} // truncate_with_ellipse + +} // truncate_with_ellipsis /** - @function show_footer - @discussion shows the footer of the page -*/ + * show_footer + * shows the footer of the page + */ function show_footer() { $class = "table-header"; echo "


     
    "; } // show_footer /** - @function show_now_playing - @discussion shows the now playing template -*/ + * show_now_playing + * shows the now playing template + */ function show_now_playing() { $dbh = dbh(); @@ -354,13 +388,12 @@ function show_now_playing() { } // show_now_playing /** - @function show_user_registration - @discussion this function is called for a new user - registration - @author Terry -*/ -//function show_user_registration ($id, $username, $fullname, $email, $access, $type, $error) { -//FIXME: See above + * show_user_registration + * this function is called for a new user + * registration + * @author Terry + * @todo Fix so that it recieves an array of values for the user reg rather than seperate + */ function show_user_registration ($values=array()) { require (conf('prefix') . "/templates/show_user_registration.inc.php"); @@ -368,9 +401,11 @@ function show_user_registration ($values=array()) { } // show_user_registration /** - @function show_edit_profile - @discussion shows a single user profile for editing -*/ + * show_edit_profile + * shows a single user profile for editing + * @package Web Interface + * @catagory Display + */ function show_edit_profile($username) { $this_user = new User($username); @@ -380,9 +415,9 @@ function show_edit_profile($username) { } // show_edit_profile /** - @function show_playlist - @discussion this shows the current playlist -*/ + * show_playlist + * this shows the current playlist + */ function show_playlist($playlist_id) { /* Create the Playlist */ @@ -399,10 +434,10 @@ function show_playlist($playlist_id) { } // show_playlist /** - @function show_play_selected - @discussion this shows the playselected/add to playlist - box, which includes a little javascript -*/ + * show_play_selected + * this shows the playselected/add to playlist + * box, which includes a little javascript + */ function show_play_selected() { require (conf('prefix') . "/templates/show_play_selected.inc.php"); @@ -410,9 +445,11 @@ function show_play_selected() { } // show_play_selected /** - @function get_now_playing - @discussion gets the now playing information -*/ + * get_now_playing + * gets the now playing information + * @package Web Interface + * @catagory Get + */ function get_now_playing() { $sql = "SELECT song_id,user_id FROM now_playing ORDER BY start_time DESC"; @@ -428,12 +465,15 @@ function get_now_playing() { } // get_now_playing /** - @function show_clear - @discussion this is a hack because of the float mojo -*/ + * show_clear + * this is a hack because of the float mojo it clears the floats + * @package Web Interface + * @catagory Hack-o-Rama + * @author Karl Vollmer + */ function show_clear() { - echo "\n
     
    \n"; + echo "\n
    \n"; } // show_clear -- cgit