diff options
author | Karl 'vollmerk' Vollmer <vollmer@ampache.org> | 2005-06-09 16:34:40 +0000 |
---|---|---|
committer | Karl 'vollmerk' Vollmer <vollmer@ampache.org> | 2005-06-09 16:34:40 +0000 |
commit | bcad40a05ab2dc2a341a3227e30b96668bce4500 (patch) | |
tree | 6fca27588d53a1b24705bd2834e9e643bb729bd1 /lib | |
download | ampache-bcad40a05ab2dc2a341a3227e30b96668bce4500.tar.gz ampache-bcad40a05ab2dc2a341a3227e30b96668bce4500.tar.bz2 ampache-bcad40a05ab2dc2a341a3227e30b96668bce4500.zip |
New Import
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Browser.php | 1082 | ||||
-rw-r--r-- | lib/album.php | 31 | ||||
-rw-r--r-- | lib/archive.php | 778 | ||||
-rw-r--r-- | lib/artist.php | 122 | ||||
-rw-r--r-- | lib/batch.php | 63 | ||||
-rw-r--r-- | lib/debug.php | 361 | ||||
-rw-r--r-- | lib/duplicates.php | 117 | ||||
-rw-r--r-- | lib/flag.php | 348 | ||||
-rw-r--r-- | lib/general.php | 554 | ||||
-rw-r--r-- | lib/gettext.php | 36 | ||||
-rw-r--r-- | lib/install.php | 238 | ||||
-rw-r--r-- | lib/log.php | 77 | ||||
-rw-r--r-- | lib/mpd.php | 75 | ||||
-rwxr-xr-x | lib/perl/Local/Ampache/Ampache.pm | 237 | ||||
-rwxr-xr-x | lib/perl/Local/Ampache/Makefile.PL | 7 | ||||
-rw-r--r-- | lib/preferences.php | 281 | ||||
-rw-r--r-- | lib/rss.php | 64 | ||||
-rw-r--r-- | lib/search.php | 185 | ||||
-rw-r--r-- | lib/song.php | 57 | ||||
-rw-r--r-- | lib/themes.php | 124 | ||||
-rw-r--r-- | lib/ui.php | 437 | ||||
-rw-r--r-- | lib/xmlrpc.php | 143 |
22 files changed, 5417 insertions, 0 deletions
diff --git a/lib/Browser.php b/lib/Browser.php new file mode 100644 index 00000000..cf97dc41 --- /dev/null +++ b/lib/Browser.php @@ -0,0 +1,1082 @@ +<?php +/** + * The Browser:: class provides capability information for the current + * web client. Browser identification is performed by examining the + * HTTP_USER_AGENT environmental variable provide by the web server. + * + * $Horde: framework/Browser/Browser.php,v 1.167 2005/03/02 16:05:15 jan Exp $ + * + * Copyright 1999-2005 Chuck Hagenbuch <chuck@horde.org> + * Copyright 1999-2005 Jon Parise <jon@horde.org> + * + * See the enclosed file COPYING for license information (LGPL). If you + * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html. + * + * @author Chuck Hagenbuch <chuck@horde.org> + * @author Jon Parise <jon@horde.org> + * @since Horde 1.3 + * @package Horde_Browser + */ +class Browser { + + /** + * Major version number. + * + * @var integer $_majorVersion + */ + var $_majorVersion = 0; + + /** + * Minor version number. + * + * @var integer $_minorVersion + */ + var $_minorVersion = 0; + + /** + * Browser name. + * + * @var string $_browser + */ + var $_browser = ''; + + /** + * Full user agent string. + * + * @var string $_agent + */ + var $_agent = ''; + + /** + * Lower-case user agent string. + * + * @var string $_agent + */ + var $_lowerAgent = ''; + + /** + * HTTP_ACCEPT string + * + * @var string $_accept + */ + var $_accept = ''; + + /** + * Platform the browser is running on. + * + * @var string $_platform + */ + var $_platform = ''; + + /** + * Known robots. + * + * @var array $_robots + */ + var $_robots = array( + /* The most common ones. */ + 'Googlebot', + 'msnbot', + 'Slurp', + 'Yahoo', + /* The rest alphabetically. */ + 'Arachnoidea', + 'ArchitextSpider', + 'Ask Jeeves', + 'B-l-i-t-z-Bot', + 'ConveraCrawler', + 'ExtractorPro', + 'FAST-WebCrawler', + 'FDSE robot', + 'fido', + 'geckobot', + 'Gigabot', + 'Girafabot', + 'grub-client', + 'Gulliver', + 'ia_archiver', + 'InfoSeek', + 'KIT-Fireball', + 'LEIA', + 'Lycos_Spider', + 'Mediapartners-Google', + 'MuscatFerret', + 'NaverBot', + 'polybot', + 'Pompos', + 'Scooter', + 'Teoma', + 'TurnitinBot', + 'Ultraseek', + 'ViolaBot', + 'webbandit', + 'www.almaden.ibm.com/cs/crawler', + 'ZyBorg', + ); + + /** + * Is this a mobile browser? + * + * @var boolean $_mobile + */ + var $_mobile = false; + + /** + * Features. + * + * @var array $_features + */ + var $_features = array( + 'html' => true, + 'hdml' => false, + 'wml' => false, + 'images' => true, + 'iframes' => false, + 'frames' => true, + 'tables' => true, + 'java' => true, + 'javascript' => true, + 'dom' => false, + 'utf' => false, + 'rte' => false, + 'homepage' => false, + 'accesskey' => false, + 'optgroup' => false, + 'xmlhttpreq' => false, + 'cite' => false, + ); + + /** + * Quirks + * + * @var array $_quirks + */ + var $_quirks = array( + 'avoid_popup_windows' => false, + 'break_disposition_header' => false, + 'break_disposition_filename' => false, + 'broken_multipart_form' => false, + 'buggy_compression' => false, + 'cache_same_url' => false, + 'cache_ssl_downloads' => false, + 'double_linebreak_textarea' => false, + 'empty_file_input_value' => false, + 'must_cache_forms' => false, + 'no_filename_spaces' => false, + 'no_hidden_overflow_tables' => false, + 'ow_gui_1.3' => false, + 'png_transparency' => false, + 'scrollbar_in_way' => false, + 'scroll_tds' => false, + ); + + /** + * List of viewable image MIME subtypes. + * This list of viewable images works for IE and Netscape/Mozilla. + * + * @var array $_images + */ + var $_images = array('jpeg', 'gif', 'png', 'pjpeg', 'x-png', 'bmp'); + + /** + + /** + * Returns a reference to the global Browser object, only creating it + * if it doesn't already exist. + * + * This method must be invoked as: + * $browser = &Browser::singleton([$userAgent[, $accept]]); + * + * @access public + * + * @param optional string $userAgent The browser string to parse. + * @param optional string $accept The HTTP_ACCEPT settings to use. + * + * @return object Browser The Browser object. + */ + function &singleton($userAgent = null, $accept = null) + { + static $instances; + + if (!isset($instances)) { + $instances = array(); + } + + $signature = serialize(array($userAgent, $accept)); + if (empty($instances[$signature])) { + $instances[$signature] = new Browser($userAgent, $accept); + } + + return $instances[$signature]; + } + + /** + * Create a browser instance (Constructor). + * + * @access public + * + * @param optional string $userAgent The browser string to parse. + * @param optional string $accept The HTTP_ACCEPT settings to use. + */ + function Browser($userAgent = null, $accept = null) + { + $this->match($userAgent, $accept); + } + + /** + * Parses the user agent string and inititializes the object with + * all the known features and quirks for the given browser. + * + * @access public + * + * @param optional string $userAgent The browser string to parse. + * @param optional string $accept The HTTP_ACCEPT settings to use. + */ + function match($userAgent = null, $accept = null) + { + // Set our agent string. + if (is_null($userAgent)) { + if (isset($_SERVER['HTTP_USER_AGENT'])) { + $this->_agent = trim($_SERVER['HTTP_USER_AGENT']); + } + } else { + $this->_agent = $userAgent; + } + $this->_lowerAgent = strtolower($this->_agent); + + // Set our accept string. + if (is_null($accept)) { + if (isset($_SERVER['HTTP_ACCEPT'])) { + $this->_accept = strtolower(trim($_SERVER['HTTP_ACCEPT'])); + } + } else { + $this->_accept = strtolower($accept); + } + + // Check for UTF support. + if (isset($_SERVER['HTTP_ACCEPT_CHARSET'])) { + $this->setFeature('utf', strpos(strtolower($_SERVER['HTTP_ACCEPT_CHARSET']), 'utf') !== false); + } + + if (!empty($this->_agent)) { + $this->_setPlatform(); + + if (preg_match('|Opera[/ ]([0-9.]+)|', $this->_agent, $version)) { + $this->setBrowser('opera'); + list($this->_majorVersion, $this->_minorVersion) = explode('.', $version[1]); + $this->setFeature('javascript', true); + $this->setQuirk('no_filename_spaces'); + + switch ($this->_majorVersion) { + case 7: + $this->setFeature('dom'); + $this->setFeature('iframes'); + $this->setFeature('accesskey'); + $this->setFeature('optgroup'); + $this->setQuirk('double_linebreak_textarea'); + break; + } + } elseif (strpos($this->_lowerAgent, 'elaine/') !== false || + strpos($this->_lowerAgent, 'palmsource') !== false || + strpos($this->_lowerAgent, 'digital paths') !== false) { + $this->setBrowser('palm'); + $this->setFeature('images', false); + $this->setFeature('frames', false); + $this->setFeature('javascript', false); + $this->setQuirk('avoid_popup_windows'); + $this->_mobile = true; + } elseif ((preg_match('|MSIE ([0-9.]+)|', $this->_agent, $version)) || + (preg_match('|Internet Explorer/([0-9.]+)|', $this->_agent, $version))) { + + $this->setBrowser('msie'); + $this->setQuirk('cache_ssl_downloads'); + $this->setQuirk('cache_same_url'); + $this->setQuirk('break_disposition_filename'); + + if (strpos($version[1], '.') !== false) { + list($this->_majorVersion, $this->_minorVersion) = explode('.', $version[1]); + } else { + $this->_majorVersion = $version[1]; + $this->_minorVersion = 0; + } + + /* IE on Windows does not support alpha transparency in PNG + * images. */ + if (preg_match('/windows/i', $this->_agent)) { + $this->setQuirk('png_transparency'); + } + + /* IE 6 (pre-SP1) and 5.5 (pre-SP1) has buggy compression. + * The versions affected are as follows: + * 6.00.2462.0000 Internet Explorer 6 Public Preview (Beta) + * 6.00.2479.0006 Internet Explorer 6 Public Preview (Beta) + Refresh + * 6.00.2600.0000 Internet Explorer 6 (Windows XP) + * 5.50.3825.1300 Internet Explorer 5.5 Developer Preview (Beta) + * 5.50.4030.2400 Internet Explorer 5.5 & Internet Tools Beta + * 5.50.4134.0100 Internet Explorer 5.5 for Windows Me (4.90.3000) + * 5.50.4134.0600 Internet Explorer 5.5 + * 5.50.4308.2900 Internet Explorer 5.5 Advanced Security Privacy Beta + * + * See: + * ==== + * http://support.microsoft.com/kb/164539; + * http://support.microsoft.com/default.aspx?scid=kb;en-us;Q312496) + * http://support.microsoft.com/default.aspx?scid=kb;en-us;Q313712 + */ + $ie_vers = $this->getIEVersion(); + $buggy_list = array( + '6,00,2462,0000', '6,00,2479,0006', '6,00,2600,0000', + '5,50,3825,1300', '5,50,4030,2400', '5,50,4134,0100', + '5,50,4134,0600', '5,50,4308,2900' + ); + if (!is_null($ie_vers) && in_array($ie_vers, $buggy_list)) { + $this->setQuirk('buggy_compression'); + } + + /* Some Handhelds have their screen resolution in the + * user agent string, which we can use to look for + * mobile agents. */ + if (preg_match('/; (120x160|240x280|240x320)\)/', $this->_agent)) { + $this->_mobile = true; + } + + switch ($this->_majorVersion) { + case 6: + $this->setFeature('javascript', 1.4); + $this->setFeature('dom'); + $this->setFeature('iframes'); + $this->setFeature('utf'); + $this->setFeature('rte'); + $this->setFeature('homepage'); + $this->setFeature('accesskey'); + $this->setFeature('optgroup'); + $this->setFeature('xmlhttpreq'); + $this->setQuirk('scrollbar_in_way'); + $this->setQuirk('broken_multipart_form'); + break; + + case 5: + if ($this->getPlatform() == 'mac') { + $this->setFeature('javascript', 1.2); + $this->setFeature('optgroup'); + } else { + // MSIE 5 for Windows. + $this->setFeature('javascript', 1.4); + $this->setFeature('dom'); + $this->setFeature('xmlhttpreq'); + if ($this->_minorVersion >= 5) { + $this->setFeature('rte'); + } + } + $this->setFeature('iframes'); + $this->setFeature('utf'); + $this->setFeature('homepage'); + $this->setFeature('accesskey'); + if ($this->_minorVersion == 5) { + $this->setQuirk('break_disposition_header'); + $this->setQuirk('broken_multipart_form'); + } + break; + + case 4: + $this->setFeature('javascript', 1.2); + $this->setFeature('accesskey'); + if ($this->_minorVersion > 0) { + $this->setFeature('utf'); + } + break; + + case 3: + $this->setFeature('javascript', 1.1); + $this->setQuirk('avoid_popup_windows'); + break; + } + } elseif (preg_match('|ANTFresco/([0-9]+)|', $this->_agent, $version)) { + $this->setBrowser('fresco'); + $this->setFeature('javascript', 1.1); + $this->setQuirk('avoid_popup_windows'); + } elseif (strpos($this->_lowerAgent, 'avantgo') !== false) { + $this->setBrowser('avantgo'); + $this->_mobile = true; + } elseif (preg_match('|Konqueror/([0-9]+)|', $this->_agent, $version) || + preg_match('|Safari/([0-9]+)\.?([0-9]+)?|', $this->_agent, $version)) { + // Konqueror and Apple's Safari both use the KHTML + // rendering engine. + $this->setBrowser('konqueror'); + $this->setQuirk('empty_file_input_value'); + $this->setQuirk('no_hidden_overflow_tables'); + $this->_majorVersion = $version[1]; + if (isset($version[2])) { + $this->_minorVersion = $version[2]; + } + + if (strpos($this->_agent, 'Safari') !== false && + $this->_majorVersion >= 60) { + // Safari. + $this->setFeature('utf'); + $this->setFeature('javascript', 1.4); + $this->setFeature('dom'); + $this->setFeature('iframes'); + if ($this->_majorVersion > 125 || + ($this->_majorVersion == 125 && + $this->_minorVersion >= 1)) { + $this->setFeature('utf'); + $this->setFeature('accesskey'); + $this->setFeature('xmlhttpreq'); + } + } else { + // Konqueror. + $this->setFeature('javascript', 1.1); + switch ($this->_majorVersion) { + case 3: + $this->setFeature('dom'); + $this->setFeature('iframes'); + break; + } + } + } elseif (preg_match('|Mozilla/([0-9.]+)|', $this->_agent, $version)) { + $this->setBrowser('mozilla'); + $this->setQuirk('must_cache_forms'); + + list($this->_majorVersion, $this->_minorVersion) = explode('.', $version[1]); + switch ($this->_majorVersion) { + case 5: + if ($this->getPlatform() == 'win') { + $this->setQuirk('break_disposition_filename'); + } + $this->setFeature('javascript', 1.4); + $this->setFeature('dom'); + $this->setFeature('accesskey'); + $this->setFeature('optgroup'); + $this->setFeature('xmlhttpreq'); + $this->setFeature('cite'); + if (preg_match('|rv:(.*)\)|', $this->_agent, $revision)) { + if ($revision[1] >= 1) { + $this->setFeature('iframes'); + } + if ($revision[1] >= 1.3) { + $this->setFeature('rte'); + } + } + break; + + case 4: + $this->setFeature('javascript', 1.3); + $this->setQuirk('buggy_compression'); + break; + + case 3: + default: + $this->setFeature('javascript', 1); + $this->setQuirk('buggy_compression'); + break; + } + } elseif (preg_match('|Lynx/([0-9]+)|', $this->_agent, $version)) { + $this->setBrowser('lynx'); + $this->setFeature('images', false); + $this->setFeature('frames', false); + $this->setFeature('javascript', false); + $this->setQuirk('avoid_popup_windows'); + } elseif (preg_match('|Links \(([0-9]+)|', $this->_agent, $version)) { + $this->setBrowser('links'); + $this->setFeature('images', false); + $this->setFeature('frames', false); + $this->setFeature('javascript', false); + $this->setQuirk('avoid_popup_windows'); + } elseif (preg_match('|HotJava/([0-9]+)|', $this->_agent, $version)) { + $this->setBrowser('hotjava'); + $this->setFeature('javascript', false); + } elseif (strpos($this->_agent, 'UP/') !== false || + strpos($this->_agent, 'UP.B') !== false || + strpos($this->_agent, 'UP.L') !== false) { + $this->setBrowser('up'); + $this->setFeature('html', false); + $this->setFeature('javascript', false); + $this->setFeature('hdml'); + $this->setFeature('wml'); + + if (strpos($this->_agent, 'GUI') !== false && + strpos($this->_agent, 'UP.Link') !== false) { + /* The device accepts Openwave GUI extensions for + * WML 1.3. Non-UP.Link gateways sometimes have + * problems, so exclude them. */ + $this->setQuirk('ow_gui_1.3'); + } + $this->_mobile = true; + } elseif (strpos($this->_agent, 'Xiino/') !== false) { + $this->setBrowser('xiino'); + $this->setFeature('hdml'); + $this->setFeature('wml'); + $this->_mobile = true; + } elseif (strpos($this->_agent, 'Palmscape/') !== false) { + $this->setBrowser('palmscape'); + $this->setFeature('javascript', false); + $this->setFeature('hdml'); + $this->setFeature('wml'); + $this->_mobile = true; + } elseif (strpos($this->_agent, 'Nokia') !== false) { + $this->setBrowser('nokia'); + $this->setFeature('html', false); + $this->setFeature('wml'); + $this->setFeature('xhtml'); + $this->_mobile = true; + } elseif (strpos($this->_agent, 'Ericsson') !== false) { + $this->setBrowser('ericsson'); + $this->setFeature('html', false); + $this->setFeature('wml'); + $this->_mobile = true; + } elseif (strpos($this->_lowerAgent, 'wap') !== false) { + $this->setBrowser('wap'); + $this->setFeature('html', false); + $this->setFeature('javascript', false); + $this->setFeature('hdml'); + $this->setFeature('wml'); + $this->_mobile = true; + } elseif (strpos($this->_lowerAgent, 'docomo') !== false || + strpos($this->_lowerAgent, 'portalmmm') !== false) { + $this->setBrowser('imode'); + $this->setFeature('images', false); + $this->_mobile = true; + } elseif (strpos($this->_lowerAgent, 'j-') !== false) { + $this->setBrowser('mml'); + $this->_mobile = true; + } + } + } + + /** + * Match the platform of the browser. + * + * This is a pretty simplistic implementation, but it's intended + * to let us tell what line breaks to send, so it's good enough + * for its purpose. + * + * @access public + * + * @since Horde 2.2 + */ + function _setPlatform() + { + if (strpos($this->_lowerAgent, 'wind') !== false) { + $this->_platform = 'win'; + } elseif (strpos($this->_lowerAgent, 'mac') !== false) { + $this->_platform = 'mac'; + } else { + $this->_platform = 'unix'; + } + } + + /** + * Return the currently matched platform. + * + * @return string The user's platform. + * + * @since Horde 2.2 + */ + function getPlatform() + { + return $this->_platform; + } + + /** + * Sets the current browser. + * + * @access public + * + * @param string $browser The browser to set as current. + */ + function setBrowser($browser) + { + $this->_browser = $browser; + } + + /** + * Determine if the given browser is the same as the current. + * + * @access public + * + * @param string $browser The browser to check. + * + * @return boolean Is the given browser the same as the current? + */ + function isBrowser($browser) + { + return ($this->_browser === $browser); + } + + /** + * Do we consider the current browser to be a mobile device? + * + * @return boolean True if we do, false if we don't. + */ + function isMobile() + { + return $this->_mobile; + } + + /** + * Determines if the browser is a robot or not. + * + * @access public + * + * @return boolean True if browser is a known robot. + */ + function isRobot() + { + foreach ($this->_robots as $robot) { + if (strpos($this->_agent, $robot) !== false) { + return true; + } + } + return false; + } + + /** + * Retrieve the current browser. + * + * @access public + * + * @return string The current browser. + */ + function getBrowser() + { + return $this->_browser; + } + + /** + * Retrieve the current browser's major version. + * + * @access public + * + * @return integer The current browser's major version. + */ + function getMajor() + { + return $this->_majorVersion; + } + + /** + * Retrieve the current browser's minor version. + * + * @access public + * + * @return integer The current browser's minor version. + */ + function getMinor() + { + return $this->_minorVersion; + } + + /** + * Retrieve the current browser's version. + * + * @access public + * + * @return string The current browser's version. + */ + function getVersion() + { + return $this->_majorVersion . '.' . $this->_minorVersion; + } + + /** + * Return the full browser agent string. + * + * @access public + * + * @return string The browser agent string. + */ + function getAgentString() + { + return $this->_agent; + } + + /** + * Set unique behavior for the current browser. + * + * @access public + * + * @param string $quirk The behavior to set. + * @param optional string $value Special behavior parameter. + */ + function setQuirk($quirk, $value = true) + { + $this->_quirks[$quirk] = $value; + } + + /** + * Check unique behavior for the current browser. + * + * @access public + * + * @param string $quirk The behavior to check. + * + * @return boolean Does the browser have the behavior set? + */ + function hasQuirk($quirk) + { + return !empty($this->_quirks[$quirk]); + } + + /** + * Retreive unique behavior for the current browser. + * + * @access public + * + * @param string $quirk The behavior to retreive. + * + * @return string The value for the requested behavior. + */ + function getQuirk($quirk) + { + return isset($this->_quirks[$quirk]) + ? $this->_quirks[$quirk] + : null; + } + + /** + * Set capabilities for the current browser. + * + * @access public + * + * @param string $feature The capability to set. + * @param optional string $value Special capability parameter. + */ + function setFeature($feature, $value = true) + { + $this->_features[$feature] = $value; + } + + /** + * Check the current browser capabilities. + * + * @access public + * + * @param string $feature The capability to check. + * + * @return boolean Does the browser have the capability set? + */ + function hasFeature($feature) + { + return !empty($this->_features[$feature]); + } + + /** + * Retreive the current browser capability. + * + * @access public + * + * @param string $feature The capability to retreive. + * + * @return string The value of the requested capability. + */ + function getFeature($feature) + { + return isset($this->_features[$feature]) + ? $this->_features[$feature] + : null; + } + + /** + * Determine if we are using a secure (SSL) connection. + * + * @access public + * + * @return boolean True if using SSL, false if not. + */ + function usingSSLConnection() + { + return ((isset($_SERVER['HTTPS']) && + ($_SERVER['HTTPS'] == 'on')) || + getenv('SSL_PROTOCOL_VERSION')); + } + + /** + * Returns the server protocol in use on the current server. + * + * @access public + * + * @return string The HTTP server protocol version. + */ + function getHTTPProtocol() + { + if (isset($_SERVER['SERVER_PROTOCOL'])) { + if (($pos = strrpos($_SERVER['SERVER_PROTOCOL'], '/'))) { + return substr($_SERVER['SERVER_PROTOCOL'], $pos + 1); + } + } + + return null; + } + + /** + * Determine if files can be uploaded to the system. + * + * @access public + * + * @return integer If uploads allowed, returns the maximum size of the + * upload in bytes. Returns 0 if uploads are not + * allowed. + */ + function allowFileUploads() + { + if (ini_get('file_uploads')) { + if (($dir = ini_get('upload_tmp_dir')) && + !is_writable($dir)) { + return 0; + } + $size = ini_get('upload_max_filesize'); + switch (strtolower(substr($size, -1, 1))) { + case 'k': + $size = intval(floatval($size) * 1024); + break; + + case 'm': + $size = intval(floatval($size) * 1024 * 1024); + break; + + default: + $size = intval($size); + break; + } + return $size; + } else { + return 0; + } + } + + /** + * Determines if the file was uploaded or not. If not, will return the + * appropriate error message. + * + * @access public + * + * @param string $field The name of the field containing the + * uploaded file. + * @param optional string $name The file description string to use in the + * error message. Default: 'file'. + * + * @return mixed True on success, PEAR_Error on error. + */ + function wasFileUploaded($field, $name = null) + { + require_once 'PEAR.php'; + + if (is_null($name)) { + $name = _("file"); + } + + if (!($uploadSize = Browser::allowFileUploads())) { + return PEAR::raiseError(_("File uploads not supported.")); + } + + /* Get any index on the field name. */ + require_once 'Horde/Array.php'; + $index = Horde_Array::getArrayParts($field, $base, $keys); + + if ($index) { + /* Index present, fetch the error var to check. */ + $keys_path = array_merge(array($base, 'error'), $keys); + $error = Horde_Array::getElement($_FILES, $keys_path); + + /* Index present, fetch the tmp_name var to check. */ + $keys_path = array_merge(array($base, 'tmp_name'), $keys); + $tmp_name = Horde_Array::getElement($_FILES, $keys_path); + } else { + /* No index, simple set up of vars to check. */ + if (!isset($_FILES[$field])) { + return PEAR::raiseError(_("No file uploaded"), UPLOAD_ERR_NO_FILE); + } + $error = $_FILES[$field]['error']; + $tmp_name = $_FILES[$field]['tmp_name']; + } + + if (!isset($_FILES) || ($error == UPLOAD_ERR_NO_FILE)) { + return PEAR::raiseError(sprintf(_("There was a problem with the file upload: No %s was uploaded."), $name), UPLOAD_ERR_NO_FILE); + } elseif (($error == UPLOAD_ERR_OK) && is_uploaded_file($tmp_name)) { + return true; + } elseif (($error == UPLOAD_ERR_INI_SIZE) || + ($error == UPLOAD_ERR_FORM_SIZE)) { + return PEAR::raiseError(sprintf(_("There was a problem with the file upload: The %s was larger than the maximum allowed size (%d bytes)."), $name, $uploadSize), $error); + } elseif ($error == UPLOAD_ERR_PARTIAL) { + return PEAR::raiseError(sprintf(_("There was a problem with the file upload: The %s was only partially uploaded."), $name), $error); + } + } + + /** + * Returns the headers for a browser download. + * + * @access public + * + * @param optional string $filename The filename of the download. + * @param optional string $cType The content-type description of the + * file. + * @param optional boolean $inline True if inline, false if attachment. + * @param optional string $cLength The content-length of this file. + * + * @since Horde 2.2 + */ + function downloadHeaders($filename = 'unknown', $cType = null, + $inline = false, $cLength = null) + { + /* Remove linebreaks from file names. */ + $filename = str_replace(array("\r\n", "\r", "\n"), ' ', $filename); + + /* Some browsers don't like spaces in the filename. */ + if ($this->hasQuirk('no_filename_spaces')) { + $filename = strtr($filename, ' ', '_'); + } + + /* MSIE doesn't like multiple periods in the file name. Convert + all periods (except the last one) to underscores. */ + if ($this->isBrowser('msie')) { + if (($pos = strrpos($filename, '.'))) { + $filename = strtr(substr($filename, 0, $pos), '.', '_') . substr($filename, $pos); + } + } + + /* Content-Type/Content-Disposition Header. */ + if ($inline) { + if (!is_null($cType)) { + header('Content-Type: ' . trim($cType)); + } elseif ($this->isBrowser('msie')) { + header('Content-Type: application/x-msdownload'); + } else { + header('Content-Type: application/octet-stream'); + } + header('Content-Disposition: inline; filename="' . $filename . '"'); + } else { + if ($this->isBrowser('msie')) { + header('Content-Type: application/x-msdownload'); + } elseif (!is_null($cType)) { + header('Content-Type: ' . trim($cType)); + } else { + header('Content-Type: application/octet-stream'); + } + + if ($this->hasQuirk('break_disposition_header')) { + header('Content-Disposition: filename="' . $filename . '"'); + } else { + header('Content-Disposition: attachment; filename="' . $filename . '"'); + } + } + + /* Content-Length Header. Don't send Content-Length for + * HTTP/1.1 servers. */ + if (($this->getHTTPProtocol() != '1.1') && !is_null($cLength)) { + header('Content-Length: ' . $cLength); + } + + /* Overwrite Pragma: and other caching headers for IE. */ + if ($this->hasQuirk('cache_ssl_downloads')) { + header('Expires: 0'); + header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); + header('Pragma: public'); + } + } + + /** + * Determines if a browser can display a given MIME type. + * + * @access public + * + * @param string $mimetype The MIME type to check. + * + * @return boolean True if the browser can display the MIME type. + */ + function isViewable($mimetype) + { + $mimetype = strtolower($mimetype); + list($type, $subtype) = explode('/', $mimetype); + + if (!empty($this->_accept)) { + $wildcard_match = false; + + if (strpos($this->_accept, $mimetype) !== false) { + return true; + } + + if (strpos($this->_accept, '*/*') !== false) { + $wildcard_match = true; + if ($type != 'image') { + return true; + } + } + + /* image/jpeg and image/pjpeg *appear* to be the same + * entity, but Mozilla doesn't seem to want to accept the + * latter. For our purposes, we will treat them the + * same. */ + if ($this->isBrowser('mozilla') && + ($mimetype == 'image/pjpeg') && + (strpos($this->_accept, 'image/jpeg') !== false)) { + return true; + } + + if (!$wildcard_match) { + return false; + } + } + + if (!$this->hasFeature('images') || ($type != 'image')) { + return false; + } + + return (in_array($subtype, $this->_images)); + } + + /** + * Escape characters in javascript code if the browser requires it. + * %23, %26, and %2B (for IE) and %27 need to be escaped or else + * jscript will interpret it as a single quote, pound sign, or + * ampersand and refuse to work. + * + * @access public + * + * @param string $code The JS code to escape. + * + * @return string The escaped code. + */ + function escapeJSCode($code) + { + $from = $to = array(); + + if ($this->isBrowser('msie') || + ($this->isBrowser('mozilla') && ($this->getMajor() >= 5))) { + $from = array('%23', '%26', '%2B'); + $to = array(urlencode('%23'), urlencode('%26'), urlencode('%2B')); + } + $from[] = '%27'; + $to[] = '\%27'; + + return str_replace($from, $to, $code); + } + + /** + * Set the IE version in the session. + * + * @access public + * + * @param string $ver The IE Version string. + */ + function setIEVersion($ver) + { + $_SESSION['__browser'] = array( + 'ie_version' => $ver + ); + } + + /** + * Return the IE version stored in the session, if available. + * + * @access public + * + * @return mixed The IE Version string or null if no string is stored. + */ + function getIEVersion() + { + return isset($_SESSION['__browser']['ie_version']) ? $_SESSION['__browser']['ie_version'] : null; + } + +} diff --git a/lib/album.php b/lib/album.php new file mode 100644 index 00000000..7d518ff8 --- /dev/null +++ b/lib/album.php @@ -0,0 +1,31 @@ +<?php +/* + + This library handles album related functions.... wooo! + //FIXME: Remove this in favor of /modules/class/album +*/ + +/*! + @function get_albums + @discussion pass a sql statement, and it gets full album info and returns + an array of the goods.. can be set to format them as well +*/ +function get_albums($sql, $action=0) { + + $db_results = mysql_query($sql, dbh()); + while ($r = mysql_fetch_array($db_results)) { + $album = new Album($r[0]); + $album->format_album(); + $albums[] = $album; + } + + return $albums; + + +} // get_albums + + + + + +?> diff --git a/lib/archive.php b/lib/archive.php new file mode 100644 index 00000000..1a605f10 --- /dev/null +++ b/lib/archive.php @@ -0,0 +1,778 @@ +<?php
+/*--------------------------------------------------
+ | TAR/GZIP/BZIP2/ZIP ARCHIVE CLASSES 2.0
+ | By Devin Doucette
+ | Copyright (c) 2004 Devin Doucette
+ | Email: darksnoopy@shaw.ca
+ +--------------------------------------------------
+ | Email bugs/suggestions to darksnoopy@shaw.ca
+ +--------------------------------------------------
+ | This script has been created and released under
+ | the GNU GPL and is free to use and redistribute
+ | only if this copyright statement is not removed
+ +--------------------------------------------------*/
+
+class archive
+{
+ function archive($name)
+ {
+ $this->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.php b/lib/artist.php new file mode 100644 index 00000000..5ccd200a --- /dev/null +++ b/lib/artist.php @@ -0,0 +1,122 @@ +<?php +/* + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + + This library handles all artist mojo + +*/ + +/*! + @function get_artists + @discussion run a search, takes string,field,type and returns an array + of results of the correct type (song, album, artist) +*/ +function get_artists($sql, $action=0) { + + $db_results = mysql_query($sql, dbh()); + + while ($r = mysql_fetch_array($db_results)) { + $artist_info = get_artist_info($r['id']); + if ($action ==='format') { $artist = format_artist($artist_info); } + else { $artist = $artist_info; } + $artists[] = $artist; + } // end while + + return $artists; + +} // get_artists + +/*! + @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($artist) { + + $web_path = conf('web_path'); + $artist['name'] = "<a href=\"$web_path/artists.php?action=show&artist=" . $artist['id'] . "\">" . $artist['prefix'] . " " . $artist['name'] . "</a>"; + + 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.php b/lib/batch.php new file mode 100644 index 00000000..a3a3aba3 --- /dev/null +++ b/lib/batch.php @@ -0,0 +1,63 @@ +<?php +/* + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + + +/* + @function get_song_files + @discussion tmakes array of song ids and returns + array of path to actual files + @param $song_ids an array of song ids whose filenames you need +*/ +function get_song_files( $song_ids ) { + global $user; + $song_files = array(); + foreach( $song_ids as $song_id ) { + $song = new Song( $song_id ); + /* Don't archive disabled songs */ + if ($song->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/debug.php b/lib/debug.php new file mode 100644 index 00000000..c554daf7 --- /dev/null +++ b/lib/debug.php @@ -0,0 +1,361 @@ +<?php +/* + + Copyright (c) 2004 Ampache.org + All rights reserved. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + + +/* + @header Debug Library + This library is loaded when somehow our mojo has + been lost, it contains functions for checking sql + connections, web paths etc.. +*/ + +/*! + @function read_config_file + @discussion checks to see if the config + file is readable, overkill I know.. + @param level 0 is readable, 1 detailed info +*/ +function read_config_file($file,$level=0) { + + $fp = @fopen($file, 'r'); + + if (!$level) { + return is_resource($fp); + } + + +} // read_config_file + +/*! + @function check_database + @discussion checks the local mysql db + and make sure life is good +*/ +function check_database($host,$username,$pass,$db,$level=0) { + + $dbh = @mysql_connect($host, $username, $pass); + + if (!is_resource($dbh)) { + $error['error_state'] = true; + $error['mysql_error'] = mysql_errno() . ": " . mysql_error() . "\n"; + } + if (!$host || !$username || !$pass) { + $error['error_state'] = true; + $error['mysql_error'] .= "<br />HOST:$host<br />User:$username<br />Pass:$pass<br />"; + } +print_r($error); + if ($error['error_state']) { return false; } + + + return $dbh; + +} // check_database + +/*! + @function check_database_inserted + @discussion checks to make sure that you + have inserted the database and that the user + you are using has access to it +*/ +function check_database_inserted($dbh,$db_name) { + + + if (!@mysql_select_db($db_name,$dbh)) { + return false; + } + + $sql = "DESCRIBE session"; + $db_results = @mysql_query($sql, $dbh); + if (!@mysql_num_rows($db_results)) { + return false; + } + + return true; + +} // check_database_inserted + +/*! + @function check_php_ver + @discussion checks the php version and makes + sure that it's good enough +*/ +function check_php_ver($level=0) { + + if (strcmp('4.1.2',phpversion()) > 0) { + $error['error_state'] = true; + $error['php_ver'] = phpversion(); + } + + if ($error['error_state']) { return false; } + + return true; + +} // check_php_ver + +/*! + @function check_php_mysql + @discussion checks for mysql support +*/ +function check_php_mysql() { + + if (!function_exists('mysql_query')) { + $error['error_state'] = true; + $error['php_mysql'] = false; + } + + if ($error['error_state']) { return false; } + + return true; + +} // check_php_mysql + +/*! + @function check_php_session + @discussion checks to make sure the needed functions + for sessions exist +*/ +function check_php_session() { + + if (!function_exists('session_set_save_handler')) { + $error['error_state'] = true; + $error['php_session'] = false; + } + + if ($error['error_state']) { return false; } + + return true; + +} // check_php_session + +/*! + @function check_php_iconv + @discussion checks to see if you have iconv installed +*/ +function check_php_iconv() { + + if (!function_exists('iconv')) { + $error['error_state'] = true; + $error['php_iconv'] = false; + } + + if ($error['error_state']) { return false; } + + return true; + +} // check_php_iconv + +/*! + @function check_config_values() + @discussion checks to make sure that they have at + least set the needed variables +*/ +function check_config_values($conf) { + + if (!$conf['libglue']['local_host']) { + return false; + } + if (!$conf['libglue']['local_db']) { + return false; + } + if (!$conf['libglue']['local_username']) { + return false; + } + if (!$conf['libglue']['local_pass']) { + return false; + } + if (!$conf['libglue']['local_length']) { + return false; + } + + return true; + +} // check_config_values + +/*! + @function show_compare_config + @discussion shows the difference between ampache.cfg + and ampache.cfg.dst +*/ +function show_compare_config($prefix) { + + + // Live Config File + $live_config = $prefix . "/config/ampache.cfg.php"; + + // Generic Config File + $generic_config = $prefix . "/config/ampache.cfg.dist"; + +} // show_compare_config + + +/*! + @function debug_read_config + @discussion this is the same as the read config function + except it will pull config values with a # before them + (basicly adding a #config="value" check) and not + ever dieing on a config file error +*/ +function debug_read_config($config_file,$debug) { + + $fp = @fopen($config_file,'r'); + if(!is_resource($fp)) return false; + $file_data = fread($fp,filesize($config_file)); + fclose($fp); + + // explode the var by \n's + $data = explode("\n",$file_data); + if($debug) echo "<pre>"; + $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 <strong>$matches[2]</strong> to existing key <strong>$matches[1]</strong>\n"; + array_push(${$config_name}[$matches[1]], $matches[2]); + } + + elseif (isset(${$config_name}[$matches[1]]) && isset($matches[2]) ) { + if($debug) echo "Adding value <strong>$matches[2]</strong> to existing key $matches[1]</strong>\n"; + ${$config_name}[$matches[1]] = array(${$config_name}[$matches[1]],$matches[2]); + } + + elseif ($matches[2] !== "") { + if($debug) echo "Adding value <strong>$matches[2]</strong> for key <strong>$matches[1]</strong>\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 <strong>$matches[1]</strong> 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 <strong>$matches[2]</strong> to existing key <strong>$matches[1]</strong>\n"; + array_push($results[$matches[1]], $matches[2]); + } + + elseif (isset($results[$matches[1]]) && isset($matches[2]) ) { + if($debug) echo "Adding value <strong>$matches[2]</strong> to existing key $matches[1]</strong>\n"; + $results[$matches[1]] = array($results[$matches[1]],$matches[2]); + } + + elseif ($matches[2] !== "") { + if($debug) echo "Adding value <strong>$matches[2]</strong> for key <strong>$matches[1]</strong>\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 <strong>$matches[1]</strong> 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 "</pre>"; + + return $results; + +} // debug_read_config + +/*! + @function debug_compare_configs + @discussion this takes two config files, and then compares + the results and returns an array of the values + that are missing from the first one passed +*/ +function debug_compare_configs($config,$dist_config) { + + + + /* Get the results from the two difference configs including #'d values */ + $results = debug_read_config($config,0); + $dist_results = debug_read_config($dist_config,0); + + $missing = array(); + if (!count($dist_results['conf'])) { $dist_results['conf'] = array(); } + if (!count($dist_results['libglue'])) { $dist_results['libglue'] = array(); } + + foreach ($dist_results['conf'] as $key=>$value) { + + if (!isset($results['conf'][$key])) { + $missing['conf'][$key] = $value; + } + + } // end foreach conf + + foreach ($dist_results['libglue'] as $key=>$value) { + + if (!isset($results['libglue'][$key])) { + $missing['libglue'][$key] = $value; + } + + } // end foreach libglue + + return $missing; + +} // debug_compare_configs + + +?> diff --git a/lib/duplicates.php b/lib/duplicates.php new file mode 100644 index 00000000..94f3deda --- /dev/null +++ b/lib/duplicates.php @@ -0,0 +1,117 @@ +<?php +/*! + @header Contains the functions for handling duplicate songs +*/ + + +/*! + @function get_duplicate_songs + @discussion +*/ +function get_duplicate_songs($search_type) { + $sql = "SELECT song.id as song,artist.name,album.name,title,count(title) as ctitle". + " FROM song,artist,album ". + " WHERE song.artist=artist.id AND song.album=album.id AND song.title<>'' ". + " GROUP BY title"; + if ($search_type=="artist_title"||$search_type=="artist_album_title") + $sql = $sql.",artist"; + if ($search_type=="artist_album_title") + $sql = $sql.",album"; + $sql = $sql." HAVING count(title) > 1"; + $sql = $sql." ORDER BY ctitle"; + + //echo $sql."<BR>"; + + $result = mysql_query($sql, dbh()); + + $arr = array(); + + while ($flag = mysql_fetch_array($result)) { + $arr[] = $flag; + } // end while + return $arr; +} // get_duplicate_songs + +/*! + @function get_duplicate_info + @discussion +*/ +function get_duplicate_info($song,$search_type) { + $artist = get_artist_name($song->artist); + $sql = "SELECT song.id as songid,song.title as song,file,bitrate,size,time,album.name AS album,album.id as albumid, artist.name AS artist,artist.id as artistid". + " FROM song,artist,album ". + " WHERE song.artist=artist.id AND song.album=album.id ". + " AND song.title= '".str_replace("'","''",$song->title)."'"; + + if ($search_type=="artist_title"||$search_type=="artist_album_title") + $sql = $sql." AND artist.id = '".$song->artist."'"; + if ($search_type=="artist_album_title") + $sql = $sql." AND album.id = '".$song->album."'"; + + $result = mysql_query($sql, dbh()); + + $arr = array(); + + while ($flag = mysql_fetch_array($result)) { + $arr[] = $flag; + } // end while + return $arr; + +} // get_duplicate_info + +/*! + @function show_duplicate_songs + @discussion +*/ +function show_duplicate_songs($flags,$search_type) { + require_once(conf('prefix').'/templates/list_duplicates.inc'); +} // show_duplicate_songs + +/*! + @function show_duplicate_searchbox + @discussion +*/ +function show_duplicate_searchbox($search_type) { +?> +<br /> +<form name="songs" action="<?php echo conf('web_path'); ?>/admin/duplicates.php" method="post" enctype="multipart/form-data" > +<table class="border" cellspacing="0" cellpadding="3" border="0" width="450px"> + <tr class="table-header"> + <td colspan="2"><b><?php echo _("Find Duplicates"); ?></b></td> + </tr> + <tr class="even"> + <td><?php echo _("Search Type"); ?>:</td> + <td> + <? + + if ($search_type=="title") + $checked = "checked=\"checked\""; + else + $checked = ""; + echo "<input type=\"radio\" name=\"search_type\" value=\"title\" ".$checked." >" . _("Title") . "<br />"; + + if ($search_type=="artist_title") + $checked = "checked=\"checked\""; + else + $checked = ""; + echo "<input type=\"radio\" name=\"search_type\" value=\"artist_title\" ".$checked." >" . _("Artist and Title") . "<br />"; + if ($search_type=="artist_album_title"OR $search_type=="") + $checked = "checked=\"checked\""; + else + $checked = ""; + echo "<input type=\"radio\" name=\"search_type\" value=\"artist_album_title\"".$checked." >" . _("Artist, Album and Title") . "<br />"; + ?> + </td> + </tr> + <tr class="odd"> + <td></td> + <td> + <input type="hidden" name="action" value="search"> + <input type="submit" value="<?php echo _("Search"); ?>" /> + </td> + </tr> +</table> +<br> +<? +} // show_duplicate_searchbox +?> diff --git a/lib/flag.php b/lib/flag.php new file mode 100644 index 00000000..01b3ba9f --- /dev/null +++ b/lib/flag.php @@ -0,0 +1,348 @@ +<?php +/* + + Copyright (c) 2004 Ampache.org + All rights reserved. + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +// +// + +function add_to_edit_queue($flags=0) +{ + $oldflags = 0; + if(empty($flags)) $flags = 0; + if($_SESSION['edit_queue']) + { + $oldflags = $_SESSION['edit_queue']; + if(!is_array($oldflags)) $oldflags = array($oldflags); + } + + if(!is_array($flags)) + { + if($flags !== 0) $flags = array($flags); + } + + if(is_array($flags)) + { + if(is_array($oldflags)) $new_array = array_merge($flags, $oldflags); + else $new_array = $flags; + } + elseif (is_array($oldflags)) $new_array = $oldflags; + + if(count($new_array)) + { + $_SESSION['edit_queue'] = $new_array; + return count($new_array); + } + else + { + unset($_SESSION['edit_queue']); + return 0; + } +} + +function show_edit_flagged($flag=0) +{ + if(empty($flag)||$flag === 0) + { + $flag = array_pop($_SESSION['edit_queue']); + } + $flaginfo = get_flag($flag); + if($flaginfo['type'] === 'badid3') + { + show_edit_badid3($flaginfo['song'],$flag); + } + else + { + echo "I don't know how to edit already edited songs yet: $flag.<br />"; + } +} + +function show_edit_badid3($songid,$flagid) +{ + $song = get_song_info($songid); + require(conf('prefix')."/templates/song_edit.inc"); +} + +function get_flag($id) +{ + if(!is_array($id)) $id = array($id); + $results = array(); + $newid = array_pop($id); + $sql = "SELECT flagged.id,user.username,type,song,date,comment" . + " FROM flagged,user WHERE flagged.user = user.id AND (flagged.song = '$newid'"; + foreach($id as $num) + { + $sql .= " OR flagged.song = '$num'"; + } + $sql .= ")"; + $result = mysql_query($sql, dbh()); + while ($row = mysql_fetch_array($result)) + { + $results[] = $row; + } + if(count($results) == 1) return $results[0]; + else return $results; +} + + +function get_flagged_songs($user = 0) +{ + $sql = "SELECT flagged.id,user.username,type,song,date,comment" . + " FROM flagged,user WHERE flagged.user = user.id AND flagged.type <> 'notify' AND flagged.type <> 'done'"; + + // If the user is not an admin, they can only see songs they've flagged + if($user) + { + if($_SESSION['userdata']['access'] === 'admin') + { + $sql .= " AND user.id = '$user'"; + } + else + { + $sql .= " AND user.id = '".$_SESSION['userdata']['id']."'"; + } + } + + $sql .= " ORDER BY date"; + $result = mysql_query($sql, dbh()); + + $arr = array(); + + while ($flag = mysql_fetch_array($result)) + { + $arr[] = $flag; + } + return $arr; +} + +function show_flagged_songs($flags) +{ + require_once(conf('prefix').'/templates/list_flagged.inc'); +} + +function accept_new_tags($flags) +{ + if(!is_array($flags)) $flags = array($flags); + foreach($flags as $flag) + { + copy_updated_tag($flag); + } + set_flag_value($flags, 'setid3'); +} + + +function reject_new_tags($flags) +{ + if(!is_array($flags)) $flags = array($flags); + $oldflags = $flags; + $flag = array_pop($flags); + $sql = "DELETE FROM flagged_songs WHERE song = '$flag'"; + + foreach($flags as $flag) + { + $sql .= " OR song = '$flag'"; + } + $result = mysql_query($sql, dbh()); + $user = $_SESSION['userdata']['username']; + set_flag_value($oldflags, 'notify', "Tag changes rejected by $user"); +} + +function set_flag_value($flags, $val, $comment = '') +{ + if(!is_array($flags)) $flags = array($flags); + $user = $_SESSION['userdata']['id']; +/* $flagid = array_pop($flags);*/ + $dbh = dbh(); + foreach($flags as $flagid) + { + $sql = "REPLACE INTO flagged (type,song,comment,user,date)". + " VALUES ('$val','$flagid','$comment','$user','".time()."')"; + $result = mysql_query($sql, $dbh); + } + return $result; +} + +function copy_updated_tag($flag) +{ + $flagdata = get_flag($flag); + $sql = "SELECT * FROM flagged_song WHERE song = '".$flagdata['song']."'"; + $result = mysql_query($sql, dbh()); + $newtag = mysql_fetch_array($result); + + if($newtag['new_artist']) + { + $newtag['artist'] = insert_artist($newtag['new_artist']); + } + if($newtag['new_album']) + { + $newtag['album'] = insert_album($newtag['new_album']); + } + + $sql = "UPDATE song SET ". + "title = '".$newtag['title']."',". + "artist = '".$newtag['artist']."',". + "album = '".$newtag['album']."',". + "track = '".$newtag['track']."',". + "genre = '".$newtag['genre']."',". + "year = '".$newtag['year']."' ". + "WHERE song.id = '".$newtag['song']."'"; + $result = mysql_query($sql, dbh()); + if($result) + { + $sql2 = "DELETE FROM flagged_song WHERE song='".$flagdata['song']."'"; + $result2 = mysql_query($sql2, dbh()); + } + return ($result && $result2); + +} + +function update_flags($songs) +{ + $accepted = array(); + $rejected = array(); + $newflags = array(); + foreach($songs as $song) + { + $accept = scrub_in($_REQUEST[$song.'_accept']); + if($accept === 'accept') $accepted[] = $song; + elseif ($accept === 'reject') $rejected[] = $song; + else + { + $newflag = scrub_in($_REQUEST[$song.'_newflag']); + $newflags[$song] = $newflag; + } + } + + if(count($accepted)) + { + accept_new_tags($accepted); + } + if(count($rejected)) + { + reject_new_tags($rejected); + } + if(count($newflags)) + { + foreach($newflags as $flag=>$type) + { + set_flag_value($flag, $type); + } + } + +} + + +function update_song_info($song) +{ + $user = $_SESSION['userdata']; + + $title = scrub_in($_REQUEST['title']); + $track = scrub_in($_REQUEST['track']); + $genre = scrub_in($_REQUEST['genre']); + $year = scrub_in($_REQUEST['year']); + + if(isset($_REQUEST['update_id3'])) + $update_id3 = 1; + + if(isset($_REQUEST['new_artist']) && $_REQUEST['new_artist'] !== '') + { + $create_artist = 1; + $artist = scrub_in($_REQUEST['new_artist']); + } + else + $artist = scrub_in($_REQUEST['artist']); + + if(isset($_REQUEST['new_album']) && $_REQUEST['new_album'] !== '') + { + $create_album = 1; + $album = scrub_in($_REQUEST['new_album']); + } + else + $album = scrub_in($_REQUEST['album']); + + if(is_array($_REQUEST['genre'])) { + $genre = $genre[0]; + } + + if($user['access'] == 'admin') + // Update the file directly + { + if($create_artist) + { + $artist = insert_artist($artist); + } + if($create_album) + { + $album = insert_album($album); + } + // Escape data (prevent " or ' snafu's) + $title = sql_escape($title); + $artist = sql_escape($artist); + $album = sql_escape($album); + $genre = sql_escape($genre); + $year = sql_escape($year); + + $sql = "UPDATE song SET" . + " title = '$title'," . + " track = '$track'," . + " genre = '$genre'," . + " year = '$year'," . + " artist = '$artist',". + " album = '$album'," . + " update_time = '".time()."'" . + " WHERE id = '$song' LIMIT 1"; + $result = mysql_query($sql, dbh() ); + if($result && $update_id3 ) + { + //Add to flagged table so we can fix the id3 tags + $date = time(); + $sql = "REPLACE INTO flagged SET " . + " type = 'setid3', song = '$song', date = '$date', user = '".$user['id']."'"; + $result = mysql_query($sql, dbh()); + } + } + + else + // Stick in the flagged_songs table to be updated by an admin + { + if($create_artist) $artist_field = 'new_artist'; + else $artist_field = 'artist'; + + if($create_album) $album_field = 'new_album'; + else $album_field = 'album'; + + $sql = "INSERT INTO flagged_song(song,title,track,genre,year,$artist_field,$album_field,update_time) " . + "VALUES ('$song','$title','$track','$genre','$year','$artist','$album','".time()."')"; + $result = mysql_query($sql, dbh() ); + + if($result && $update_id3 ) + { + //Add to flagged table so we can fix the id3 tags + $date = time(); + $sql = "REPLACE INTO flagged SET " . + " type = 'newid3', song = '$song', date = '$date', user = '".$user['id']."'"; + $result = mysql_query($sql, dbh()); + } + echo "Thanks for helping to keep the catalog up to date. Someone will review your changes, and you will be notified on the main page when they're approved."; + + } +} + diff --git a/lib/general.php b/lib/general.php new file mode 100644 index 00000000..1184db45 --- /dev/null +++ b/lib/general.php @@ -0,0 +1,554 @@ +<?php +/* + @header General Library + This is the general library that contains misc functions + that doesn't have a home elsewhere +*/ + +/*! + @function sql_escape + @discussion this takes a sql statement + and properly escapes it before a query is run + against it. +*/ +function sql_escape($sql,$dbh=0) { + + if (!is_resource($dbh)) { + $dbh = dbh(); + } + + if (function_exists('mysql_real_escape_string')) { + $sql = mysql_real_escape_string($sql,$dbh); + } + else { + $sql = mysql_escape_string($sql); + } + + return $sql; + +} // sql_escape + +/*! + @function ip2int + @discussion turns a dotted quad ip into an + int +*/ +function ip2int($ip) { + + $a=explode(".",$ip); + return $a[0]*256*256*256+$a[1]*256*256+$a[2]*256+$a[3]; + +} // ip2int + +/*! + @function int2ip + @discussion turns a int into a dotted quad +*/ +function int2ip($i) { + $d[0]=(int)($i/256/256/256); + $d[1]=(int)(($i-$d[0]*256*256*256)/256/256); + $d[2]=(int)(($i-$d[0]*256*256*256-$d[1]*256*256)/256); + $d[3]=$i-$d[0]*256*256*256-$d[1]*256*256-$d[2]*256; + return "$d[0].$d[1].$d[2].$d[3]"; +} // int2ip + +/*! + @function show_template + @discussion show a template from the /templates directory, automaticly appends .inc + to the passed filename + @param $template Name of Template +*/ +function show_template($template) { + + /* Check for a 'Theme' template */ + if (is_readable(conf('prefix') . conf('theme_path') . "/templates/$template".".inc")) { + require (conf('prefix') . conf('theme_path') . "/templates/$template".".inc"); + } + else { + require (conf('prefix') . "/templates/$template".".inc"); + } + +} // show_template + + +/*! + @function read_config + @discussion reads the config file for ampache +*/ +function read_config($config_file, $debug=0, $test=0) { + + $fp = @fopen($config_file,'r'); + if(!is_resource($fp)) return false; + $file_data = fread($fp,filesize($config_file)); + fclose($fp); + + // explode the var by \n's + $data = explode("\n",$file_data); + if($debug) echo "<pre>"; + + $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 <strong>$matches[2]</strong> to existing key <strong>$matches[1]</strong>\n"; + array_push(${$config_name}[$matches[1]], $matches[2]); + } + + elseif (isset(${$config_name}[$matches[1]]) && isset($matches[2]) ) { + if($debug) echo "Adding value <strong>$matches[2]</strong> to existing key $matches[1]</strong>\n"; + ${$config_name}[$matches[1]] = array(${$config_name}[$matches[1]],$matches[2]); + } + + elseif ($matches[2] !== "") { + if($debug) echo "Adding value <strong>$matches[2]</strong> for key <strong>$matches[1]</strong>\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 <strong>$matches[1]</strong> 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 <strong>$matches[2]</strong> to existing key <strong>$matches[1]</strong>\n"; + array_push($results[$matches[1]], $matches[2]); + } + + elseif (isset($results[$matches[1]]) && isset($matches[2]) ) { + if($debug) echo "Adding value <strong>$matches[2]</strong> to existing key $matches[1]</strong>\n"; + $results[$matches[1]] = array($results[$matches[1]],$matches[2]); + } + + elseif ($matches[2] !== "") { + if($debug) echo "Adding value <strong>$matches[2]</strong> for key <strong>$matches[1]</strong>\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 <strong>$matches[1]</strong> 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 "</pre>"; + + 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 + +/*! + @function cleanup_and_exit + @discussion used specificly for the play/index.php file + this functions nukes now playing and then exits +*/ +function cleanup_and_exit($playing_id) { + + /* Clear now playing */ + // 900 = 15 min + $expire = time() - 900; + $sql = "DELETE FROM now_playing WHERE id='$lastid' OR start_time < $expire"; + $db_results = mysql_query($sql, dbh()); + exit(); + +} // cleanup_and_exit + +?> diff --git a/lib/gettext.php b/lib/gettext.php new file mode 100644 index 00000000..064173d6 --- /dev/null +++ b/lib/gettext.php @@ -0,0 +1,36 @@ +<?php +/* + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +/*! + @function load_gettext + @discussion sets the local +*/ +function load_gettext() { + /* If we have gettext */ + if (function_exists('bindtextdomain')) { + bindtextdomain('messages', conf('prefix') . "/locale/"); + textdomain('messages'); + putenv("LANG=" . conf('lang')); + setlocale(LC_ALL, conf('lang')); + } + +} // load_gettext + + +?> diff --git a/lib/install.php b/lib/install.php new file mode 100644 index 00000000..c337b1e8 --- /dev/null +++ b/lib/install.php @@ -0,0 +1,238 @@ +<? +/* + + Copyright (c) 2001 - 2005 Ampache.org + All rights reserved. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +/*! + @header Install docuement + @discussion this document contains the functions needed to see if + ampache needs to be installed +*/ + +/*! + @function split_sql + @discussion splits up a standard SQL dump file into distinct + sql queryies +*/ +function split_sql($sql) { + $sql = trim($sql); + $sql = ereg_replace("\n#[^\n]*\n", "\n", $sql); + $buffer = array(); + $ret = array(); + $in_string = false; + for($i=0; $i<strlen($sql)-1; $i++) { + if($sql[$i] == ";" && !$in_string) { + $ret[] = substr($sql, 0, $i); + $sql = substr($sql, $i + 1); + $i = 0; + } + if($in_string && ($sql[$i] == $in_string) && $buffer[1] != "\\") { + $in_string = false; + } + elseif(!$in_string && ($sql[$i] == '"' || $sql[$i] == "'") && (!isset($buffer[0]) || $buffer[0] != "\\")) { + $in_string = $sql[$i]; + } + if(isset($buffer[1])) { + $buffer[0] = $buffer[1]; + } + $buffer[1] = $sql[$i]; + } + if(!empty($sql)) { + $ret[] = $sql; + } + return($ret); +} // split_sql + +/*! + @function install_check_status() + @discussion this function checks to see if we actually + still need to install ampache. This function is + very important, we don't want to reinstall over top + of an existing install +*/ +function install_check_status($configfile) { + + /* + Check and see if the config file exists + if it does they can't use the web interface + to install ampache. + */ + if (!file_exists($configfile)) { + return true; + } + + /* + Check and see if they've got _any_ account + if they don't then they're cool + */ + $results = read_config($GLOBALS['configfile'], 0, 0); + $dbh = check_database($results['libglue']['local_host'],$results['libglue']['local_username'],$results['libglue']['local_pass'],$results['libglue']['local_db']); + + if (is_resource($dbh)) { + mysql_select_db($results['libglue']['local_db'],$dbh); + $sql = "SELECT * FROM user"; + $db_results = @mysql_query($sql, $dbh); + if (!@mysql_num_rows($db_results)) { + return true; + } + } + + + /* Defaut to no */ + return false; + +} // install_check_status + +/*! + @function install_insert_db() + @discussion this function inserts the database + using the username/pass/host provided + and reading the .sql file +*/ +function install_insert_db($username,$password,$hostname,$database) { + + /* Attempt to make DB connection */ + $dbh = @mysql_pconnect($hostname,$username,$password); + + + /* Check/Create Database as needed */ + $db_selected = @mysql_select_db($database, $dbh); + if (!$db_selected) { + $sql = "CREATE DATABASE `" . $database . "`"; + if (!$db_results = @mysql_query($sql, $dbh)) { + return false; + } + @mysql_select_db($database, $dbh); + } // if db can't be selected + + + /* Attempt to insert database */ + $query = fread(fopen("sql/ampache.sql", "r"), filesize("sql/ampache.sql")); + $pieces = split_sql($query); + for ($i=0; $i<count($pieces); $i++) { + $pieces[$i] = trim($pieces[$i]); + if(!empty($pieces[$i]) && $pieces[$i] != "#") { + //FIXME: This is for a DB prefix when we get around to it +// $pieces[$i] = str_replace( "#__", $DBPrefix, $pieces[$i]); + if (!$result = mysql_query ($pieces[$i])) { + $errors[] = array ( mysql_error(), $pieces[$i] ); + } // end if + } // end if + } // end for + + return true; + +} // install_insert_db + +/*! + @function install_create_config() + @discussion attempts to write out the config file + if it can't write it out it will prompt the + user to download the config file. +*/ +function install_create_config($web_path,$username,$password,$hostname,$database) { + + /* + First Test The Variables they've given us to make + sure that they actually work! + */ + // Connect to the DB + if(!$dbh = @mysql_pconnect($hostname,$username,$password)) { + return false; + } + if (!$db_selected = @mysql_select_db($database, $dbh)) { + return false; + } + + + /* Read in the .dist file and spit out the .cfg */ + $dist_handle = @fopen("config/ampache.cfg.php.dist",'r'); + $dist_data = @fread($dist_handle,filesize("config/ampache.cfg.php.dist")); + fclose($dist_handle); + + $dist_array = explode("\n",$dist_data); + + // Rather then write it out right away, let's build the string + // incase we can't write to the FS and have to make it a download + + foreach ($dist_array as $row) { + + if (preg_match("/^#?web_path\s*=/",$row)) { + $row = "web_path = \"$web_path\""; + } + elseif (preg_match("/^#?local_db\s*=/",$row)) { + $row = "local_db = \"$database\""; + } + elseif (preg_match("/^#?local_host\s*=/",$row)) { + $row = "local_host = \"$hostname\""; + } + elseif (preg_match("/^#?local_username\s*=/",$row)) { + $row = "local_username = \"$username\""; + } + elseif (preg_match("/^#?local_pass\s*=/",$row)) { + $row = "local_pass = \"$password\""; + } + + $config_data .= $row . "\n"; + + } // foreach row in config file + + /* Attempt to Write out File */ + if (!$config_handle = @fopen("config/ampache.cfg.php",'w')) { + $browser = new Browser(); + $browser->downloadHeaders("ampache.cfg.php","text/plain",false,filesize("config/ampache.cfg.php.dist")); + + echo $config_data; + exit(); + + } + if (!@fwrite($config_handle,$config_data)) { + return false; + } + + return true; + +} // install_create_config + +/*! + @function install_create_account + @discussion this creates your initial account +*/ +function install_create_account($username,$password) { + + $results = read_config($GLOBALS['configfile'], 0, 0); + $dbh = check_database($results['libglue']['local_host'],$results['libglue']['local_username'],$results['libglue']['local_pass'],$results['libglue']['local_db']); + + @mysql_select_db($results['libglue']['local_db'],$dbh); + + $username = sql_escape($username,$dbh); + $password = sql_escape($password,$dbh); + + $sql = "INSERT INTO user (`username`,`password`,`offset_limit`,`access`) VALUES ('$username',PASSWORD('$password'),'50','admin')"; + $db_results = mysql_query($sql, $dbh); + + $insert_id = mysql_insert_id($dbh); + + if (!$insert_id) { return false; } + + return true; + +} // install_create_account + +?> diff --git a/lib/log.php b/lib/log.php new file mode 100644 index 00000000..7a3d8faf --- /dev/null +++ b/lib/log.php @@ -0,0 +1,77 @@ +<?php +/* + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +/*! + @function log_event + @discussion logs an event either to a database + or to a defined log file based on config options +*/ +function log_event($username='Unknown',$event_name,$event_description,$log_name='ampache') { + + /* Set it up here to make sure it's _always_ the same */ + $log_time = time(); + + set_time_limit(0); + + $log_filename = conf('log_path') . "/$log_name." . date("Ymd",$log_time) . ".log"; + $log_line = date("Y-m-d H:i:s",$log_time) . " { $username } ( $event_name ) - $event_description \n"; + + + error_log($log_line, 3, $log_filename) or die("Error: Unable to write to log ($log_filename)"); + +} // log_event + +/*! + @function ampache_error_handler + @discussion an error handler for ampache that traps + as many errors as it can and logs em +*/ +function ampache_error_handler($errno, $errstr, $errfile, $errline) { + + switch ($errno) { + case '2': + case '128': + case '8': + case '32': + return true; + break; + case '1': + $error_name = "Fatal run-time Error"; + break; + case '4': + $error_name = "Parse Error"; + break; + case '16': + $error_name = "Fatal Core Error"; + break; + case '64': + $error_name = "Zend run-time Error"; + break; + default: + $error_name = "Error"; + break; + } // end switch + + + $log_line = "[$errstr] $error_name on line $errline in $errfile"; + log_event($_SESSION['userdata']['username'],'error',$log_line,'ampache-error'); + +} // ampache_error_handler + +?> diff --git a/lib/mpd.php b/lib/mpd.php new file mode 100644 index 00000000..166bfe5b --- /dev/null +++ b/lib/mpd.php @@ -0,0 +1,75 @@ +<?php +/* + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +/*! + @function addToPlaylist() + @discussion adds a bunch of songs to the mpd playlist + this takes a mpd object, and an array of songs +*/ +function addToPlaylist( $myMpd, $song_ids=array()) { + + foreach( $song_ids as $song_id ) { + + /* There are two ways to do this, filename or URL */ + if (conf('mpd_method') == 'url') { + // We just need to generate a standard stream URL and pass that + $song = new Song($song_id); + $sess_id = session_id(); + if ($song->type == ".flac") { $song->type = ".ogg"; } + if ($GLOBALS['user']->prefs['play_type'] == 'downsample') { + $ds = $GLOBALS['user']->prefs['sample_rate']; + } + $song_url = conf('web_path') . "/play/index.php?song=$song_id&uid=" . $GLOBALS['user']->id . "&sid=$sess_id&ds=$ds&name=." . $song->type; + if (is_null( $myMpd->PlAdd($song_url) ) ) { + $log_line = _("Error") . ": " . _("Could not add") . ": " . $song_url . " : " . $myMpd->errStr; + echo "<font class=\"error\">$log_line</font><br />\n"; + log_event($GLOBALS['user']->username,'add',$log_line); + } // if it's null + } // if we want urls + else { + $song = new Song( $song_id ); + $song_filename = $song->get_rel_path(); + if( is_null( $myMpd->PLAdd( $song_filename ) ) ) { + $log_line = _("Error") . ": " . _("Could not add") . ": " . $song_filename . " : " . $myMpd->errStr; + echo "<font class=\"error\">$log_line</font><br />\n"; + log_event($_SESSION['userdata']['username'],'add',$log_line); + } // end if it's null + // We still need to count if they use the file method + else { + $GLOBALS['user']->update_stats( $song_id ); + } // end else + + } // end else not url method + } // end foreach + +} // addToPlaylist + +/*! + @function show_mpd_control + @discussion shows the mpd controls +*/ +function show_mpd_control() { + + $_REQUEST['action'] = 'show_control'; + require_once ('amp-mpd.php'); + + +} // show_mpd_control + +?> diff --git a/lib/perl/Local/Ampache/Ampache.pm b/lib/perl/Local/Ampache/Ampache.pm new file mode 100755 index 00000000..3bceb7e6 --- /dev/null +++ b/lib/perl/Local/Ampache/Ampache.pm @@ -0,0 +1,237 @@ +#!/usr/bin/perl -w + +# Find and file away MP3's. Run multiple times and will +# ignore addition of duplicates in db (based on MD5 hash +# of full file path. + +package Local::Ampache; +#use File::Find; +use DBI; +#use strict; +use Data::Dumper; +use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %ampache); +require Exporter; + +@ISA = qw(Exporter AutoLoader); +@EXPORT = qw( + +); + +my $TRUE = 1; +my $FALSE = 0; +$VERSION = ''; + + +my %ampache = (); + + +sub new { + my ($class, $path) = @_; + + + open(CONFIG, "< $path/config/ampache.cfg") + or die "Could not find $path/config/ampache.cfg. Is it readable by me?\n"; + + my %config = (); + + while (<CONFIG>) { + next if ($_ =~ /^#.*/); + + if ( $_ =~ /(.*?)\s+=\s+(.*)/ ) { + $config{$1} = $2; + } + } + + my $name = $config{'local_db'}; + + my $self = + { + _name => $config{'local_db'}, + _database => $config{'local_db'}, + _sth_cache => {}, + _connect => { + dbd => 'mysql', + host => $config{'local_host'}, + port => '3306', + username => $config{'local_username'}, + password => $config{'local_pass'} + }, + _dbh => '', + _path => $path, + _config => \%config, + _debug => $FALSE + }; + + $VERSION = $config{'VERSION'}; + + $Local::Ampache::ampache{$name} = bless ($self, $class); + + $self->{_dbh} = $self->dbh( $name ); + + return $self; + +} # End New Ampache Module + +sub DESTROY { + my ($self) = @_; + + foreach my $sth (values %{$self->{_sth_cache}}) { + if (defined($sth)) { $sth->finish(); } + } + + if (defined($self->{_dbh}) and $self->{_dbh} ne "") { + $self->{_dbh}->disconnect(); + } +} + +sub get +{ + my ($class, $name) = @_; + + if (not $Local::Ampache::ampache{$name}) { + $Local::Ampache::ampache{$name} = Local::Ampache->new($name); + } + return bless $Local::Ampache::ampache{$name}, $class; +} + +sub dbh +{ + my ($self, $database) = @_; + my $dbh = ''; + + if($self->{_dbh} ) + { + return $self->{_dbh}; + } + else + { + my $connect_string = [ sprintf("dbi:%s:database=%s;host=%s;port=%s", + $self->{_connect}{dbd}, + $self->{_database}, + $self->{_connect}{host}, + $self->{_connect}{port}), + $self->{_connect}{username}, + $self->{_connect}{password} ]; + $dbh = DBI->connect( @{$connect_string}, + {PrintError => 0, + RaiseError => 0, + AutoCommit => 1}); + + if ( !$dbh ) + { + die "Failed to connect to database. Exiting."; + } + } + + return $dbh; +} + +sub prepare_sth_cache { + my ($self, $sql) = @_; + + # the call to dbh() forces a connection if one has dropped + my $dbh = $self->dbh(); + return $dbh->prepare($sql); +} + +sub get_table_where +{ + my ($self, $name, $where,$select) = @_; + if (!$select) { $select = "*"; } + my ($sql, $sth); + my $dbh = $self->dbh(); + $sql = qq{SELECT $select FROM $name $where}; + $sth = $dbh->prepare($sql); + $sth->execute(); + + my @table = (); + while ( my $ary = $sth->fetchrow_hashref() ) + { + push(@table, $ary); + } + return (@table); +} + +sub get_catalog_option +{ + my ($self, $catalog, $field) = @_; + if(!$self->{_catalog}{$catalog}) { + print "Loading catalog settings\n"; + my ($sql, $sth); + $sql = qq{SELECT * FROM catalog WHERE path = '$catalog'}; + my $dbh = $self->dbh(); + $sth = $dbh->prepare($sql); + $sth->execute(); + $self->{_catalog}{$catalog} = $sth->fetchrow_hashref(); + } + return $self->{_catalog}->{$catalog}->{$field}; +} + +sub change_flags +{ + my ($self, $song, $oldflag, $newflag) = @_; + my ($sql, $sth); + my $dbh = $self->dbh(); + $sql = "UPDATE flagged SET type = '$newflag' WHERE song = '".$song->{'id'}."' AND type = '$oldflag'"; + $sth = $dbh->prepare($sql); + $sth->execute(); +} + + sub update_song +{ + my ($self, $filename, $song) = @_; + my ($sql, $sth); + my $dbh = $self->dbh(); + $filename =~ s/'/\\'/g; + $filename =~ s/"/\\"/g; + $filename =~ s/\Q%\E//g; + $sql = "UPDATE song SET file = '$filename' WHERE id = '".$song->{'id'}."'"; + $sth = $dbh->prepare($sql); + $sth->execute(); +} + +sub get_song_info +{ + my ($self, $song) = @_; + my ($sql, $sth); + my $dbh = $self->dbh(); + if ( not $self->{_sth_cache}{get_song_info}) + { + $self->{_sth_cache}{get_song_info} = $self->prepare_sth_cache( + qq{SELECT catalog.path AS catalog,song.file,song.id,song.title,song.track,song.year,song.comment,album.name AS album, artist.name AS artist,genre FROM song,album,artist,catalog WHERE song.id = ? AND album.id = song.album AND artist.id = song.artist AND song.catalog = catalog.id}); + + } + $sth = $self->{_sth_cache}{get_song_info}; + $sth->execute($song); + + my @table = (); + while ( my $ary = $sth->fetchrow_hashref() ) + { + push(@table, $ary); + } + return (@table); +} + +#sub get_song_info +#{ +# my ($self, $song) = @_; +# +# my ($sql, $sth); +# my $dbh = $self->dbh(); +# if ( not $self->{_sth_cache}{song_info}{$song} ) +# { +# $sql = qq{SELECT * FROM song WHERE id = $song}; +# $sth = $dbh->prepare($sql); +# $self->{_sth_cache}{song_info}{$song} = $sth; +# } +# +# $sth = $self->{_sth_cache}{song_info}{$song}; +# $sth->execute(); +# +# my @song_info = $sth->fetchrow_hashref(); +# return (@song_info); +#} + + +1; +__END__ diff --git a/lib/perl/Local/Ampache/Makefile.PL b/lib/perl/Local/Ampache/Makefile.PL new file mode 100755 index 00000000..a51e5d54 --- /dev/null +++ b/lib/perl/Local/Ampache/Makefile.PL @@ -0,0 +1,7 @@ +use ExtUtils::MakeMaker; +# See lib/ExtUtils/MakeMaker.pm for details of how to influence +# the contents of the Makefile that is written. +WriteMakefile( + 'NAME' => 'Local::Ampache', + 'VERSION_FROM' => 'Ampache.pm', # finds $VERSION +); diff --git a/lib/preferences.php b/lib/preferences.php new file mode 100644 index 00000000..b6c6e0c9 --- /dev/null +++ b/lib/preferences.php @@ -0,0 +1,281 @@ +<?php +/* + + Copyright (c) 2001 - 2005 Ampache.org + All rights reserved. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +/*! + @header Preferences Library + @discussion This contains all of the functions needed for the preferences +*/ + +/*! + @function get_site_preferences + @discussion gets all of the preferences for this Ampache site +*/ +function get_site_preferences() { + + $results = array(); + + $sql = "SELECT preferences.name, preferences.type, user_preference.value, preferences.description FROM preferences,user_preference " . + " WHERE preferences.id=user_preference.preference AND user_preference.user = '0' ORDER BY `type`,`name`"; + $db_results = mysql_query($sql, dbh()); + + while ($r = mysql_fetch_object($db_results)) { + $results[] = $r; + } + + return $results; + +} // get_site_preferences + +/*! + @function set_site_preferences + @discussion sets the conf() function with the current site preferences from the db +*/ +function set_site_preferences() { + + $results = array(); + + $sql = "SELECT preferences.name,user_preference.value FROM preferences,user_preference WHERE user='0' AND user_preference.preference=preferences.id"; + $db_results = @mysql_query($sql, dbh()); + + while ($r = @mysql_fetch_object($db_results)) { + $results[$r->name] = $r->value; + } // db results + + if (strlen($results['theme_name']) > 0) { + $results['theme_path'] = "/themes/" . $results['theme_name']; + } + + conf($results,1); + +} // set_site_preferences + +/*! + @function clean_preference_name + @discussion s/_/ /g & upper case first +*/ +function clean_preference_name($name) { + + $name = str_replace("_"," ",$name); + $name = ucwords($name); + + return $name; + +} // clean_preference_name + +/*! + @function update_preferences + @discussion grabs the current keys that should be added + and then runs throught $_REQUEST looking for those + values and updates them for this user +*/ +function update_preferences($pref_id=0) { + + $pref_user = new User(0,$pref_id); + + /* Get current keys */ + $sql = "SELECT id,name,type FROM preferences"; + if ($pref_id != '0') { $sql .= " WHERE type='user'"; } + $db_results = mysql_query($sql, dbh()); + + // Collect the current possible keys + while ($r = mysql_fetch_object($db_results)) { + $results[] = array('id' => $r->id, 'name' => $r->name,'type' => $r->type); + } + + foreach ($results as $data) { + /* Get the Value from POST/GET var called $data */ + //FIXME: Do this right.... + $type = $data['type']; + $name = $data['name']; + $apply_to_all = "check_" . $data['name']; + $id = $data['id']; + $value = sql_escape(scrub_in($_REQUEST[$name])); + + if (has_preference_access($name) AND isset($_REQUEST[$name])) { + $sql = "UPDATE user_preference SET `value`='$value' WHERE preference='$id' AND user='$pref_id'"; + $db_results = mysql_query($sql, dbh()); + + /* Check to see if this is a theme, and if so run the theme updater */ + if ($name == "theme_name" AND $pref_user->prefs['theme_name'] != $_REQUEST[$name]) { + set_theme_colors($value,$pref_id); + } // run theme updater + + } // if access + + if ($GLOBALS['user']->has_access(100) AND $_REQUEST[$apply_to_all] =='1') { + $sql = "UPDATE user_preference SET `value`='$value' WHERE preference='$id'"; + $db_results = mysql_query($sql, dbh()); + } + } // end foreach preferences + + +} // update_preferences + +/*! + @function has_preference_access + @discussion makes sure that the user has sufficient + rights to actually set this preference, handle + as allow all, deny X + //FIXME: + // This is no longer needed, we just need to check against preferences.level +*/ +function has_preference_access($name) { + global $user; + + if (conf('demo_mode')) { + return false; + } + + switch($name) { + + case 'download': + case 'upload': + case 'quarantine': + case 'upload_dir': + case 'sample_rate': + case 'direct_link': + $level = 100; + break; + default: + $level = 1; + break; + } // end switch key + if ($user->has_access($level)) { + return true; + } + + return false; + +} // has_preference_access + + +/*! + @function create_preference_input + @discussion takes the key and then creates + the correct type of input for updating it +*/ +function create_preference_input($name,$value) { + + $len = strlen($value); + if ($len <= 1) { $len = 8; } + + if (!has_preference_access($name)) { + if ($value == '1') { + echo "Enabled"; + } + elseif ($value == '0') { + echo "Disabled"; + } + else { + echo $value; + } + return; + } // if we don't have access to it + + switch($name) { + + case 'download': + case 'quarantine': + case 'upload': + case 'access_list': + case 'lock_songs': + case 'xml_rpc': + case 'force_http_play': + case 'no_symlinks': + case 'use_auth': + case 'access_control': + case 'demo_mode': + case 'direct_link': + if ($value == '1') { $is_true = "selected=\"selected\""; } + else { $is_false = "selected=\"selected\""; } + echo "<select name=\"$name\">\n"; + echo "\t<option value=\"1\" $is_true>" . _("Enable") . "</option>\n"; + echo "\t<option value=\"0\" $is_false>" . _("Disable") . "</option>\n"; + echo "</select>\n"; + break; + case 'play_type': + if ($value == 'local_play') { $is_local = "selected=\"selected\""; } + elseif ($value == 'icecast2') { $is_ice = "selected=\"selected\""; } + elseif ($value == 'downsample') { $is_down = "selected=\"selected\""; } + elseif ($value == 'mpd') { $is_mpd = "selected=\"selected\""; } + elseif ($value == 'slim') { $is_slim = "selected=\"selected\""; } + else { $is_stream = "selected=\"selected\""; } + echo "<select name=\"$name\">\n"; + if (conf('allow_local_playback')) { + echo "\t<option value=\"local_play\" $is_local>" . _("Local") . "</option>\n"; + } + if (conf('allow_stream_playback')) { + echo "\t<option value=\"stream\" $is_stream>" . _("Stream") . "</option>\n"; + } + if (conf('allow_icecast_playback')) { + echo "\t<option value=\"icecast2\" $is_ice>" . _("IceCast") . "</option>\n"; + } + if (conf('allow_downsample_playback')) { + echo "\t<option value=\"downsample\" $is_down>" . _("Downsample") . "</option>\n"; + } + if (conf('allow_mpd_playback')) { + echo "\t<option value=\"mpd\" $is_mpd>" . _("Music Player Daemon") . "</option>\n"; + } + if (conf('allow_slim_playback')) { + echo "\t<option value=\"slim\" $is_slim>" . _("SlimServer") . "</option>\n"; + } + + echo "</select>\n"; + break; + case 'playlist_type': + $var_name = $value . "_type"; + ${$var_name} = "selected=\"selected\""; + echo "<select name=\"$name\">\n"; + echo "\t<option value=\"m3u\" $m3u_type>" . _("M3U") . "</option>\n"; + echo "\t<option value=\"simple_m3u\" $simple_m3u_type>" . _("Simple M3U") . "</option>\n"; + echo "\t<option value=\"pls\" $pls_type>" . _("PLS") . "</option>\n"; + echo "\t<option value=\"asx\" $asx_type>" . _("Asx") . "</option>\n"; + echo "</select>\n"; + break; + case 'lang': + $var_name = $value . "_lang"; + ${$var_name} = "selected=\"selected\""; + echo "<select name=\"$name\">\n"; + echo "\t<option value=\"en_US\" $en_US_lang>" . _("English") . "</option>\n"; + echo "\t<option value=\"de_DE\" $de_DE_lang>" . _("German") . "</option>\n"; + echo "\t<option value=\"fr_FR\" $fr_FR_lang>" . _("French") . "</option>\n"; + echo "\t<option value=\"tr_TR\" $tr_TR_lang>" . _("Turkish") . "</option>\n"; + echo "</select>\n"; + break; + case 'theme_name': + $themes = get_themes(); + echo "<select name=\"$name\">\n"; + foreach ($themes as $theme) { + $is_selected = ""; + if ($value == $theme['path']) { $is_selected = "selected=\"selected\""; } + echo "\t<option value=\"" . $theme['path'] . "\" $is_selected>" . $theme['name'] . "</option>\n"; + } // foreach themes + echo "</select>\n"; + break; + default: + echo "<input type=\"text\" size=\"$len\" name=\"$name\" value=\"$value\" />"; + break; + + } + +} // create_preference_input + +?> diff --git a/lib/rss.php b/lib/rss.php new file mode 100644 index 00000000..efb6cba9 --- /dev/null +++ b/lib/rss.php @@ -0,0 +1,64 @@ +<?php +/* + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +/*! + @function show_now_playingRSS + @discussion creates a RSS fead for the now + playing information +*/ +function show_now_playingRSS () { + + $dbh = dbh(); + $web_path = conf('web_path'); + $rss_main_title = conf('rss_main_title'); + $rss_main_description = conf('rss_main_description'); + $rss_main_copyright = conf('rss_main_copyright'); + $rss_main_language = conf('rss_main_language'); + $rss_song_description = conf('rss_song_description'); + + $sql = "SELECT * FROM now_playing ORDER BY start_time DESC"; + + $db_result = mysql_query($sql, $dbh); + $today = date("d-m-Y"); + + echo "<rss version=\"0.91\">"; + echo "<channel>\n<title>$rss_main_title</title>\n"; + echo "<link>$web_path</link>\n<description>$rss_main_description</description>\n"; + echo "<copyright>$rss_main_copyright</copyright>"; + echo "<pubDate>$today</pubDate>\n<language>$rss_main_language</language>\n"; + + while ($r = mysql_fetch_object($db_result)) { + $song = new Song($r->song_id); + $song->format_song(); + $user = get_user_byid($r->user_id); + if (is_object($song)) { + $artist = $song->f_artist; + $album = $song->get_album_name(); + $text = "$artist - $song->f_title"; + echo "<item> "; + echo " <title><![CDATA[$text]]></title> "; + echo " <link>$web_path/albums.php?action=show&album=$song->album</link>"; + echo " <description>$rss_song_description</description>"; + echo " <pubDate>$today</pubDate>"; + echo "</item>"; + } + } + + echo "</channel>\n</rss>"; +} // show_now_playingRSS +?> diff --git a/lib/search.php b/lib/search.php new file mode 100644 index 00000000..54192750 --- /dev/null +++ b/lib/search.php @@ -0,0 +1,185 @@ +<?php +/* + + Copyright (c) 2004 ampache.org + All rights reserved. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + This library handles all the searching! + +*/ + +/*! + @function run_search + @discussion run a search, takes string,field,type and returns an array + of results of the correct type (song, album, artist) +*/ +function run_search($string,$field,$type) { + + // Clear this so it doesn't try any fanzy view mojo on us + unset($_SESSION['view_script']); + + // Escape input string + $string = sql_escape($string); + + // Switch on the field --> type and setup sql statement + switch ($field === 0 ? '': $field) { + case 'artist': + if ($type === 'fuzzy') { + $sql = "SELECT id FROM artist WHERE name LIKE '%$string%'"; + } + else { + $sql = "SELECT id FROM artist WHERE name ='$string'"; + } + $artists = get_artists($sql, 'format'); + if ($artists) { + show_artists($artists); + } + else { + echo "<div class=\"error\" align=\"center\">" . _("No Results Found") . "</div>"; + } + break; + + case 'album': + if ($type === 'fuzzy') { + $sql = "SELECT id FROM album WHERE name LIKE '%$string%'"; + } + else { + $sql = "SELECT id FROM album WHERE name='$string'"; + } + $albums = get_albums($sql); + if (count($albums)) { + show_albums($albums); + } + else { + echo "<div class=\"error\" align=\"center\">" . _("No Results Found") . "</div>"; + } + break; + + case 'song_title': + if ($type === 'fuzzy') { + $sql = "SELECT id FROM song WHERE title LIKE '%$string%'"; + } + else { + $sql = "SELECT id FROM song WHERE title = '$string'"; + } + $song_ids = get_songs($sql, 'format'); + if ($song_ids) { + show_songs($song_ids); + } + else { + echo "<div class=\"error\" align=\"center\">" . _("No Results Found") . "</div>"; + } + break; + + case 'song_genre': + if ($type === 'fuzzy') { + $sql = "SELECT song.id FROM song,genre WHERE song.genre=genre.id AND genre.name LIKE '%$string%'"; + } + else { + $sql = "SELECT song.id FROM song,genre WHERE song.genre=genre.id AND genre.name='$string'"; + } + $song_ids = get_songs($sql, 'format'); + if ($song_ids) { + show_songs($song_ids); + } + else { + echo "<div class=\"error\" align=\"center\">" . _("No Results Found") . "</div>"; + } + break; + + case 'song_year': + if ($type === 'fuzzy') { + $sql = "SELECT song.id FROM song WHERE song.year LIKE '%$string%'"; + } + else { + $sql = "SELECT song.id FROM song WHERE song.year='$string'"; + } + $song_ids = get_songs($sql, 'format'); + if ($song_ids) { + show_songs($song_ids); + } + else { + echo "<div class=\"error\" align=\"center\">" . _("No Results Found") . "</div>"; + } + break; + + case 'song_length': + case 'song_bitrate': + if ($type === 'fuzzy') { + $sql = "SELECT song.id FROM song WHERE song.bitrate LIKE '%$string%'"; + } + else { + $sql = "SELECT song.id FROM song WHERE song.bitrate='$string'"; + } + $song_ids = get_songs($sql, 'format'); + if ($song_ids) { + show_songs($song_ids); + } + else { + echo "<div class=\"error\" align=\"center\">" . _("No Results Found") . "</div>"; + } + break; + + case 'song_min_bitrate': + $string = $string * 1000; + $sql = "SELECT song.id FROM song WHERE song.bitrate >= '$string'"; + $song_ids = get_songs($sql, 'format'); + if ($song_ids) { + show_songs($song_ids); + } + else { + echo "<div class=\"error\" align=\"center\">" . _("No Results Found") . "</div>"; + } + break; + + case 'song_comment': + if ($type === 'fuzzy') { + $sql = "SELECT song.id FROM song WHERE song.comment LIKE '%$string%'"; + } + else { + $sql = "SELECT song.id FROM song WHERE song.comment='$string'"; + } + $song_ids = get_songs($sql, 'format'); + if ($song_ids) { + show_songs($song_ids); + } + else { + echo "<div class=\"error\" align=\"center\">" . _("No Results Found") . "</div>"; + } + break; + + case 'song_filename': + if ($type === 'fuzzy') { + $sql = "SELECT song.id FROM song WHERE song.file LIKE '%$string%'"; + } + else { + $sql = "SELECT song.id FROM song WHERE song.file='$string'"; + } + $song_ids = get_songs($sql, 'format'); + if ($song_ids) { + show_songs($song_ids); + } + else { + echo "<div class=\"error\" align=\"center\">" . _("No Results Found") . "</div>"; + } + break; + + } // end switch + +} // run_search + +?> diff --git a/lib/song.php b/lib/song.php new file mode 100644 index 00000000..0e847ad9 --- /dev/null +++ b/lib/song.php @@ -0,0 +1,57 @@ +<?php +/* + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +/* + @header Song Library + @discussion This library handles song related functions.... woohoo! + This library is defunt, please try use the song class if possible + +*/ + +/*! + @function get_songs + @discussion pass a sql statement, and it gets full song info and returns + an array of the goods.. can be set to format them as well +*/ +function get_songs($sql, $action=0) { + + $db_results = mysql_query($sql, dbh()); + while ($r = mysql_fetch_array($db_results)) { +// $song_info = get_songinfo($r['id']); +// if ($action === 'format') { $song = format_song($song_info); } +// else { $song = $song_info; } + $results[] = $r['id']; + } + + return $results; + + +} // get_albums + +/*! + @function format_song + @discussion takes a song array and makes it html friendly +*/ +function format_song($song) { + + return $song; + +} // format_song + + +?> diff --git a/lib/themes.php b/lib/themes.php new file mode 100644 index 00000000..ca4a92c7 --- /dev/null +++ b/lib/themes.php @@ -0,0 +1,124 @@ +<?php +/* + + Copyright (c) 2001 - 2005 Ampache.org + All Rights Reserved + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +/*! + @function get_themes() + @discussion this looks in /themes and pulls all of the + theme.cfg.php files it can find and returns an + array of the results +*/ +function get_themes() { + + /* Open the themes dir and start reading it */ + $handle = @opendir(conf('prefix') . "/themes"); + + if (!is_resource($handle)) { + if (conf('debug')) { log_event($_SESSION['userdata']['username'],'theme',"Error unable to open Themes Directory"); } + } + + $results = array(); + + while ($file = readdir($handle)) { + + $full_file = conf('prefix') . "/themes/" . $file; + /* See if it's a directory */ + if (is_dir($full_file) AND substr($file,0,1) != ".") { + $config_file = $full_file . "/theme.cfg.php"; + /* Open the theme.cfg.php file */ + $r = read_config($config_file); + $r['path'] = $file; + $results[] = $r; + } + + } // end while directory + + return $results; + +} // get_themes + +/*! + @function get_theme + @discussion get a single theme and read the config file + then return the results +*/ +function get_theme($name) { + + $config_file = conf('prefix') . "/themes/" . $name . "/theme.cfg.php"; + $results = read_config($config_file); + $results['path'] = $name; + return $results; + +} // get_theme + +/*! + @function set_theme + @discussion Resets all of the colors for this theme +*/ +function set_theme_colors($theme_name,$user_id) { + + /* We assume if we've made it this far we've got the right to do it + This could be dangerous but eah! + */ + $theme = get_theme($theme_name); + if (!count($theme['color'])) { return false; } + + foreach ($theme['color'] as $key=>$color) { + + $sql = "SELECT id FROM preferences WHERE name='" . sql_escape($key) . "'"; + $db_results = mysql_query($sql, dbh()); + + $results = mysql_fetch_array($db_results); + + $sql = "UPDATE user_preference SET `value`='" . sql_escape($color) . "' WHERE `user`='" . $user_id . "' AND " . + " preference='" . $results[0] . "'"; + $db_results = mysql_query($sql, dbh()); + + } // theme colors + +} // set_theme_colors + +/*! + @function set_theme + @discussion this sets the needed vars for the theme +*/ +function set_theme() { + + if (strlen(conf('theme_name')) > 0) { + $theme_path = "/themes/" . conf('theme_name'); + conf(array('theme_path'=>$theme_path),1); + } + +} // set_theme + +/*! + @function get_theme_author + @discussion returns the author of this theme +*/ +function get_theme_author($theme_name) { + + $theme_path = conf('prefix') . "/themes/" . conf('theme_name') . "/theme.cfg.php"; + $results = read_config($theme_path); + + return $results['author']; + +} // get_theme_author +?> diff --git a/lib/ui.php b/lib/ui.php new file mode 100644 index 00000000..bd1bb882 --- /dev/null +++ b/lib/ui.php @@ -0,0 +1,437 @@ +<?php +/* + + Copyright (c) 2001 - 2005 Ampache.org + All rights reserved. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +/*! + @header UI Function Library + This contains functions that are generic, and display information + things like a confirmation box, etc and so forth +*/ + +/*! + @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 +*/ +function show_confirmation($title,$text,$next_url) { + + if (substr_count($next_url,conf('web_path'))) { + $path = $next_url; + } + else { + $path = conf('web_path') . "/$next_url"; + } + + require (conf('prefix') . "/templates/show_confirmation.inc.php"); + +} // show_confirmation + +/*! + @function set_preferences + @discussion legacy function... + //FIXME: Remove References +*/ +function set_preferences() { + + get_preferences(); + return true; + +} // set_preferences + +/*! + @function get_preferences + @discussion reads this users preferences +*/ +function get_preferences($username=0) { + + /* Get System Preferences first */ + $sql = "SELECT preferences.name,user_preference.value FROM preferences,user_preference WHERE user_preference.user='0' " . + " AND user_preference.preference = preferences.id AND preferences.type='system'"; + $db_results = mysql_query($sql, dbh()); + + while ($r = mysql_fetch_object($db_results)) { + $results[$r->name] = $r->value; + } // end while sys prefs + + conf($results, 1); + + unset($results); + + if (!$username) { $username = $_SESSION['userdata']['username']; } + + $user = new User($username); + + $sql = "SELECT preferences.name,user_preference.value FROM preferences,user_preference WHERE user_preference.user='$user->id'" . + " AND user_preference.preference=preferences.id"; + $db_results = mysql_query($sql, dbh()); + + while ($r = mysql_fetch_object($db_results)) { + $results[$r->name] = $r->value; + } + + unset($results['user'], $results['id']); + + conf($results, 1); + +} // 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] +*/ +function flip_class($array=0) { + + static $classes = array(); + + if ($array) { + $classes = $array; + } + else { + $classes = array_reverse($classes); + return $classes[0]; + } + +} // flip_class + +/*! + @function clear_now_playing + @discussion Clears the now playing information incase something has + gotten stuck in there +*/ +function clear_now_playing() { + + $sql = "DELETE FROM now_playing"; + $db_results = mysql_query($sql, dbh()); + + return true; + +} // clear_now_playing + +/*! + @function show_tool_box + @discussion shows the toolbox +*/ +function show_tool_box ($title, $items) { + + include(conf('prefix') . "/templates/tool_box.inc"); + +}// show_tool_box + +/*! + @function show_box + @discussion shows a generic box +*/ +function show_box($title,$items) { + + include(conf('prefix') . "/templates/show_box.inc"); + +} // show_box + +/*! + @function show_menu_items + @discussion shows menu items +*/ +function show_menu_items ($high) { + + include(conf('prefix') . "/templates/menu.inc"); + +} // show_menu_items + +/*! + @function _ + @discussion checks to see if the alias _ is defined + if it isn't it defines it as a simple return +*/ +if (!function_exists('_')) { + function _($string) { + + return $string; + + } // _ +} // if _ isn't defined + +/*! + @function show_playlist_menu + @discussion playlist functions +*/ +function show_playlist_menu () { + + echo "<br /><span class=\"header2\">" . _("Playlist Actions") . ": <a href=\"" . conf('web_path') . "/playlist.php?action=new\">" . _("New") ."</a> | "; + echo "<a href=\"" . conf('web_path') . "/playlist.php\"> " . _("View All") . "</a> | "; + echo "<a href=\"" . conf('web_path') . "/playlist.php?action=show_import_playlist\"> " . _("Import") . "</a>"; + echo "</span><br /><br />"; + +} // show_playlist_menu + +/*! + @function show_admin_menu + @discussion 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 +*/ +function access_denied() { + + show_template('style'); + show_footer(); + echo "<br /><br /><br />"; + echo "<div class=\"fatalerror\">Error Access Denied</div>\n"; + show_footer(); + exit(); + +} // access_denied + +/*! + @function show_users + @discussion shows all users (admin function) +*/ +function show_users () { + + $dbh = dbh(); + + // Setup the View Ojbect + $view = new View(); + $view->import_session_view(); + + // if we are returning + if ($_REQUEST['keep_view']) { + $view->initialize(); + } + // If we aren't keeping the view then initlize it + else { + $sql = "SELECT username FROM user"; + $db_results = mysql_query($sql, $dbh); + $total_items = mysql_num_rows($db_results); + if ($match != "Show_all") { $offset_limit = $_SESSION['userdata']['offset_limit']; } + $view = new View($sql, 'admin/users.php','fullname',$total_items,$offset_limit); + } + + $db_result = mysql_query($view->sql, $dbh); + + require(conf('prefix') . "/templates/show_users.inc"); + +} // show_users() + + +/*! + @function return_referer + @discussion 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'])) . "/"; + $next = str_replace($web_path,"",$_SERVER['HTTP_REFERER']); + + // If there is more than one :// we know it's fudged + // and just return the index + if (substr_count($next,"://") > 1) { + return "index.php"; + } + + return $next; + +} // return_referer + +/*! + @function show_alphabet_list + @discussion 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"); + + $style_name = "style_" . strtolower($selected); + ${$style_name} = "style=\"font-weight:bold;\""; + + echo "<div class=\"alphabet\">"; + foreach ($list as $l) { + $style_name = "style_" . strtolower($l); + echo "<a href=\"". conf('web_path') ."/$script?action=match&match=$l\" " . ${$style_name} . ">$l</a> | \n"; + } + + echo " <a href=\"". conf('web_path') ."/$script?action=match&match=Browse\" $style_browse>" . _("Browse") . "</a> | \n"; + if ($script == "albums.php") { + echo " <a href=\"". conf('web_path') ."/$script?action=match&match=Show_missing_art\" $style_show_missing_art>" . _("Show w/o art") . "</a> | \n"; + } // if we are on the albums page + + echo " <a href=\"". conf('web_path') ."/$script?action=match&match=Show_all\" $style_show_all>" . _("Show all") . "</a>"; + + echo "</div>\n"; +} // show_alphabet_list + +/*! + @function show_local_control + @discussion shows the controls + for localplay +*/ +function show_local_control () { + + require_once(conf('prefix') . "/templates/show_localplay.inc"); + +} // 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) +*/ +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'), "..."); + } + } + /* 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 + +/*! + @function show_footer + @discussion shows the footer of the page +*/ +function show_footer() { + $class = "table-header"; + echo "<br /><br /><br /><div class=\"$class\" style=\"border: solid thin black;\"> </div>"; +} // show_footer + +/*! + @function show_now_playing + @discussion shows the now playing template +*/ +function show_now_playing() { + + $dbh = dbh(); + $web_path = conf('web_path'); + $results = get_now_playing(); + require (conf('prefix') . "/templates/show_now_playing.inc"); + +} // 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 +function show_user_registration ($values=array()) { + + require (conf('prefix') . "/templates/show_user_registration.inc.php"); + +} // show_user_registration + +/*! + @function show_edit_profile + @discussion shows a single user profile for editing +*/ +function show_edit_profile($username) { + + $this_user = new User($username); + + require (conf('prefix') . "/templates/show_user.inc.php"); + +} // show_edit_profile + +/*! + @function show_playlist + @discussion this shows the current playlist +*/ +function show_playlist($playlist_id) { + + /* Create the Playlist */ + $playlist = new Playlist($playlist_id); + $song_ids = $playlist->get_songs(); + + if (count($song_ids) > 0) { + show_songs($song_ids, $playlist->id); + } + else { + echo "<p>" . _("No songs in this playlist.") . "</p>\n"; + } + +} // show_playlist + +/*! + @function show_play_selected + @discussion 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"); + +} // show_play_selected + +/*! + @function get_now_playing + @discussion gets the now playing information +*/ +function get_now_playing() { + + $sql = "SELECT song_id,user_id FROM now_playing ORDER BY start_time DESC"; + $db_results = mysql_query($sql, dbh()); + while ($r = mysql_fetch_assoc($db_results)) { + $song = new Song($r['song_id']); + $song->format_song(); + $np_user = new User(0,$r['user_id']); + $results[] = array('song'=>$song,'user'=>$np_user); + } // end while + return $results; + +} // get_now_playing + +/*! + @function show_clear + @discussion this is a hack because of the float mojo +*/ +function show_clear() { + + echo "\n<div style=\"clear:both;\"> </div>\n"; + +} // show_clear + +?> diff --git a/lib/xmlrpc.php b/lib/xmlrpc.php new file mode 100644 index 00000000..7b810dd6 --- /dev/null +++ b/lib/xmlrpc.php @@ -0,0 +1,143 @@ +<?php +/* + + Copyright (c) 2004 Ampache.org + All rights reserved. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +/*! + @header XML-RPC Library + @discussion If you want an honest answer NFC. Copy and paste baby! +*/ + +/*! + @function remote_server_query + @discussion don't ask don't tell +*/ +function remote_server_query($m) { + + $result = array(); + + // we only want to send the local entries + $sql = "SELECT name FROM catalog WHERE catalog_type='local'"; + $db_result = mysql_query($sql, dbh()); + + while ( $i = mysql_fetch_row($db_result) ) { + $result[] = $i; + } + + + set_time_limit(0); + $encoded_array = new xmlrpcval($result); + log_event($_SESSION['userdata']['username'],'xml-rpc_encoded',$encoded_array); + return new xmlrpcresp($encoded_array); + return $result; + +} // remote_server_query + +/*! + @function remote_song_query + @discussion return all local songs and their + information +*/ +function remote_song_query() { + + + //FIXME: We should add catalog level access control + + // Get me a list of all local catalogs + $sql = "SELECT catalog.id FROM catalog WHERE catalog_type='local'"; + $db_results = mysql_query($sql, dbh()); + + $results = array(); + //FIXME: enabled --> smallint(1) T/F boolean mojo + $sql = "SELECT song.id FROM song WHERE song.status='enabled' AND"; + + // Get the catalogs and build the query! + while ($r = mysql_fetch_object($db_results)) { + if (preg_match("/catalog/",$sql)) { + $sql .= " OR song.catalog='$r->id'"; + } + else { + $sql .= " song.catalog='$r->id'"; + } + } // build query + + $db_results = mysql_query($sql, dbh()); + + // Recurse through the songs and build a results + // array that is base64_encoded + while ($r = mysql_fetch_object($db_results)) { + + $song = new Song($r->id); + $song->album = $song->get_album_name(); + $song->artist = $song->get_artist_name(); + $song->genre = $song->get_genre_name(); + + // Format the output + $output = ''; + $output = $song->artist . "::" . $song->album . "::" . $song->title . "::" . $song->comment . + "::" . $song->year . "::" . $song->bitrate . "::" . $song->rate . "::" . $song->mode . + "::" . $song->size . "::" . $song->time . "::" . $song->track . "::" . $song->genre . "::" . $r->id; + $output = base64_encode($output); + $results[] = $output; + + // Prevent Timeout + set_time_limit(0); + + } // while songs + + set_time_limit(0); + $encoded_array = old_xmlrpc_encode($results); + return new xmlrpcresp($encoded_array); + +} // remote_song_query + +/*! + @function remote_server_denied + @discussion Access Denied Sucka! +*/ +function remote_server_denied() { + + $result = array(); + + $result['access_denied'] = "Access Denied: Sorry, but " . $_SERVER['REMOTE_ADDR'] . " does not have access to " . + "this server's catalog. Please make sure that you have been added to this server's access list.\n"; + + $encoded_array = old_xmlrpc_encode($result); + return new xmlrpcresp($encoded_array); + +} // remote_server_deniee + + + + + + + + + + + + + + + + + +?> |