diff options
Diffstat (limited to 'pear')
| -rw-r--r-- | pear/Makefile.frag | 4 | ||||
| -rw-r--r-- | pear/install-pear-nozlib.phar | 32107 |
2 files changed, 16398 insertions, 15713 deletions
diff --git a/pear/Makefile.frag b/pear/Makefile.frag index e036dcbaa..1f6f70ec0 100644 --- a/pear/Makefile.frag +++ b/pear/Makefile.frag @@ -7,9 +7,11 @@ PEAR_INSTALL_FLAGS = -n -dshort_open_tag=0 -dsafe_mode=0 -dopen_basedir= -derror WGET = `which wget 2>/dev/null` FETCH = `which fetch 2>/dev/null` +PEAR_PREFIX = -dp a${program_prefix} +PEAR_SUFFIX = -ds a$(program_suffix) install-pear-installer: $(SAPI_CLI_PATH) - @$(top_builddir)/sapi/cli/php $(PEAR_INSTALL_FLAGS) $(builddir)/install-pear-nozlib.phar -d "$(peardir)" -b "$(bindir)" + @$(top_builddir)/sapi/cli/php $(PEAR_INSTALL_FLAGS) pear/install-pear-nozlib.phar -d "$(peardir)" -b "$(bindir)" ${PEAR_PREFIX} ${PEAR_SUFFIX} install-pear: @echo "Installing PEAR environment: $(INSTALL_ROOT)$(peardir)/" diff --git a/pear/install-pear-nozlib.phar b/pear/install-pear-nozlib.phar index 81f77ebe9..33424482c 100644 --- a/pear/install-pear-nozlib.phar +++ b/pear/install-pear-nozlib.phar @@ -1234,27 +1234,54 @@ if (extension_loaded('phar')) {if (isset($_SERVER) && isset($_SERVER['REQUEST_UR require_once 'phar://install-pear-nozlib.phar/index.php'; -__HALT_COMPILER();Ú
-Žm - -/* vim: set ts=4 sw=4: */ -// +----------------------------------------------------------------------+ -// | PHP Version 4 | -// +----------------------------------------------------------------------+ -// | Copyright (c) 1997-2003 The PHP Group | -// +----------------------------------------------------------------------+ -// | This source file is subject to version 3.0 of the PHP license, | -// | that is bundled with this package in the file LICENSE, and is | -// | available through the world-wide-web at the following url: | -// | http://www.php.net/license/3_0.txt. | -// | If you did not receive a copy of the PHP license and are unable to | -// | obtain it through the world-wide-web, please send a note to | -// | license@php.net so we can mail you a copy immediately. | -// +----------------------------------------------------------------------+ -// | Author: Vincent Blavet <vincent@phpconcept.net> | -// +----------------------------------------------------------------------+ -// -// $Id: Tar.php,v 1.24 2007/01/06 04:03:32 cellog Exp $ +__HALT_COMPILER();ÿ
+m +2 +2 + + +Žm + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * File::CSV + * + * PHP versions 4 and 5 + * + * Copyright (c) 1997-2008, + * Vincent Blavet <vincent@phpconcept.net> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + * @category File_Formats + * @package Archive_Tar + * @author Vincent Blavet <vincent@phpconcept.net> + * @copyright 1997-2008 The Authors + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: Tar.php 287963 2009-09-02 08:18:55Z mrook $ + * @link http://pear.php.net/package/Archive_Tar + */ require_once 'phar://install-pear-nozlib.phar/' . 'PEAR.php'; @@ -1266,8 +1293,9 @@ define ('ARCHIVE_TAR_END_BLOCK', pack("a512", '')); * Creates a (compressed) Tar archive * * @author Vincent Blavet <vincent@phpconcept.net> -* @version $Revision: 1.24 $ -* @package Archive +* @version $Revision: 287963 $ +* @license http://www.opensource.org/licenses/bsd-license.php New BSD License +* @package Archive_Tar */ class Archive_Tar extends PEAR { @@ -1356,7 +1384,7 @@ class Archive_Tar extends PEAR $this->_compress = true; $this->_compress_type = 'bz2'; } else { - die("Unsupported compression type '$p_compress'\n". + $this->_error("Unsupported compression type '$p_compress'\n". "Supported types are 'gz' and 'bz2'.\n"); return false; } @@ -1372,7 +1400,7 @@ class Archive_Tar extends PEAR PEAR::loadExtension($extname); } if (!extension_loaded($extname)) { - die("The extension '$extname' couldn't be found.\n". + $this->_error("The extension '$extname' couldn't be found.\n". "Please make sure your version of PHP was built ". "with '$extname' support.\n"); return false; @@ -1615,14 +1643,14 @@ class Archive_Tar extends PEAR function addString($p_filename, $p_string) { $v_result = true; - + if (!$this->_isArchive()) { if (!$this->_openWrite()) { return false; } $this->_close(); } - + if (!$this->_openAppend()) return false; @@ -1762,12 +1790,12 @@ class Archive_Tar extends PEAR function setAttribute() { $v_result = true; - + // ----- Get the number of variable list of arguments if (($v_size = func_num_args()) == 0) { return true; } - + // ----- Get the arguments $v_att_list = &func_get_args(); @@ -1827,7 +1855,7 @@ class Archive_Tar extends PEAR $p_filename = $this->_tarname; } clearstatcache(); - return @is_file($p_filename); + return @is_file($p_filename) && !@is_link($p_filename); } // }}} @@ -1837,7 +1865,7 @@ class Archive_Tar extends PEAR if ($this->_compress_type == 'gz') $this->_file = @gzopen($this->_tarname, "wb9"); else if ($this->_compress_type == 'bz2') - $this->_file = @bzopen($this->_tarname, "wb"); + $this->_file = @bzopen($this->_tarname, "w"); else if ($this->_compress_type == 'none') $this->_file = @fopen($this->_tarname, "wb"); else @@ -1890,7 +1918,7 @@ class Archive_Tar extends PEAR if ($this->_compress_type == 'gz') $this->_file = @gzopen($v_filename, "rb"); else if ($this->_compress_type == 'bz2') - $this->_file = @bzopen($v_filename, "rb"); + $this->_file = @bzopen($v_filename, "r"); else if ($this->_compress_type == 'none') $this->_file = @fopen($v_filename, "rb"); else @@ -1911,9 +1939,11 @@ class Archive_Tar extends PEAR { if ($this->_compress_type == 'gz') $this->_file = @gzopen($this->_tarname, "r+b"); - else if ($this->_compress_type == 'bz2') - $this->_file = @bzopen($this->_tarname, "r+b"); - else if ($this->_compress_type == 'none') + else if ($this->_compress_type == 'bz2') { + $this->_error('Unable to open bz2 in read/write mode \'' + .$this->_tarname.'\' (limitation of bz2 extension)'); + return false; + } else if ($this->_compress_type == 'none') $this->_file = @fopen($this->_tarname, "r+b"); else $this->_error('Unknown or missing compression type (' @@ -2104,7 +2134,7 @@ class Archive_Tar extends PEAR if (!$this->_addFile($v_filename, $v_header, $p_add_dir, $p_remove_dir)) return false; - if (@is_dir($v_filename)) { + if (@is_dir($v_filename) && !@is_link($v_filename)) { if (!($p_hdir = opendir($v_filename))) { $this->_warning("Directory '$v_filename' can not be read"); continue; @@ -2237,31 +2267,45 @@ class Archive_Tar extends PEAR return false; } - $v_info = stat($p_filename); - $v_uid = sprintf("%6s ", DecOct($v_info[4])); - $v_gid = sprintf("%6s ", DecOct($v_info[5])); - $v_perms = sprintf("%6s ", DecOct(fileperms($p_filename))); + $v_info = lstat($p_filename); + $v_uid = sprintf("%07s", DecOct($v_info[4])); + $v_gid = sprintf("%07s", DecOct($v_info[5])); + $v_perms = sprintf("%07s", DecOct($v_info['mode'] & 000777)); - $v_mtime = sprintf("%11s", DecOct(filemtime($p_filename))); + $v_mtime = sprintf("%011s", DecOct($v_info['mtime'])); + + $v_linkname = ''; - if (@is_dir($p_filename)) { + if (@is_link($p_filename)) { + $v_typeflag = '2'; + $v_linkname = readlink($p_filename); + $v_size = sprintf("%011s", DecOct(0)); + } elseif (@is_dir($p_filename)) { $v_typeflag = "5"; - $v_size = sprintf("%11s ", DecOct(0)); + $v_size = sprintf("%011s", DecOct(0)); } else { - $v_typeflag = ''; + $v_typeflag = '0'; clearstatcache(); - $v_size = sprintf("%11s ", DecOct(filesize($p_filename))); + $v_size = sprintf("%011s", DecOct($v_info['size'])); } - $v_linkname = ''; - - $v_magic = ''; - - $v_version = ''; + $v_magic = 'ustar '; - $v_uname = ''; - - $v_gname = ''; + $v_version = ' '; + + if (function_exists('posix_getpwuid')) + { + $userinfo = posix_getpwuid($v_info[4]); + $groupinfo = posix_getgrgid($v_info[5]); + + $v_uname = $userinfo['name']; + $v_gname = $groupinfo['name']; + } + else + { + $v_uname = ''; + $v_gname = ''; + } $v_devmajor = ''; @@ -2269,7 +2313,7 @@ class Archive_Tar extends PEAR $v_prefix = ''; - $v_binary_data_first = pack("a100a8a8a8a12A12", + $v_binary_data_first = pack("a100a8a8a8a12a12", $v_reduce_filename, $v_perms, $v_uid, $v_gid, $v_size, $v_mtime); $v_binary_data_last = pack("a1a100a6a2a32a32a8a8a155a12", @@ -2293,7 +2337,7 @@ class Archive_Tar extends PEAR $this->_writeBlock($v_binary_data_first, 148); // ----- Write the calculated checksum - $v_checksum = sprintf("%6s ", DecOct($v_checksum)); + $v_checksum = sprintf("%06s ", DecOct($v_checksum)); $v_binary_data = pack("a8", $v_checksum); $this->_writeBlock($v_binary_data, 8); @@ -2316,27 +2360,37 @@ class Archive_Tar extends PEAR } if ($p_type == "5") { - $v_size = sprintf("%11s ", DecOct(0)); + $v_size = sprintf("%011s", DecOct(0)); } else { - $v_size = sprintf("%11s ", DecOct($p_size)); + $v_size = sprintf("%011s", DecOct($p_size)); } - $v_uid = sprintf("%6s ", DecOct($p_uid)); - $v_gid = sprintf("%6s ", DecOct($p_gid)); - $v_perms = sprintf("%6s ", DecOct($p_perms)); + $v_uid = sprintf("%07s", DecOct($p_uid)); + $v_gid = sprintf("%07s", DecOct($p_gid)); + $v_perms = sprintf("%07s", DecOct($p_perms & 000777)); $v_mtime = sprintf("%11s", DecOct($p_mtime)); $v_linkname = ''; - $v_magic = ''; - - $v_version = ''; + $v_magic = 'ustar '; - $v_uname = ''; - - $v_gname = ''; + $v_version = ' '; + if (function_exists('posix_getpwuid')) + { + $userinfo = posix_getpwuid($p_uid); + $groupinfo = posix_getgrgid($p_gid); + + $v_uname = $userinfo['name']; + $v_gname = $groupinfo['name']; + } + else + { + $v_uname = ''; + $v_gname = ''; + } + $v_devmajor = ''; $v_devminor = ''; @@ -2367,7 +2421,7 @@ class Archive_Tar extends PEAR $this->_writeBlock($v_binary_data_first, 148); // ----- Write the calculated checksum - $v_checksum = sprintf("%6s ", DecOct($v_checksum)); + $v_checksum = sprintf("%06s ", DecOct($v_checksum)); $v_binary_data = pack("a8", $v_checksum); $this->_writeBlock($v_binary_data, 8); @@ -2401,7 +2455,7 @@ class Archive_Tar extends PEAR $v_prefix = ''; - $v_binary_data_first = pack("a100a8a8a8a12A12", + $v_binary_data_first = pack("a100a8a8a8a12a12", '././@LongLink', 0, 0, 0, $v_size, 0); $v_binary_data_last = pack("a1a100a6a2a32a32a8a8a155a12", $v_typeflag, $v_linkname, $v_magic, @@ -2424,7 +2478,7 @@ class Archive_Tar extends PEAR $this->_writeBlock($v_binary_data_first, 148); // ----- Write the calculated checksum - $v_checksum = sprintf("%6s ", DecOct($v_checksum)); + $v_checksum = sprintf("%06s ", DecOct($v_checksum)); $v_binary_data = pack("a8", $v_checksum); $this->_writeBlock($v_binary_data, 8); @@ -2492,7 +2546,7 @@ class Archive_Tar extends PEAR } // ----- Extract the properties - $v_header['filename'] = trim($v_data['filename']); + $v_header['filename'] = $v_data['filename']; if ($this->_maliciousFilename($v_header['filename'])) { $this->_error('Malicious .tar detected, file "' . $v_header['filename'] . '" will not install in desired directory tree'); @@ -2552,7 +2606,7 @@ class Archive_Tar extends PEAR } if (($v_header['size'] % 512) != 0) { $v_content = $this->_readBlock(); - $v_filename .= $v_content; + $v_filename .= trim($v_content); } // ----- Read the next header @@ -2561,6 +2615,7 @@ class Archive_Tar extends PEAR if (!$this->_readHeader($v_binary_data, $v_header)) return false; + $v_filename = trim($v_filename); $v_header['filename'] = $v_filename; if ($this->_maliciousFilename($v_filename)) { $this->_error('Malicious .tar detected, file "' . $v_filename . @@ -2768,6 +2823,9 @@ class Archive_Tar extends PEAR } } } elseif ($v_header['typeflag'] == "2") { + if (@file_exists($v_header['filename'])) { + @unlink($v_header['filename']); + } if (!@symlink($v_header['link'], $v_header['filename'])) { $this->_error('Unable to extract symbolic link {' .$v_header['filename'].'}'); @@ -2849,7 +2907,7 @@ class Archive_Tar extends PEAR { if (filesize($this->_tarname) == 0) return $this->_openWrite(); - + if ($this->_compress) { $this->_close(); @@ -2863,8 +2921,8 @@ class Archive_Tar extends PEAR if ($this->_compress_type == 'gz') $v_temp_tar = @gzopen($this->_tarname.".tmp", "rb"); elseif ($this->_compress_type == 'bz2') - $v_temp_tar = @bzopen($this->_tarname.".tmp", "rb"); - + $v_temp_tar = @bzopen($this->_tarname.".tmp", "r"); + if ($v_temp_tar == 0) { $this->_error('Unable to open file \''.$this->_tarname .'.tmp\' in binary read mode'); @@ -2918,14 +2976,14 @@ class Archive_Tar extends PEAR $v_size = filesize($this->_tarname); // We might have zero, one or two end blocks. - // The standard is two, but we should try to handle + // The standard is two, but we should try to handle // other cases. fseek($this->_file, $v_size - 1024); if (fread($this->_file, 512) == ARCHIVE_TAR_END_BLOCK) { fseek($this->_file, $v_size - 1024); } elseif (fread($this->_file, 512) == ARCHIVE_TAR_END_BLOCK) { - fseek($this->_file, $v_size - 512); + fseek($this->_file, $v_size - 512); } } @@ -2938,7 +2996,7 @@ class Archive_Tar extends PEAR { if (!$this->_openAppend()) return false; - + if ($this->_addList($p_filelist, $p_add_dir, $p_remove_dir)) $this->_writeFooter(); @@ -2984,7 +3042,7 @@ class Archive_Tar extends PEAR // {{{ _pathReduction() /** - * Compress path by changing for example "/dir/foo/../bar" to "/dir/bar", + * Compress path by changing for example "/dir/foo/../bar" to "/dir/bar", * rand emove double slashes. * * @param string $p_dir path to reduce @@ -5764,33 +5822,43 @@ Correct Bug #9352 Bug on _dirCheck function over nfs path </package> /* vim: set expandtab tabstop=4 shiftwidth=4: */ -// +----------------------------------------------------------------------+ -// | PHP Version 5 | -// +----------------------------------------------------------------------+ -// | Copyright (c) 1997-2004 The PHP Group | -// +----------------------------------------------------------------------+ -// | This source file is subject to version 3.0 of the PHP license, | -// | that is bundled with this package in the file LICENSE, and is | -// | available through the world-wide-web at the following url: | -// | http://www.php.net/license/3_0.txt. | -// | If you did not receive a copy of the PHP license and are unable to | -// | obtain it through the world-wide-web, please send a note to | -// | license@php.net so we can mail you a copy immediately. | -// +----------------------------------------------------------------------+ -// | Author: Andrei Zmievski <andrei@php.net> | -// +----------------------------------------------------------------------+ -// -// $Id: Getopt.php,v 1.32 2007/02/18 04:13:07 cellog Exp $ +/** + * Color.php + * + * PHP Version 5 + * + * Copyright (c) 1997-2004 The PHP Group + * + * This source file is subject to version 3.0 of the PHP license, + * that is bundled with this package in the file LICENSE, and is + * available through the world-wide-web at the following url: + * http://www.php.net/license/3_0.txt. + * If you did not receive a copy of the PHP license and are unable to + * obtain it through the world-wide-web, please send a note to + * license@php.net so we can mail you a copy immediately. + * + * @category Console + * @package Console_Getopt + * @author Andrei Zmievski <andrei@php.net> + * @license http://www.php.net/license/3_0.txt PHP 3.0 + * @version CVS: $Id: Getopt.php 267328 2008-10-14 18:53:25Z andrei $ + * @link http://pear.php.net/package/Console_Getopt + */ require_once 'phar://install-pear-nozlib.phar/' . 'PEAR.php'; /** * Command-line options parsing class. * - * @author Andrei Zmievski <andrei@php.net> - * + * @category Console + * @package Console_Getopt + * @author Andrei Zmievski <andrei@php.net> + * @license http://www.php.net/license/3_0.txt PHP 3.0 + * @link http://pear.php.net/package/Console_Getopt */ -class Console_Getopt { +class Console_Getopt +{ + /** * Parses the command-line options. * @@ -5817,15 +5885,13 @@ class Console_Getopt { * * Most of the semantics of this function are based on GNU getopt_long(). * - * @param array $args an array of command-line arguments - * @param string $short_options specifies the list of allowed short options - * @param array $long_options specifies the list of allowed long options + * @param array $args an array of command-line arguments + * @param string $short_options specifies the list of allowed short options + * @param array $long_options specifies the list of allowed long options * * @return array two-element array containing the list of parsed options and * the non-option arguments - * * @access public - * */ function getopt2($args, $short_options, $long_options = null) { @@ -5835,7 +5901,14 @@ class Console_Getopt { /** * This function expects $args to start with the script name (POSIX-style). * Preserved for backwards compatibility. + * + * @param array $args an array of command-line arguments + * @param string $short_options specifies the list of allowed short options + * @param array $long_options specifies the list of allowed long options + * * @see getopt2() + * @return array two-element array containing the list of parsed options and + * the non-option arguments */ function getopt($args, $short_options, $long_options = null) { @@ -5844,6 +5917,13 @@ class Console_Getopt { /** * The actual implementation of the argument parsing code. + * + * @param int $version Version to use + * @param array $args an array of command-line arguments + * @param string $short_options specifies the list of allowed short options + * @param array $long_options specifies the list of allowed long options + * + * @return array */ function doGetopt($version, $args, $short_options, $long_options = null) { @@ -5884,17 +5964,28 @@ class Console_Getopt { break; } - if ($arg{0} != '-' || (strlen($arg) > 1 && $arg{1} == '-' && !$long_options)) { + if ($arg{0} != '-' || (strlen($arg) > 1 && $arg{1} == '-' + && !$long_options)) { $non_opts = array_merge($non_opts, array_slice($args, $i)); break; } elseif (strlen($arg) > 1 && $arg{1} == '-') { - $error = Console_Getopt::_parseLongOption(substr($arg, 2), $long_options, $opts, $args); - if (PEAR::isError($error)) + $error = Console_Getopt::_parseLongOption(substr($arg, 2), + $long_options, $opts, + $args); + if (PEAR::isError($error)) { return $error; + } + } elseif ($arg == '-') { + // - is stdin + $non_opts = array_merge($non_opts, array_slice($args, $i)); + break; } else { - $error = Console_Getopt::_parseShortOption(substr($arg, 1), $short_options, $opts, $args); - if (PEAR::isError($error)) + $error = Console_Getopt::_parseShortOption(substr($arg, 1), + $short_options, $opts, + $args); + if (PEAR::isError($error)) { return $error; + } } } @@ -5902,19 +5993,27 @@ class Console_Getopt { } /** - * @access private + * Parse short option + * + * @param string $arg Argument + * @param string[] $short_options Available short options + * @param string[][] &$opts + * @param string[] &$args * + * @access private + * @return void */ function _parseShortOption($arg, $short_options, &$opts, &$args) { for ($i = 0; $i < strlen($arg); $i++) { - $opt = $arg{$i}; + $opt = $arg{$i}; $opt_arg = null; /* Try to find the short option in the specifier string. */ - if (($spec = strstr($short_options, $opt)) === false || $arg{$i} == ':') - { - return PEAR::raiseError("Console_Getopt: unrecognized option -- $opt"); + if (($spec = strstr($short_options, $opt)) === false + || $arg{$i} == ':') { + $msg = "Console_Getopt: unrecognized option -- $opt"; + return PEAR::raiseError($msg); } if (strlen($spec) > 1 && $spec{1} == ':') { @@ -5933,11 +6032,14 @@ class Console_Getopt { break; } else if (list(, $opt_arg) = each($args)) { /* Else use the next argument. */; - if (Console_Getopt::_isShortOpt($opt_arg) || Console_Getopt::_isLongOpt($opt_arg)) { - return PEAR::raiseError("Console_Getopt: option requires an argument -- $opt"); + if (Console_Getopt::_isShortOpt($opt_arg) + || Console_Getopt::_isLongOpt($opt_arg)) { + $msg = "option requires an argument --$opt"; + return PEAR::raiseError("Console_Getopt:" . $msg); } } else { - return PEAR::raiseError("Console_Getopt: option requires an argument -- $opt"); + $msg = "option requires an argument --$opt"; + return PEAR::raiseError("Console_Getopt:" . $msg); } } } @@ -5947,36 +6049,54 @@ class Console_Getopt { } /** - * @access private + * Checks if an argument is a short option + * + * @param string $arg Argument to check * + * @access private + * @return bool */ function _isShortOpt($arg) { - return strlen($arg) == 2 && $arg[0] == '-' && preg_match('/[a-zA-Z]/', $arg[1]); + return strlen($arg) == 2 && $arg[0] == '-' + && preg_match('/[a-zA-Z]/', $arg[1]); } /** - * @access private + * Checks if an argument is a long option + * + * @param string $arg Argument to check * + * @access private + * @return bool */ function _isLongOpt($arg) { return strlen($arg) > 2 && $arg[0] == '-' && $arg[1] == '-' && - preg_match('/[a-zA-Z]+$/', substr($arg, 2)); + preg_match('/[a-zA-Z]+$/', substr($arg, 2)); } /** - * @access private + * Parse long option + * + * @param string $arg Argument + * @param string[] $long_options Available long options + * @param string[][] &$opts + * @param string[] &$args * + * @access private + * @return void|PEAR_Error */ function _parseLongOption($arg, $long_options, &$opts, &$args) { @list($opt, $opt_arg) = explode('=', $arg, 2); + $opt_len = strlen($opt); for ($i = 0; $i < count($long_options); $i++) { $long_opt = $long_options[$i]; $opt_start = substr($long_opt, 0, $opt_len); + $long_opt_name = str_replace('=', '', $long_opt); /* Option doesn't match. Go on to the next one. */ @@ -5984,17 +6104,24 @@ class Console_Getopt { continue; } - $opt_rest = substr($long_opt, $opt_len); + $opt_rest = substr($long_opt, $opt_len); /* Check that the options uniquely matches one of the allowed options. */ - $next_option_rest = substr($long_options[$i + 1], $opt_len); + if ($i + 1 < count($long_options)) { + $next_option_rest = substr($long_options[$i + 1], $opt_len); + } else { + $next_option_rest = ''; + } + if ($opt_rest != '' && $opt{0} != '=' && $i + 1 < count($long_options) && $opt == substr($long_options[$i+1], 0, $opt_len) && $next_option_rest != '' && $next_option_rest{0} != '=') { - return PEAR::raiseError("Console_Getopt: option --$opt is ambiguous"); + + $msg = "Console_Getopt: option --$opt is ambiguous"; + return PEAR::raiseError($msg); } if (substr($long_opt, -1) == '=') { @@ -6002,11 +6129,19 @@ class Console_Getopt { /* Long option requires an argument. Take the next argument if one wasn't specified. */; if (!strlen($opt_arg) && !(list(, $opt_arg) = each($args))) { - return PEAR::raiseError("Console_Getopt: option --$opt requires an argument"); + $msg = "Console_Getopt: option requires an argument --$opt"; + return PEAR::raiseError($msg); + } + + if (Console_Getopt::_isShortOpt($opt_arg) + || Console_Getopt::_isLongOpt($opt_arg)) { + $msg = "Console_Getopt: option requires an argument --$opt"; + return PEAR::raiseError($msg); } } } else if ($opt_arg) { - return PEAR::raiseError("Console_Getopt: option --$opt doesn't allow an argument"); + $msg = "Console_Getopt: option --$opt doesn't allow an argument"; + return PEAR::raiseError($msg); } $opts[] = array('--' . $opt, $opt_arg); @@ -6017,19 +6152,20 @@ class Console_Getopt { } /** - * Safely read the $argv PHP array across different PHP configurations. - * Will take care on register_globals and register_argc_argv ini directives - * - * @access public - * @return mixed the $argv PHP array or PEAR error if not registered - */ + * Safely read the $argv PHP array across different PHP configurations. + * Will take care on register_globals and register_argc_argv ini directives + * + * @access public + * @return mixed the $argv PHP array or PEAR error if not registered + */ function readPHPArgv() { global $argv; if (!is_array($argv)) { if (!@is_array($_SERVER['argv'])) { if (!@is_array($GLOBALS['HTTP_SERVER_VARS']['argv'])) { - return PEAR::raiseError("Console_Getopt: Could not read cmd args (register_argc_argv=Off?)"); + $msg = "Could not read cmd args (register_argc_argv=Off?)"; + return PEAR::raiseError("Console_Getopt: " . $msg); } return $GLOBALS['HTTP_SERVER_VARS']['argv']; } @@ -6486,278 +6622,307 @@ class Console_Getopt { } ?> - -
-/* $Id: install-pear.php,v 1.37 2009/02/16 00:46:55 dufuz Exp $ */
-
-error_reporting(1803);
-
-if (ini_get('date.timezone') === '' && function_exists('date_default_timezone_set')) {
- date_default_timezone_set('UTC');
-}
-
-$pear_dir = dirname(__FILE__);
-ini_set('include_path', '');
-if (function_exists('mb_internal_encoding')) {
- mb_internal_encoding('ASCII');
-}
-set_time_limit(0);
-include_once 'phar://install-pear-nozlib.phar/PEAR.php';
-include_once 'phar://install-pear-nozlib.phar/PEAR/Installer.php';
-include_once 'phar://install-pear-nozlib.phar/PEAR/Registry.php';
-include_once 'phar://install-pear-nozlib.phar/PEAR/PackageFile.php';
-include_once 'phar://install-pear-nozlib.phar/PEAR/Downloader/Package.php';
-include_once 'phar://install-pear-nozlib.phar/PEAR/Frontend.php';
-$a = true;
-if (!PEAR::loadExtension('xml')) {
- $a = false;
- echo "[PEAR] xml extension is required\n";
-}
-if (!PEAR::loadExtension('pcre')) {
- $a = false;
- echo "[PEAR] pcre extension is required\n";
-}
-if (!$a) {
- return -1;
-}
-
-$force = false;
+ + +/* $Id: install-pear.php 287906 2009-08-30 20:43:17Z dufuz $ */ + +error_reporting(1803); + +if (ini_get('date.timezone') === '' && function_exists('date_default_timezone_set')) { + date_default_timezone_set('UTC'); +} + +$pear_dir = dirname(__FILE__); +ini_set('include_path', ''); +if (function_exists('mb_internal_encoding')) { + mb_internal_encoding('ASCII'); +} +set_time_limit(0); +include_once 'phar://install-pear-nozlib.phar/PEAR.php'; +include_once 'phar://install-pear-nozlib.phar/PEAR/Installer.php'; +include_once 'phar://install-pear-nozlib.phar/PEAR/Registry.php'; +include_once 'phar://install-pear-nozlib.phar/PEAR/PackageFile.php'; +include_once 'phar://install-pear-nozlib.phar/PEAR/Downloader/Package.php'; +include_once 'phar://install-pear-nozlib.phar/PEAR/Frontend.php'; +$a = true; +if (!PEAR::loadExtension('xml')) { + $a = false; + echo "[PEAR] xml extension is required\n"; +} +if (!PEAR::loadExtension('pcre')) { + $a = false; + echo "[PEAR] pcre extension is required\n"; +} +if (!$a) { + return -1; +} + +$force = false; $install_files = array('Archive_Tar' => 'phar://install-pear-nozlib.phar/Archive_Tar-1.3.3.tar', 'Console_Getopt' => 'phar://install-pear-nozlib.phar/Console_Getopt-1.2.3.tar', 'Structures_Graph' => 'phar://install-pear-nozlib.phar/Structures_Graph-1.0.2.tar', 'XML_Util' => 'phar://install-pear-nozlib.phar/XML_Util-1.2.1.tar', -'PEAR' => 'phar://install-pear-nozlib.phar/PEAR-1.8.0.tar', -);
-array_shift($argv);
-$debug = false;
-for ($i = 0; $i < sizeof($argv); $i++) {
- $arg = $argv[$i];
- $bn = basename($arg);
- if (ereg('package-(.*)\.xml$', $bn, $matches) ||
- ereg('([A-Za-z0-9_:]+)-.*\.(tar|tgz)$', $bn, $matches)) {
- $install_files[$matches[1]] = $arg;
- } elseif ($arg == '-a') {
- $cache_dir = $argv[$i+1];
- $i++;
- } elseif ($arg == '--force') {
- $force = true;
- } elseif ($arg == '-d') {
- $with_dir = $argv[$i+1];
- $i++;
- } elseif ($arg == '-b') {
- $bin_dir = $argv[$i+1];
- $i++;
- } elseif ($arg == '-c') {
- $cfg_dir = $argv[$i+1];
- $i++;
- } elseif ($arg == '-w') {
- $www_dir = $argv[$i+1];
- $i++;
- } elseif ($arg == '-p') {
- $php_bin = $argv[$i+1];
- $i++;
- } elseif ($arg == '-o') {
- $download_dir = $argv[$i+1];
- $i++;
- } elseif ($arg == '-t') {
- $temp_dir = $argv[$i+1];
- $i++;
- } elseif ($arg == '--debug') {
- $debug = 1;
- } elseif ($arg == '--extremedebug') {
- $debug = 2;
- }
-}
-
-$config = PEAR_Config::singleton();
-
-if (PEAR::isError($config)) {
- $locs = PEAR_Config::getDefaultConfigFiles();
- die("ERROR: One of $locs[user] or $locs[system] is corrupt, please remove them and try again");
-}
-
-// make sure we use only default values
-$config_layers = $config->getLayers();
-foreach ($config_layers as $layer) {
- if ($layer == 'default') continue;
- $config->removeLayer($layer);
-}
-$keys = $config->getKeys();
-if ($debug) {
- $config->set('verbose', 5, 'default');
-} else {
- $config->set('verbose', 0, 'default');
-}
-// PEAR executables
-if (!empty($bin_dir)) {
- $config->set('bin_dir', $bin_dir, 'default');
-}
-
-// Cache files
-if (!empty($cache_dir)) {
- $config->set('cache_dir', $cache_dir, 'default');
-}
-
-// Config files
-if (!empty($cfg_dir)) {
- $config->set('cfg_dir', $cfg_dir, 'default');
-}
-
-// Web files
-if (!empty($www_dir)) {
- $config->set('www_dir', $www_dir, 'default');
-}
-
-// Downloaded files
-if (!empty($download_dir)) {
- $config->set('download_dir', $download_dir, 'default');
-}
-
-// Temporary files
-if (!empty($temp_dir)) {
- $config->set('temp_dir', $temp_dir, 'default');
-}
-
-// User supplied a dir prefix
-if (!empty($with_dir)) {
- $ds = DIRECTORY_SEPARATOR;
- $config->set('php_dir', $with_dir, 'default');
- $config->set('doc_dir', $with_dir . $ds . 'doc', 'default');
- $config->set('data_dir', $with_dir . $ds . 'data', 'default');
- $config->set('test_dir', $with_dir . $ds . 'test', 'default');
- if (empty($www_dir)) {
- $config->set('www_dir', $with_dir . $ds . 'htdocs', 'default');
- }
- if (empty($cfg_dir)) {
- $config->set('cfg_dir', $with_dir . $ds . 'cfg', 'default');
- }
- if (!is_writable($config->get('cache_dir'))) {
- include_once 'phar://install-pear-nozlib.phar/System.php';
- $cdir = System::mktemp(array('-d', 'pear'));
- if (PEAR::isError($cdir)) {
- $ui->outputData("[PEAR] cannot make new temporary directory: " . $cdir);
- die(1);
- }
- $oldcachedir = $config->get('cache_dir');
- $config->set('cache_dir', $cdir);
- }
-}
-if (!empty($php_bin)) {
- $config->set('php_bin', $php_bin);
-}
-/* Print PEAR Conf (useful for debuging do NOT REMOVE) */
-if ($debug) {
- sort($keys);
- foreach ($keys as $key) {
- echo $key . ' ' .
- $config->getPrompt($key) . ": " . $config->get($key, null, 'default') . "\n";
- }
- if ($debug == 2) { // extreme debugging
- exit;
- }
-}
-// end print
-
-$php_dir = $config->get('php_dir');
-$options = array();
-$options['upgrade'] = true;
-$install_root = getenv('INSTALL_ROOT');
-if (!empty($install_root)) {
- $options['packagingroot'] = $install_root;
- $reg = &new PEAR_Registry($options['packagingroot']);
-} else {
- $reg = $config->getRegistry('default');
-}
-
-$ui = PEAR_Frontend::singleton('PEAR_Frontend_CLI');
-if (PEAR::isError($ui)) {
- die($ui->getMessage());
-}
-$installer = new PEAR_Installer($ui);
-$pkg = new PEAR_PackageFile($config, $debug);
-
-foreach ($install_files as $package => $instfile) {
- $info = $pkg->fromAnyFile($instfile, PEAR_VALIDATE_INSTALLING);
- if (PEAR::isError($info)) {
- if (is_array($info->getUserInfo())) {
- foreach ($info->getUserInfo() as $err) {
- $ui->outputData(sprintf("[PEAR] %s: %s", $package, $err['message']));
- }
- }
- $ui->outputData(sprintf("[PEAR] %s: %s", $package, $info->getMessage()));
- continue;
- }
- $new_ver = $info->getVersion();
- $downloaderpackage = new PEAR_Downloader_Package($installer);
- $err = $downloaderpackage->initialize($instfile);
- if (PEAR::isError($err)) {
- $ui->outputData(sprintf("[PEAR] %s: %s", $package, $err->getMessage()));
- continue;
- }
- if ($reg->packageExists($package)) {
- $old_ver = $reg->packageInfo($package, 'version');
- if (version_compare($new_ver, $old_ver, 'gt')) {
- $installer->setOptions($options);
- $dp = array($downloaderpackage);
- $installer->setDownloadedPackages($dp);
- $err = $installer->install($downloaderpackage, $options);
- if (PEAR::isError($err)) {
- $ui->outputData(sprintf("[PEAR] %s: %s", $package, $err->getMessage()));
- continue;
- }
- $ui->outputData(sprintf("[PEAR] %-15s- upgraded: %s", $package, $new_ver));
- } else {
- if ($force) {
- $options['force'] = true;
- $installer->setOptions($options);
- $dp = array($downloaderpackage);
- $installer->setDownloadedPackages($dp);
- $err = $installer->install($downloaderpackage, $options);
- if (PEAR::isError($err)) {
- $ui->outputData(sprintf("[PEAR] %s: %s", $package, $err->getMessage()));
- continue;
- }
- $ui->outputData(sprintf("[PEAR] %-15s- installed: %s", $package, $new_ver));
- } else {
- $ui->outputData(sprintf("[PEAR] %-15s- already installed: %s", $package, $old_ver));
- }
- }
- } else {
- $options['nodeps'] = true;
- $installer->setOptions($options);
- $dp = array($downloaderpackage);
- $installer->setDownloadedPackages($dp);
- $err = $installer->install($downloaderpackage, $options);
- if (PEAR::isError($err)) {
- $ui->outputData(sprintf("[PEAR] %s: %s", $package, $err->getMessage()));
- continue;
- }
- $ui->outputData(sprintf("[PEAR] %-15s- installed: %s", $package, $new_ver));
- }
- if ($package == 'PEAR') {
- if (is_file($ufile = $config->getConfFile('user'))) {
- $ui->outputData('Warning! a PEAR user config file already exists from ' .
- 'a previous PEAR installation at ' .
- "'$ufile'. You may probably want to remove it.");
- }
- $config->set('verbose', 1, 'default');
- if (isset($oldcachedir)) {
- $config->set('cache_dir', $oldcachedir);
- }
- $data = array();
- foreach ($config->getKeys() as $key) {
- $data[$key] = $config->get($key);
- }
- $cnf_file = $config->getConfFile('system');
- if (!empty($install_root)) {
- $cnf_file = $install_root . DIRECTORY_SEPARATOR . $cnf_file;
- }
- $config->writeConfigFile($cnf_file, 'system', $data);
- $ui->outputData('Wrote PEAR system config file at: ' . $cnf_file);
- $ui->outputData('You may want to add: ' . $config->get('php_dir') . ' to your php.ini include_path');
- }
-}
-?>
+'PEAR' => 'phar://install-pear-nozlib.phar/PEAR-1.9.0.tar', +); +array_shift($argv); +$debug = false; +for ($i = 0; $i < sizeof($argv); $i++) { + $arg = $argv[$i]; + $bn = basename($arg); + if (preg_match('/package-(.*)\.xml$/', $bn, $matches) || + preg_match('/([A-Za-z0-9_:]+)-.*\.(tar|tgz)$/', $bn, $matches)) { + $install_files[$matches[1]] = $arg; + } elseif ($arg == '-a') { + $cache_dir = $argv[$i+1]; + $i++; + } elseif ($arg == '--force') { + $force = true; + } elseif ($arg == '-dp') { + $prefix = $argv[$i+1]; + $i++; + } elseif ($arg == '-ds') { + $suffix = $argv[$i+1]; + $i++; + } elseif ($arg == '-d') { + $with_dir = $argv[$i+1]; + $i++; + } elseif ($arg == '-b') { + $bin_dir = $argv[$i+1]; + $i++; + } elseif ($arg == '-c') { + $cfg_dir = $argv[$i+1]; + $i++; + } elseif ($arg == '-w') { + $www_dir = $argv[$i+1]; + $i++; + } elseif ($arg == '-p') { + $php_bin = $argv[$i+1]; + $i++; + } elseif ($arg == '-o') { + $download_dir = $argv[$i+1]; + $i++; + } elseif ($arg == '-t') { + $temp_dir = $argv[$i+1]; + $i++; + } elseif ($arg == '--debug') { + $debug = 1; + } elseif ($arg == '--extremedebug') { + $debug = 2; + } +} + +$config = PEAR_Config::singleton(); + +if (PEAR::isError($config)) { + $locs = PEAR_Config::getDefaultConfigFiles(); + die("ERROR: One of $locs[user] or $locs[system] is corrupt, please remove them and try again"); +} + +// make sure we use only default values +$config_layers = $config->getLayers(); +foreach ($config_layers as $layer) { + if ($layer == 'default') continue; + $config->removeLayer($layer); +} +$keys = $config->getKeys(); +if ($debug) { + $config->set('verbose', 5, 'default'); +} else { + $config->set('verbose', 0, 'default'); +} +// PEAR executables +if (!empty($bin_dir)) { + $config->set('bin_dir', $bin_dir, 'default'); +} + +// Cache files +if (!empty($cache_dir)) { + $config->set('cache_dir', $cache_dir, 'default'); +} + +// Config files +if (!empty($cfg_dir)) { + $config->set('cfg_dir', $cfg_dir, 'default'); +} + +// Web files +if (!empty($www_dir)) { + $config->set('www_dir', $www_dir, 'default'); +} + +// Downloaded files +if (!empty($download_dir)) { + $config->set('download_dir', $download_dir, 'default'); +} + +// Temporary files +if (!empty($temp_dir)) { + $config->set('temp_dir', $temp_dir, 'default'); +} + +// User supplied a dir prefix +if (!empty($with_dir)) { + $ds = DIRECTORY_SEPARATOR; + $config->set('php_dir', $with_dir, 'default'); + $config->set('doc_dir', $with_dir . $ds . 'doc', 'default'); + $config->set('data_dir', $with_dir . $ds . 'data', 'default'); + $config->set('test_dir', $with_dir . $ds . 'test', 'default'); + if (empty($www_dir)) { + $config->set('www_dir', $with_dir . $ds . 'htdocs', 'default'); + } + if (empty($cfg_dir)) { + $config->set('cfg_dir', $with_dir . $ds . 'cfg', 'default'); + } + if (!is_writable($config->get('cache_dir'))) { + include_once 'phar://install-pear-nozlib.phar/System.php'; + $cdir = System::mktemp(array('-d', 'pear')); + if (PEAR::isError($cdir)) { + $ui->outputData("[PEAR] cannot make new temporary directory: " . $cdir); + die(1); + } + $oldcachedir = $config->get('cache_dir'); + $config->set('cache_dir', $cdir); + } +} + +// PHP executable +if (!empty($php_bin)) { + $config->set('php_bin', $php_bin); +} + +// PHP prefix +if (isset($prefix)) { + if ($prefix != 'a') { + if ($prefix[0] == 'a') { + $prefix = substr($prefix, 1); + } + $config->set('php_prefix', $prefix, 'system'); + } +} + +// PHP suffix +if (isset($suffix)) { + if ($suffix != 'a') { + if ($suffix[0] == 'a') { + $suffix = substr($suffix, 1); + } + $config->set('php_suffix', $suffix, 'system'); + } +} + +/* Print PEAR Conf (useful for debuging do NOT REMOVE) */ +if ($debug) { + sort($keys); + foreach ($keys as $key) { + echo $key . ' ' . + $config->getPrompt($key) . ": " . $config->get($key, null, 'default') . "\n"; + } + if ($debug == 2) { // extreme debugging + exit; + } +} +// end print + +$php_dir = $config->get('php_dir'); +$options = array(); +$options['upgrade'] = true; +$install_root = getenv('INSTALL_ROOT'); +if (!empty($install_root)) { + $options['packagingroot'] = $install_root; + $reg = &new PEAR_Registry($options['packagingroot']); +} else { + $reg = $config->getRegistry('default'); +} + +$ui = PEAR_Frontend::singleton('PEAR_Frontend_CLI'); +if (PEAR::isError($ui)) { + die($ui->getMessage()); +} +$installer = new PEAR_Installer($ui); +$pkg = new PEAR_PackageFile($config, $debug); + +foreach ($install_files as $package => $instfile) { + $info = $pkg->fromAnyFile($instfile, PEAR_VALIDATE_INSTALLING); + if (PEAR::isError($info)) { + if (is_array($info->getUserInfo())) { + foreach ($info->getUserInfo() as $err) { + $ui->outputData(sprintf("[PEAR] %s: %s", $package, $err['message'])); + } + } + $ui->outputData(sprintf("[PEAR] %s: %s", $package, $info->getMessage())); + continue; + } + $new_ver = $info->getVersion(); + $downloaderpackage = new PEAR_Downloader_Package($installer); + $err = $downloaderpackage->initialize($instfile); + if (PEAR::isError($err)) { + $ui->outputData(sprintf("[PEAR] %s: %s", $package, $err->getMessage())); + continue; + } + if ($reg->packageExists($package)) { + $old_ver = $reg->packageInfo($package, 'version'); + if (version_compare($new_ver, $old_ver, 'gt')) { + $installer->setOptions($options); + $dp = array($downloaderpackage); + $installer->setDownloadedPackages($dp); + $err = $installer->install($downloaderpackage, $options); + if (PEAR::isError($err)) { + $ui->outputData(sprintf("[PEAR] %s: %s", $package, $err->getMessage())); + continue; + } + $ui->outputData(sprintf("[PEAR] %-15s- upgraded: %s", $package, $new_ver)); + } else { + if ($force) { + $options['force'] = true; + $installer->setOptions($options); + $dp = array($downloaderpackage); + $installer->setDownloadedPackages($dp); + $err = $installer->install($downloaderpackage, $options); + if (PEAR::isError($err)) { + $ui->outputData(sprintf("[PEAR] %s: %s", $package, $err->getMessage())); + continue; + } + $ui->outputData(sprintf("[PEAR] %-15s- installed: %s", $package, $new_ver)); + } else { + $ui->outputData(sprintf("[PEAR] %-15s- already installed: %s", $package, $old_ver)); + } + } + } else { + $options['nodeps'] = true; + $installer->setOptions($options); + $dp = array($downloaderpackage); + $installer->setDownloadedPackages($dp); + $err = $installer->install($downloaderpackage, $options); + if (PEAR::isError($err)) { + $ui->outputData(sprintf("[PEAR] %s: %s", $package, $err->getMessage())); + continue; + } + $ui->outputData(sprintf("[PEAR] %-15s- installed: %s", $package, $new_ver)); + } + if ($package == 'PEAR') { + if (is_file($ufile = $config->getConfFile('user'))) { + $ui->outputData('Warning! a PEAR user config file already exists from ' . + 'a previous PEAR installation at ' . + "'$ufile'. You may probably want to remove it."); + } + $config->set('verbose', 1, 'default'); + if (isset($oldcachedir)) { + $config->set('cache_dir', $oldcachedir); + } + $data = array(); + foreach ($config->getKeys() as $key) { + $data[$key] = $config->get($key); + } + $cnf_file = $config->getConfFile('system'); + if (!empty($install_root)) { + $cnf_file = $install_root . DIRECTORY_SEPARATOR . $cnf_file; + } + $config->writeConfigFile($cnf_file, 'system', $data); + $ui->outputData('Wrote PEAR system config file at: ' . $cnf_file); + $ui->outputData('You may want to add: ' . $config->get('php_dir') . ' to your php.ini include_path'); + } +} +?> <?php /** * The OS_Guess class @@ -6770,7 +6935,7 @@ foreach ($install_files as $package => $instfile) { * @author Gregory Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Guess.php,v 1.29 2009/04/09 22:24:12 dufuz Exp $ + * @version CVS: $Id: Guess.php 278521 2009-04-09 22:24:12Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since PEAR 0.1 */ @@ -6847,7 +7012,7 @@ foreach ($install_files as $package => $instfile) { * @author Gregory Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 0.1 */ @@ -7095,8 +7260,8 @@ class OS_Guess * indent-tabs-mode: nil * c-basic-offset: 4 * End: - */package2.xml -<package packagerversion="1.8.0" version="2.0" xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd"> + */package2.xml +<package packagerversion="1.9.0RC4" version="2.0" xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd"> <name>PEAR</name> <channel>pear.php.net</channel> <summary>PEAR Base System</summary> @@ -7178,325 +7343,246 @@ class OS_Guess <email>mj@php.net</email> <active>no</active> </helper> - <date>2009-04-10</date> - <time>21:01:25</time> + <date>2009-09-03</date> + <time>13:13:10</time> <version> - <release>1.8.0</release> - <api>1.8.0</api> + <release>1.9.0</release> + <api>1.9.0</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> - <license uri="http://opensource.org/licenses/bsd-license.php New BSD License">New BSD License</license> + <license uri="http://opensource.org/licenses/bsd-license.php">New BSD License</license> <notes> -Changes since RC1: - * Fix Bug #14792: Bad md5sum for files with replaced content [dufuz] - * Fix Bug #16057:-r is limited to 4 directories in depth [dufuz] - * Fix Bug #16077: PEAR5::getStaticProperty does not return a reference to the property [dufuz] - - Remove custom XML_Util class in favor of using upstream XML_Util package as dependency - -RC1 Release Notes: - * Fix Bug #14331: pear cvstag only works from inside the package directory [dufuz] - * Fix Bug #16045: E_Notice: Undefined index: channel in PEAR/DependencyDB.php [dufuz] - - * Implemented Request #11230: better error message when mirror not in channel.xml file [dufuz] - * Implemented Request #13150: Add support for following HTTP 302 redirects [dufuz] - -Alpha1 Release Notes: - * Implement Request #10373: if pref_state=stable and installed package=beta, allow up to latest beta version [dufuz] - * Implement Request #10581: login / logout should map to channel-login / channel-logout [dufuz] - * Implement Request #10825: Only display the "invalid or missing package file"-error if it makes sense [dufuz] - * Implement Request #11170: script to generate Command/[command].xml [dufuz] - * Implement Request #11176: improve channel ... has updated its protocols message [dufuz] - * Implement Request #12706: pear list -a hard to read [dufuz] - * Implement Request #11353: upgrade-all and upgrade commands to upgrade within the same stability level [dufuz] - * Implement Request #13015: Add https discovery for channel.xml [dufuz / initial patch by Martin Roos] - * Implement Request #13927: install-pear.php should have option to set www_dir [timj] - * Implement Request #14324: Make the pear install command behave similar to apt-get [dufuz] - * Implement Request #14325: make pear upgrade with no params behave like pear upgrade-all [dufuz] - - upgrade-all can be considered deprecated in favor of calling upgrade with no parameters to replicate - better what other package managers are doing. upgrade-all will still work as intended. - * Implement Request #14504: add a channel parameter support to the upgrade function [dufuz] - - Options -c ezc and --channel=ezc got added to upgrade and upgrade-all to allow for - channel specific upgrades - * Implement Request #14556: install-pear-nozlib.phar should get download_dir config and other options [cweiske] - * Implement Request #15566: Add doc.php.net as a default channel [dufuz / saltybeagle] - - * Fix PHP Bug #43857: --program-suffix not always reflected everywhere [cellog] - * Fix PHP Bug #47323: strotime warnings in make install [dufuz] - - * Fix Bug #13908: pear info command and maintainers inactive not mentioned [dufuz] - * Fix Bug #13926: install-pear.php does not set cfg_dir if -d option set with no -c option [timj] - * Fix Bug #13943: tests fail when php.exe path contains spaces [dufuz / jorrit] - * Fix Bug #13953: config-set/config-show with channel alias fail [cellog] - * Fix Bug #13958: When a phpt tests exit() or die() xdebug coverage is not generated, patch by izi (David Jean Louis) [izi / dufuz] - * Fix Bug #14041: Unpredictable unit test processing sequence [dufuz] - * Fix Bug #14140: Strict warning not suppressed in the shutdown function [dufuz] - * Fix Bug #14210: pear list -ia brings warnings [dufuz] - * Fix Bug #14274: PEAR packager mangles package.xml encoding, then complains about it [dufuz] - * Fix Bug #14287: cannot upgrade from stable to beta via -beta when config is set to stable [dufuz] - * Fix Bug #14300: Package files themselves can not be served over https [dufuz / initial patch by Martin Roos] - * Fix Bug #14437: openbasedir warning when loading config [dufuz] - * Fix Bug #14558: PackageFile.php creates tmp directory outside configured temp_dir [cweiske] - * Fix Bug #14947: downloadHttp() is missing Host part of the HTTP Request when using Proxy [ifeghali] - * Fix Bug #14977: PEAR/Frontend.php doesn't require_once PEAR.php [dufuz] - * Fix Bug #15750: Unreachable code in PEAR_Downloader [dufuz] - * Fix Bug #15979: Package files incorrectly removed when splitting a package into multiple pkgs [dufuz] - * Fix Bug #15914: pear upgrade installs different version if desired version not found [dufuz] - - NOTE! - Functions that have been deprecated for 3+ years in PEAR_Common, please take a moment - to migrate over to one of the alternatives that have ben provided: - * PEAR_Common->downloadHttp (use PEAR_Downloader->downloadHttp instead) - * PEAR_Common->infoFromTgzFile (use PEAR_PackageFile->fromTgzFile instead) - * PEAR_Common->infoFromDescriptionFile (use PEAR_PackageFile->fromPackageFile instead) - * PEAR_Common->infoFromString (use PEAR_PackageFile->fromXmlstring instead) - * PEAR_Common->infoFromArray (use PEAR_PackageFile->fromAnyFile instead) - * PEAR_Common->xmlFromInfo (use a PEAR_PackageFile_v* object's generator instead) - * PEAR_Common->validatePackageInfo (use the validation of PEAR_PackageFile objects) - * PEAR_Common->analyzeSourceCode (use a PEAR_PackageFile_v* object instead) - * PEAR_Common->detectDependencies (use PEAR_Downloader_Package->detectDependencies instead) - * PEAR_Common->buildProvidesArray (use PEAR_PackageFile_v1->_buildProvidesArray or - PEAR_PackageFile_v2_Validator->_buildProvidesArray) - - PHP 4.4 and 5.1.6 are now the minimum PHP requirements, for brave souls - pear upgrade -f PEAR will allow people with lower versions - to upgrade to this release but no guarantees will be made that it will work properly. - - Support for XML RPC channels has been dropped - The only ones that used it - (pear.php.net and pecl.php.net) have used the REST interface for years now. - SOAP support also removed as it was only proof of concept. - - Move codebase from the PHP License to New BSD 2 clause license +* Fix Bug #16547: The phar for PEAR installer uses ereg() which is deprecated [dufuz] </notes> <contents> <dir name="/"> - <file md5sum="c5b7cabb1fd56e54d51de624b10e7e0a" name="OS/Guess.php" role="php"> + <file md5sum="f063d5b84d03538b85f05cde9aae8037" name="OS/Guess.php" role="php"> <tasks:replace from="@package_version@" to="version" type="package-info" /> </file> - <file md5sum="58e6a076eaedbcfa157080c122bb0f6b" name="PEAR/ChannelFile/Parser.php" role="php"> + <file md5sum="e839d4a327219441507bd5de7409ee5b" name="PEAR/ChannelFile/Parser.php" role="php"> <tasks:replace from="@package_version@" to="version" type="package-info" /> </file> <file md5sum="8fd87e64002e11fd86eb2f3fbfee6599" name="PEAR/Command/Auth.xml" role="php" /> - <file md5sum="cf9d055aabc38596be6729d63919f0a1" name="PEAR/Command/Auth.php" role="php"> + <file md5sum="7d3f1696902faf5442059393e541ad2d" name="PEAR/Command/Auth.php" role="php"> <tasks:replace from="@package_version@" to="version" type="package-info" /> </file> - <file md5sum="483dd90056453bc93314472a66388057" name="PEAR/Command/Build.xml" role="php" /> - <file md5sum="e01afa618052f88b2ffe0c037c7892d2" name="PEAR/Command/Build.php" role="php"> + <file md5sum="73602fd7f051eaf8d37452d0e3063bdb" name="PEAR/Command/Build.xml" role="php" /> + <file md5sum="99e6dae6555a272f16f1cf2265d221c0" name="PEAR/Command/Build.php" role="php"> <tasks:replace from="@package_version@" to="version" type="package-info" /> </file> - <file md5sum="dec008667dd7c3cb3740b5aa7d3ac619" name="PEAR/Command/Channels.xml" role="php" /> - <file md5sum="d32278c6471cc9276890f72645d3993c" name="PEAR/Command/Channels.php" role="php"> + <file md5sum="6d5aab4d4308c3005b5f584c7783a031" name="PEAR/Command/Channels.xml" role="php" /> + <file md5sum="63a395cf6c752e8121e1fa2ae1f9ac28" name="PEAR/Command/Channels.php" role="php"> <tasks:replace from="@package_version@" to="version" type="package-info" /> </file> - <file md5sum="86b458158392cdba2f2c62131a238a6b" name="PEAR/Command/Common.php" role="php"> + <file md5sum="dc4961036d632859bb1bda5e32a8c346" name="PEAR/Command/Common.php" role="php"> <tasks:replace from="@package_version@" to="version" type="package-info" /> </file> <file md5sum="91f189cb9423b5e87ee0abc5ea1a2be3" name="PEAR/Command/Config.xml" role="php" /> - <file md5sum="c1ff72162e26064888987e77ff2fb851" name="PEAR/Command/Config.php" role="php"> + <file md5sum="f0c106b4ba5e12236c59b161b75f4182" name="PEAR/Command/Config.php" role="php"> <tasks:replace from="@package_version@" to="version" type="package-info" /> </file> - <file md5sum="54c542190627909c2ccabdc844dbd5e9" name="PEAR/Command/Install.xml" role="php" /> - <file md5sum="8b564d859a10dc4c881d8275793305d5" name="PEAR/Command/Install.php" role="php"> + <file md5sum="2db0386b865d3f9a29f9126728722ece" name="PEAR/Command/Install.xml" role="php" /> + <file md5sum="034593b2194bf8feb689722833e1c9b0" name="PEAR/Command/Install.php" role="php"> <tasks:replace from="@package_version@" to="version" type="package-info" /> </file> <file md5sum="5cb62a04c0a268f4edd64a49a3895c92" name="PEAR/Command/Mirror.xml" role="php" /> - <file md5sum="6a05eff162094574269851bf8d2eb86e" name="PEAR/Command/Mirror.php" role="php"> + <file md5sum="8bc9265e1046ec67a85571557515bb1b" name="PEAR/Command/Mirror.php" role="php"> <tasks:replace from="@package_version@" to="version" type="package-info" /> </file> - <file md5sum="fedae0702f3bdc32c37a9912dc8fe171" name="PEAR/Command/Package.xml" role="php" /> - <file md5sum="db75e44ce6d61a2d84271cefc847ee67" name="PEAR/Command/Package.php" role="php"> + <file md5sum="6c3061a594644e49b0648798dce6de32" name="PEAR/Command/Package.xml" role="php" /> + <file md5sum="2d4e5f5200fdbdbb5f1c2bf0a27ab754" name="PEAR/Command/Package.php" role="php"> <tasks:replace from="@DATA-DIR@" to="data_dir" type="pear-config" /> <tasks:replace from="@package_version@" to="version" type="package-info" /> </file> <file md5sum="28dc842ea725d8787b9f9c3dbca5aa22" name="PEAR/Command/Pickle.xml" role="php" /> - <file md5sum="a56f511146a5aceded33637631c17b74" name="PEAR/Command/Pickle.php" role="php"> + <file md5sum="6a794c2a0545fff7300217dd6e133c17" name="PEAR/Command/Pickle.php" role="php"> <tasks:replace from="@package_version@" to="version" type="package-info" /> </file> <file md5sum="49b046cfc14747f0365e02e9c3f0e6dc" name="PEAR/Command/Registry.xml" role="php" /> - <file md5sum="c28030095775bcf060571ffceefe17da" name="PEAR/Command/Registry.php" role="php"> + <file md5sum="567687617b7f406bd1ba55e37060edf8" name="PEAR/Command/Registry.php" role="php"> <tasks:replace from="@package_version@" to="version" type="package-info" /> </file> <file md5sum="29c02e823879b4e3e291f6b36fb339f1" name="PEAR/Command/Remote.xml" role="php" /> - <file md5sum="170e88fb6930a13c348ece2c2c915ee8" name="PEAR/Command/Remote.php" role="php"> + <file md5sum="374366b6f361c401ae22edc5b76b7a90" name="PEAR/Command/Remote.php" role="php"> <tasks:replace from="@package_version@" to="version" type="package-info" /> </file> - <file md5sum="ff80fba20e3637a1d53a68b9fa017197" name="PEAR/Command/Test.xml" role="php" /> - <file md5sum="a2684aabe6246adb0e4483f860d5e11a" name="PEAR/Command/Test.php" role="php"> + <file md5sum="a50c32015005e0761cc3b04679b29ed0" name="PEAR/Command/Test.xml" role="php" /> + <file md5sum="01252c8d6c005f53f250344bb4453a59" name="PEAR/Command/Test.php" role="php"> <tasks:replace from="@package_version@" to="version" type="package-info" /> </file> - <file md5sum="d2ff9bb14e39abf0ed122b806a086a6d" name="PEAR/Downloader/Package.php" role="php"> + <file md5sum="73a70ef0ac6d521fcbc972de10341bbe" name="PEAR/Downloader/Package.php" role="php"> <tasks:replace from="@PEAR-VER@" to="version" type="package-info" /> </file> - <file md5sum="ad5d4d946dfd6b990007450e30b3dfb1" name="PEAR/Frontend/CLI.php" role="php"> + <file md5sum="e613fdf2c8090bf8f7289dbeaa06a97c" name="PEAR/Frontend/CLI.php" role="php"> <tasks:replace from="@package_version@" to="version" type="package-info" /> </file> - <file md5sum="3c882c3ef0b2c42516ffecefcff26f9e" name="PEAR/Installer/Role/Common.php" role="php"> + <file md5sum="d3c3a546ced9a12889eda5e368583944" name="PEAR/Installer/Role/Common.php" role="php"> <tasks:replace from="@package_version@" to="version" type="package-info" /> </file> <file md5sum="d8c62e6275e3aaa7784290912406092c" name="PEAR/Installer/Role/Cfg.xml" role="php" /> - <file md5sum="97524d269a5289ca703b906f30906942" name="PEAR/Installer/Role/Cfg.php" role="php"> + <file md5sum="a3bb43296f00bd5459a0fbf8314f8917" name="PEAR/Installer/Role/Cfg.php" role="php"> <tasks:replace from="@package_version@" to="version" type="package-info" /> </file> <file md5sum="89a4a2a286e842d45a98974f40a0565c" name="PEAR/Installer/Role/Data.xml" role="php" /> - <file md5sum="de4de130aa45ebbca82432bdc0b5e929" name="PEAR/Installer/Role/Data.php" role="php"> + <file md5sum="2cb74a7dd5fdfce5b78717e1847d463c" name="PEAR/Installer/Role/Data.php" role="php"> <tasks:replace from="@package_version@" to="version" type="package-info" /> </file> <file md5sum="b1ce0fe105251c3b75209d6518ee69ac" name="PEAR/Installer/Role/Doc.xml" role="php" /> - <file md5sum="747444f4c829d356d812eaf7c9c0b099" name="PEAR/Installer/Role/Doc.php" role="php"> + <file md5sum="5c0b53e95ae25306da82cf6dd87da4dc" name="PEAR/Installer/Role/Doc.php" role="php"> <tasks:replace from="@package_version@" to="version" type="package-info" /> </file> <file md5sum="af71c0ad42d16a323afe24a4f884ef15" name="PEAR/Installer/Role/Ext.xml" role="php" /> - <file md5sum="14cedff64246d06ac73597cc7008e9fe" name="PEAR/Installer/Role/Ext.php" role="php"> + <file md5sum="b3c70e10e63273ef1f2e5cd0a2bd33e8" name="PEAR/Installer/Role/Ext.php" role="php"> <tasks:replace from="@package_version@" to="version" type="package-info" /> </file> <file md5sum="ef88f0321d3e481c2130c95122cf76d8" name="PEAR/Installer/Role/Php.xml" role="php" /> - <file md5sum="3ffee54fd27e11c57805de49ccb9599d" name="PEAR/Installer/Role/Php.php" role="php"> + <file md5sum="9e4a34e2a332b704417590cb734ffc93" name="PEAR/Installer/Role/Php.php" role="php"> <tasks:replace from="@package_version@" to="version" type="package-info" /> </file> <file md5sum="746461dc3b48af6d24094cb0211608f2" name="PEAR/Installer/Role/Script.xml" role="php" /> - <file md5sum="f4c2288d22e16db5222e9423ac27ba3f" name="PEAR/Installer/Role/Script.php" role="php"> + <file md5sum="eb20ad9051db4db53a1c30e9f1b0dab5" name="PEAR/Installer/Role/Script.php" role="php"> <tasks:replace from="@package_version@" to="version" type="package-info" /> </file> - <file md5sum="999bc34ddef1d3cfc1d03ac64a45d680" name="PEAR/Installer/Role/Src.xml" role="php" /> - <file md5sum="0d1ddded65dbd723ac268c76b5b52a18" name="PEAR/Installer/Role/Src.php" role="php"> + <file md5sum="e147d63f168ea156fc2be38caaa63804" name="PEAR/Installer/Role/Src.xml" role="php" /> + <file md5sum="656ad25a2fa1a13f53aad6121edfba91" name="PEAR/Installer/Role/Src.php" role="php"> <tasks:replace from="@package_version@" to="version" type="package-info" /> </file> <file md5sum="a24b596ec987aa5688fc19e8ed4e97ea" name="PEAR/Installer/Role/Test.xml" role="php" /> - <file md5sum="9a955fcc40e6ff3187604dc71af21d2a" name="PEAR/Installer/Role/Test.php" role="php"> + <file md5sum="5601a755c633dafb639a8fbd1abe0261" name="PEAR/Installer/Role/Test.php" role="php"> <tasks:replace from="@package_version@" to="version" type="package-info" /> </file> - <file md5sum="26f696fe4e32a1a4d95441ba8a9ec66e" name="PEAR/Installer/Role/Www.xml" role="php" /> - <file md5sum="1776b898ec03d9212a0b9b85a5841dcf" name="PEAR/Installer/Role/Www.php" role="php"> + <file md5sum="7641e71c5785bb33a4261ebe25ed0fd7" name="PEAR/Installer/Role/Www.xml" role="php" /> + <file md5sum="8ab36d60bc9eb361885d7d901b107c0c" name="PEAR/Installer/Role/Www.php" role="php"> <tasks:replace from="@package_version@" to="version" type="package-info" /> </file> - <file md5sum="935f9dc1ad736be6f92889414b477a23" name="PEAR/Installer/Role.php" role="php"> + <file md5sum="0dab463a3402a0401616c7a1630bebcb" name="PEAR/Installer/Role.php" role="php"> <tasks:replace from="@package_version@" to="version" type="package-info" /> </file> - <file md5sum="59655b9d4816cc1e94a661764b49e229" name="PEAR/PackageFile/Generator/v1.php" role="php"> + <file md5sum="cd8b1ef4c311e0e4f5a00e5e36d48d43" name="PEAR/PackageFile/Generator/v1.php" role="php"> <tasks:replace from="@PEAR-VER@" to="version" type="package-info" /> </file> - <file md5sum="2a25244b486984ef074a5023865969b9" name="PEAR/PackageFile/Generator/v2.php" role="php"> + <file md5sum="f7ed15b3d6d1aab0b6f8ee2fe0d9d3db" name="PEAR/PackageFile/Generator/v2.php" role="php"> <tasks:replace from="@PEAR-VER@" to="version" type="package-info" /> </file> - <file md5sum="50058789604936483b9e82c5990f5751" name="PEAR/PackageFile/Parser/v1.php" role="php"> + <file md5sum="7d3828c0f41aadc34d948f5215c4cd66" name="PEAR/PackageFile/Parser/v1.php" role="php"> <tasks:replace from="@package_version@" to="version" type="package-info" /> </file> - <file md5sum="eb78e5f34b4e0ae993fe2f43830ca367" name="PEAR/PackageFile/Parser/v2.php" role="php"> + <file md5sum="a5f847fdba24116593efc223425a9609" name="PEAR/PackageFile/Parser/v2.php" role="php"> <tasks:replace from="@package_version@" to="version" type="package-info" /> </file> - <file md5sum="3863e2343baa5cfab1c4c1f386deb9ba" name="PEAR/PackageFile/v2/rw.php" role="php"> + <file md5sum="9a159d7f8e70bf9f57f9ade64dd5e377" name="PEAR/PackageFile/v2/rw.php" role="php"> <tasks:replace from="@package_version@" to="version" type="package-info" /> </file> - <file md5sum="105d1ef053e38954ef32b056fe057101" name="PEAR/PackageFile/v2/Validator.php" role="php"> + <file md5sum="cf2b5655d9accc025e5cf5f0476302a8" name="PEAR/PackageFile/v2/Validator.php" role="php"> <tasks:replace from="@package_version@" to="version" type="package-info" /> </file> - <file md5sum="d1001b5d6336ab4e218c72624cf591d0" name="PEAR/PackageFile/v1.php" role="php"> + <file md5sum="7736b857a1153b02453d42dd476d6f8a" name="PEAR/PackageFile/v1.php" role="php"> <tasks:replace from="@package_version@" to="version" type="package-info" /> </file> - <file md5sum="9170859737fc3c16a0a380acb036c871" name="PEAR/PackageFile/v2.php" role="php"> + <file md5sum="7026083ae0b038045dc117d68dc32a0a" name="PEAR/PackageFile/v2.php" role="php"> <tasks:replace from="@package_version@" to="version" type="package-info" /> </file> - <file md5sum="71161e2ad26859b65ade1121df4e581c" name="PEAR/REST/10.php" role="php"> + <file md5sum="b0b343c594552895492692d52561bc52" name="PEAR/REST/10.php" role="php"> <tasks:replace from="@package_version@" to="version" type="package-info" /> </file> - <file md5sum="226d07e4adaf0cffa766a61a60674614" name="PEAR/REST/11.php" role="php"> + <file md5sum="41f230e5d3282221e6b55466cb0510d3" name="PEAR/REST/11.php" role="php"> <tasks:replace from="@package_version@" to="version" type="package-info" /> </file> - <file md5sum="3cd456e38ecc49a3d2494ed3d2aa10af" name="PEAR/REST/13.php" role="php"> + <file md5sum="897908bf87ac9ae617a0a42e13f8e0cd" name="PEAR/REST/13.php" role="php"> <tasks:replace from="@package_version@" to="version" type="package-info" /> </file> - <file md5sum="4205d96470d330b79785470092da51b7" name="PEAR/Task/Postinstallscript/rw.php" role="php"> + <file md5sum="bff16b5498aa831d106061ebbaba484c" name="PEAR/Task/Postinstallscript/rw.php" role="php"> <tasks:replace from="@package_version@" to="version" type="package-info" /> </file> - <file md5sum="5c493ff8705bcd75745679cf946ccce3" name="PEAR/Task/Replace/rw.php" role="php"> + <file md5sum="d4f525ae7d94c48662d45769643abada" name="PEAR/Task/Replace/rw.php" role="php"> <tasks:replace from="@package_version@" to="version" type="package-info" /> </file> - <file md5sum="47f9acf9063cf8709d34adc9fd506e22" name="PEAR/Task/Unixeol/rw.php" role="php"> + <file md5sum="0787e483b91cb6842b9cfedbb486aabf" name="PEAR/Task/Unixeol/rw.php" role="php"> <tasks:replace from="@package_version@" to="version" type="package-info" /> </file> - <file md5sum="36d60522e57f34da581af0595dc02df3" name="PEAR/Task/Windowseol/rw.php" role="php"> + <file md5sum="a5545cfac22a53d0aad99f4acdbee50c" name="PEAR/Task/Windowseol/rw.php" role="php"> <tasks:replace from="@package_version@" to="version" type="package-info" /> </file> - <file md5sum="3e8d8a967da5a7571331819a2b340150" name="PEAR/Task/Common.php" role="php"> + <file md5sum="e61537de629cb2f7f7e1bc497038902e" name="PEAR/Task/Common.php" role="php"> <tasks:replace from="@package_version@" to="version" type="package-info" /> </file> - <file md5sum="542744e38c5f49462047c6b0f21b27be" name="PEAR/Task/Postinstallscript.php" role="php"> + <file md5sum="34d4c4f16734388faca7e418ab206f68" name="PEAR/Task/Postinstallscript.php" role="php"> <tasks:replace from="@package_version@" to="version" type="package-info" /> </file> - <file md5sum="fe0e5e543a72531908f9feedeb904384" name="PEAR/Task/Replace.php" role="php"> + <file md5sum="0fecedc2f99e5f010b327650c353e4db" name="PEAR/Task/Replace.php" role="php"> <tasks:replace from="@package_version@" to="version" type="package-info" /> </file> - <file md5sum="1e4ab461f8c59644fba160eff3729f42" name="PEAR/Task/Unixeol.php" role="php"> + <file md5sum="85ee9fd0fa58d4aef2161d5ac5d9b539" name="PEAR/Task/Unixeol.php" role="php"> <tasks:replace from="@package_version@" to="version" type="package-info" /> </file> - <file md5sum="20ae133e8f43ff99c2ab25f12dbd52a6" name="PEAR/Task/Windowseol.php" role="php"> + <file md5sum="33bc10b55f7c90425054024b42d0e944" name="PEAR/Task/Windowseol.php" role="php"> <tasks:replace from="@package_version@" to="version" type="package-info" /> </file> - <file md5sum="70389318e500120b2fdd6df9cf9eb9e2" name="PEAR/Validator/PECL.php" role="php"> + <file md5sum="a18f1a10bb85cc988f7c2de9914c1e9f" name="PEAR/Validator/PECL.php" role="php"> <tasks:replace from="@package_version@" to="version" type="package-info" /> </file> - <file md5sum="8dff2754449b92d30700617b0d95c5b3" name="PEAR/Autoloader.php" role="php"> + <file md5sum="b6d6b167ca1514d0765533d4abafca1d" name="PEAR/Autoloader.php" role="php"> <tasks:replace from="@package_version@" to="version" type="package-info" /> </file> - <file md5sum="6fedb21642af9a4a5dac405b8f335874" name="PEAR/Builder.php" role="php"> + <file md5sum="d9d3b94e0d1bf2f2c377a5cd8201481c" name="PEAR/Builder.php" role="php"> <tasks:replace from="@PEAR-VER@" to="version" type="package-info" /> </file> - <file md5sum="c0ca2d8695b28855002f8d2675a88519" name="PEAR/ChannelFile.php" role="php"> + <file md5sum="f9d18b3c198a2a0f0771036c6b0404f7" name="PEAR/ChannelFile.php" role="php"> <tasks:replace from="@package_version@" to="version" type="package-info" /> </file> - <file md5sum="7b0a88899e6ff37694546a9ff32ed6f8" name="PEAR/Command.php" role="php"> + <file md5sum="150c15a2fb2fd57166ca8276e29cb74b" name="PEAR/Command.php" role="php"> <tasks:replace from="@package_version@" to="version" type="package-info" /> </file> - <file md5sum="e76884b29acc9273c3cb13c55734ba9b" name="PEAR/Common.php" role="php"> + <file md5sum="7c0ff45e0ee9df0ddbaa9b8c4c31b2fd" name="PEAR/Common.php" role="php"> <tasks:replace from="@package_version@" to="version" type="package-info" /> </file> - <file md5sum="09ede5947b2145f79074c6df4ecdbe5a" name="PEAR/Config.php" role="php"> + <file md5sum="5080a36f685fcef9b160617e8cb02870" name="PEAR/Config.php" role="php"> <tasks:replace from="@package_version@" to="version" type="package-info" /> </file> - <file md5sum="3b0923bb6eb52049b57b1a1553a93cff" name="PEAR/DependencyDB.php" role="php"> + <file md5sum="c161acaf73f7938ea48b3165d891998b" name="PEAR/DependencyDB.php" role="php"> <tasks:replace from="@package_version@" to="version" type="package-info" /> </file> - <file md5sum="20ba6fb65adce82c8ad000f2d622f69c" name="PEAR/Dependency2.php" role="php"> + <file md5sum="b0d1ee5d0acd02ca9351e076f73cc9da" name="PEAR/Dependency2.php" role="php"> <tasks:replace from="@PEAR-VER@" to="version" type="package-info" /> </file> - <file md5sum="1029b9ad5560624b9d4f17838d02983f" name="PEAR/Downloader.php" role="php"> + <file md5sum="2185eb7a493f863ea3d3510195e7c901" name="PEAR/Downloader.php" role="php"> <tasks:replace from="@package_version@" to="version" type="package-info" /> </file> - <file md5sum="278eefd89ba1d74a62c4436dda6dfca8" name="PEAR/ErrorStack.php" role="php"> + <file md5sum="33ce30b4478cdb76e29bd75058c842e3" name="PEAR/ErrorStack.php" role="php"> <tasks:replace from="@package_version@" to="version" type="package-info" /> </file> - <file md5sum="abf45593961edd5bb1f92d70e4623997" name="PEAR/Exception.php" role="php"> + <file md5sum="f364e75223744d460a6bb08420ac94f9" name="PEAR/Exception.php" role="php"> <tasks:replace from="@package_version@" to="version" type="package-info" /> </file> <file md5sum="e0e4cbcec4a972fbad779d0f9d323120" name="PEAR/FixPHP5PEARWarnings.php" role="php" /> - <file md5sum="68f488516741f6f8a3af57c16678e0fd" name="PEAR/Frontend.php" role="php"> + <file md5sum="52c3acdba716110657f7bf86ca2012e1" name="PEAR/Frontend.php" role="php"> <tasks:replace from="@package_version@" to="version" type="package-info" /> </file> - <file md5sum="4e03c62b818773511b1cc25ef4061bb9" name="PEAR/Installer.php" role="php"> + <file md5sum="45f4c064607a7d3d4f68b0f06f98db5c" name="PEAR/Installer.php" role="php"> <tasks:replace from="@package_version@" to="version" type="package-info" /> </file> - <file md5sum="8078d5d41ed18a6fe6eefe9abe68e5b0" name="PEAR/PackageFile.php" role="php"> + <file md5sum="df9c5cc34b6fbbf661d534cecb315c9f" name="PEAR/PackageFile.php" role="php"> <tasks:replace from="@PEAR-VER@" to="version" type="package-info" /> </file> - <file md5sum="7448e3df885514343512094b946f475b" name="PEAR/Packager.php" role="php"> + <file md5sum="821b72d18cbdc2e8b9c5087bc9b99854" name="PEAR/Packager.php" role="php"> <tasks:replace from="@package_version@" to="version" type="package-info" /> </file> - <file md5sum="45503b28720431d9ad8d64c36bb87bc1" name="PEAR/Registry.php" role="php"> + <file md5sum="a58437db39d3d71bb93f44a660334720" name="PEAR/Registry.php" role="php"> <tasks:replace from="@package_version@" to="version" type="package-info" /> </file> - <file md5sum="63a2caea137e35fadd6d9085b6894d94" name="PEAR/REST.php" role="php"> + <file md5sum="28e5f3b905280051309e65d3e85d0b15" name="PEAR/REST.php" role="php"> <tasks:replace from="@package_version@" to="version" type="package-info" /> </file> - <file md5sum="5c2b6d2791b94bf8d98cff37dc6f1bfc" name="PEAR/RunTest.php" role="php"> + <file md5sum="34a0d9008da01b3987a610d94837a80c" name="PEAR/RunTest.php" role="php"> <tasks:replace from="@package_version@" to="version" type="package-info" /> </file> - <file md5sum="4235e4ed6a3be97da6eff9c069e93516" name="PEAR/Validate.php" role="php"> + <file md5sum="c5ea781c8abb14ff62b04b6db5e10e0f" name="PEAR/Validate.php" role="php"> <tasks:replace from="@package_version@" to="version" type="package-info" /> </file> - <file md5sum="f3e6145dd13e447ea0d8e9a0e3f7812b" name="PEAR/XMLParser.php" role="php"> + <file md5sum="c6de49d413a1cf97a1f8a4668766e3ab" name="PEAR/XMLParser.php" role="php"> <tasks:replace from="@package_version@" to="version" type="package-info" /> </file> <file baseinstalldir="/" md5sum="bd65b087b7707463525e9f0092337793" name="scripts/pear.bat" role="script"> @@ -7505,7 +7591,7 @@ Alpha1 Release Notes: <tasks:replace from="@include_path@" to="php_dir" type="pear-config" /> <tasks:windowseol /> </file> - <file baseinstalldir="/" md5sum="f92ee8acc4f00a7ca9ffedc1fe959b69" name="scripts/peardev.bat" role="script"> + <file baseinstalldir="/" md5sum="92cafd038c7d6a212111c84ca4907a13" name="scripts/peardev.bat" role="script"> <tasks:replace from="@bin_dir@" to="bin_dir" type="pear-config" /> <tasks:replace from="@php_bin@" to="php_bin" type="pear-config" /> <tasks:replace from="@include_path@" to="php_dir" type="pear-config" /> @@ -7538,26 +7624,27 @@ Alpha1 Release Notes: <tasks:replace from="@include_path@" to="php_dir" type="pear-config" /> <tasks:unixeol /> </file> - <file baseinstalldir="/" md5sum="d52e189171fbd1b50aeb7fd9ae79f3f5" name="scripts/pearcmd.php" role="php"> + <file baseinstalldir="/" md5sum="55426bdbfd8e1bc050a79e3c6095d8e5" name="scripts/pearcmd.php" role="php"> <tasks:replace from="@php_bin@" to="php_bin" type="pear-config" /> <tasks:replace from="@php_dir@" to="php_dir" type="pear-config" /> <tasks:replace from="@pear_version@" to="version" type="package-info" /> <tasks:replace from="@include_path@" to="php_dir" type="pear-config" /> </file> - <file baseinstalldir="/" md5sum="c7bd82e5f20e548980aa1f0bae4427a4" name="scripts/peclcmd.php" role="php"> + <file baseinstalldir="/" md5sum="320849b646e4cdaeca543af666524e73" name="scripts/peclcmd.php" role="php"> <tasks:replace from="@php_bin@" to="php_bin" type="pear-config" /> <tasks:replace from="@php_dir@" to="php_dir" type="pear-config" /> <tasks:replace from="@pear_version@" to="version" type="package-info" /> <tasks:replace from="@include_path@" to="php_dir" type="pear-config" /> </file> <file md5sum="45b44486d8090de17b2a8b4211fab247" name="LICENSE" role="doc" /> - <file md5sum="671e6690634062ee521d2027a9971f22" name="INSTALL" role="doc" /> - <file md5sum="ca444da9174e05f8a0dc71d8ee47900f" name="package.dtd" role="data" /> - <file md5sum="0965c4c961762dc0c99ef4e62f69cd25" name="PEAR.php" role="php"> + <file md5sum="45b1a9dcc368539cb8f2a65c30b2f453" name="INSTALL" role="doc" /> + <file md5sum="4a49bc83a392934e57af45c70a589fda" name="package.dtd" role="data" /> + <file md5sum="1a8f67d58009372a6cbcddd638b128cf" name="PEAR5.php" role="php" /> + <file md5sum="4e4941a59ed97ca61c93deb6a7ff918c" name="PEAR.php" role="php"> <tasks:replace from="@package_version@" to="version" type="package-info" /> </file> - <file md5sum="ae70dd96347165e048bd37521d6437f2" name="README" role="doc" /> - <file md5sum="9aeb41ebb0a0072a9b537d0b3d9767a8" name="System.php" role="php"> + <file md5sum="d3b517006b304817731eb77cc2154258" name="README" role="doc" /> + <file md5sum="8bf4cfb58d10d72b5082c3022c887710" name="System.php" role="php"> <tasks:replace from="@package_version@" to="version" type="package-info" /> </file> <file md5sum="acd010e3bc43c0f72df584acde7b9158" name="template.spec" role="data" /> @@ -7684,7 +7771,7 @@ Alpha1 Release Notes: <api>stable</api> </stability> <date>2009-03-09</date> - <license uri="http://opensource.org/licenses/bsd-license.php New BSD License">New BSD License</license> + <license uri="http://opensource.org/licenses/bsd-license.php">New BSD License</license> <notes> * Implement Request #10373: if pref_state=stable and installed package=beta, allow up to latest beta version [dufuz] * Implement Request #10581: login / logout should map to channel-login / channel-logout [dufuz] @@ -7763,7 +7850,7 @@ Move codebase from the PHP License to New BSD 2 clause license <release>beta</release> <api>stable</api> </stability> - <license uri="http://opensource.org/licenses/bsd-license.php New BSD License">New BSD License</license> + <license uri="http://opensource.org/licenses/bsd-license.php">New BSD License</license> <notes> * Fix Bug #14331: pear cvstag only works from inside the package directory [dufuz] * Fix Bug #16045: E_Notice: Undefined index: channel in PEAR/DependencyDB.php [dufuz] @@ -7782,7 +7869,7 @@ Move codebase from the PHP License to New BSD 2 clause license <release>stable</release> <api>stable</api> </stability> - <license uri="http://opensource.org/licenses/bsd-license.php New BSD License">New BSD License</license> + <license uri="http://opensource.org/licenses/bsd-license.php">New BSD License</license> <notes> Changes since RC1: * Fix Bug #14792: Bad md5sum for files with replaced content [dufuz] @@ -7866,9 +7953,116 @@ Alpha1 Release Notes: Move codebase from the PHP License to New BSD 2 clause license </notes> </release> + <release> + <date>2009-04-15</date> + <version> + <release>1.8.1</release> + <api>1.8.1</api> + </version> + <stability> + <release>stable</release> + <api>stable</api> + </stability> + <license uri="http://opensource.org/licenses/bsd-license.php">New BSD License</license> + <notes> +* Fix Bug #16099 PEAR crash on PHP4 (parse error) [dufuz] + </notes> + </release> + <release> + <date>2009-08-18</date> + <version> + <release>1.9.0RC1</release> + <api>1.9.0RC1</api> + </version> + <stability> + <release>beta</release> + <api>stable</api> + </stability> + <license uri="http://opensource.org/licenses/bsd-license.php">New BSD License</license> + <notes> +* Implement Request #16213: add alias to list-channels output [dufuz] +* Implement Request #16378: pear svntag [dufuz] +* Implement Request #16386: PEAR_Config::remove() does not support specifying a channel [timj] +* Implement Request #16396: package-dependencies should allow package names [dufuz] + +* Fix Bug #11181: pear requests channel.xml from main server instead from mirror [dufuz] +* Fix Bug #14493: pear install --offline doesn't print out errors [dufuz] +* Fix Bug #11348: pear package-dependencies isn't well explained [dufuz] +* Fix Bug #16108: PEAR_PackageFile_Generator_v2 PHP4 parse error when running upgrade-all [dufuz] +* Fix Bug #16113: Installing certain packages fails due incorrect encoding handling [dufuz] +* Fix Bug #16122: PEAR RunTest failed to run as expected [dufuz] +* Fix Bug #16366: compiling 5.2.10 leads to non-functioning pear [dufuz] +* Fix Bug #16387: channel-logout does not support logging out from a non-default channel [timj] +* Fix Bug #16444: Setting preferred mirror fails [dufuz] +* Fix the shutdown functions where a index might not exist and thus raise a notice [derick] + </notes> + </release> + <release> + <date>2009-08-20</date> + <version> + <release>1.9.0RC2</release> + <api>1.9.0RC2</api> + </version> + <stability> + <release>beta</release> + <api>stable</api> + </stability> + <license uri="http://opensource.org/licenses/bsd-license.php">New BSD License</license> + <notes> +* REST 1.4 file was occasionally being included but REST 1.4 is not intended for this release cycle [dufuz] + </notes> + </release> + <release> + <date>2009-08-21</date> + <version> + <release>1.9.0RC3</release> + <api>1.9.0RC3</api> + </version> + <stability> + <release>beta</release> + <api>stable</api> + </stability> + <license uri="http://opensource.org/licenses/bsd-license.php">New BSD License</license> + <notes> +* Improved svntag support to handle packages like PEAR it self [dufuz] + </notes> + </release> + <release> + <date>2009-08-23</date> + <version> + <release>1.9.0RC4</release> + <api>1.9.0RC4</api> + </version> + <stability> + <release>beta</release> + <api>stable</api> + </stability> + <license uri="http://opensource.org/licenses/bsd-license.php">New BSD License</license> + <notes> +* Fixed a problem where the original channel could not be set as a preferred_mirror again [dufuz] +* Make sure channel aliases can't be made to start with - [dufuz] +* Output issues with pear search [dufuz] +* Fixed couple of stray notices [dufuz] + </notes> + </release> + <release> + <date>2009-09-03</date> + <version> + <release>1.9.0</release> + <api>1.9.0</api> + </version> + <stability> + <release>stable</release> + <api>stable</api> + </stability> + <license uri="http://opensource.org/licenses/bsd-license.php">New BSD License</license> + <notes> +* Fix Bug #16547: The phar for PEAR installer uses ereg() which is deprecated [dufuz] + </notes> + </release> </changelog> </package> - + /** * The OS_Guess class * @@ -7880,7 +8074,7 @@ Alpha1 Release Notes: * @author Gregory Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Guess.php,v 1.29 2009/04/09 22:24:12 dufuz Exp $ + * @version CVS: $Id: Guess.php 278521 2009-04-09 22:24:12Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since PEAR 0.1 */ @@ -7957,7 +8151,7 @@ Alpha1 Release Notes: * @author Gregory Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 0.1 */ @@ -8205,7 +8399,7 @@ class OS_Guess * indent-tabs-mode: nil * c-basic-offset: 4 * End: - */ + */ /** * PEAR_ChannelFile_Parser for parsing channel.xml * @@ -8216,7 +8410,7 @@ class OS_Guess * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Parser.php,v 1.7 2009/02/24 23:39:07 dufuz Exp $ + * @version CVS: $Id: Parser.php 276383 2009-02-24 23:39:37Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ @@ -8233,7 +8427,7 @@ require_once 'PEAR/ChannelFile.php'; * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ @@ -8272,7 +8466,7 @@ class PEAR_ChannelFile_Parser extends PEAR_XMLParser $ret->setPackagefile($file, $archive); return $ret; } -} +} <login> <summary>Connects and authenticates to remote server [Deprecated in favor of channel-login]</summary> <function>doLogin</function> @@ -8301,7 +8495,7 @@ Logs out from the remote server. This command does not actually connect to the remote server, it only deletes the stored username and password from your user configuration.</doc> </logout> -</commands> +</commands> /** * PEAR_Command_Auth (login, logout commands) * @@ -8313,7 +8507,7 @@ password from your user configuration.</doc> * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Auth.php,v 1.36 2009/02/24 23:39:29 dufuz Exp $ + * @version CVS: $Id: Auth.php 276383 2009-02-24 23:39:37Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 0.1 * @deprecated since 1.8.0alpha1 @@ -8333,7 +8527,7 @@ require_once 'PEAR/Command/Channels.php'; * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 0.1 * @deprecated since 1.8.0alpha1 @@ -8381,100 +8575,100 @@ password from your user configuration.', { parent::PEAR_Command_Channels($ui, $config); } -} +} <build> <summary>Build an Extension From C Source</summary> <function>doBuild</function> <shortcut>b</shortcut> <options /> - <doc>[package.xml]
+ <doc>[package.xml] Builds one or more extensions contained in a package.</doc> </build> -</commands> -/**
- * PEAR_Command_Auth (build command)
- *
- * PHP versions 4 and 5
- *
- * @category pear
- * @package PEAR
- * @author Stig Bakken <ssb@php.net>
- * @author Tomas V.V.Cox <cox@idecnet.com>
- * @author Greg Beaver <cellog@php.net>
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version CVS: $Id: Build.php,v 1.16 2009/02/24 23:39:29 dufuz Exp $
- * @link http://pear.php.net/package/PEAR
- * @since File available since Release 0.1
- */
-
-/**
- * base class
- */
-require_once 'PEAR/Command/Common.php';
-
-/**
- * PEAR commands for building extensions.
- *
- * @category pear
- * @package PEAR
- * @author Stig Bakken <ssb@php.net>
- * @author Tomas V.V.Cox <cox@idecnet.com>
- * @author Greg Beaver <cellog@php.net>
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.8.0
- * @link http://pear.php.net/package/PEAR
- * @since Class available since Release 0.1
- */
-class PEAR_Command_Build extends PEAR_Command_Common
-{
- var $commands = array(
- 'build' => array(
- 'summary' => 'Build an Extension From C Source',
- 'function' => 'doBuild',
- 'shortcut' => 'b',
- 'options' => array(),
- 'doc' => '[package.xml]
-Builds one or more extensions contained in a package.'
- ),
- );
-
- /**
- * PEAR_Command_Build constructor.
- *
- * @access public
- */
- function PEAR_Command_Build(&$ui, &$config)
- {
- parent::PEAR_Command_Common($ui, $config);
- }
-
- function doBuild($command, $options, $params)
- {
- require_once 'PEAR/Builder.php';
- if (sizeof($params) < 1) {
- $params[0] = 'package.xml';
- }
-
- $builder = &new PEAR_Builder($this->ui);
- $this->debug = $this->config->get('verbose');
- $err = $builder->build($params[0], array(&$this, 'buildCallback'));
- if (PEAR::isError($err)) {
- return $err;
- }
-
- return true;
- }
-
- function buildCallback($what, $data)
- {
- if (($what == 'cmdoutput' && $this->debug > 1) ||
- ($what == 'output' && $this->debug > 0)) {
- $this->ui->outputData(rtrim($data), 'build');
- }
- }
-} +</commands> +/** + * PEAR_Command_Auth (build command) + * + * PHP versions 4 and 5 + * + * @category pear + * @package PEAR + * @author Stig Bakken <ssb@php.net> + * @author Tomas V.V.Cox <cox@idecnet.com> + * @author Greg Beaver <cellog@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: Build.php 276383 2009-02-24 23:39:37Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 0.1 + */ + +/** + * base class + */ +require_once 'PEAR/Command/Common.php'; + +/** + * PEAR commands for building extensions. + * + * @category pear + * @package PEAR + * @author Stig Bakken <ssb@php.net> + * @author Tomas V.V.Cox <cox@idecnet.com> + * @author Greg Beaver <cellog@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 0.1 + */ +class PEAR_Command_Build extends PEAR_Command_Common +{ + var $commands = array( + 'build' => array( + 'summary' => 'Build an Extension From C Source', + 'function' => 'doBuild', + 'shortcut' => 'b', + 'options' => array(), + 'doc' => '[package.xml] +Builds one or more extensions contained in a package.' + ), + ); + + /** + * PEAR_Command_Build constructor. + * + * @access public + */ + function PEAR_Command_Build(&$ui, &$config) + { + parent::PEAR_Command_Common($ui, $config); + } + + function doBuild($command, $options, $params) + { + require_once 'PEAR/Builder.php'; + if (sizeof($params) < 1) { + $params[0] = 'package.xml'; + } + + $builder = &new PEAR_Builder($this->ui); + $this->debug = $this->config->get('verbose'); + $err = $builder->build($params[0], array(&$this, 'buildCallback')); + if (PEAR::isError($err)) { + return $err; + } + + return true; + } + + function buildCallback($what, $data) + { + if (($what == 'cmdoutput' && $this->debug > 1) || + ($what == 'output' && $this->debug > 0)) { + $this->ui->outputData(rtrim($data), 'build'); + } + } +} <list-channels> <summary>List Available Channels</summary> <function>doList</function> @@ -8590,12 +8784,13 @@ operations on the remote server.</doc> <function>doLogout</function> <shortcut>clo</shortcut> <options /> - <doc> -Logs out from the remote server. This command does not actually -connect to the remote server, it only deletes the stored username and -password from your user configuration.</doc> + <doc><channel name> +Logs out from a remote channel server. If <channel name> is not supplied, +the default channel is used. This command does not actually connect to the +remote server, it only deletes the stored username and password from your user +configuration.</doc> </channel-logout> -</commands> +</commands> // /* vim: set expandtab tabstop=4 shiftwidth=4: */ /** * PEAR_Command_Channels (list-channels, update-channels, channel-delete, channel-add, @@ -8609,7 +8804,7 @@ password from your user configuration.</doc> * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Channels.php,v 1.64 2009/02/24 23:39:29 dufuz Exp $ + * @version CVS: $Id: Channels.php 287561 2009-08-21 22:42:58Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ @@ -8629,7 +8824,7 @@ define('PEAR_COMMAND_CHANNELS_CHANNEL_EXISTS', -500); * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ @@ -8751,10 +8946,11 @@ operations on the remote server.', 'shortcut' => 'clo', 'function' => 'doLogout', 'options' => array(), - 'doc' => ' -Logs out from the remote server. This command does not actually -connect to the remote server, it only deletes the stored username and -password from your user configuration.', + 'doc' => '<channel name> +Logs out from a remote channel server. If <channel name> is not supplied, +the default channel is used. This command does not actually connect to the +remote server, it only deletes the stored username and password from your user +configuration.', ), ); @@ -8782,11 +8978,12 @@ password from your user configuration.', $data = array( 'caption' => 'Registered Channels:', 'border' => true, - 'headline' => array('Channel', 'Summary') + 'headline' => array('Channel', 'Alias', 'Summary') ); foreach ($registered as $channel) { $data['data'][] = array($channel->getName(), - $channel->getSummary()); + $channel->getAlias(), + $channel->getSummary()); } if (count($registered) === 0) { @@ -9269,7 +9466,7 @@ password from your user configuration.', return $this->raiseError('No channel alias specified'); } - if (count($params) !== 2) { + if (count($params) !== 2 || (!empty($params[1]) && $params[1]{0} == '-')) { return $this->raiseError( 'Invalid format, correct is: channel-alias channel alias'); } @@ -9459,20 +9656,23 @@ password from your user configuration.', function doLogout($command, $options, $params) { $reg = &$this->config->getRegistry(); - $channel = $this->config->get('default_channel'); + + // If a parameter is supplied, use that as the channel to log in to + $channel = isset($params[0]) ? $params[0] : $this->config->get('default_channel'); + $chan = $reg->getChannel($channel); if (PEAR::isError($chan)) { return $this->raiseError($chan); } - $server = $this->config->get('preferred_mirror'); + $server = $this->config->get('preferred_mirror', null, $channel); $this->ui->outputData("Logging out from $server.", $command); - $this->config->remove('username'); - $this->config->remove('password'); + $this->config->remove('username', 'user', $channel); + $this->config->remove('password', 'user', $channel); $this->config->store(); return true; } -} +} /** * PEAR_Command_Common base class * @@ -9484,7 +9684,7 @@ password from your user configuration.', * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Common.php,v 1.39 2009/02/24 23:39:29 dufuz Exp $ + * @version CVS: $Id: Common.php 276383 2009-02-24 23:39:37Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 0.1 */ @@ -9503,7 +9703,7 @@ require_once 'PEAR.php'; * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 0.1 */ @@ -9744,7 +9944,7 @@ class PEAR_Command_Common extends PEAR return $this->$func($command, $options, $params); } -} +} <config-show> <summary>Show All Settings</summary> <function>doConfigShow</function> @@ -9835,7 +10035,7 @@ PEAR installation (using the --remoteconfig option of install, upgrade, and uninstall). </doc> </config-create> -</commands> +</commands> /** * PEAR_Command_Config (config-show, config-get, config-set, config-help, config-create commands) * @@ -9847,7 +10047,7 @@ and uninstall). * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Config.php,v 1.61 2009/03/26 21:36:32 dufuz Exp $ + * @version CVS: $Id: Config.php 287554 2009-08-21 21:16:25Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 0.1 */ @@ -9866,7 +10066,7 @@ require_once 'PEAR/Command/Common.php'; * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 0.1 */ @@ -10079,7 +10279,12 @@ and uninstall). return $this->raiseError('Channel "' . $params[1] . '" does not exist'); } - if ($params[0] == 'preferred_mirror' && !$reg->channelExists($params[1])) { + if ($params[0] == 'preferred_mirror' + && ( + !$reg->mirrorExists($channel, $params[1]) && + (!$reg->channelExists($params[1]) || $channel != $params[1]) + ) + ) { $msg = 'Channel Mirror "' . $params[1] . '" does not exist'; $msg .= ' in your registry for channel "' . $channel . '".'; $msg .= "\n" . 'Attempt to run "pear channel-update ' . $channel .'"'; @@ -10242,7 +10447,7 @@ and uninstall). return false; } -} +} <install> <summary>Install Package</summary> <function>doInstall</function> @@ -10474,7 +10679,7 @@ more stable. <arg>DIR</arg> </installroot> <ignore-errors> - <shortopt>f</shortopt> + <shortopt></shortopt> <doc>force install even if there were errors</doc> </ignore-errors> <offline> @@ -10499,7 +10704,7 @@ channel not in your default channel ({config default_channel}) <arg>DIR</arg> </destination> <force> - <shortopt></shortopt> + <shortopt>f</shortopt> <doc>Force the unpacking even if there were errors in the package</doc> </force> </options> @@ -10517,7 +10722,7 @@ package if needed. Run post-installation scripts in package <package>, if any exist. </doc> </run-scripts> -</commands> +</commands> /** * PEAR_Command_Install (install, upgrade, upgrade-all, uninstall, bundle, run-scripts commands) * @@ -10529,7 +10734,7 @@ Run post-installation scripts in package <package>, if any exist. * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Install.php,v 1.153 2009/03/08 04:01:11 dufuz Exp $ + * @version CVS: $Id: Install.php 287477 2009-08-19 14:19:43Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 0.1 */ @@ -10549,7 +10754,7 @@ require_once 'PEAR/Command/Common.php'; * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 0.1 */ @@ -11082,8 +11287,7 @@ Run post-installation scripts in package <package>, if any exist. } } - $abstractpackages = array(); - $otherpackages = array(); + $abstractpackages = $otherpackages = array(); // parse params PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); @@ -11177,7 +11381,7 @@ Run post-installation scripts in package <package>, if any exist. } $this->downloader = &$this->getDownloader($this->ui, $options, $this->config); - $errors = $downloaded = $binaries = array(); + $errors = $downloaded = $binaries = array(); $downloaded = &$this->downloader->download($packages); if (PEAR::isError($downloaded)) { return $this->raiseError($downloaded); @@ -11222,8 +11426,7 @@ Run post-installation scripts in package <package>, if any exist. return true; } - $extrainfo = array(); - $binaries = array(); + $binaries = $extrainfo = array(); foreach ($downloaded as $param) { PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); $info = $this->installer->install($param, $options); @@ -11722,10 +11925,14 @@ Run post-installation scripts in package <package>, if any exist. return $this->raiseError($chan); } + $base2 = false; $preferred_mirror = $this->config->get('preferred_mirror', null, $channel); if ($chan->supportsREST($preferred_mirror) && - $base = $chan->getBaseURL('REST1.0', $preferred_mirror)) - { + ( + //($base2 = $chan->getBaseURL('REST1.4', $preferred_mirror)) || + ($base = $chan->getBaseURL('REST1.0', $preferred_mirror)) + ) + ) { $dorest = true; } @@ -11737,10 +11944,15 @@ Run post-installation scripts in package <package>, if any exist. } if ($dorest) { - $rest = &$this->config->getREST('1.0', array()); - $installed = array_flip($reg->listPackages($channel)); + if ($base2) { + $rest = &$this->config->getREST('1.4', array()); + $base = $base2; + } else { + $rest = &$this->config->getREST('1.0', array()); + } - $latest = $rest->listLatestUpgrades($base, $state, $installed, $channel, $reg); + $installed = array_flip($reg->listPackages($channel)); + $latest = $rest->listLatestUpgrades($base, $state, $installed, $channel, $reg); } PEAR::staticPopErrorHandling(); @@ -11775,7 +11987,7 @@ Run post-installation scripts in package <package>, if any exist. return $ret; } -} +} <download-all> <summary>Downloads each available package from the default channel</summary> <function>doDownloadAll</function> @@ -11792,7 +12004,7 @@ Requests a list of available packages from the default channel ({config default_ and downloads them to current working directory. Note: only packages within preferred_state ({config preferred_state}) will be downloaded</doc> </download-all> -</commands> +</commands> /** * PEAR_Command_Mirror (download-all command) * @@ -11803,7 +12015,7 @@ packages within preferred_state ({config preferred_state}) will be downloaded</d * @author Alexander Merz <alexmerz@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Mirror.php,v 1.23 2009/02/24 23:39:29 dufuz Exp $ + * @version CVS: $Id: Mirror.php 276383 2009-02-24 23:39:37Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.2.0 */ @@ -11821,7 +12033,7 @@ require_once 'PEAR/Command/Common.php'; * @author Alexander Merz <alexmerz@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.2.0 */ @@ -11930,7 +12142,7 @@ packages within preferred_state ({config preferred_state}) will be downloaded' return true; } -} +} <package> <summary>Build Package</summary> <function>doPackage</function> @@ -11945,13 +12157,13 @@ packages within preferred_state ({config preferred_state}) will be downloaded' <doc>Print the name of the packaged file.</doc> </showname> </options> - <doc>[descfile] [descfile2]
-Creates a PEAR package from its description file (usually called
-package.xml). If a second packagefile is passed in, then
-the packager will check to make sure that one is a package.xml
-version 1.0, and the other is a package.xml version 2.0. The
-package.xml version 1.0 will be saved as "package.xml" in the archive,
-and the other as "package2.xml" in the archive"
+ <doc>[descfile] [descfile2] +Creates a PEAR package from its description file (usually called +package.xml). If a second packagefile is passed in, then +the packager will check to make sure that one is a package.xml +version 1.0, and the other is a package.xml version 2.0. The +package.xml version 1.0 will be saved as "package.xml" in the archive, +and the other as "package2.xml" in the archive" </doc> </package> <package-validate> @@ -11959,7 +12171,7 @@ and the other as "package2.xml" in the archive" <function>doPackageValidate</function> <shortcut>pv</shortcut> <options /> - <doc>
+ <doc> </doc> </package-validate> <cvsdiff> @@ -12019,13 +12231,46 @@ and the other as "package2.xml" in the archive" <doc>Don't do anything, just pretend</doc> </dry-run> </options> - <doc><package.xml>
-Compares all the files in a package. Without any options, this
-command will compare the current code with the last checked-in code.
-Using the -r or -R option you may compare the current code with that
-of a specific release.
+ <doc><package.xml> +Compares all the files in a package. Without any options, this +command will compare the current code with the last checked-in code. +Using the -r or -R option you may compare the current code with that +of a specific release. </doc> </cvsdiff> + <svntag> + <summary>Set SVN Release Tag</summary> + <function>doSvnTag</function> + <shortcut>sv</shortcut> + <options> + <quiet> + <shortopt>q</shortopt> + <doc>Be quiet</doc> + </quiet> + <slide> + <shortopt>F</shortopt> + <doc>Move (slide) tag if it exists</doc> + </slide> + <delete> + <shortopt>d</shortopt> + <doc>Remove tag</doc> + </delete> + <dry-run> + <shortopt>n</shortopt> + <doc>Don't do anything, just pretend</doc> + </dry-run> + </options> + <doc><package.xml> [files...] + Sets a SVN tag on all files in a package. Use this command after you have + packaged a distribution tarball with the "package" command to tag what + revisions of what files were in that release. If need to fix something + after running cvstag once, but before the tarball is released to the public, + use the "slide" option to move the release tag. + + to include files (such as a second package.xml, or tests not included in the + release), pass them as additional parameters. + </doc> + </svntag> <cvstag> <summary>Set CVS Release Tag</summary> <function>doCvsTag</function> @@ -12052,15 +12297,15 @@ of a specific release. <doc>Don't do anything, just pretend</doc> </dry-run> </options> - <doc><package.xml> [files...]
-Sets a CVS tag on all files in a package. Use this command after you have
-packaged a distribution tarball with the "package" command to tag what
-revisions of what files were in that release. If need to fix something
-after running cvstag once, but before the tarball is released to the public,
-use the "slide" option to move the release tag.
-
-to include files (such as a second package.xml, or tests not included in the
-release), pass them as additional parameters.
+ <doc><package.xml> [files...] +Sets a CVS tag on all files in a package. Use this command after you have +packaged a distribution tarball with the "package" command to tag what +revisions of what files were in that release. If need to fix something +after running cvstag once, but before the tarball is released to the public, +use the "slide" option to move the release tag. + +to include files (such as a second package.xml, or tests not included in the +release), pass them as additional parameters. </doc> </cvstag> <package-dependencies> @@ -12068,8 +12313,9 @@ release), pass them as additional parameters. <function>doPackageDependencies</function> <shortcut>pd</shortcut> <options /> - <doc>
-List all dependencies the package has.</doc> + <doc><package-file> or <package.xml> or <install-package-name> +List all dependencies the package has. +Can take a tgz / tar file, package.xml or a package name of an installed package.</doc> </package-dependencies> <sign> <summary>Sign a package distribution file</summary> @@ -12081,7 +12327,7 @@ List all dependencies the package has.</doc> <doc>Display GnuPG output</doc> </verbose> </options> - <doc><package-file>
+ <doc><package-file> Signs a package distribution (.tar or .tgz) file with GnuPG.</doc> </sign> <makerpm> @@ -12096,22 +12342,22 @@ Signs a package distribution (.tar or .tgz) file with GnuPG.</doc> </spec-template> <rpm-pkgname> <shortopt>p</shortopt> - <doc>Use FORMAT as format string for RPM package name, %s is replaced
+ <doc>Use FORMAT as format string for RPM package name, %s is replaced by the PEAR package name, defaults to "PEAR::%s".</doc> <arg>FORMAT</arg> </rpm-pkgname> </options> - <doc><package-file>
-
-Creates an RPM .spec file for wrapping a PEAR package inside an RPM
-package. Intended to be used from the SPECS directory, with the PEAR
-package tarball in the SOURCES directory:
-
-$ pear makerpm ../SOURCES/Net_Socket-1.0.tgz
-Wrote RPM spec file PEAR::Net_Geo-1.0.spec
-$ rpm -bb PEAR::Net_Socket-1.0.spec
-...
-Wrote: /usr/src/redhat/RPMS/i386/PEAR::Net_Socket-1.0-1.i386.rpm
+ <doc><package-file> + +Creates an RPM .spec file for wrapping a PEAR package inside an RPM +package. Intended to be used from the SPECS directory, with the PEAR +package tarball in the SOURCES directory: + +$ pear makerpm ../SOURCES/Net_Socket-1.0.tgz +Wrote RPM spec file PEAR::Net_Geo-1.0.spec +$ rpm -bb PEAR::Net_Socket-1.0.spec +... +Wrote: /usr/src/redhat/RPMS/i386/PEAR::Net_Socket-1.0-1.i386.rpm </doc> </makerpm> <convert> @@ -12124,881 +12370,1122 @@ Wrote: /usr/src/redhat/RPMS/i386/PEAR::Net_Socket-1.0-1.i386.rpm <doc>do not beautify the filelist.</doc> </flat> </options> - <doc>[descfile] [descfile2]
-Converts a package.xml in 1.0 format into a package.xml
-in 2.0 format. The new file will be named package2.xml by default,
-and package.xml will be used as the old file by default.
-This is not the most intelligent conversion, and should only be
-used for automated conversion or learning the format.
+ <doc>[descfile] [descfile2] +Converts a package.xml in 1.0 format into a package.xml +in 2.0 format. The new file will be named package2.xml by default, +and package.xml will be used as the old file by default. +This is not the most intelligent conversion, and should only be +used for automated conversion or learning the format. </doc> </convert> -</commands> -/**
- * PEAR_Command_Package (package, package-validate, cvsdiff, cvstag, package-dependencies,
- * sign, makerpm, convert commands)
- *
- * PHP versions 4 and 5
- *
- * @category pear
- * @package PEAR
- * @author Stig Bakken <ssb@php.net>
- * @author Martin Jansen <mj@php.net>
- * @author Greg Beaver <cellog@php.net>
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version CVS: $Id: Package.php,v 1.133 2009/03/25 02:15:57 dufuz Exp $
- * @link http://pear.php.net/package/PEAR
- * @since File available since Release 0.1
- */
-
-/**
- * base class
- */
-require_once 'PEAR/Command/Common.php';
-
-/**
- * PEAR commands for login/logout
- *
- * @category pear
- * @package PEAR
- * @author Stig Bakken <ssb@php.net>
- * @author Martin Jansen <mj@php.net>
- * @author Greg Beaver <cellog@php.net>
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: @package_version@
- * @link http://pear.php.net/package/PEAR
- * @since Class available since Release 0.1
- */
-
-class PEAR_Command_Package extends PEAR_Command_Common
-{
- var $commands = array(
- 'package' => array(
- 'summary' => 'Build Package',
- 'function' => 'doPackage',
- 'shortcut' => 'p',
- 'options' => array(
- 'nocompress' => array(
- 'shortopt' => 'Z',
- 'doc' => 'Do not gzip the package file'
- ),
- 'showname' => array(
- 'shortopt' => 'n',
- 'doc' => 'Print the name of the packaged file.',
- ),
- ),
- 'doc' => '[descfile] [descfile2]
-Creates a PEAR package from its description file (usually called
-package.xml). If a second packagefile is passed in, then
-the packager will check to make sure that one is a package.xml
-version 1.0, and the other is a package.xml version 2.0. The
-package.xml version 1.0 will be saved as "package.xml" in the archive,
-and the other as "package2.xml" in the archive"
-'
- ),
- 'package-validate' => array(
- 'summary' => 'Validate Package Consistency',
- 'function' => 'doPackageValidate',
- 'shortcut' => 'pv',
- 'options' => array(),
- 'doc' => '
-',
- ),
- 'cvsdiff' => array(
- 'summary' => 'Run a "cvs diff" for all files in a package',
- 'function' => 'doCvsDiff',
- 'shortcut' => 'cd',
- 'options' => array(
- 'quiet' => array(
- 'shortopt' => 'q',
- 'doc' => 'Be quiet',
- ),
- 'reallyquiet' => array(
- 'shortopt' => 'Q',
- 'doc' => 'Be really quiet',
- ),
- 'date' => array(
- 'shortopt' => 'D',
- 'doc' => 'Diff against revision of DATE',
- 'arg' => 'DATE',
- ),
- 'release' => array(
- 'shortopt' => 'R',
- 'doc' => 'Diff against tag for package release REL',
- 'arg' => 'REL',
- ),
- 'revision' => array(
- 'shortopt' => 'r',
- 'doc' => 'Diff against revision REV',
- 'arg' => 'REV',
- ),
- 'context' => array(
- 'shortopt' => 'c',
- 'doc' => 'Generate context diff',
- ),
- 'unified' => array(
- 'shortopt' => 'u',
- 'doc' => 'Generate unified diff',
- ),
- 'ignore-case' => array(
- 'shortopt' => 'i',
- 'doc' => 'Ignore case, consider upper- and lower-case letters equivalent',
- ),
- 'ignore-whitespace' => array(
- 'shortopt' => 'b',
- 'doc' => 'Ignore changes in amount of white space',
- ),
- 'ignore-blank-lines' => array(
- 'shortopt' => 'B',
- 'doc' => 'Ignore changes that insert or delete blank lines',
- ),
- 'brief' => array(
- 'doc' => 'Report only whether the files differ, no details',
- ),
- 'dry-run' => array(
- 'shortopt' => 'n',
- 'doc' => 'Don\'t do anything, just pretend',
- ),
- ),
- 'doc' => '<package.xml>
-Compares all the files in a package. Without any options, this
-command will compare the current code with the last checked-in code.
-Using the -r or -R option you may compare the current code with that
-of a specific release.
-',
- ),
- 'cvstag' => array(
- 'summary' => 'Set CVS Release Tag',
- 'function' => 'doCvsTag',
- 'shortcut' => 'ct',
- 'options' => array(
- 'quiet' => array(
- 'shortopt' => 'q',
- 'doc' => 'Be quiet',
- ),
- 'reallyquiet' => array(
- 'shortopt' => 'Q',
- 'doc' => 'Be really quiet',
- ),
- 'slide' => array(
- 'shortopt' => 'F',
- 'doc' => 'Move (slide) tag if it exists',
- ),
- 'delete' => array(
- 'shortopt' => 'd',
- 'doc' => 'Remove tag',
- ),
- 'dry-run' => array(
- 'shortopt' => 'n',
- 'doc' => 'Don\'t do anything, just pretend',
- ),
- ),
- 'doc' => '<package.xml> [files...]
-Sets a CVS tag on all files in a package. Use this command after you have
-packaged a distribution tarball with the "package" command to tag what
-revisions of what files were in that release. If need to fix something
-after running cvstag once, but before the tarball is released to the public,
-use the "slide" option to move the release tag.
-
-to include files (such as a second package.xml, or tests not included in the
-release), pass them as additional parameters.
-',
- ),
- 'package-dependencies' => array(
- 'summary' => 'Show package dependencies',
- 'function' => 'doPackageDependencies',
- 'shortcut' => 'pd',
- 'options' => array(),
- 'doc' => '
-List all dependencies the package has.'
- ),
- 'sign' => array(
- 'summary' => 'Sign a package distribution file',
- 'function' => 'doSign',
- 'shortcut' => 'si',
- 'options' => array(
- 'verbose' => array(
- 'shortopt' => 'v',
- 'doc' => 'Display GnuPG output',
- ),
- ),
- 'doc' => '<package-file>
-Signs a package distribution (.tar or .tgz) file with GnuPG.',
- ),
- 'makerpm' => array(
- 'summary' => 'Builds an RPM spec file from a PEAR package',
- 'function' => 'doMakeRPM',
- 'shortcut' => 'rpm',
- 'options' => array(
- 'spec-template' => array(
- 'shortopt' => 't',
- 'arg' => 'FILE',
- 'doc' => 'Use FILE as RPM spec file template'
- ),
- 'rpm-pkgname' => array(
- 'shortopt' => 'p',
- 'arg' => 'FORMAT',
- 'doc' => 'Use FORMAT as format string for RPM package name, %s is replaced
-by the PEAR package name, defaults to "PEAR::%s".',
- ),
- ),
- 'doc' => '<package-file>
-
-Creates an RPM .spec file for wrapping a PEAR package inside an RPM
-package. Intended to be used from the SPECS directory, with the PEAR
-package tarball in the SOURCES directory:
-
-$ pear makerpm ../SOURCES/Net_Socket-1.0.tgz
-Wrote RPM spec file PEAR::Net_Geo-1.0.spec
-$ rpm -bb PEAR::Net_Socket-1.0.spec
-...
-Wrote: /usr/src/redhat/RPMS/i386/PEAR::Net_Socket-1.0-1.i386.rpm
-',
- ),
- 'convert' => array(
- 'summary' => 'Convert a package.xml 1.0 to package.xml 2.0 format',
- 'function' => 'doConvert',
- 'shortcut' => 'c2',
- 'options' => array(
- 'flat' => array(
- 'shortopt' => 'f',
- 'doc' => 'do not beautify the filelist.',
- ),
- ),
- 'doc' => '[descfile] [descfile2]
-Converts a package.xml in 1.0 format into a package.xml
-in 2.0 format. The new file will be named package2.xml by default,
-and package.xml will be used as the old file by default.
-This is not the most intelligent conversion, and should only be
-used for automated conversion or learning the format.
-'
- ),
- );
-
- var $output;
-
- /**
- * PEAR_Command_Package constructor.
- *
- * @access public
- */
- function PEAR_Command_Package(&$ui, &$config)
- {
- parent::PEAR_Command_Common($ui, $config);
- }
-
- function _displayValidationResults($err, $warn, $strict = false)
- {
- foreach ($err as $e) {
- $this->output .= "Error: $e\n";
- }
- foreach ($warn as $w) {
- $this->output .= "Warning: $w\n";
- }
- $this->output .= sprintf('Validation: %d error(s), %d warning(s)'."\n",
- sizeof($err), sizeof($warn));
- if ($strict && count($err) > 0) {
- $this->output .= "Fix these errors and try again.";
- return false;
- }
- return true;
- }
-
- function &getPackager()
- {
- if (!class_exists('PEAR_Packager')) {
- require_once 'PEAR/Packager.php';
- }
- $a = &new PEAR_Packager;
- return $a;
- }
-
- function &getPackageFile($config, $debug = false, $tmpdir = null)
- {
- if (!class_exists('PEAR_Common')) {
- require_once 'PEAR/Common.php';
- }
- if (!class_exists('PEAR_PackageFile')) {
- require_once 'PEAR/PackageFile.php';
- }
- $a = &new PEAR_PackageFile($config, $debug, $tmpdir);
- $common = new PEAR_Common;
- $common->ui = $this->ui;
- $a->setLogger($common);
- return $a;
- }
-
- function doPackage($command, $options, $params)
- {
- $this->output = '';
- $pkginfofile = isset($params[0]) ? $params[0] : 'package.xml';
- $pkg2 = isset($params[1]) ? $params[1] : null;
- if (!$pkg2 && !isset($params[0]) && file_exists('package2.xml')) {
- $pkg2 = 'package2.xml';
- }
-
- $packager = &$this->getPackager();
- $compress = empty($options['nocompress']) ? true : false;
- $result = $packager->package($pkginfofile, $compress, $pkg2);
- if (PEAR::isError($result)) {
- return $this->raiseError($result);
- }
-
- // Don't want output, only the package file name just created
- if (isset($options['showname'])) {
- $this->output = $result;
- }
-
- if ($this->output) {
- $this->ui->outputData($this->output, $command);
- }
-
- return true;
- }
-
- function doPackageValidate($command, $options, $params)
- {
- $this->output = '';
- if (count($params) < 1) {
- $params[0] = 'package.xml';
- }
-
- $obj = &$this->getPackageFile($this->config, $this->_debug);
- $obj->rawReturn();
- PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
- $info = $obj->fromTgzFile($params[0], PEAR_VALIDATE_NORMAL);
- if (PEAR::isError($info)) {
- $info = $obj->fromPackageFile($params[0], PEAR_VALIDATE_NORMAL);
- } else {
- $archive = $info->getArchiveFile();
- $tar = &new Archive_Tar($archive);
- $tar->extract(dirname($info->getPackageFile()));
- $info->setPackageFile(dirname($info->getPackageFile()) . DIRECTORY_SEPARATOR .
- $info->getPackage() . '-' . $info->getVersion() . DIRECTORY_SEPARATOR .
- basename($info->getPackageFile()));
- }
-
- PEAR::staticPopErrorHandling();
- if (PEAR::isError($info)) {
- return $this->raiseError($info);
- }
-
- $valid = false;
- if ($info->getPackagexmlVersion() == '2.0') {
- if ($valid = $info->validate(PEAR_VALIDATE_NORMAL)) {
- $info->flattenFileList();
- $valid = $info->validate(PEAR_VALIDATE_PACKAGING);
- }
- } else {
- $valid = $info->validate(PEAR_VALIDATE_PACKAGING);
- }
-
- $err = $warn = array();
- if ($errors = $info->getValidationWarnings()) {
- foreach ($errors as $error) {
- if ($error['level'] == 'warning') {
- $warn[] = $error['message'];
- } else {
- $err[] = $error['message'];
- }
- }
- }
-
- $this->_displayValidationResults($err, $warn);
- $this->ui->outputData($this->output, $command);
- return true;
- }
-
- function doCvsTag($command, $options, $params)
- {
- $this->output = '';
- $_cmd = $command;
- if (count($params) < 1) {
- $help = $this->getHelp($command);
- return $this->raiseError("$command: missing parameter: $help[0]");
- }
-
- $packageFile = realpath($params[0]);
- $obj = &$this->getPackageFile($this->config, $this->_debug);
- $info = $obj->fromAnyFile($packageFile, PEAR_VALIDATE_NORMAL);
- if (PEAR::isError($info)) {
- return $this->raiseError($info);
- }
-
- $err = $warn = array();
- if (!$info->validate()) {
- foreach ($info->getValidationWarnings() as $error) {
- if ($error['level'] == 'warning') {
- $warn[] = $error['message'];
- } else {
- $err[] = $error['message'];
- }
- }
- }
-
- if (!$this->_displayValidationResults($err, $warn, true)) {
- $this->ui->outputData($this->output, $command);
- return $this->raiseError('CVS tag failed');
- }
-
- $version = $info->getVersion();
- $cvsversion = preg_replace('/[^a-z0-9]/i', '_', $version);
- $cvstag = "RELEASE_$cvsversion";
- $files = array_keys($info->getFilelist());
- $command = 'cvs';
- if (isset($options['quiet'])) {
- $command .= ' -q';
- }
-
- if (isset($options['reallyquiet'])) {
- $command .= ' -Q';
- }
-
- $command .= ' tag';
- if (isset($options['slide'])) {
- $command .= ' -F';
- }
-
- if (isset($options['delete'])) {
- $command .= ' -d';
- }
-
- $command .= ' ' . $cvstag . ' ' . escapeshellarg($params[0]);
- array_shift($params);
- if (count($params)) {
- // add in additional files to be tagged
- $files = array_merge($files, $params);
- }
-
- $dir = dirname($packageFile);
- $dir = substr($dir, strrpos($dir, '/') + 1);
- foreach ($files as $file) {
- if (!file_exists($file)) {
- $file = $dir . DIRECTORY_SEPARATOR . $file;
- }
- $command .= ' ' . escapeshellarg($file);
- }
-
- if ($this->config->get('verbose') > 1) {
- $this->output .= "+ $command\n";
- }
-
- $this->output .= "+ $command\n";
- if (empty($options['dry-run'])) {
- $fp = popen($command, "r");
- while ($line = fgets($fp, 1024)) {
- $this->output .= rtrim($line)."\n";
- }
- pclose($fp);
- }
-
- $this->ui->outputData($this->output, $_cmd);
- return true;
- }
-
- function doCvsDiff($command, $options, $params)
- {
- $this->output = '';
- if (sizeof($params) < 1) {
- $help = $this->getHelp($command);
- return $this->raiseError("$command: missing parameter: $help[0]");
- }
-
- $file = realpath($params[0]);
- $obj = &$this->getPackageFile($this->config, $this->_debug);
- $info = $obj->fromAnyFile($file, PEAR_VALIDATE_NORMAL);
- if (PEAR::isError($info)) {
- return $this->raiseError($info);
- }
-
- $err = $warn = array();
- if (!$info->validate()) {
- foreach ($info->getValidationWarnings() as $error) {
- if ($error['level'] == 'warning') {
- $warn[] = $error['message'];
- } else {
- $err[] = $error['message'];
- }
- }
- }
-
- if (!$this->_displayValidationResults($err, $warn, true)) {
- $this->ui->outputData($this->output, $command);
- return $this->raiseError('CVS diff failed');
- }
-
- $info1 = $info->getFilelist();
- $files = $info1;
- $cmd = "cvs";
- if (isset($options['quiet'])) {
- $cmd .= ' -q';
- unset($options['quiet']);
- }
-
- if (isset($options['reallyquiet'])) {
- $cmd .= ' -Q';
- unset($options['reallyquiet']);
- }
-
- if (isset($options['release'])) {
- $cvsversion = preg_replace('/[^a-z0-9]/i', '_', $options['release']);
- $cvstag = "RELEASE_$cvsversion";
- $options['revision'] = $cvstag;
- unset($options['release']);
- }
-
- $execute = true;
- if (isset($options['dry-run'])) {
- $execute = false;
- unset($options['dry-run']);
- }
-
- $cmd .= ' diff';
- // the rest of the options are passed right on to "cvs diff"
- foreach ($options as $option => $optarg) {
- $arg = $short = false;
- if (isset($this->commands[$command]['options'][$option])) {
- $arg = $this->commands[$command]['options'][$option]['arg'];
- $short = $this->commands[$command]['options'][$option]['shortopt'];
- }
- $cmd .= $short ? " -$short" : " --$option";
- if ($arg && $optarg) {
- $cmd .= ($short ? '' : '=') . escapeshellarg($optarg);
- }
- }
-
- foreach ($files as $file) {
- $cmd .= ' ' . escapeshellarg($file['name']);
- }
-
- if ($this->config->get('verbose') > 1) {
- $this->output .= "+ $cmd\n";
- }
-
- if ($execute) {
- $fp = popen($cmd, "r");
- while ($line = fgets($fp, 1024)) {
- $this->output .= rtrim($line)."\n";
- }
- pclose($fp);
- }
-
- $this->ui->outputData($this->output, $command);
- return true;
- }
-
- function doPackageDependencies($command, $options, $params)
- {
- // $params[0] -> the PEAR package to list its information
- if (count($params) !== 1) {
- return $this->raiseError("bad parameter(s), try \"help $command\"");
- }
-
- $obj = &$this->getPackageFile($this->config, $this->_debug);
- $info = $obj->fromAnyFile($params[0], PEAR_VALIDATE_NORMAL);
- if (PEAR::isError($info)) {
- return $this->raiseError($info);
- }
-
- $deps = $info->getDeps();
- if (is_array($deps)) {
- if ($info->getPackagexmlVersion() == '1.0') {
- $data = array(
- 'caption' => 'Dependencies for pear/' . $info->getPackage(),
- 'border' => true,
- 'headline' => array("Required?", "Type", "Name", "Relation", "Version"),
- );
-
- foreach ($deps as $d) {
- if (isset($d['optional'])) {
- if ($d['optional'] == 'yes') {
- $req = 'No';
- } else {
- $req = 'Yes';
- }
- } else {
- $req = 'Yes';
- }
-
- if (isset($this->_deps_rel_trans[$d['rel']])) {
- $rel = $this->_deps_rel_trans[$d['rel']];
- } else {
- $rel = $d['rel'];
- }
-
- if (isset($this->_deps_type_trans[$d['type']])) {
- $type = ucfirst($this->_deps_type_trans[$d['type']]);
- } else {
- $type = $d['type'];
- }
-
- if (isset($d['name'])) {
- $name = $d['name'];
- } else {
- $name = '';
- }
-
- if (isset($d['version'])) {
- $version = $d['version'];
- } else {
- $version = '';
- }
-
- $data['data'][] = array($req, $type, $name, $rel, $version);
- }
- } else { // package.xml 2.0 dependencies display
- require_once 'PEAR/Dependency2.php';
- $deps = $info->getDependencies();
- $reg = &$this->config->getRegistry();
- if (is_array($deps)) {
- $d = new PEAR_Dependency2($this->config, array(), '');
- $data = array(
- 'caption' => 'Dependencies for ' . $info->getPackage(),
- 'border' => true,
- 'headline' => array("Required?", "Type", "Name", 'Versioning', 'Group'),
- );
- foreach ($deps as $type => $subd) {
- $req = ($type == 'required') ? 'Yes' : 'No';
- if ($type == 'group') {
- $group = $subd['attribs']['name'];
- } else {
- $group = '';
- }
-
- if (!isset($subd[0])) {
- $subd = array($subd);
- }
-
- foreach ($subd as $groupa) {
- foreach ($groupa as $deptype => $depinfo) {
- if ($deptype == 'attribs') {
- continue;
- }
-
- if ($deptype == 'pearinstaller') {
- $deptype = 'pear Installer';
- }
-
- if (!isset($depinfo[0])) {
- $depinfo = array($depinfo);
- }
-
- foreach ($depinfo as $inf) {
- $name = '';
- if (isset($inf['channel'])) {
- $alias = $reg->channelAlias($inf['channel']);
- if (!$alias) {
- $alias = '(channel?) ' .$inf['channel'];
- }
- $name = $alias . '/';
-
- }
- if (isset($inf['name'])) {
- $name .= $inf['name'];
- } elseif (isset($inf['pattern'])) {
- $name .= $inf['pattern'];
- } else {
- $name .= '';
- }
-
- if (isset($inf['uri'])) {
- $name .= ' [' . $inf['uri'] . ']';
- }
-
- if (isset($inf['conflicts'])) {
- $ver = 'conflicts';
- } else {
- $ver = $d->_getExtraString($inf);
- }
-
- $data['data'][] = array($req, ucfirst($deptype), $name,
- $ver, $group);
- }
- }
- }
- }
- }
- }
-
- $this->ui->outputData($data, $command);
- return true;
- }
-
- // Fallback
- $this->ui->outputData("This package does not have any dependencies.", $command);
- }
-
- function doSign($command, $options, $params)
- {
- // should move most of this code into PEAR_Packager
- // so it'll be easy to implement "pear package --sign"
- if (count($params) !== 1) {
- return $this->raiseError("bad parameter(s), try \"help $command\"");
- }
-
- require_once 'System.php';
- require_once 'Archive/Tar.php';
-
- if (!file_exists($params[0])) {
- return $this->raiseError("file does not exist: $params[0]");
- }
-
- $obj = $this->getPackageFile($this->config, $this->_debug);
- $info = $obj->fromTgzFile($params[0], PEAR_VALIDATE_NORMAL);
- if (PEAR::isError($info)) {
- return $this->raiseError($info);
- }
-
- $tar = new Archive_Tar($params[0]);
- $tmpdir = System::mktemp('-d pearsign');
- if (!$tar->extractList('package2.xml package.xml package.sig', $tmpdir)) {
- return $this->raiseError("failed to extract tar file");
- }
-
- if (file_exists("$tmpdir/package.sig")) {
- return $this->raiseError("package already signed");
- }
-
- $packagexml = 'package.xml';
- if (file_exists("$tmpdir/package2.xml")) {
- $packagexml = 'package2.xml';
- }
-
- if (file_exists("$tmpdir/package.sig")) {
- unlink("$tmpdir/package.sig");
- }
-
- if (!file_exists("$tmpdir/$packagexml")) {
- return $this->raiseError("Extracted file $tmpdir/$packagexml not found.");
- }
-
- $input = $this->ui->userDialog($command,
- array('GnuPG Passphrase'),
- array('password'));
- if (!isset($input[0])) {
- //use empty passphrase
- $input[0] = '';
- }
-
- $devnull = (isset($options['verbose'])) ? '' : ' 2>/dev/null';
- $gpg = popen("gpg --batch --passphrase-fd 0 --armor --detach-sign --output $tmpdir/package.sig $tmpdir/$packagexml" . $devnull, "w");
- if (!$gpg) {
- return $this->raiseError("gpg command failed");
- }
-
- fwrite($gpg, "$input[0]\n");
- if (pclose($gpg) || !file_exists("$tmpdir/package.sig")) {
- return $this->raiseError("gpg sign failed");
- }
-
- if (!$tar->addModify("$tmpdir/package.sig", '', $tmpdir)) {
- return $this->raiseError('failed adding signature to file');
- }
-
- $this->ui->outputData("Package signed.", $command);
- return true;
- }
-
- /**
- * For unit testing purposes
- */
- function &getInstaller(&$ui)
- {
- if (!class_exists('PEAR_Installer')) {
- require_once 'PEAR/Installer.php';
- }
- $a = &new PEAR_Installer($ui);
- return $a;
- }
-
- /**
- * For unit testing purposes
- */
- function &getCommandPackaging(&$ui, &$config)
- {
- if (!class_exists('PEAR_Command_Packaging')) {
- if ($fp = @fopen('PEAR/Command/Packaging.php', 'r', true)) {
- fclose($fp);
- include_once 'PEAR/Command/Packaging.php';
- }
- }
-
- if (class_exists('PEAR_Command_Packaging')) {
- $a = &new PEAR_Command_Packaging($ui, $config);
- } else {
- $a = null;
- }
-
- return $a;
- }
-
- function doMakeRPM($command, $options, $params)
- {
-
- // Check to see if PEAR_Command_Packaging is installed, and
- // transparently switch to use the "make-rpm-spec" command from it
- // instead, if it does. Otherwise, continue to use the old version
- // of "makerpm" supplied with this package (PEAR).
- $packaging_cmd = $this->getCommandPackaging($this->ui, $this->config);
- if ($packaging_cmd !== null) {
- $this->ui->outputData('PEAR_Command_Packaging is installed; using '.
- 'newer "make-rpm-spec" command instead');
- return $packaging_cmd->run('make-rpm-spec', $options, $params);
- }
-
- $this->ui->outputData('WARNING: "pear makerpm" is no longer available; an '.
- 'improved version is available via "pear make-rpm-spec", which '.
- 'is available by installing PEAR_Command_Packaging');
- return true;
- }
-
- function doConvert($command, $options, $params)
- {
- $packagexml = isset($params[0]) ? $params[0] : 'package.xml';
- $newpackagexml = isset($params[1]) ? $params[1] : dirname($packagexml) .
- DIRECTORY_SEPARATOR . 'package2.xml';
- $pkg = &$this->getPackageFile($this->config, $this->_debug);
- PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
- $pf = $pkg->fromPackageFile($packagexml, PEAR_VALIDATE_NORMAL);
- PEAR::staticPopErrorHandling();
- if (PEAR::isError($pf)) {
- if (is_array($pf->getUserInfo())) {
- foreach ($pf->getUserInfo() as $warning) {
- $this->ui->outputData($warning['message']);
- }
- }
- return $this->raiseError($pf);
- }
-
- if (is_a($pf, 'PEAR_PackageFile_v2')) {
- $this->ui->outputData($packagexml . ' is already a package.xml version 2.0');
- return true;
- }
-
- $gen = &$pf->getDefaultGenerator();
- $newpf = &$gen->toV2();
- $newpf->setPackagefile($newpackagexml);
- $gen = &$newpf->getDefaultGenerator();
- PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
- $state = (isset($options['flat']) ? PEAR_VALIDATE_PACKAGING : PEAR_VALIDATE_NORMAL);
- $saved = $gen->toPackageFile(dirname($newpackagexml), $state, basename($newpackagexml));
- PEAR::staticPopErrorHandling();
- if (PEAR::isError($saved)) {
- if (is_array($saved->getUserInfo())) {
- foreach ($saved->getUserInfo() as $warning) {
- $this->ui->outputData($warning['message']);
- }
- }
-
- $this->ui->outputData($saved->getMessage());
- return true;
- }
-
- $this->ui->outputData('Wrote new version 2.0 package.xml to "' . $saved . '"');
- return true;
- }
-} +</commands> +/** + * PEAR_Command_Package (package, package-validate, cvsdiff, cvstag, package-dependencies, + * sign, makerpm, convert commands) + * + * PHP versions 4 and 5 + * + * @category pear + * @package PEAR + * @author Stig Bakken <ssb@php.net> + * @author Martin Jansen <mj@php.net> + * @author Greg Beaver <cellog@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: Package.php 287559 2009-08-21 22:33:10Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 0.1 + */ + +/** + * base class + */ +require_once 'PEAR/Command/Common.php'; + +/** + * PEAR commands for login/logout + * + * @category pear + * @package PEAR + * @author Stig Bakken <ssb@php.net> + * @author Martin Jansen <mj@php.net> + * @author Greg Beaver <cellog@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: @package_version@ + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 0.1 + */ + +class PEAR_Command_Package extends PEAR_Command_Common +{ + var $commands = array( + 'package' => array( + 'summary' => 'Build Package', + 'function' => 'doPackage', + 'shortcut' => 'p', + 'options' => array( + 'nocompress' => array( + 'shortopt' => 'Z', + 'doc' => 'Do not gzip the package file' + ), + 'showname' => array( + 'shortopt' => 'n', + 'doc' => 'Print the name of the packaged file.', + ), + ), + 'doc' => '[descfile] [descfile2] +Creates a PEAR package from its description file (usually called +package.xml). If a second packagefile is passed in, then +the packager will check to make sure that one is a package.xml +version 1.0, and the other is a package.xml version 2.0. The +package.xml version 1.0 will be saved as "package.xml" in the archive, +and the other as "package2.xml" in the archive" +' + ), + 'package-validate' => array( + 'summary' => 'Validate Package Consistency', + 'function' => 'doPackageValidate', + 'shortcut' => 'pv', + 'options' => array(), + 'doc' => ' +', + ), + 'cvsdiff' => array( + 'summary' => 'Run a "cvs diff" for all files in a package', + 'function' => 'doCvsDiff', + 'shortcut' => 'cd', + 'options' => array( + 'quiet' => array( + 'shortopt' => 'q', + 'doc' => 'Be quiet', + ), + 'reallyquiet' => array( + 'shortopt' => 'Q', + 'doc' => 'Be really quiet', + ), + 'date' => array( + 'shortopt' => 'D', + 'doc' => 'Diff against revision of DATE', + 'arg' => 'DATE', + ), + 'release' => array( + 'shortopt' => 'R', + 'doc' => 'Diff against tag for package release REL', + 'arg' => 'REL', + ), + 'revision' => array( + 'shortopt' => 'r', + 'doc' => 'Diff against revision REV', + 'arg' => 'REV', + ), + 'context' => array( + 'shortopt' => 'c', + 'doc' => 'Generate context diff', + ), + 'unified' => array( + 'shortopt' => 'u', + 'doc' => 'Generate unified diff', + ), + 'ignore-case' => array( + 'shortopt' => 'i', + 'doc' => 'Ignore case, consider upper- and lower-case letters equivalent', + ), + 'ignore-whitespace' => array( + 'shortopt' => 'b', + 'doc' => 'Ignore changes in amount of white space', + ), + 'ignore-blank-lines' => array( + 'shortopt' => 'B', + 'doc' => 'Ignore changes that insert or delete blank lines', + ), + 'brief' => array( + 'doc' => 'Report only whether the files differ, no details', + ), + 'dry-run' => array( + 'shortopt' => 'n', + 'doc' => 'Don\'t do anything, just pretend', + ), + ), + 'doc' => '<package.xml> +Compares all the files in a package. Without any options, this +command will compare the current code with the last checked-in code. +Using the -r or -R option you may compare the current code with that +of a specific release. +', + ), + 'svntag' => array( + 'summary' => 'Set SVN Release Tag', + 'function' => 'doSvnTag', + 'shortcut' => 'sv', + 'options' => array( + 'quiet' => array( + 'shortopt' => 'q', + 'doc' => 'Be quiet', + ), + 'slide' => array( + 'shortopt' => 'F', + 'doc' => 'Move (slide) tag if it exists', + ), + 'delete' => array( + 'shortopt' => 'd', + 'doc' => 'Remove tag', + ), + 'dry-run' => array( + 'shortopt' => 'n', + 'doc' => 'Don\'t do anything, just pretend', + ), + ), + 'doc' => '<package.xml> [files...] + Sets a SVN tag on all files in a package. Use this command after you have + packaged a distribution tarball with the "package" command to tag what + revisions of what files were in that release. If need to fix something + after running cvstag once, but before the tarball is released to the public, + use the "slide" option to move the release tag. + + to include files (such as a second package.xml, or tests not included in the + release), pass them as additional parameters. + ', + ), + 'cvstag' => array( + 'summary' => 'Set CVS Release Tag', + 'function' => 'doCvsTag', + 'shortcut' => 'ct', + 'options' => array( + 'quiet' => array( + 'shortopt' => 'q', + 'doc' => 'Be quiet', + ), + 'reallyquiet' => array( + 'shortopt' => 'Q', + 'doc' => 'Be really quiet', + ), + 'slide' => array( + 'shortopt' => 'F', + 'doc' => 'Move (slide) tag if it exists', + ), + 'delete' => array( + 'shortopt' => 'd', + 'doc' => 'Remove tag', + ), + 'dry-run' => array( + 'shortopt' => 'n', + 'doc' => 'Don\'t do anything, just pretend', + ), + ), + 'doc' => '<package.xml> [files...] +Sets a CVS tag on all files in a package. Use this command after you have +packaged a distribution tarball with the "package" command to tag what +revisions of what files were in that release. If need to fix something +after running cvstag once, but before the tarball is released to the public, +use the "slide" option to move the release tag. + +to include files (such as a second package.xml, or tests not included in the +release), pass them as additional parameters. +', + ), + 'package-dependencies' => array( + 'summary' => 'Show package dependencies', + 'function' => 'doPackageDependencies', + 'shortcut' => 'pd', + 'options' => array(), + 'doc' => '<package-file> or <package.xml> or <install-package-name> +List all dependencies the package has. +Can take a tgz / tar file, package.xml or a package name of an installed package.' + ), + 'sign' => array( + 'summary' => 'Sign a package distribution file', + 'function' => 'doSign', + 'shortcut' => 'si', + 'options' => array( + 'verbose' => array( + 'shortopt' => 'v', + 'doc' => 'Display GnuPG output', + ), + ), + 'doc' => '<package-file> +Signs a package distribution (.tar or .tgz) file with GnuPG.', + ), + 'makerpm' => array( + 'summary' => 'Builds an RPM spec file from a PEAR package', + 'function' => 'doMakeRPM', + 'shortcut' => 'rpm', + 'options' => array( + 'spec-template' => array( + 'shortopt' => 't', + 'arg' => 'FILE', + 'doc' => 'Use FILE as RPM spec file template' + ), + 'rpm-pkgname' => array( + 'shortopt' => 'p', + 'arg' => 'FORMAT', + 'doc' => 'Use FORMAT as format string for RPM package name, %s is replaced +by the PEAR package name, defaults to "PEAR::%s".', + ), + ), + 'doc' => '<package-file> + +Creates an RPM .spec file for wrapping a PEAR package inside an RPM +package. Intended to be used from the SPECS directory, with the PEAR +package tarball in the SOURCES directory: + +$ pear makerpm ../SOURCES/Net_Socket-1.0.tgz +Wrote RPM spec file PEAR::Net_Geo-1.0.spec +$ rpm -bb PEAR::Net_Socket-1.0.spec +... +Wrote: /usr/src/redhat/RPMS/i386/PEAR::Net_Socket-1.0-1.i386.rpm +', + ), + 'convert' => array( + 'summary' => 'Convert a package.xml 1.0 to package.xml 2.0 format', + 'function' => 'doConvert', + 'shortcut' => 'c2', + 'options' => array( + 'flat' => array( + 'shortopt' => 'f', + 'doc' => 'do not beautify the filelist.', + ), + ), + 'doc' => '[descfile] [descfile2] +Converts a package.xml in 1.0 format into a package.xml +in 2.0 format. The new file will be named package2.xml by default, +and package.xml will be used as the old file by default. +This is not the most intelligent conversion, and should only be +used for automated conversion or learning the format. +' + ), + ); + + var $output; + + /** + * PEAR_Command_Package constructor. + * + * @access public + */ + function PEAR_Command_Package(&$ui, &$config) + { + parent::PEAR_Command_Common($ui, $config); + } + + function _displayValidationResults($err, $warn, $strict = false) + { + foreach ($err as $e) { + $this->output .= "Error: $e\n"; + } + foreach ($warn as $w) { + $this->output .= "Warning: $w\n"; + } + $this->output .= sprintf('Validation: %d error(s), %d warning(s)'."\n", + sizeof($err), sizeof($warn)); + if ($strict && count($err) > 0) { + $this->output .= "Fix these errors and try again."; + return false; + } + return true; + } + + function &getPackager() + { + if (!class_exists('PEAR_Packager')) { + require_once 'PEAR/Packager.php'; + } + $a = &new PEAR_Packager; + return $a; + } + + function &getPackageFile($config, $debug = false, $tmpdir = null) + { + if (!class_exists('PEAR_Common')) { + require_once 'PEAR/Common.php'; + } + if (!class_exists('PEAR_PackageFile')) { + require_once 'PEAR/PackageFile.php'; + } + $a = &new PEAR_PackageFile($config, $debug, $tmpdir); + $common = new PEAR_Common; + $common->ui = $this->ui; + $a->setLogger($common); + return $a; + } + + function doPackage($command, $options, $params) + { + $this->output = ''; + $pkginfofile = isset($params[0]) ? $params[0] : 'package.xml'; + $pkg2 = isset($params[1]) ? $params[1] : null; + if (!$pkg2 && !isset($params[0]) && file_exists('package2.xml')) { + $pkg2 = 'package2.xml'; + } + + $packager = &$this->getPackager(); + $compress = empty($options['nocompress']) ? true : false; + $result = $packager->package($pkginfofile, $compress, $pkg2); + if (PEAR::isError($result)) { + return $this->raiseError($result); + } + + // Don't want output, only the package file name just created + if (isset($options['showname'])) { + $this->output = $result; + } + + if ($this->output) { + $this->ui->outputData($this->output, $command); + } + + return true; + } + + function doPackageValidate($command, $options, $params) + { + $this->output = ''; + if (count($params) < 1) { + $params[0] = 'package.xml'; + } + + $obj = &$this->getPackageFile($this->config, $this->_debug); + $obj->rawReturn(); + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + $info = $obj->fromTgzFile($params[0], PEAR_VALIDATE_NORMAL); + if (PEAR::isError($info)) { + $info = $obj->fromPackageFile($params[0], PEAR_VALIDATE_NORMAL); + } else { + $archive = $info->getArchiveFile(); + $tar = &new Archive_Tar($archive); + $tar->extract(dirname($info->getPackageFile())); + $info->setPackageFile(dirname($info->getPackageFile()) . DIRECTORY_SEPARATOR . + $info->getPackage() . '-' . $info->getVersion() . DIRECTORY_SEPARATOR . + basename($info->getPackageFile())); + } + + PEAR::staticPopErrorHandling(); + if (PEAR::isError($info)) { + return $this->raiseError($info); + } + + $valid = false; + if ($info->getPackagexmlVersion() == '2.0') { + if ($valid = $info->validate(PEAR_VALIDATE_NORMAL)) { + $info->flattenFileList(); + $valid = $info->validate(PEAR_VALIDATE_PACKAGING); + } + } else { + $valid = $info->validate(PEAR_VALIDATE_PACKAGING); + } + + $err = $warn = array(); + if ($errors = $info->getValidationWarnings()) { + foreach ($errors as $error) { + if ($error['level'] == 'warning') { + $warn[] = $error['message']; + } else { + $err[] = $error['message']; + } + } + } + + $this->_displayValidationResults($err, $warn); + $this->ui->outputData($this->output, $command); + return true; + } + + function doSvnTag($command, $options, $params) + { + $this->output = ''; + $_cmd = $command; + if (count($params) < 1) { + $help = $this->getHelp($command); + return $this->raiseError("$command: missing parameter: $help[0]"); + } + + $packageFile = realpath($params[0]); + $dir = dirname($packageFile); + $dir = substr($dir, strrpos($dir, '/') + 1); + $obj = &$this->getPackageFile($this->config, $this->_debug); + $info = $obj->fromAnyFile($packageFile, PEAR_VALIDATE_NORMAL); + if (PEAR::isError($info)) { + return $this->raiseError($info); + } + + $err = $warn = array(); + if (!$info->validate()) { + foreach ($info->getValidationWarnings() as $error) { + if ($error['level'] == 'warning') { + $warn[] = $error['message']; + } else { + $err[] = $error['message']; + } + } + } + + if (!$this->_displayValidationResults($err, $warn, true)) { + $this->ui->outputData($this->output, $command); + return $this->raiseError('SVN tag failed'); + } + + $version = $info->getVersion(); + $package = $info->getName(); + $svntag = "$package-$version"; + + if (isset($options['delete'])) { + return $this->_svnRemoveTag($version, $package, $svntag, $packageFile, $options); + } + + $path = $this->_svnFindPath($packageFile); + + // Check if there are any modified files + $fp = popen('svn st --xml ' . dirname($packageFile), "r"); + $out = ''; + while ($line = fgets($fp, 1024)) { + $out .= rtrim($line)."\n"; + } + pclose($fp); + + if (!isset($options['quiet']) && strpos($out, 'item="modified"')) { + $params = array(array( + 'name' => 'modified', + 'type' => 'yesno', + 'default' => 'no', + 'prompt' => 'You have files in your SVN checkout (' . $path['from'] . ') that have been modified but not commited, do you still want to tag ' . $version . '?', + )); + $answers = $this->ui->confirmDialog($params); + + if (!in_array($answers['modified'], array('y', 'yes', 'on', '1'))) { + return true; + } + } + + if (isset($options['slide'])) { + $this->_svnRemoveTag($version, $package, $svntag, $packageFile, $options); + } + + // Check if tag already exists + $releaseTag = $path['local']['base'] . 'tags/' . $svntag; + $existsCommand = 'svn ls ' . $path['base'] . 'tags/'; + + $fp = popen($existsCommand, "r"); + $out = ''; + while ($line = fgets($fp, 1024)) { + $out .= rtrim($line)."\n"; + } + pclose($fp); + + if (in_array($svntag . '/', explode("\n", $out))) { + $this->ui->outputData($this->output, $command); + return $this->raiseError('SVN tag ' . $svntag . ' for ' . $package . ' already exists.'); + } else { + $makeCommand = 'svn mkdir ' . $releaseTag; + $this->output .= "+ $makeCommand\n"; + if (empty($options['dry-run'])) { + // We need to create the tag dir. + $fp = popen($makeCommand, "r"); + $out = ''; + while ($line = fgets($fp, 1024)) { + $out .= rtrim($line)."\n"; + } + pclose($fp); + $this->output .= "$out\n"; + } + } + + $command = 'svn'; + if (isset($options['quiet'])) { + $command .= ' -q'; + } + + $command .= ' copy --parents '; + + $dir = dirname($packageFile); + $dir = substr($dir, strrpos($dir, '/') + 1); + $files = array_keys($info->getFilelist()); + $commands = array(); + foreach ($files as $file) { + if (!file_exists($file)) { + $file = $dir . DIRECTORY_SEPARATOR . $file; + } + $commands[] = $command . ' ' . escapeshellarg($file) . ' ' . + escapeshellarg($releaseTag . DIRECTORY_SEPARATOR . $file); + } + + $this->output .= implode("\n", $commands) . "\n"; + if (empty($options['dry-run'])) { + foreach ($commands as $command) { + $fp = popen($command, "r"); + while ($line = fgets($fp, 1024)) { + $this->output .= rtrim($line)."\n"; + } + pclose($fp); + } + } + + $command = 'svn ci -m "Tagging the ' . $version . ' release" ' . $releaseTag . "\n"; + $this->output .= "+ $command\n"; + if (empty($options['dry-run'])) { + $fp = popen($command, "r"); + while ($line = fgets($fp, 1024)) { + $this->output .= rtrim($line)."\n"; + } + pclose($fp); + } + + $this->ui->outputData($this->output, $_cmd); + return true; + } + + function _svnFindPath($file) + { + $xml = ''; + $command = "svn info --xml $file"; + $fp = popen($command, "r"); + while ($line = fgets($fp, 1024)) { + $xml .= rtrim($line)."\n"; + } + pclose($fp); + $url_tag = strpos($xml, '<url>'); + $url = substr($xml, $url_tag + 5, strpos($xml, '</url>', $url_tag + 5) - ($url_tag + 5)); + + $path = array(); + $path['from'] = substr($url, 0, strrpos($url, '/')); + $path['base'] = substr($path['from'], 0, strrpos($path['from'], '/') + 1); + + // Figure out the local paths + $pos = strpos($file, '/trunk/'); + if ($pos === false) { + $pos = strpos($file, '/branches/'); + } + $path['local']['base'] = substr($file, 0, $pos + 1); + + return $path; + } + + function _svnRemoveTag($version, $package, $tag, $packageFile, $options) + { + $command = 'svn'; + + if (isset($options['quiet'])) { + $command .= ' -q'; + } + + $command .= ' remove'; + $command .= ' -m "Removing tag for the ' . $version . ' release."'; + + $path = $this->_svnFindPath($packageFile); + $command .= ' ' . $path['base'] . 'tags/' . $tag; + + + if ($this->config->get('verbose') > 1) { + $this->output .= "+ $command\n"; + } + + $this->output .= "+ $command\n"; + if (empty($options['dry-run'])) { + $fp = popen($command, "r"); + while ($line = fgets($fp, 1024)) { + $this->output .= rtrim($line)."\n"; + } + pclose($fp); + } + + $this->ui->outputData($this->output, $command); + return true; + } + + function doCvsTag($command, $options, $params) + { + $this->output = ''; + $_cmd = $command; + if (count($params) < 1) { + $help = $this->getHelp($command); + return $this->raiseError("$command: missing parameter: $help[0]"); + } + + $packageFile = realpath($params[0]); + $obj = &$this->getPackageFile($this->config, $this->_debug); + $info = $obj->fromAnyFile($packageFile, PEAR_VALIDATE_NORMAL); + if (PEAR::isError($info)) { + return $this->raiseError($info); + } + + $err = $warn = array(); + if (!$info->validate()) { + foreach ($info->getValidationWarnings() as $error) { + if ($error['level'] == 'warning') { + $warn[] = $error['message']; + } else { + $err[] = $error['message']; + } + } + } + + if (!$this->_displayValidationResults($err, $warn, true)) { + $this->ui->outputData($this->output, $command); + return $this->raiseError('CVS tag failed'); + } + + $version = $info->getVersion(); + $cvsversion = preg_replace('/[^a-z0-9]/i', '_', $version); + $cvstag = "RELEASE_$cvsversion"; + $files = array_keys($info->getFilelist()); + $command = 'cvs'; + if (isset($options['quiet'])) { + $command .= ' -q'; + } + + if (isset($options['reallyquiet'])) { + $command .= ' -Q'; + } + + $command .= ' tag'; + if (isset($options['slide'])) { + $command .= ' -F'; + } + + if (isset($options['delete'])) { + $command .= ' -d'; + } + + $command .= ' ' . $cvstag . ' ' . escapeshellarg($params[0]); + array_shift($params); + if (count($params)) { + // add in additional files to be tagged + $files = array_merge($files, $params); + } + + $dir = dirname($packageFile); + $dir = substr($dir, strrpos($dir, '/') + 1); + foreach ($files as $file) { + if (!file_exists($file)) { + $file = $dir . DIRECTORY_SEPARATOR . $file; + } + $command .= ' ' . escapeshellarg($file); + } + + if ($this->config->get('verbose') > 1) { + $this->output .= "+ $command\n"; + } + + $this->output .= "+ $command\n"; + if (empty($options['dry-run'])) { + $fp = popen($command, "r"); + while ($line = fgets($fp, 1024)) { + $this->output .= rtrim($line)."\n"; + } + pclose($fp); + } + + $this->ui->outputData($this->output, $_cmd); + return true; + } + + function doCvsDiff($command, $options, $params) + { + $this->output = ''; + if (sizeof($params) < 1) { + $help = $this->getHelp($command); + return $this->raiseError("$command: missing parameter: $help[0]"); + } + + $file = realpath($params[0]); + $obj = &$this->getPackageFile($this->config, $this->_debug); + $info = $obj->fromAnyFile($file, PEAR_VALIDATE_NORMAL); + if (PEAR::isError($info)) { + return $this->raiseError($info); + } + + $err = $warn = array(); + if (!$info->validate()) { + foreach ($info->getValidationWarnings() as $error) { + if ($error['level'] == 'warning') { + $warn[] = $error['message']; + } else { + $err[] = $error['message']; + } + } + } + + if (!$this->_displayValidationResults($err, $warn, true)) { + $this->ui->outputData($this->output, $command); + return $this->raiseError('CVS diff failed'); + } + + $info1 = $info->getFilelist(); + $files = $info1; + $cmd = "cvs"; + if (isset($options['quiet'])) { + $cmd .= ' -q'; + unset($options['quiet']); + } + + if (isset($options['reallyquiet'])) { + $cmd .= ' -Q'; + unset($options['reallyquiet']); + } + + if (isset($options['release'])) { + $cvsversion = preg_replace('/[^a-z0-9]/i', '_', $options['release']); + $cvstag = "RELEASE_$cvsversion"; + $options['revision'] = $cvstag; + unset($options['release']); + } + + $execute = true; + if (isset($options['dry-run'])) { + $execute = false; + unset($options['dry-run']); + } + + $cmd .= ' diff'; + // the rest of the options are passed right on to "cvs diff" + foreach ($options as $option => $optarg) { + $arg = $short = false; + if (isset($this->commands[$command]['options'][$option])) { + $arg = $this->commands[$command]['options'][$option]['arg']; + $short = $this->commands[$command]['options'][$option]['shortopt']; + } + $cmd .= $short ? " -$short" : " --$option"; + if ($arg && $optarg) { + $cmd .= ($short ? '' : '=') . escapeshellarg($optarg); + } + } + + foreach ($files as $file) { + $cmd .= ' ' . escapeshellarg($file['name']); + } + + if ($this->config->get('verbose') > 1) { + $this->output .= "+ $cmd\n"; + } + + if ($execute) { + $fp = popen($cmd, "r"); + while ($line = fgets($fp, 1024)) { + $this->output .= rtrim($line)."\n"; + } + pclose($fp); + } + + $this->ui->outputData($this->output, $command); + return true; + } + + function doPackageDependencies($command, $options, $params) + { + // $params[0] -> the PEAR package to list its information + if (count($params) !== 1) { + return $this->raiseError("bad parameter(s), try \"help $command\""); + } + + $obj = &$this->getPackageFile($this->config, $this->_debug); + if (is_file($params[0]) || strpos($params[0], '.xml') > 0) { + $info = $obj->fromAnyFile($params[0], PEAR_VALIDATE_NORMAL); + } else { + $reg = $this->config->getRegistry(); + $info = $obj->fromArray($reg->packageInfo($params[0])); + } + + if (PEAR::isError($info)) { + return $this->raiseError($info); + } + + $deps = $info->getDeps(); + if (is_array($deps)) { + if ($info->getPackagexmlVersion() == '1.0') { + $data = array( + 'caption' => 'Dependencies for pear/' . $info->getPackage(), + 'border' => true, + 'headline' => array("Required?", "Type", "Name", "Relation", "Version"), + ); + + foreach ($deps as $d) { + if (isset($d['optional'])) { + if ($d['optional'] == 'yes') { + $req = 'No'; + } else { + $req = 'Yes'; + } + } else { + $req = 'Yes'; + } + + if (isset($this->_deps_rel_trans[$d['rel']])) { + $rel = $this->_deps_rel_trans[$d['rel']]; + } else { + $rel = $d['rel']; + } + + if (isset($this->_deps_type_trans[$d['type']])) { + $type = ucfirst($this->_deps_type_trans[$d['type']]); + } else { + $type = $d['type']; + } + + if (isset($d['name'])) { + $name = $d['name']; + } else { + $name = ''; + } + + if (isset($d['version'])) { + $version = $d['version']; + } else { + $version = ''; + } + + $data['data'][] = array($req, $type, $name, $rel, $version); + } + } else { // package.xml 2.0 dependencies display + require_once 'PEAR/Dependency2.php'; + $deps = $info->getDependencies(); + $reg = &$this->config->getRegistry(); + if (is_array($deps)) { + $d = new PEAR_Dependency2($this->config, array(), ''); + $data = array( + 'caption' => 'Dependencies for ' . $info->getPackage(), + 'border' => true, + 'headline' => array("Required?", "Type", "Name", 'Versioning', 'Group'), + ); + foreach ($deps as $type => $subd) { + $req = ($type == 'required') ? 'Yes' : 'No'; + if ($type == 'group') { + $group = $subd['attribs']['name']; + } else { + $group = ''; + } + + if (!isset($subd[0])) { + $subd = array($subd); + } + + foreach ($subd as $groupa) { + foreach ($groupa as $deptype => $depinfo) { + if ($deptype == 'attribs') { + continue; + } + + if ($deptype == 'pearinstaller') { + $deptype = 'pear Installer'; + } + + if (!isset($depinfo[0])) { + $depinfo = array($depinfo); + } + + foreach ($depinfo as $inf) { + $name = ''; + if (isset($inf['channel'])) { + $alias = $reg->channelAlias($inf['channel']); + if (!$alias) { + $alias = '(channel?) ' .$inf['channel']; + } + $name = $alias . '/'; + + } + if (isset($inf['name'])) { + $name .= $inf['name']; + } elseif (isset($inf['pattern'])) { + $name .= $inf['pattern']; + } else { + $name .= ''; + } + + if (isset($inf['uri'])) { + $name .= ' [' . $inf['uri'] . ']'; + } + + if (isset($inf['conflicts'])) { + $ver = 'conflicts'; + } else { + $ver = $d->_getExtraString($inf); + } + + $data['data'][] = array($req, ucfirst($deptype), $name, + $ver, $group); + } + } + } + } + } + } + + $this->ui->outputData($data, $command); + return true; + } + + // Fallback + $this->ui->outputData("This package does not have any dependencies.", $command); + } + + function doSign($command, $options, $params) + { + // should move most of this code into PEAR_Packager + // so it'll be easy to implement "pear package --sign" + if (count($params) !== 1) { + return $this->raiseError("bad parameter(s), try \"help $command\""); + } + + require_once 'System.php'; + require_once 'Archive/Tar.php'; + + if (!file_exists($params[0])) { + return $this->raiseError("file does not exist: $params[0]"); + } + + $obj = $this->getPackageFile($this->config, $this->_debug); + $info = $obj->fromTgzFile($params[0], PEAR_VALIDATE_NORMAL); + if (PEAR::isError($info)) { + return $this->raiseError($info); + } + + $tar = new Archive_Tar($params[0]); + $tmpdir = System::mktemp('-d pearsign'); + if (!$tar->extractList('package2.xml package.xml package.sig', $tmpdir)) { + return $this->raiseError("failed to extract tar file"); + } + + if (file_exists("$tmpdir/package.sig")) { + return $this->raiseError("package already signed"); + } + + $packagexml = 'package.xml'; + if (file_exists("$tmpdir/package2.xml")) { + $packagexml = 'package2.xml'; + } + + if (file_exists("$tmpdir/package.sig")) { + unlink("$tmpdir/package.sig"); + } + + if (!file_exists("$tmpdir/$packagexml")) { + return $this->raiseError("Extracted file $tmpdir/$packagexml not found."); + } + + $input = $this->ui->userDialog($command, + array('GnuPG Passphrase'), + array('password')); + if (!isset($input[0])) { + //use empty passphrase + $input[0] = ''; + } + + $devnull = (isset($options['verbose'])) ? '' : ' 2>/dev/null'; + $gpg = popen("gpg --batch --passphrase-fd 0 --armor --detach-sign --output $tmpdir/package.sig $tmpdir/$packagexml" . $devnull, "w"); + if (!$gpg) { + return $this->raiseError("gpg command failed"); + } + + fwrite($gpg, "$input[0]\n"); + if (pclose($gpg) || !file_exists("$tmpdir/package.sig")) { + return $this->raiseError("gpg sign failed"); + } + + if (!$tar->addModify("$tmpdir/package.sig", '', $tmpdir)) { + return $this->raiseError('failed adding signature to file'); + } + + $this->ui->outputData("Package signed.", $command); + return true; + } + + /** + * For unit testing purposes + */ + function &getInstaller(&$ui) + { + if (!class_exists('PEAR_Installer')) { + require_once 'PEAR/Installer.php'; + } + $a = &new PEAR_Installer($ui); + return $a; + } + + /** + * For unit testing purposes + */ + function &getCommandPackaging(&$ui, &$config) + { + if (!class_exists('PEAR_Command_Packaging')) { + if ($fp = @fopen('PEAR/Command/Packaging.php', 'r', true)) { + fclose($fp); + include_once 'PEAR/Command/Packaging.php'; + } + } + + if (class_exists('PEAR_Command_Packaging')) { + $a = &new PEAR_Command_Packaging($ui, $config); + } else { + $a = null; + } + + return $a; + } + + function doMakeRPM($command, $options, $params) + { + + // Check to see if PEAR_Command_Packaging is installed, and + // transparently switch to use the "make-rpm-spec" command from it + // instead, if it does. Otherwise, continue to use the old version + // of "makerpm" supplied with this package (PEAR). + $packaging_cmd = $this->getCommandPackaging($this->ui, $this->config); + if ($packaging_cmd !== null) { + $this->ui->outputData('PEAR_Command_Packaging is installed; using '. + 'newer "make-rpm-spec" command instead'); + return $packaging_cmd->run('make-rpm-spec', $options, $params); + } + + $this->ui->outputData('WARNING: "pear makerpm" is no longer available; an '. + 'improved version is available via "pear make-rpm-spec", which '. + 'is available by installing PEAR_Command_Packaging'); + return true; + } + + function doConvert($command, $options, $params) + { + $packagexml = isset($params[0]) ? $params[0] : 'package.xml'; + $newpackagexml = isset($params[1]) ? $params[1] : dirname($packagexml) . + DIRECTORY_SEPARATOR . 'package2.xml'; + $pkg = &$this->getPackageFile($this->config, $this->_debug); + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + $pf = $pkg->fromPackageFile($packagexml, PEAR_VALIDATE_NORMAL); + PEAR::staticPopErrorHandling(); + if (PEAR::isError($pf)) { + if (is_array($pf->getUserInfo())) { + foreach ($pf->getUserInfo() as $warning) { + $this->ui->outputData($warning['message']); + } + } + return $this->raiseError($pf); + } + + if (is_a($pf, 'PEAR_PackageFile_v2')) { + $this->ui->outputData($packagexml . ' is already a package.xml version 2.0'); + return true; + } + + $gen = &$pf->getDefaultGenerator(); + $newpf = &$gen->toV2(); + $newpf->setPackagefile($newpackagexml); + $gen = &$newpf->getDefaultGenerator(); + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + $state = (isset($options['flat']) ? PEAR_VALIDATE_PACKAGING : PEAR_VALIDATE_NORMAL); + $saved = $gen->toPackageFile(dirname($newpackagexml), $state, basename($newpackagexml)); + PEAR::staticPopErrorHandling(); + if (PEAR::isError($saved)) { + if (is_array($saved->getUserInfo())) { + foreach ($saved->getUserInfo() as $warning) { + $this->ui->outputData($warning['message']); + } + } + + $this->ui->outputData($saved->getMessage()); + return true; + } + + $this->ui->outputData('Wrote new version 2.0 package.xml to "' . $saved . '"'); + return true; + } +} <pickle> <summary>Build PECL Package</summary> <function>doPackage</function> @@ -13033,7 +13520,7 @@ uses any of these features, you are best off using PEAR_PackageFileManager to generate both package.xml. </doc> </pickle> -</commands> +</commands> /** * PEAR_Command_Pickle (pickle command) * @@ -13044,7 +13531,7 @@ generate both package.xml. * @author Greg Beaver <cellog@php.net> * @copyright 2005-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Pickle.php,v 1.13 2009/02/24 23:39:29 dufuz Exp $ + * @version CVS: $Id: Pickle.php 276383 2009-02-24 23:39:37Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.1 */ @@ -13062,7 +13549,7 @@ require_once 'PEAR/Command/Common.php'; * @author Greg Beaver <cellog@php.net> * @copyright 2005-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.1 */ @@ -13453,7 +13940,7 @@ generate both package.xml. $gen = &$pf->getDefaultGenerator(); $gen->toPackageFile('.'); } -} +} <list> <summary>List Installed Packages In The Default Channel</summary> <function>doList</function> @@ -13510,7 +13997,7 @@ Displays information about a package. The package argument may be a local package file, an URL to a package file, or the name of an installed package.</doc> </info> -</commands> +</commands> /** * PEAR_Command_Registry (list, list-files, shell-test, info commands) * @@ -13522,7 +14009,7 @@ installed package.</doc> * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Registry.php,v 1.88 2009/02/24 23:39:29 dufuz Exp $ + * @version CVS: $Id: Registry.php 276383 2009-02-24 23:39:37Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 0.1 */ @@ -13541,7 +14028,7 @@ require_once 'PEAR/Command/Common.php'; * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 0.1 */ @@ -14652,7 +15139,7 @@ installed package.' $data['raw'] = $obj->getArray(); // no validation needed $this->ui->outputData($data, 'package-info'); } -} +} <remote-info> <summary>Information About Remote Packages</summary> <function>doRemoteInfo</function> @@ -14760,7 +15247,7 @@ Clear the XML-RPC/REST cache. See also the cache_ttl configuration parameter. </doc> </clear-cache> -</commands> +</commands> /** * PEAR_Command_Remote (remote-info, list-upgrades, remote-list, search, list-all, download, * clear-cache commands) @@ -14773,7 +15260,7 @@ parameter. * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Remote.php,v 1.120 2009/03/09 01:33:20 dufuz Exp $ + * @version CVS: $Id: Remote.php 287477 2009-08-19 14:19:43Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 0.1 */ @@ -14793,7 +15280,7 @@ require_once 'PEAR/REST.php'; * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 0.1 */ @@ -15426,9 +15913,22 @@ parameter. } $latest = array(); - if ($chan->supportsREST($this->config->get('preferred_mirror')) && - $base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) { - $rest = &$this->config->getREST('1.0', array()); + $base2 = false; + $preferred_mirror = $this->config->get('preferred_mirror'); + if ($chan->supportsREST($preferred_mirror) && + ( + //($base2 = $chan->getBaseURL('REST1.4', $preferred_mirror)) || + ($base = $chan->getBaseURL('REST1.0', $preferred_mirror)) + ) + + ) { + if ($base2) { + $rest = &$this->config->getREST('1.4', array()); + $base = $base2; + } else { + $rest = &$this->config->getREST('1.0', array()); + } + if (empty($state) || $state == 'any') { $state = false; } else { @@ -15555,7 +16055,7 @@ parameter. $this->ui->outputData(rtrim($output), $command); return $num; } -} +} <run-tests> <summary>Run Regression Tests</summary> <function>doRunTests</function> @@ -15588,7 +16088,7 @@ parameter. </package> <phpunit> <shortopt>u</shortopt> - <doc>Search parameters for AllTests.php, and use that to run phpunit-based tests
+ <doc>Search parameters for AllTests.php, and use that to run phpunit-based tests If none is found, all .phpt tests will be tried instead.</doc> </phpunit> <tapoutput> @@ -15605,346 +16105,346 @@ If none is found, all .phpt tests will be tried instead.</doc> <doc>Generate a code coverage report (requires Xdebug 2.0.0+)</doc> </coverage> </options> - <doc>[testfile|dir ...]
+ <doc>[testfile|dir ...] Run regression tests with PHP's regression testing script (run-tests.php).</doc> </run-tests> -</commands> -/**
- * PEAR_Command_Test (run-tests)
- *
- * PHP versions 4 and 5
- *
- * @category pear
- * @package PEAR
- * @author Stig Bakken <ssb@php.net>
- * @author Martin Jansen <mj@php.net>
- * @author Greg Beaver <cellog@php.net>
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version CVS: $Id: Test.php,v 1.32 2009/04/04 00:06:17 dufuz Exp $
- * @link http://pear.php.net/package/PEAR
- * @since File available since Release 0.1
- */
-
-/**
- * base class
- */
-require_once 'PEAR/Command/Common.php';
-
-/**
- * PEAR commands for login/logout
- *
- * @category pear
- * @package PEAR
- * @author Stig Bakken <ssb@php.net>
- * @author Martin Jansen <mj@php.net>
- * @author Greg Beaver <cellog@php.net>
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.8.0
- * @link http://pear.php.net/package/PEAR
- * @since Class available since Release 0.1
- */
-
-class PEAR_Command_Test extends PEAR_Command_Common
-{
- var $commands = array(
- 'run-tests' => array(
- 'summary' => 'Run Regression Tests',
- 'function' => 'doRunTests',
- 'shortcut' => 'rt',
- 'options' => array(
- 'recur' => array(
- 'shortopt' => 'r',
- 'doc' => 'Run tests in child directories, recursively. 4 dirs deep maximum',
- ),
- 'ini' => array(
- 'shortopt' => 'i',
- 'doc' => 'actual string of settings to pass to php in format " -d setting=blah"',
- 'arg' => 'SETTINGS'
- ),
- 'realtimelog' => array(
- 'shortopt' => 'l',
- 'doc' => 'Log test runs/results as they are run',
- ),
- 'quiet' => array(
- 'shortopt' => 'q',
- 'doc' => 'Only display detail for failed tests',
- ),
- 'simple' => array(
- 'shortopt' => 's',
- 'doc' => 'Display simple output for all tests',
- ),
- 'package' => array(
- 'shortopt' => 'p',
- 'doc' => 'Treat parameters as installed packages from which to run tests',
- ),
- 'phpunit' => array(
- 'shortopt' => 'u',
- 'doc' => 'Search parameters for AllTests.php, and use that to run phpunit-based tests
-If none is found, all .phpt tests will be tried instead.',
- ),
- 'tapoutput' => array(
- 'shortopt' => 't',
- 'doc' => 'Output run-tests.log in TAP-compliant format',
- ),
- 'cgi' => array(
- 'shortopt' => 'c',
- 'doc' => 'CGI php executable (needed for tests with POST/GET section)',
- 'arg' => 'PHPCGI',
- ),
- 'coverage' => array(
- 'shortopt' => 'x',
- 'doc' => 'Generate a code coverage report (requires Xdebug 2.0.0+)',
- ),
- ),
- 'doc' => '[testfile|dir ...]
-Run regression tests with PHP\'s regression testing script (run-tests.php).',
- ),
- );
-
- var $output;
-
- /**
- * PEAR_Command_Test constructor.
- *
- * @access public
- */
- function PEAR_Command_Test(&$ui, &$config)
- {
- parent::PEAR_Command_Common($ui, $config);
- }
-
- function doRunTests($command, $options, $params)
- {
- if (isset($options['phpunit']) && isset($options['tapoutput'])) {
- return $this->raiseError('ERROR: cannot use both --phpunit and --tapoutput at the same time');
- }
-
- require_once 'PEAR/Common.php';
- require_once 'System.php';
- $log = new PEAR_Common;
- $log->ui = &$this->ui; // slightly hacky, but it will work
- $tests = array();
- $depth = isset($options['recur']) ? 14 : 1;
-
- if (!count($params)) {
- $params[] = '.';
- }
-
- if (isset($options['package'])) {
- $oldparams = $params;
- $params = array();
- $reg = &$this->config->getRegistry();
- foreach ($oldparams as $param) {
- $pname = $reg->parsePackageName($param, $this->config->get('default_channel'));
- if (PEAR::isError($pname)) {
- return $this->raiseError($pname);
- }
-
- $package = &$reg->getPackage($pname['package'], $pname['channel']);
- if (!$package) {
- return PEAR::raiseError('Unknown package "' .
- $reg->parsedPackageNameToString($pname) . '"');
- }
-
- $filelist = $package->getFilelist();
- foreach ($filelist as $name => $atts) {
- if (isset($atts['role']) && $atts['role'] != 'test') {
- continue;
- }
-
- if (isset($options['phpunit']) && preg_match('/AllTests\.php\\z/i', $name)) {
- $params[] = $atts['installed_as'];
- continue;
- } elseif (!preg_match('/\.phpt\\z/', $name)) {
- continue;
- }
- $params[] = $atts['installed_as'];
- }
- }
- }
-
- foreach ($params as $p) {
- if (is_dir($p)) {
- if (isset($options['phpunit'])) {
- $dir = System::find(array($p, '-type', 'f',
- '-maxdepth', $depth,
- '-name', 'AllTests.php'));
- if (count($dir)) {
- foreach ($dir as $p) {
- $p = realpath($p);
- if (!count($tests) ||
- (count($tests) && strlen($p) < strlen($tests[0]))) {
- // this is in a higher-level directory, use this one instead.
- $tests = array($p);
- }
- }
- }
- continue;
- }
-
- $args = array($p, '-type', 'f', '-name', '*.phpt');
- } else {
- if (isset($options['phpunit'])) {
- if (preg_match('/AllTests\.php\\z/i', $p)) {
- $p = realpath($p);
- if (!count($tests) ||
- (count($tests) && strlen($p) < strlen($tests[0]))) {
- // this is in a higher-level directory, use this one instead.
- $tests = array($p);
- }
- }
- continue;
- }
-
- if (file_exists($p) && preg_match('/\.phpt$/', $p)) {
- $tests[] = $p;
- continue;
- }
-
- if (!preg_match('/\.phpt\\z/', $p)) {
- $p .= '.phpt';
- }
-
- $args = array(dirname($p), '-type', 'f', '-name', $p);
- }
-
- if (!isset($options['recur'])) {
- $args[] = '-maxdepth';
- $args[] = 1;
- }
-
- $dir = System::find($args);
- $tests = array_merge($tests, $dir);
- }
-
- $ini_settings = '';
- if (isset($options['ini'])) {
- $ini_settings .= $options['ini'];
- }
-
- if (isset($_ENV['TEST_PHP_INCLUDE_PATH'])) {
- $ini_settings .= " -d include_path={$_ENV['TEST_PHP_INCLUDE_PATH']}";
- }
-
- if ($ini_settings) {
- $this->ui->outputData('Using INI settings: "' . $ini_settings . '"');
- }
-
- $skipped = $passed = $failed = array();
- $tests_count = count($tests);
- $this->ui->outputData('Running ' . $tests_count . ' tests', $command);
- $start = time();
- if (isset($options['realtimelog']) && file_exists('run-tests.log')) {
- unlink('run-tests.log');
- }
-
- if (isset($options['tapoutput'])) {
- $tap = '1..' . $tests_count . "\n";
- }
-
- require_once 'PEAR/RunTest.php';
- $run = new PEAR_RunTest($log, $options);
- $run->tests_count = $tests_count;
-
- if (isset($options['coverage']) && extension_loaded('xdebug')){
- $run->xdebug_loaded = true;
- } else {
- $run->xdebug_loaded = false;
- }
-
- $j = $i = 1;
- foreach ($tests as $t) {
- if (isset($options['realtimelog'])) {
- $fp = @fopen('run-tests.log', 'a');
- if ($fp) {
- fwrite($fp, "Running test [$i / $tests_count] $t...");
- fclose($fp);
- }
- }
- PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
- if (isset($options['phpunit'])) {
- $result = $run->runPHPUnit($t, $ini_settings);
- } else {
- $result = $run->run($t, $ini_settings, $j);
- }
- PEAR::staticPopErrorHandling();
- if (PEAR::isError($result)) {
- $this->ui->log($result->getMessage());
- continue;
- }
-
- if (isset($options['tapoutput'])) {
- $tap .= $result[0] . ' ' . $i . $result[1] . "\n";
- continue;
- }
-
- if (isset($options['realtimelog'])) {
- $fp = @fopen('run-tests.log', 'a');
- if ($fp) {
- fwrite($fp, "$result\n");
- fclose($fp);
- }
- }
-
- if ($result == 'FAILED') {
- $failed[] = $t;
- }
- if ($result == 'PASSED') {
- $passed[] = $t;
- }
- if ($result == 'SKIPPED') {
- $skipped[] = $t;
- }
-
- $j++;
- }
-
- $total = date('i:s', time() - $start);
- if (isset($options['tapoutput'])) {
- $fp = @fopen('run-tests.log', 'w');
- if ($fp) {
- fwrite($fp, $tap, strlen($tap));
- fclose($fp);
- $this->ui->outputData('wrote TAP-format log to "' .realpath('run-tests.log') .
- '"', $command);
- }
- } else {
- if (count($failed)) {
- $output = "TOTAL TIME: $total\n";
- $output .= count($passed) . " PASSED TESTS\n";
- $output .= count($skipped) . " SKIPPED TESTS\n";
- $output .= count($failed) . " FAILED TESTS:\n";
- foreach ($failed as $failure) {
- $output .= $failure . "\n";
- }
-
- $mode = isset($options['realtimelog']) ? 'a' : 'w';
- $fp = @fopen('run-tests.log', $mode);
-
- if ($fp) {
- fwrite($fp, $output, strlen($output));
- fclose($fp);
- $this->ui->outputData('wrote log to "' . realpath('run-tests.log') . '"', $command);
- }
- } elseif (file_exists('run-tests.log') && !is_dir('run-tests.log')) {
- @unlink('run-tests.log');
- }
- }
- $this->ui->outputData('TOTAL TIME: ' . $total);
- $this->ui->outputData(count($passed) . ' PASSED TESTS', $command);
- $this->ui->outputData(count($skipped) . ' SKIPPED TESTS', $command);
- if (count($failed)) {
- $this->ui->outputData(count($failed) . ' FAILED TESTS:', $command);
- foreach ($failed as $failure) {
- $this->ui->outputData($failure, $command);
- }
- }
-
- return true;
- }
-} +</commands> +/** + * PEAR_Command_Test (run-tests) + * + * PHP versions 4 and 5 + * + * @category pear + * @package PEAR + * @author Stig Bakken <ssb@php.net> + * @author Martin Jansen <mj@php.net> + * @author Greg Beaver <cellog@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: Test.php 279072 2009-04-20 19:57:41Z cellog $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 0.1 + */ + +/** + * base class + */ +require_once 'PEAR/Command/Common.php'; + +/** + * PEAR commands for login/logout + * + * @category pear + * @package PEAR + * @author Stig Bakken <ssb@php.net> + * @author Martin Jansen <mj@php.net> + * @author Greg Beaver <cellog@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 0.1 + */ + +class PEAR_Command_Test extends PEAR_Command_Common +{ + var $commands = array( + 'run-tests' => array( + 'summary' => 'Run Regression Tests', + 'function' => 'doRunTests', + 'shortcut' => 'rt', + 'options' => array( + 'recur' => array( + 'shortopt' => 'r', + 'doc' => 'Run tests in child directories, recursively. 4 dirs deep maximum', + ), + 'ini' => array( + 'shortopt' => 'i', + 'doc' => 'actual string of settings to pass to php in format " -d setting=blah"', + 'arg' => 'SETTINGS' + ), + 'realtimelog' => array( + 'shortopt' => 'l', + 'doc' => 'Log test runs/results as they are run', + ), + 'quiet' => array( + 'shortopt' => 'q', + 'doc' => 'Only display detail for failed tests', + ), + 'simple' => array( + 'shortopt' => 's', + 'doc' => 'Display simple output for all tests', + ), + 'package' => array( + 'shortopt' => 'p', + 'doc' => 'Treat parameters as installed packages from which to run tests', + ), + 'phpunit' => array( + 'shortopt' => 'u', + 'doc' => 'Search parameters for AllTests.php, and use that to run phpunit-based tests +If none is found, all .phpt tests will be tried instead.', + ), + 'tapoutput' => array( + 'shortopt' => 't', + 'doc' => 'Output run-tests.log in TAP-compliant format', + ), + 'cgi' => array( + 'shortopt' => 'c', + 'doc' => 'CGI php executable (needed for tests with POST/GET section)', + 'arg' => 'PHPCGI', + ), + 'coverage' => array( + 'shortopt' => 'x', + 'doc' => 'Generate a code coverage report (requires Xdebug 2.0.0+)', + ), + ), + 'doc' => '[testfile|dir ...] +Run regression tests with PHP\'s regression testing script (run-tests.php).', + ), + ); + + var $output; + + /** + * PEAR_Command_Test constructor. + * + * @access public + */ + function PEAR_Command_Test(&$ui, &$config) + { + parent::PEAR_Command_Common($ui, $config); + } + + function doRunTests($command, $options, $params) + { + if (isset($options['phpunit']) && isset($options['tapoutput'])) { + return $this->raiseError('ERROR: cannot use both --phpunit and --tapoutput at the same time'); + } + + require_once 'PEAR/Common.php'; + require_once 'System.php'; + $log = new PEAR_Common; + $log->ui = &$this->ui; // slightly hacky, but it will work + $tests = array(); + $depth = isset($options['recur']) ? 14 : 1; + + if (!count($params)) { + $params[] = '.'; + } + + if (isset($options['package'])) { + $oldparams = $params; + $params = array(); + $reg = &$this->config->getRegistry(); + foreach ($oldparams as $param) { + $pname = $reg->parsePackageName($param, $this->config->get('default_channel')); + if (PEAR::isError($pname)) { + return $this->raiseError($pname); + } + + $package = &$reg->getPackage($pname['package'], $pname['channel']); + if (!$package) { + return PEAR::raiseError('Unknown package "' . + $reg->parsedPackageNameToString($pname) . '"'); + } + + $filelist = $package->getFilelist(); + foreach ($filelist as $name => $atts) { + if (isset($atts['role']) && $atts['role'] != 'test') { + continue; + } + + if (isset($options['phpunit']) && preg_match('/AllTests\.php\\z/i', $name)) { + $params[] = $atts['installed_as']; + continue; + } elseif (!preg_match('/\.phpt\\z/', $name)) { + continue; + } + $params[] = $atts['installed_as']; + } + } + } + + foreach ($params as $p) { + if (is_dir($p)) { + if (isset($options['phpunit'])) { + $dir = System::find(array($p, '-type', 'f', + '-maxdepth', $depth, + '-name', 'AllTests.php')); + if (count($dir)) { + foreach ($dir as $p) { + $p = realpath($p); + if (!count($tests) || + (count($tests) && strlen($p) < strlen($tests[0]))) { + // this is in a higher-level directory, use this one instead. + $tests = array($p); + } + } + } + continue; + } + + $args = array($p, '-type', 'f', '-name', '*.phpt'); + } else { + if (isset($options['phpunit'])) { + if (preg_match('/AllTests\.php\\z/i', $p)) { + $p = realpath($p); + if (!count($tests) || + (count($tests) && strlen($p) < strlen($tests[0]))) { + // this is in a higher-level directory, use this one instead. + $tests = array($p); + } + } + continue; + } + + if (file_exists($p) && preg_match('/\.phpt$/', $p)) { + $tests[] = $p; + continue; + } + + if (!preg_match('/\.phpt\\z/', $p)) { + $p .= '.phpt'; + } + + $args = array(dirname($p), '-type', 'f', '-name', $p); + } + + if (!isset($options['recur'])) { + $args[] = '-maxdepth'; + $args[] = 1; + } + + $dir = System::find($args); + $tests = array_merge($tests, $dir); + } + + $ini_settings = ''; + if (isset($options['ini'])) { + $ini_settings .= $options['ini']; + } + + if (isset($_ENV['TEST_PHP_INCLUDE_PATH'])) { + $ini_settings .= " -d include_path={$_ENV['TEST_PHP_INCLUDE_PATH']}"; + } + + if ($ini_settings) { + $this->ui->outputData('Using INI settings: "' . $ini_settings . '"'); + } + + $skipped = $passed = $failed = array(); + $tests_count = count($tests); + $this->ui->outputData('Running ' . $tests_count . ' tests', $command); + $start = time(); + if (isset($options['realtimelog']) && file_exists('run-tests.log')) { + unlink('run-tests.log'); + } + + if (isset($options['tapoutput'])) { + $tap = '1..' . $tests_count . "\n"; + } + + require_once 'PEAR/RunTest.php'; + $run = new PEAR_RunTest($log, $options); + $run->tests_count = $tests_count; + + if (isset($options['coverage']) && extension_loaded('xdebug')){ + $run->xdebug_loaded = true; + } else { + $run->xdebug_loaded = false; + } + + $j = $i = 1; + foreach ($tests as $t) { + if (isset($options['realtimelog'])) { + $fp = @fopen('run-tests.log', 'a'); + if ($fp) { + fwrite($fp, "Running test [$i / $tests_count] $t..."); + fclose($fp); + } + } + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + if (isset($options['phpunit'])) { + $result = $run->runPHPUnit($t, $ini_settings); + } else { + $result = $run->run($t, $ini_settings, $j); + } + PEAR::staticPopErrorHandling(); + if (PEAR::isError($result)) { + $this->ui->log($result->getMessage()); + continue; + } + + if (isset($options['tapoutput'])) { + $tap .= $result[0] . ' ' . $i . $result[1] . "\n"; + continue; + } + + if (isset($options['realtimelog'])) { + $fp = @fopen('run-tests.log', 'a'); + if ($fp) { + fwrite($fp, "$result\n"); + fclose($fp); + } + } + + if ($result == 'FAILED') { + $failed[] = $t; + } + if ($result == 'PASSED') { + $passed[] = $t; + } + if ($result == 'SKIPPED') { + $skipped[] = $t; + } + + $j++; + } + + $total = date('i:s', time() - $start); + if (isset($options['tapoutput'])) { + $fp = @fopen('run-tests.log', 'w'); + if ($fp) { + fwrite($fp, $tap, strlen($tap)); + fclose($fp); + $this->ui->outputData('wrote TAP-format log to "' .realpath('run-tests.log') . + '"', $command); + } + } else { + if (count($failed)) { + $output = "TOTAL TIME: $total\n"; + $output .= count($passed) . " PASSED TESTS\n"; + $output .= count($skipped) . " SKIPPED TESTS\n"; + $output .= count($failed) . " FAILED TESTS:\n"; + foreach ($failed as $failure) { + $output .= $failure . "\n"; + } + + $mode = isset($options['realtimelog']) ? 'a' : 'w'; + $fp = @fopen('run-tests.log', $mode); + + if ($fp) { + fwrite($fp, $output, strlen($output)); + fclose($fp); + $this->ui->outputData('wrote log to "' . realpath('run-tests.log') . '"', $command); + } + } elseif (file_exists('run-tests.log') && !is_dir('run-tests.log')) { + @unlink('run-tests.log'); + } + } + $this->ui->outputData('TOTAL TIME: ' . $total); + $this->ui->outputData(count($passed) . ' PASSED TESTS', $command); + $this->ui->outputData(count($skipped) . ' SKIPPED TESTS', $command); + if (count($failed)) { + $this->ui->outputData(count($failed) . ' FAILED TESTS:', $command); + foreach ($failed as $failure) { + $this->ui->outputData($failure, $command); + } + } + + return true; + } +} /** * PEAR_Downloader_Package * @@ -15955,7 +16455,7 @@ Run regression tests with PHP\'s regression testing script (run-tests.php).', * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Package.php,v 1.126 2009/03/07 21:51:52 dufuz Exp $ + * @version CVS: $Id: Package.php 287560 2009-08-21 22:36:18Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ @@ -15996,7 +16496,7 @@ define('PEAR_DOWNLOADER_PACKAGE_PHPVERSION', -1004); * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ @@ -16111,6 +16611,12 @@ class PEAR_Downloader_Package $options = $this->_downloader->getOptions(); if (isset($options['offline'])) { if (PEAR::isError($origErr) && !isset($options['soft'])) { + foreach ($origErr->getUserInfo() as $userInfo) { + if (isset($userInfo['message'])) { + $this->_downloader->log(0, $userInfo['message']); + } + } + $this->_downloader->log(0, $origErr->getMessage()); } @@ -16208,8 +16714,15 @@ class PEAR_Downloader_Package if ($info != $newinfo) { do { - if ($info['package'] == 'pecl.php.net' && $newinfo['package'] == 'pear.php.net') { - $info['package'] = 'pear.php.net'; + if ($info['channel'] == 'pecl.php.net' && $newinfo['channel'] == 'pear.php.net') { + $info['channel'] = 'pear.php.net'; + if ($info == $newinfo) { + // skip the channel check if a pecl package says it's a PEAR package + break; + } + } + if ($info['channel'] == 'pear.php.net' && $newinfo['channel'] == 'pecl.php.net') { + $info['channel'] = 'pecl.php.net'; if ($info == $newinfo) { // skip the channel check if a pecl package says it's a PEAR package break; @@ -16598,8 +17111,7 @@ class PEAR_Downloader_Package // we can't determine whether upgrade is necessary until we know what // version would be downloaded if (!isset($options['force']) && $this->isInstalled($ret, $oper)) { - $version = $this->_installRegistry->packageInfo($dep['name'], 'version', - $dep['channel']); + $version = $this->_installRegistry->packageInfo($dep['name'], 'version', $dep['channel']); $dep['package'] = $dep['name']; if (!isset($options['soft'])) { $this->_downloader->log(3, $this->getShortName() . ': Skipping ' . $group . @@ -16676,8 +17188,7 @@ class PEAR_Downloader_Package $newdep = $newdep[0]; $newdep['channel'] = 'pecl.php.net'; $chan = 'pecl.php.net'; - $url = - $this->_downloader->_getDepPackageDownloadUrl($newdep, $pname); + $url = $this->_downloader->_getDepPackageDownloadUrl($newdep, $pname); $obj = &$this->_installRegistry->getPackage($dep['name']); if (PEAR::isError($url)) { PEAR::popErrorHandling(); @@ -16761,8 +17272,7 @@ class PEAR_Downloader_Package 'optional'; $dep['package'] = $dep['name']; if (isset($newdep)) { - $version = $this->_installRegistry->packageInfo($newdep['name'], 'version', - $newdep['channel']); + $version = $this->_installRegistry->packageInfo($newdep['name'], 'version', $newdep['channel']); } else { $version = $this->_installRegistry->packageInfo($dep['name'], 'version'); } @@ -17081,6 +17591,7 @@ class PEAR_Downloader_Package $channel = 'pear.php.net'; } } + return (strtolower($package) == strtolower($this->getPackage()) && $channel == $this->getChannel() && version_compare($newdep['min'], $this->getVersion(), '<=') && @@ -17225,13 +17736,9 @@ class PEAR_Downloader_Package if (!$param) { continue; } - if ($param->getPackage()) { - if ($ignoreGroups) { - $group = ''; - } else { - $group = $param->getGroup(); - } + if ($param->getPackage()) { + $group = $ignoreGroups ? '' : $param->getGroup(); $pnames[$i] = $param->getChannel() . '/' . $param->getPackage() . '-' . $param->getVersion() . '#' . $group; } @@ -17761,7 +18268,7 @@ class PEAR_Downloader_Package if ($info['version'] === $package_version) { if (!isset($options['soft'])) { $this->_downloader->log(1, 'WARNING: failed to download ' . $pname['channel'] . - '/' . $pname['package'] . '-' . $pname['version'] . ', additionally the suggested version' . + '/' . $pname['package'] . '-' . $package_version. ', additionally the suggested version' . ' (' . $package_version . ') is the same as the locally installed one.'); } @@ -17771,7 +18278,7 @@ class PEAR_Downloader_Package if (version_compare($info['version'], $package_version, '<=')) { if (!isset($options['soft'])) { $this->_downloader->log(1, 'WARNING: failed to download ' . $pname['channel'] . - '/' . $pname['package'] . '-' . $pname['version'] . ', additionally the suggested version' . + '/' . $pname['package'] . '-' . $package_version . ', additionally the suggested version' . ' (' . $info['version'] . ') is a lower version than the locally installed one (' . $package_version . ').'); } @@ -17940,7 +18447,7 @@ class PEAR_Downloader_Package return $info; } -} +} /** * PEAR_Frontend_CLI * @@ -17952,7 +18459,7 @@ class PEAR_Downloader_Package * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: CLI.php,v 1.76 2009/04/04 00:09:14 dufuz Exp $ + * @version CVS: $Id: CLI.php 278236 2009-04-04 00:09:14Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 0.1 */ @@ -17969,7 +18476,7 @@ require_once 'PEAR/Frontend.php'; * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 0.1 */ @@ -18671,7 +19178,7 @@ class PEAR_Frontend_CLI extends PEAR_Frontend { print $text; } -} +} /** * Base class for all installation roles. * @@ -18682,7 +19189,7 @@ class PEAR_Frontend_CLI extends PEAR_Frontend * @author Greg Beaver <cellog@php.net> * @copyright 1997-2006 The PHP Group * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Common.php,v 1.13 2009/02/24 23:39:37 dufuz Exp $ + * @version CVS: $Id: Common.php 276383 2009-02-24 23:39:37Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ @@ -18697,7 +19204,7 @@ class PEAR_Frontend_CLI extends PEAR_Frontend * @author Greg Beaver <cellog@php.net> * @copyright 1997-2006 The PHP Group * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ @@ -18844,7 +19351,7 @@ class PEAR_Installer_Role_Common return $roleInfo['phpextension']; } } -?> +?> <releasetypes>php</releasetypes> <releasetypes>extsrc</releasetypes> <releasetypes>extbin</releasetypes> @@ -18858,7 +19365,7 @@ class PEAR_Installer_Role_Common <executable /> <phpextension /> <config_vars /> -</role> +</role> /** * PEAR_Installer_Role_Cfg * @@ -18869,7 +19376,7 @@ class PEAR_Installer_Role_Common * @author Greg Beaver <cellog@php.net> * @copyright 2007-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Cfg.php,v 1.9 2009/02/24 23:39:37 dufuz Exp $ + * @version CVS: $Id: Cfg.php 276383 2009-02-24 23:39:37Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.7.0 */ @@ -18880,7 +19387,7 @@ class PEAR_Installer_Role_Common * @author Greg Beaver <cellog@php.net> * @copyright 2007-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.7.0 */ @@ -18963,7 +19470,7 @@ class PEAR_Installer_Role_Cfg extends PEAR_Installer_Role_Common return $test; } -} +} <releasetypes>php</releasetypes> <releasetypes>extsrc</releasetypes> <releasetypes>extbin</releasetypes> @@ -18977,34 +19484,34 @@ class PEAR_Installer_Role_Cfg extends PEAR_Installer_Role_Common <executable /> <phpextension /> <config_vars /> -</role> -/**
- * PEAR_Installer_Role_Data
- *
- * PHP versions 4 and 5
- *
- * @category pear
- * @package PEAR
- * @author Greg Beaver <cellog@php.net>
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version CVS: $Id: Data.php,v 1.8 2009/02/24 23:39:37 dufuz Exp $
- * @link http://pear.php.net/package/PEAR
- * @since File available since Release 1.4.0a1
- */
-
-/**
- * @category pear
- * @package PEAR
- * @author Greg Beaver <cellog@php.net>
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.8.0
- * @link http://pear.php.net/package/PEAR
- * @since Class available since Release 1.4.0a1
- */
-class PEAR_Installer_Role_Data extends PEAR_Installer_Role_Common {}
-?> +</role> +/** + * PEAR_Installer_Role_Data + * + * PHP versions 4 and 5 + * + * @category pear + * @package PEAR + * @author Greg Beaver <cellog@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: Data.php 276383 2009-02-24 23:39:37Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ + +/** + * @category pear + * @package PEAR + * @author Greg Beaver <cellog@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_Installer_Role_Data extends PEAR_Installer_Role_Common {} +?> <releasetypes>php</releasetypes> <releasetypes>extsrc</releasetypes> <releasetypes>extbin</releasetypes> @@ -19018,34 +19525,34 @@ class PEAR_Installer_Role_Data extends PEAR_Installer_Role_Common {} <executable /> <phpextension /> <config_vars /> -</role> -/**
- * PEAR_Installer_Role_Doc
- *
- * PHP versions 4 and 5
- *
- * @category pear
- * @package PEAR
- * @author Greg Beaver <cellog@php.net>
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version CVS: $Id: Doc.php,v 1.8 2009/02/24 23:39:37 dufuz Exp $
- * @link http://pear.php.net/package/PEAR
- * @since File available since Release 1.4.0a1
- */
-
-/**
- * @category pear
- * @package PEAR
- * @author Greg Beaver <cellog@php.net>
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.8.0
- * @link http://pear.php.net/package/PEAR
- * @since Class available since Release 1.4.0a1
- */
-class PEAR_Installer_Role_Doc extends PEAR_Installer_Role_Common {}
-?> +</role> +/** + * PEAR_Installer_Role_Doc + * + * PHP versions 4 and 5 + * + * @category pear + * @package PEAR + * @author Greg Beaver <cellog@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: Doc.php 276383 2009-02-24 23:39:37Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ + +/** + * @category pear + * @package PEAR + * @author Greg Beaver <cellog@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_Installer_Role_Doc extends PEAR_Installer_Role_Common {} +?> <releasetypes>extbin</releasetypes> <releasetypes>zendextbin</releasetypes> <installable>1</installable> @@ -19056,34 +19563,34 @@ class PEAR_Installer_Role_Doc extends PEAR_Installer_Role_Common {} <executable /> <phpextension>1</phpextension> <config_vars /> -</role> -/**
- * PEAR_Installer_Role_Ext
- *
- * PHP versions 4 and 5
- *
- * @category pear
- * @package PEAR
- * @author Greg Beaver <cellog@php.net>
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version CVS: $Id: Ext.php,v 1.8 2009/02/24 23:39:37 dufuz Exp $
- * @link http://pear.php.net/package/PEAR
- * @since File available since Release 1.4.0a1
- */
-
-/**
- * @category pear
- * @package PEAR
- * @author Greg Beaver <cellog@php.net>
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.8.0
- * @link http://pear.php.net/package/PEAR
- * @since Class available since Release 1.4.0a1
- */
-class PEAR_Installer_Role_Ext extends PEAR_Installer_Role_Common {}
-?> +</role> +/** + * PEAR_Installer_Role_Ext + * + * PHP versions 4 and 5 + * + * @category pear + * @package PEAR + * @author Greg Beaver <cellog@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: Ext.php 276383 2009-02-24 23:39:37Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ + +/** + * @category pear + * @package PEAR + * @author Greg Beaver <cellog@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_Installer_Role_Ext extends PEAR_Installer_Role_Common {} +?> <releasetypes>php</releasetypes> <releasetypes>extsrc</releasetypes> <releasetypes>extbin</releasetypes> @@ -19097,34 +19604,34 @@ class PEAR_Installer_Role_Ext extends PEAR_Installer_Role_Common {} <executable /> <phpextension /> <config_vars /> -</role> -/**
- * PEAR_Installer_Role_Php
- *
- * PHP versions 4 and 5
- *
- * @category pear
- * @package PEAR
- * @author Greg Beaver <cellog@php.net>
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version CVS: $Id: Php.php,v 1.9 2009/02/24 23:39:37 dufuz Exp $
- * @link http://pear.php.net/package/PEAR
- * @since File available since Release 1.4.0a1
- */
-
-/**
- * @category pear
- * @package PEAR
- * @author Greg Beaver <cellog@php.net>
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.8.0
- * @link http://pear.php.net/package/PEAR
- * @since Class available since Release 1.4.0a1
- */
-class PEAR_Installer_Role_Php extends PEAR_Installer_Role_Common {}
-?> +</role> +/** + * PEAR_Installer_Role_Php + * + * PHP versions 4 and 5 + * + * @category pear + * @package PEAR + * @author Greg Beaver <cellog@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: Php.php 276383 2009-02-24 23:39:37Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ + +/** + * @category pear + * @package PEAR + * @author Greg Beaver <cellog@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_Installer_Role_Php extends PEAR_Installer_Role_Common {} +?> <releasetypes>php</releasetypes> <releasetypes>extsrc</releasetypes> <releasetypes>extbin</releasetypes> @@ -19138,78 +19645,78 @@ class PEAR_Installer_Role_Php extends PEAR_Installer_Role_Common {} <executable>1</executable> <phpextension /> <config_vars /> -</role> -/**
- * PEAR_Installer_Role_Script
- *
- * PHP versions 4 and 5
- *
- * @category pear
- * @package PEAR
- * @author Greg Beaver <cellog@php.net>
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version CVS: $Id: Script.php,v 1.8 2009/02/24 23:39:37 dufuz Exp $
- * @link http://pear.php.net/package/PEAR
- * @since File available since Release 1.4.0a1
- */
-
-/**
- * @category pear
- * @package PEAR
- * @author Greg Beaver <cellog@php.net>
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.8.0
- * @link http://pear.php.net/package/PEAR
- * @since Class available since Release 1.4.0a1
- */
-class PEAR_Installer_Role_Script extends PEAR_Installer_Role_Common {}
-?> - <releasetypes>extsrc</releasetypes>
- <releasetypes>zendextsrc</releasetypes>
- <installable>1</installable>
- <locationconfig>temp_dir</locationconfig>
- <honorsbaseinstall />
- <unusualbaseinstall />
- <phpfile />
- <executable />
- <phpextension />
- <config_vars />
-</role> -/**
- * PEAR_Installer_Role_Src
- *
- * PHP versions 4 and 5
- *
- * @category pear
- * @package PEAR
- * @author Greg Beaver <cellog@php.net>
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version CVS: $Id: Src.php,v 1.8 2009/02/24 23:39:37 dufuz Exp $
- * @link http://pear.php.net/package/PEAR
- * @since File available since Release 1.4.0a1
- */
-
-/**
- * @category pear
- * @package PEAR
- * @author Greg Beaver <cellog@php.net>
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.8.0
- * @link http://pear.php.net/package/PEAR
- * @since Class available since Release 1.4.0a1
- */
-class PEAR_Installer_Role_Src extends PEAR_Installer_Role_Common
-{
- function setup(&$installer, $pkg, $atts, $file)
- {
- $installer->source_files++;
- }
-}
-?> +</role> +/** + * PEAR_Installer_Role_Script + * + * PHP versions 4 and 5 + * + * @category pear + * @package PEAR + * @author Greg Beaver <cellog@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: Script.php 276383 2009-02-24 23:39:37Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ + +/** + * @category pear + * @package PEAR + * @author Greg Beaver <cellog@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_Installer_Role_Script extends PEAR_Installer_Role_Common {} +?> + <releasetypes>extsrc</releasetypes> + <releasetypes>zendextsrc</releasetypes> + <installable>1</installable> + <locationconfig>temp_dir</locationconfig> + <honorsbaseinstall /> + <unusualbaseinstall /> + <phpfile /> + <executable /> + <phpextension /> + <config_vars /> +</role> +/** + * PEAR_Installer_Role_Src + * + * PHP versions 4 and 5 + * + * @category pear + * @package PEAR + * @author Greg Beaver <cellog@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: Src.php 276383 2009-02-24 23:39:37Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ + +/** + * @category pear + * @package PEAR + * @author Greg Beaver <cellog@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_Installer_Role_Src extends PEAR_Installer_Role_Common +{ + function setup(&$installer, $pkg, $atts, $file) + { + $installer->source_files++; + } +} +?> <releasetypes>php</releasetypes> <releasetypes>extsrc</releasetypes> <releasetypes>extbin</releasetypes> @@ -19223,350 +19730,350 @@ class PEAR_Installer_Role_Src extends PEAR_Installer_Role_Common <executable /> <phpextension /> <config_vars /> -</role> -/**
- * PEAR_Installer_Role_Test
- *
- * PHP versions 4 and 5
- *
- * @category pear
- * @package PEAR
- * @author Greg Beaver <cellog@php.net>
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version CVS: $Id: Test.php,v 1.8 2009/02/24 23:39:37 dufuz Exp $
- * @link http://pear.php.net/package/PEAR
- * @since File available since Release 1.4.0a1
- */
-
-/**
- * @category pear
- * @package PEAR
- * @author Greg Beaver <cellog@php.net>
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.8.0
- * @link http://pear.php.net/package/PEAR
- * @since Class available since Release 1.4.0a1
- */
-class PEAR_Installer_Role_Test extends PEAR_Installer_Role_Common {}
-?> - <releasetypes>php</releasetypes>
- <releasetypes>extsrc</releasetypes>
- <releasetypes>extbin</releasetypes>
- <releasetypes>zendextsrc</releasetypes>
- <releasetypes>zendextbin</releasetypes>
- <installable>1</installable>
- <locationconfig>www_dir</locationconfig>
- <honorsbaseinstall>1</honorsbaseinstall>
- <unusualbaseinstall />
- <phpfile />
- <executable />
- <phpextension />
- <config_vars />
-</role> -/**
- * PEAR_Installer_Role_Www
- *
- * PHP versions 4 and 5
- *
- * @category pear
- * @package PEAR
- * @author Greg Beaver <cellog@php.net>
- * @copyright 2007-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version CVS: $Id: Www.php,v 1.3 2009/02/24 23:39:37 dufuz Exp $
- * @link http://pear.php.net/package/PEAR
- * @since File available since Release 1.7.0
- */
-
-/**
- * @category pear
- * @package PEAR
- * @author Greg Beaver <cellog@php.net>
- * @copyright 2007-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.8.0
- * @link http://pear.php.net/package/PEAR
- * @since Class available since Release 1.7.0
- */
-class PEAR_Installer_Role_Www extends PEAR_Installer_Role_Common {}
-?> -/**
- * PEAR_Installer_Role
- *
- * PHP versions 4 and 5
- *
- * @category pear
- * @package PEAR
- * @author Greg Beaver <cellog@php.net>
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version CVS: $Id: Role.php,v 1.22 2009/04/10 19:42:49 dufuz Exp $
- * @link http://pear.php.net/package/PEAR
- * @since File available since Release 1.4.0a1
- */
-
-/**
- * base class for installer roles
- */
-require_once 'PEAR/Installer/Role/Common.php';
-require_once 'PEAR/XMLParser.php';
-/**
- * @category pear
- * @package PEAR
- * @author Greg Beaver <cellog@php.net>
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.8.0
- * @link http://pear.php.net/package/PEAR
- * @since Class available since Release 1.4.0a1
- */
-class PEAR_Installer_Role
-{
- /**
- * Set up any additional configuration variables that file roles require
- *
- * Never call this directly, it is called by the PEAR_Config constructor
- * @param PEAR_Config
- * @access private
- * @static
- */
- function initializeConfig(&$config)
- {
- if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) {
- PEAR_Installer_Role::registerRoles();
- }
-
- foreach ($GLOBALS['_PEAR_INSTALLER_ROLES'] as $class => $info) {
- if (!$info['config_vars']) {
- continue;
- }
-
- $config->_addConfigVars($class, $info['config_vars']);
- }
- }
-
- /**
- * @param PEAR_PackageFile_v2
- * @param string role name
- * @param PEAR_Config
- * @return PEAR_Installer_Role_Common
- * @static
- */
- function &factory($pkg, $role, &$config)
- {
- if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) {
- PEAR_Installer_Role::registerRoles();
- }
-
- if (!in_array($role, PEAR_Installer_Role::getValidRoles($pkg->getPackageType()))) {
- $a = false;
- return $a;
- }
-
- $a = 'PEAR_Installer_Role_' . ucfirst($role);
- if (!class_exists($a)) {
- require_once str_replace('_', '/', $a) . '.php';
- }
-
- $b = new $a($config);
- return $b;
- }
-
- /**
- * Get a list of file roles that are valid for the particular release type.
- *
- * For instance, src files serve no purpose in regular php releases.
- * @param string
- * @param bool clear cache
- * @return array
- * @static
- */
- function getValidRoles($release, $clear = false)
- {
- if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) {
- PEAR_Installer_Role::registerRoles();
- }
-
- static $ret = array();
- if ($clear) {
- $ret = array();
- }
-
- if (isset($ret[$release])) {
- return $ret[$release];
- }
-
- $ret[$release] = array();
- foreach ($GLOBALS['_PEAR_INSTALLER_ROLES'] as $role => $okreleases) {
- if (in_array($release, $okreleases['releasetypes'])) {
- $ret[$release][] = strtolower(str_replace('PEAR_Installer_Role_', '', $role));
- }
- }
-
- return $ret[$release];
- }
-
- /**
- * Get a list of roles that require their files to be installed
- *
- * Most roles must be installed, but src and package roles, for instance
- * are pseudo-roles. src files are compiled into a new extension. Package
- * roles are actually fully bundled releases of a package
- * @param bool clear cache
- * @return array
- * @static
- */
- function getInstallableRoles($clear = false)
- {
- if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) {
- PEAR_Installer_Role::registerRoles();
- }
-
- static $ret;
- if ($clear) {
- unset($ret);
- }
-
- if (isset($ret)) {
- return $ret;
- }
-
- $ret = array();
- foreach ($GLOBALS['_PEAR_INSTALLER_ROLES'] as $role => $okreleases) {
- if ($okreleases['installable']) {
- $ret[] = strtolower(str_replace('PEAR_Installer_Role_', '', $role));
- }
- }
-
- return $ret;
- }
-
- /**
- * Return an array of roles that are affected by the baseinstalldir attribute
- *
- * Most roles ignore this attribute, and instead install directly into:
- * PackageName/filepath
- * so a tests file tests/file.phpt is installed into PackageName/tests/filepath.php
- * @param bool clear cache
- * @return array
- * @static
- */
- function getBaseinstallRoles($clear = false)
- {
- if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) {
- PEAR_Installer_Role::registerRoles();
- }
-
- static $ret;
- if ($clear) {
- unset($ret);
- }
-
- if (isset($ret)) {
- return $ret;
- }
-
- $ret = array();
- foreach ($GLOBALS['_PEAR_INSTALLER_ROLES'] as $role => $okreleases) {
- if ($okreleases['honorsbaseinstall']) {
- $ret[] = strtolower(str_replace('PEAR_Installer_Role_', '', $role));
- }
- }
-
- return $ret;
- }
-
- /**
- * Return an array of file roles that should be analyzed for PHP content at package time,
- * like the "php" role.
- * @param bool clear cache
- * @return array
- * @static
- */
- function getPhpRoles($clear = false)
- {
- if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) {
- PEAR_Installer_Role::registerRoles();
- }
-
- static $ret;
- if ($clear) {
- unset($ret);
- }
-
- if (isset($ret)) {
- return $ret;
- }
-
- $ret = array();
- foreach ($GLOBALS['_PEAR_INSTALLER_ROLES'] as $role => $okreleases) {
- if ($okreleases['phpfile']) {
- $ret[] = strtolower(str_replace('PEAR_Installer_Role_', '', $role));
- }
- }
-
- return $ret;
- }
-
- /**
- * Scan through the Command directory looking for classes
- * and see what commands they implement.
- * @param string which directory to look for classes, defaults to
- * the Installer/Roles subdirectory of
- * the directory from where this file (__FILE__) is
- * included.
- *
- * @return bool TRUE on success, a PEAR error on failure
- * @access public
- * @static
- */
- function registerRoles($dir = null)
- {
- $GLOBALS['_PEAR_INSTALLER_ROLES'] = array();
- $parser = new PEAR_XMLParser;
- if ($dir === null) {
- $dir = dirname(__FILE__) . '/Role';
- }
-
- if (!file_exists($dir) || !is_dir($dir)) {
- return PEAR::raiseError("registerRoles: opendir($dir) failed: does not exist/is not directory");
- }
-
- $dp = @opendir($dir);
- if (empty($dp)) {
- return PEAR::raiseError("registerRoles: opendir($dir) failed: $php_errmsg");
- }
-
- while ($entry = readdir($dp)) {
- if ($entry{0} == '.' || substr($entry, -4) != '.xml') {
- continue;
- }
-
- $class = "PEAR_Installer_Role_".substr($entry, 0, -4);
- // List of roles
- if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'][$class])) {
- $file = "$dir/$entry";
- $parser->parse(file_get_contents($file));
- $data = $parser->getData();
- if (!is_array($data['releasetypes'])) {
- $data['releasetypes'] = array($data['releasetypes']);
- }
-
- $GLOBALS['_PEAR_INSTALLER_ROLES'][$class] = $data;
- }
- }
-
- closedir($dp);
- ksort($GLOBALS['_PEAR_INSTALLER_ROLES']);
- PEAR_Installer_Role::getBaseinstallRoles(true);
- PEAR_Installer_Role::getInstallableRoles(true);
- PEAR_Installer_Role::getPhpRoles(true);
- PEAR_Installer_Role::getValidRoles('****', true);
- return true;
- }
-} +</role> +/** + * PEAR_Installer_Role_Test + * + * PHP versions 4 and 5 + * + * @category pear + * @package PEAR + * @author Greg Beaver <cellog@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: Test.php 276383 2009-02-24 23:39:37Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ + +/** + * @category pear + * @package PEAR + * @author Greg Beaver <cellog@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_Installer_Role_Test extends PEAR_Installer_Role_Common {} +?> + <releasetypes>php</releasetypes> + <releasetypes>extsrc</releasetypes> + <releasetypes>extbin</releasetypes> + <releasetypes>zendextsrc</releasetypes> + <releasetypes>zendextbin</releasetypes> + <installable>1</installable> + <locationconfig>www_dir</locationconfig> + <honorsbaseinstall>1</honorsbaseinstall> + <unusualbaseinstall /> + <phpfile /> + <executable /> + <phpextension /> + <config_vars /> +</role> +/** + * PEAR_Installer_Role_Www + * + * PHP versions 4 and 5 + * + * @category pear + * @package PEAR + * @author Greg Beaver <cellog@php.net> + * @copyright 2007-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: Www.php 276383 2009-02-24 23:39:37Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.7.0 + */ + +/** + * @category pear + * @package PEAR + * @author Greg Beaver <cellog@php.net> + * @copyright 2007-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.7.0 + */ +class PEAR_Installer_Role_Www extends PEAR_Installer_Role_Common {} +?> +/** + * PEAR_Installer_Role + * + * PHP versions 4 and 5 + * + * @category pear + * @package PEAR + * @author Greg Beaver <cellog@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: Role.php 278552 2009-04-10 19:42:49Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ + +/** + * base class for installer roles + */ +require_once 'PEAR/Installer/Role/Common.php'; +require_once 'PEAR/XMLParser.php'; +/** + * @category pear + * @package PEAR + * @author Greg Beaver <cellog@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_Installer_Role +{ + /** + * Set up any additional configuration variables that file roles require + * + * Never call this directly, it is called by the PEAR_Config constructor + * @param PEAR_Config + * @access private + * @static + */ + function initializeConfig(&$config) + { + if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) { + PEAR_Installer_Role::registerRoles(); + } + + foreach ($GLOBALS['_PEAR_INSTALLER_ROLES'] as $class => $info) { + if (!$info['config_vars']) { + continue; + } + + $config->_addConfigVars($class, $info['config_vars']); + } + } + + /** + * @param PEAR_PackageFile_v2 + * @param string role name + * @param PEAR_Config + * @return PEAR_Installer_Role_Common + * @static + */ + function &factory($pkg, $role, &$config) + { + if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) { + PEAR_Installer_Role::registerRoles(); + } + + if (!in_array($role, PEAR_Installer_Role::getValidRoles($pkg->getPackageType()))) { + $a = false; + return $a; + } + + $a = 'PEAR_Installer_Role_' . ucfirst($role); + if (!class_exists($a)) { + require_once str_replace('_', '/', $a) . '.php'; + } + + $b = new $a($config); + return $b; + } + + /** + * Get a list of file roles that are valid for the particular release type. + * + * For instance, src files serve no purpose in regular php releases. + * @param string + * @param bool clear cache + * @return array + * @static + */ + function getValidRoles($release, $clear = false) + { + if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) { + PEAR_Installer_Role::registerRoles(); + } + + static $ret = array(); + if ($clear) { + $ret = array(); + } + + if (isset($ret[$release])) { + return $ret[$release]; + } + + $ret[$release] = array(); + foreach ($GLOBALS['_PEAR_INSTALLER_ROLES'] as $role => $okreleases) { + if (in_array($release, $okreleases['releasetypes'])) { + $ret[$release][] = strtolower(str_replace('PEAR_Installer_Role_', '', $role)); + } + } + + return $ret[$release]; + } + + /** + * Get a list of roles that require their files to be installed + * + * Most roles must be installed, but src and package roles, for instance + * are pseudo-roles. src files are compiled into a new extension. Package + * roles are actually fully bundled releases of a package + * @param bool clear cache + * @return array + * @static + */ + function getInstallableRoles($clear = false) + { + if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) { + PEAR_Installer_Role::registerRoles(); + } + + static $ret; + if ($clear) { + unset($ret); + } + + if (isset($ret)) { + return $ret; + } + + $ret = array(); + foreach ($GLOBALS['_PEAR_INSTALLER_ROLES'] as $role => $okreleases) { + if ($okreleases['installable']) { + $ret[] = strtolower(str_replace('PEAR_Installer_Role_', '', $role)); + } + } + + return $ret; + } + + /** + * Return an array of roles that are affected by the baseinstalldir attribute + * + * Most roles ignore this attribute, and instead install directly into: + * PackageName/filepath + * so a tests file tests/file.phpt is installed into PackageName/tests/filepath.php + * @param bool clear cache + * @return array + * @static + */ + function getBaseinstallRoles($clear = false) + { + if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) { + PEAR_Installer_Role::registerRoles(); + } + + static $ret; + if ($clear) { + unset($ret); + } + + if (isset($ret)) { + return $ret; + } + + $ret = array(); + foreach ($GLOBALS['_PEAR_INSTALLER_ROLES'] as $role => $okreleases) { + if ($okreleases['honorsbaseinstall']) { + $ret[] = strtolower(str_replace('PEAR_Installer_Role_', '', $role)); + } + } + + return $ret; + } + + /** + * Return an array of file roles that should be analyzed for PHP content at package time, + * like the "php" role. + * @param bool clear cache + * @return array + * @static + */ + function getPhpRoles($clear = false) + { + if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) { + PEAR_Installer_Role::registerRoles(); + } + + static $ret; + if ($clear) { + unset($ret); + } + + if (isset($ret)) { + return $ret; + } + + $ret = array(); + foreach ($GLOBALS['_PEAR_INSTALLER_ROLES'] as $role => $okreleases) { + if ($okreleases['phpfile']) { + $ret[] = strtolower(str_replace('PEAR_Installer_Role_', '', $role)); + } + } + + return $ret; + } + + /** + * Scan through the Command directory looking for classes + * and see what commands they implement. + * @param string which directory to look for classes, defaults to + * the Installer/Roles subdirectory of + * the directory from where this file (__FILE__) is + * included. + * + * @return bool TRUE on success, a PEAR error on failure + * @access public + * @static + */ + function registerRoles($dir = null) + { + $GLOBALS['_PEAR_INSTALLER_ROLES'] = array(); + $parser = new PEAR_XMLParser; + if ($dir === null) { + $dir = dirname(__FILE__) . '/Role'; + } + + if (!file_exists($dir) || !is_dir($dir)) { + return PEAR::raiseError("registerRoles: opendir($dir) failed: does not exist/is not directory"); + } + + $dp = @opendir($dir); + if (empty($dp)) { + return PEAR::raiseError("registerRoles: opendir($dir) failed: $php_errmsg"); + } + + while ($entry = readdir($dp)) { + if ($entry{0} == '.' || substr($entry, -4) != '.xml') { + continue; + } + + $class = "PEAR_Installer_Role_".substr($entry, 0, -4); + // List of roles + if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'][$class])) { + $file = "$dir/$entry"; + $parser->parse(file_get_contents($file)); + $data = $parser->getData(); + if (!is_array($data['releasetypes'])) { + $data['releasetypes'] = array($data['releasetypes']); + } + + $GLOBALS['_PEAR_INSTALLER_ROLES'][$class] = $data; + } + } + + closedir($dp); + ksort($GLOBALS['_PEAR_INSTALLER_ROLES']); + PEAR_Installer_Role::getBaseinstallRoles(true); + PEAR_Installer_Role::getInstallableRoles(true); + PEAR_Installer_Role::getPhpRoles(true); + PEAR_Installer_Role::getValidRoles('****', true); + return true; + } +} /** * package.xml generation class, package.xml version 1.0 * @@ -19577,7 +20084,7 @@ class PEAR_Installer_Role * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: v1.php,v 1.76 2009/02/24 23:45:26 dufuz Exp $ + * @version CVS: $Id: v1.php 286494 2009-07-29 06:57:11Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ @@ -19597,7 +20104,7 @@ require_once 'PEAR/PackageFile/v2.php'; * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ @@ -19614,7 +20121,7 @@ class PEAR_PackageFile_Generator_v1 function getPackagerVersion() { - return '1.8.0'; + return '1.9.0'; } /** @@ -19768,7 +20275,7 @@ class PEAR_PackageFile_Generator_v1 ); $ret = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"; $ret .= "<!DOCTYPE package SYSTEM \"http://pear.php.net/dtd/package-1.0\">\n"; - $ret .= "<package version=\"1.0\" packagerversion=\"1.8.0\">\n" . + $ret .= "<package version=\"1.0\" packagerversion=\"1.9.0\">\n" . " <name>$pkginfo[package]</name>"; if (isset($pkginfo['extends'])) { $ret .= "\n<extends>$pkginfo[extends]</extends>"; @@ -20783,16 +21290,15 @@ class PEAR_PackageFile_Generator_v1 */ function _processMultipleDepsName($deps) { - $tests = array(); + $ret = $tests = array(); foreach ($deps as $name => $dep) { foreach ($dep as $d) { $tests[$name][] = $this->_processDep($d); } } + foreach ($tests as $name => $test) { - $php = array(); - $min = array(); - $max = array(); + $max = $min = $php = array(); $php['name'] = $name; foreach ($test as $dep) { if (!$dep) { @@ -20850,7 +21356,7 @@ class PEAR_PackageFile_Generator_v1 return $ret; } } -?> +?> /** * package.xml generation class, package.xml version 2.0 * @@ -20862,7 +21368,7 @@ class PEAR_PackageFile_Generator_v1 * @author Stephan Schmidt (original XML_Serializer code) * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: v2.php,v 1.51 2009/03/27 17:11:18 dufuz Exp $ + * @version CVS: $Id: v2.php 278907 2009-04-17 21:10:04Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ @@ -20883,7 +21389,7 @@ require_once 'XML/Util.php'; * @author Stephan Schmidt (original XML_Serializer code) * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ @@ -20965,7 +21471,7 @@ http://pear.php.net/dtd/package-2.0.xsd', */ function getPackagerVersion() { - return '1.8.0'; + return '1.9.0'; } /** @@ -21229,7 +21735,8 @@ http://pear.php.net/dtd/package-2.0.xsd', $arr['changelog']['release'][0] = $release; } - foreach ($arr['changelog']['release'] as &$c) { + foreach (array_keys($arr['changelog']['release']) as $key) { + $c =& $arr['changelog']['release'][$key]; if (isset($c['notes'])) { // This trims out the indenting, needs fixing $c['notes'] = "\n" . trim($c['notes']) . "\n"; @@ -21249,7 +21756,7 @@ http://pear.php.net/dtd/package-2.0.xsd', $this->options['beautifyFilelist'] = true; } - $arr['attribs']['packagerversion'] = '1.8.0'; + $arr['attribs']['packagerversion'] = '1.9.0'; if ($this->serialize($arr, $options)) { return $this->_serializedData . "\n"; } @@ -21723,7 +22230,7 @@ http://pear.php.net/dtd/package-2.0.xsd', if ($this->options['encoding'] == 'UTF-8' && version_compare(phpversion(), '5.0.0', 'lt') ) { - $tag = utf8_encode($tag); + $tag['content'] = utf8_encode($tag['content']); } if ($replaceEntities === true) { @@ -21741,7 +22248,7 @@ http://pear.php.net/dtd/package-2.0.xsd', } return $tag; } -} +} /** * package.xml parsing class, package.xml version 1.0 * @@ -21752,7 +22259,7 @@ http://pear.php.net/dtd/package-2.0.xsd', * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: v1.php,v 1.30 2009/02/24 23:45:22 dufuz Exp $ + * @version CVS: $Id: v1.php 276385 2009-02-24 23:46:03Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ @@ -22199,7 +22706,7 @@ class PEAR_PackageFile_Parser_v1 // }}} } -?> +?> /** * package.xml parsing class, package.xml version 2.0 * @@ -22210,7 +22717,7 @@ class PEAR_PackageFile_Parser_v1 * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: v2.php,v 1.24 2009/02/24 23:45:22 dufuz Exp $ + * @version CVS: $Id: v2.php 276385 2009-02-24 23:46:03Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ @@ -22311,7 +22818,7 @@ class PEAR_PackageFile_Parser_v2 extends PEAR_XMLParser $ret->setPackagefile($file, $archive); return $ret; } -} +} /** * PEAR_PackageFile_v2, package.xml version 2.0, read/write version * @@ -22322,7 +22829,7 @@ class PEAR_PackageFile_Parser_v2 extends PEAR_XMLParser * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: rw.php,v 1.25 2009/02/24 23:46:03 dufuz Exp $ + * @version CVS: $Id: rw.php 276385 2009-02-24 23:46:03Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a8 */ @@ -22336,7 +22843,7 @@ require_once 'PEAR/PackageFile/v2.php'; * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a8 */ @@ -23914,7 +24421,7 @@ class PEAR_PackageFile_v2_rw extends PEAR_PackageFile_v2 { unset($this->_packageInfo['changelog']); } -} +} /** * PEAR_PackageFile_v2, package.xml version 2.0, read/write version * @@ -23925,7 +24432,7 @@ class PEAR_PackageFile_v2_rw extends PEAR_PackageFile_v2 * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Validator.php,v 1.110 2009/03/27 19:29:31 dufuz Exp $ + * @version CVS: $Id: Validator.php 277885 2009-03-27 19:29:31Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a8 */ @@ -23937,7 +24444,7 @@ class PEAR_PackageFile_v2_rw extends PEAR_PackageFile_v2 * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a8 * @access private @@ -24028,7 +24535,7 @@ class PEAR_PackageFile_v2_Validator isset($test['dependencies']['required']) && isset($test['dependencies']['required']['pearinstaller']) && isset($test['dependencies']['required']['pearinstaller']['min']) && - version_compare('1.8.0', + version_compare('1.9.0', $test['dependencies']['required']['pearinstaller']['min'], '<') ) { $this->_pearVersionTooLow($test['dependencies']['required']['pearinstaller']['min']); @@ -25267,7 +25774,7 @@ class PEAR_PackageFile_v2_Validator $this->_stack->push(__FUNCTION__, 'error', array('version' => $version), 'This package.xml requires PEAR version %version% to parse properly, we are ' . - 'version 1.8.0'); + 'version 1.9.0'); } function _invalidTagOrder($oktags, $actual, $root) @@ -26067,1619 +26574,1619 @@ class PEAR_PackageFile_v2_Validator return $providesret; } -} -/**
- * PEAR_PackageFile_v1, package.xml version 1.0
- *
- * PHP versions 4 and 5
- *
- * @category pear
- * @package PEAR
- * @author Greg Beaver <cellog@php.net>
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version CVS: $Id: v1.php,v 1.75 2009/02/24 23:39:16 dufuz Exp $
- * @link http://pear.php.net/package/PEAR
- * @since File available since Release 1.4.0a1
- */
-/**
- * For error handling
- */
-require_once 'PEAR/ErrorStack.php';
-
-/**
- * Error code if parsing is attempted with no xml extension
- */
-define('PEAR_PACKAGEFILE_ERROR_NO_XML_EXT', 3);
-
-/**
- * Error code if creating the xml parser resource fails
- */
-define('PEAR_PACKAGEFILE_ERROR_CANT_MAKE_PARSER', 4);
-
-/**
- * Error code used for all sax xml parsing errors
- */
-define('PEAR_PACKAGEFILE_ERROR_PARSER_ERROR', 5);
-
-/**
- * Error code used when there is no name
- */
-define('PEAR_PACKAGEFILE_ERROR_NO_NAME', 6);
-
-/**
- * Error code when a package name is not valid
- */
-define('PEAR_PACKAGEFILE_ERROR_INVALID_NAME', 7);
-
-/**
- * Error code used when no summary is parsed
- */
-define('PEAR_PACKAGEFILE_ERROR_NO_SUMMARY', 8);
-
-/**
- * Error code for summaries that are more than 1 line
- */
-define('PEAR_PACKAGEFILE_ERROR_MULTILINE_SUMMARY', 9);
-
-/**
- * Error code used when no description is present
- */
-define('PEAR_PACKAGEFILE_ERROR_NO_DESCRIPTION', 10);
-
-/**
- * Error code used when no license is present
- */
-define('PEAR_PACKAGEFILE_ERROR_NO_LICENSE', 11);
-
-/**
- * Error code used when a <version> version number is not present
- */
-define('PEAR_PACKAGEFILE_ERROR_NO_VERSION', 12);
-
-/**
- * Error code used when a <version> version number is invalid
- */
-define('PEAR_PACKAGEFILE_ERROR_INVALID_VERSION', 13);
-
-/**
- * Error code when release state is missing
- */
-define('PEAR_PACKAGEFILE_ERROR_NO_STATE', 14);
-
-/**
- * Error code when release state is invalid
- */
-define('PEAR_PACKAGEFILE_ERROR_INVALID_STATE', 15);
-
-/**
- * Error code when release state is missing
- */
-define('PEAR_PACKAGEFILE_ERROR_NO_DATE', 16);
-
-/**
- * Error code when release state is invalid
- */
-define('PEAR_PACKAGEFILE_ERROR_INVALID_DATE', 17);
-
-/**
- * Error code when no release notes are found
- */
-define('PEAR_PACKAGEFILE_ERROR_NO_NOTES', 18);
-
-/**
- * Error code when no maintainers are found
- */
-define('PEAR_PACKAGEFILE_ERROR_NO_MAINTAINERS', 19);
-
-/**
- * Error code when a maintainer has no handle
- */
-define('PEAR_PACKAGEFILE_ERROR_NO_MAINTHANDLE', 20);
-
-/**
- * Error code when a maintainer has no handle
- */
-define('PEAR_PACKAGEFILE_ERROR_NO_MAINTROLE', 21);
-
-/**
- * Error code when a maintainer has no name
- */
-define('PEAR_PACKAGEFILE_ERROR_NO_MAINTNAME', 22);
-
-/**
- * Error code when a maintainer has no email
- */
-define('PEAR_PACKAGEFILE_ERROR_NO_MAINTEMAIL', 23);
-
-/**
- * Error code when a maintainer has no handle
- */
-define('PEAR_PACKAGEFILE_ERROR_INVALID_MAINTROLE', 24);
-
-/**
- * Error code when a dependency is not a PHP dependency, but has no name
- */
-define('PEAR_PACKAGEFILE_ERROR_NO_DEPNAME', 25);
-
-/**
- * Error code when a dependency has no type (pkg, php, etc.)
- */
-define('PEAR_PACKAGEFILE_ERROR_NO_DEPTYPE', 26);
-
-/**
- * Error code when a dependency has no relation (lt, ge, has, etc.)
- */
-define('PEAR_PACKAGEFILE_ERROR_NO_DEPREL', 27);
-
-/**
- * Error code when a dependency is not a 'has' relation, but has no version
- */
-define('PEAR_PACKAGEFILE_ERROR_NO_DEPVERSION', 28);
-
-/**
- * Error code when a dependency has an invalid relation
- */
-define('PEAR_PACKAGEFILE_ERROR_INVALID_DEPREL', 29);
-
-/**
- * Error code when a dependency has an invalid type
- */
-define('PEAR_PACKAGEFILE_ERROR_INVALID_DEPTYPE', 30);
-
-/**
- * Error code when a dependency has an invalid optional option
- */
-define('PEAR_PACKAGEFILE_ERROR_INVALID_DEPOPTIONAL', 31);
-
-/**
- * Error code when a dependency is a pkg dependency, and has an invalid package name
- */
-define('PEAR_PACKAGEFILE_ERROR_INVALID_DEPNAME', 32);
-
-/**
- * Error code when a dependency has a channel="foo" attribute, and foo is not a registered channel
- */
-define('PEAR_PACKAGEFILE_ERROR_UNKNOWN_DEPCHANNEL', 33);
-
-/**
- * Error code when rel="has" and version attribute is present.
- */
-define('PEAR_PACKAGEFILE_ERROR_DEPVERSION_IGNORED', 34);
-
-/**
- * Error code when type="php" and dependency name is present
- */
-define('PEAR_PACKAGEFILE_ERROR_DEPNAME_IGNORED', 35);
-
-/**
- * Error code when a configure option has no name
- */
-define('PEAR_PACKAGEFILE_ERROR_NO_CONFNAME', 36);
-
-/**
- * Error code when a configure option has no name
- */
-define('PEAR_PACKAGEFILE_ERROR_NO_CONFPROMPT', 37);
-
-/**
- * Error code when a file in the filelist has an invalid role
- */
-define('PEAR_PACKAGEFILE_ERROR_INVALID_FILEROLE', 38);
-
-/**
- * Error code when a file in the filelist has no role
- */
-define('PEAR_PACKAGEFILE_ERROR_NO_FILEROLE', 39);
-
-/**
- * Error code when analyzing a php source file that has parse errors
- */
-define('PEAR_PACKAGEFILE_ERROR_INVALID_PHPFILE', 40);
-
-/**
- * Error code when analyzing a php source file reveals a source element
- * without a package name prefix
- */
-define('PEAR_PACKAGEFILE_ERROR_NO_PNAME_PREFIX', 41);
-
-/**
- * Error code when an unknown channel is specified
- */
-define('PEAR_PACKAGEFILE_ERROR_UNKNOWN_CHANNEL', 42);
-
-/**
- * Error code when no files are found in the filelist
- */
-define('PEAR_PACKAGEFILE_ERROR_NO_FILES', 43);
-
-/**
- * Error code when a file is not valid php according to _analyzeSourceCode()
- */
-define('PEAR_PACKAGEFILE_ERROR_INVALID_FILE', 44);
-
-/**
- * Error code when the channel validator returns an error or warning
- */
-define('PEAR_PACKAGEFILE_ERROR_CHANNELVAL', 45);
-
-/**
- * Error code when a php5 package is packaged in php4 (analysis doesn't work)
- */
-define('PEAR_PACKAGEFILE_ERROR_PHP5', 46);
-
-/**
- * Error code when a file is listed in package.xml but does not exist
- */
-define('PEAR_PACKAGEFILE_ERROR_FILE_NOTFOUND', 47);
-
-/**
- * Error code when a <dep type="php" rel="not"... is encountered (use rel="ne")
- */
-define('PEAR_PACKAGEFILE_PHP_NO_NOT', 48);
-
-/**
- * Error code when a package.xml contains non-ISO-8859-1 characters
- */
-define('PEAR_PACKAGEFILE_ERROR_NON_ISO_CHARS', 49);
-
-/**
- * Error code when a dependency is not a 'has' relation, but has no version
- */
-define('PEAR_PACKAGEFILE_ERROR_NO_DEPPHPVERSION', 50);
-
-/**
- * Error code when a package has no lead developer
- */
-define('PEAR_PACKAGEFILE_ERROR_NO_LEAD', 51);
-
-/**
- * Error code when a filename begins with "."
- */
-define('PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME', 52);
-/**
- * package.xml encapsulator
- * @category pear
- * @package PEAR
- * @author Greg Beaver <cellog@php.net>
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.8.0
- * @link http://pear.php.net/package/PEAR
- * @since Class available since Release 1.4.0a1
- */
-class PEAR_PackageFile_v1
-{
- /**
- * @access private
- * @var PEAR_ErrorStack
- * @access private
- */
- var $_stack;
-
- /**
- * A registry object, used to access the package name validation regex for non-standard channels
- * @var PEAR_Registry
- * @access private
- */
- var $_registry;
-
- /**
- * An object that contains a log method that matches PEAR_Common::log's signature
- * @var object
- * @access private
- */
- var $_logger;
-
- /**
- * Parsed package information
- * @var array
- * @access private
- */
- var $_packageInfo;
-
- /**
- * path to package.xml
- * @var string
- * @access private
- */
- var $_packageFile;
-
- /**
- * path to package .tgz or false if this is a local/extracted package.xml
- * @var string
- * @access private
- */
- var $_archiveFile;
-
- /**
- * @var int
- * @access private
- */
- var $_isValid = 0;
-
- /**
- * Determines whether this packagefile was initialized only with partial package info
- *
- * If this package file was constructed via parsing REST, it will only contain
- *
- * - package name
- * - channel name
- * - dependencies
- * @var boolean
- * @access private
- */
- var $_incomplete = true;
-
- /**
- * @param bool determines whether to return a PEAR_Error object, or use the PEAR_ErrorStack
- * @param string Name of Error Stack class to use.
- */
- function PEAR_PackageFile_v1()
- {
- $this->_stack = &new PEAR_ErrorStack('PEAR_PackageFile_v1');
- $this->_stack->setErrorMessageTemplate($this->_getErrorMessage());
- $this->_isValid = 0;
- }
-
- function installBinary($installer)
- {
- return false;
- }
-
- function isExtension($name)
- {
- return false;
- }
-
- function setConfig(&$config)
- {
- $this->_config = &$config;
- $this->_registry = &$config->getRegistry();
- }
-
- function setRequestedGroup()
- {
- // placeholder
- }
-
- /**
- * For saving in the registry.
- *
- * Set the last version that was installed
- * @param string
- */
- function setLastInstalledVersion($version)
- {
- $this->_packageInfo['_lastversion'] = $version;
- }
-
- /**
- * @return string|false
- */
- function getLastInstalledVersion()
- {
- if (isset($this->_packageInfo['_lastversion'])) {
- return $this->_packageInfo['_lastversion'];
- }
- return false;
- }
-
- function getInstalledBinary()
- {
- return false;
- }
-
- function listPostinstallScripts()
- {
- return false;
- }
-
- function initPostinstallScripts()
- {
- return false;
- }
-
- function setLogger(&$logger)
- {
- if ($logger && (!is_object($logger) || !method_exists($logger, 'log'))) {
- return PEAR::raiseError('Logger must be compatible with PEAR_Common::log');
- }
- $this->_logger = &$logger;
- }
-
- function setPackagefile($file, $archive = false)
- {
- $this->_packageFile = $file;
- $this->_archiveFile = $archive ? $archive : $file;
- }
-
- function getPackageFile()
- {
- return isset($this->_packageFile) ? $this->_packageFile : false;
- }
-
- function getPackageType()
- {
- return 'php';
- }
-
- function getArchiveFile()
- {
- return $this->_archiveFile;
- }
-
- function packageInfo($field)
- {
- if (!is_string($field) || empty($field) ||
- !isset($this->_packageInfo[$field])) {
- return false;
- }
- return $this->_packageInfo[$field];
- }
-
- function setDirtree($path)
- {
- if (!isset($this->_packageInfo['dirtree'])) {
- $this->_packageInfo['dirtree'] = array();
- }
- $this->_packageInfo['dirtree'][$path] = true;
- }
-
- function getDirtree()
- {
- if (isset($this->_packageInfo['dirtree']) && count($this->_packageInfo['dirtree'])) {
- return $this->_packageInfo['dirtree'];
- }
- return false;
- }
-
- function resetDirtree()
- {
- unset($this->_packageInfo['dirtree']);
- }
-
- function fromArray($pinfo)
- {
- $this->_incomplete = false;
- $this->_packageInfo = $pinfo;
- }
-
- function isIncomplete()
- {
- return $this->_incomplete;
- }
-
- function getChannel()
- {
- return 'pear.php.net';
- }
-
- function getUri()
- {
- return false;
- }
-
- function getTime()
- {
- return false;
- }
-
- function getExtends()
- {
- if (isset($this->_packageInfo['extends'])) {
- return $this->_packageInfo['extends'];
- }
- return false;
- }
-
- /**
- * @return array
- */
- function toArray()
- {
- if (!$this->validate(PEAR_VALIDATE_NORMAL)) {
- return false;
- }
- return $this->getArray();
- }
-
- function getArray()
- {
- return $this->_packageInfo;
- }
-
- function getName()
- {
- return $this->getPackage();
- }
-
- function getPackage()
- {
- if (isset($this->_packageInfo['package'])) {
- return $this->_packageInfo['package'];
- }
- return false;
- }
-
- /**
- * WARNING - don't use this unless you know what you are doing
- */
- function setRawPackage($package)
- {
- $this->_packageInfo['package'] = $package;
- }
-
- function setPackage($package)
- {
- $this->_packageInfo['package'] = $package;
- $this->_isValid = false;
- }
-
- function getVersion()
- {
- if (isset($this->_packageInfo['version'])) {
- return $this->_packageInfo['version'];
- }
- return false;
- }
-
- function setVersion($version)
- {
- $this->_packageInfo['version'] = $version;
- $this->_isValid = false;
- }
-
- function clearMaintainers()
- {
- unset($this->_packageInfo['maintainers']);
- }
-
- function getMaintainers()
- {
- if (isset($this->_packageInfo['maintainers'])) {
- return $this->_packageInfo['maintainers'];
- }
- return false;
- }
-
- /**
- * Adds a new maintainer - no checking of duplicates is performed, use
- * updatemaintainer for that purpose.
- */
- function addMaintainer($role, $handle, $name, $email)
- {
- $this->_packageInfo['maintainers'][] =
- array('handle' => $handle, 'role' => $role, 'email' => $email, 'name' => $name);
- $this->_isValid = false;
- }
-
- function updateMaintainer($role, $handle, $name, $email)
- {
- $found = false;
- if (!isset($this->_packageInfo['maintainers']) ||
- !is_array($this->_packageInfo['maintainers'])) {
- return $this->addMaintainer($role, $handle, $name, $email);
- }
- foreach ($this->_packageInfo['maintainers'] as $i => $maintainer) {
- if ($maintainer['handle'] == $handle) {
- $found = $i;
- break;
- }
- }
- if ($found !== false) {
- unset($this->_packageInfo['maintainers'][$found]);
- $this->_packageInfo['maintainers'] =
- array_values($this->_packageInfo['maintainers']);
- }
- $this->addMaintainer($role, $handle, $name, $email);
- }
-
- function deleteMaintainer($handle)
- {
- $found = false;
- foreach ($this->_packageInfo['maintainers'] as $i => $maintainer) {
- if ($maintainer['handle'] == $handle) {
- $found = $i;
- break;
- }
- }
- if ($found !== false) {
- unset($this->_packageInfo['maintainers'][$found]);
- $this->_packageInfo['maintainers'] =
- array_values($this->_packageInfo['maintainers']);
- return true;
- }
- return false;
- }
-
- function getState()
- {
- if (isset($this->_packageInfo['release_state'])) {
- return $this->_packageInfo['release_state'];
- }
- return false;
- }
-
- function setRawState($state)
- {
- $this->_packageInfo['release_state'] = $state;
- }
-
- function setState($state)
- {
- $this->_packageInfo['release_state'] = $state;
- $this->_isValid = false;
- }
-
- function getDate()
- {
- if (isset($this->_packageInfo['release_date'])) {
- return $this->_packageInfo['release_date'];
- }
- return false;
- }
-
- function setDate($date)
- {
- $this->_packageInfo['release_date'] = $date;
- $this->_isValid = false;
- }
-
- function getLicense()
- {
- if (isset($this->_packageInfo['release_license'])) {
- return $this->_packageInfo['release_license'];
- }
- return false;
- }
-
- function setLicense($date)
- {
- $this->_packageInfo['release_license'] = $date;
- $this->_isValid = false;
- }
-
- function getSummary()
- {
- if (isset($this->_packageInfo['summary'])) {
- return $this->_packageInfo['summary'];
- }
- return false;
- }
-
- function setSummary($summary)
- {
- $this->_packageInfo['summary'] = $summary;
- $this->_isValid = false;
- }
-
- function getDescription()
- {
- if (isset($this->_packageInfo['description'])) {
- return $this->_packageInfo['description'];
- }
- return false;
- }
-
- function setDescription($desc)
- {
- $this->_packageInfo['description'] = $desc;
- $this->_isValid = false;
- }
-
- function getNotes()
- {
- if (isset($this->_packageInfo['release_notes'])) {
- return $this->_packageInfo['release_notes'];
- }
- return false;
- }
-
- function setNotes($notes)
- {
- $this->_packageInfo['release_notes'] = $notes;
- $this->_isValid = false;
- }
-
- function getDeps()
- {
- if (isset($this->_packageInfo['release_deps'])) {
- return $this->_packageInfo['release_deps'];
- }
- return false;
- }
-
- /**
- * Reset dependencies prior to adding new ones
- */
- function clearDeps()
- {
- unset($this->_packageInfo['release_deps']);
- }
-
- function addPhpDep($version, $rel)
- {
- $this->_isValid = false;
- $this->_packageInfo['release_deps'][] =
- array('type' => 'php',
- 'rel' => $rel,
- 'version' => $version);
- }
-
- function addPackageDep($name, $version, $rel, $optional = 'no')
- {
- $this->_isValid = false;
- $dep =
- array('type' => 'pkg',
- 'name' => $name,
- 'rel' => $rel,
- 'optional' => $optional);
- if ($rel != 'has' && $rel != 'not') {
- $dep['version'] = $version;
- }
- $this->_packageInfo['release_deps'][] = $dep;
- }
-
- function addExtensionDep($name, $version, $rel, $optional = 'no')
- {
- $this->_isValid = false;
- $this->_packageInfo['release_deps'][] =
- array('type' => 'ext',
- 'name' => $name,
- 'rel' => $rel,
- 'version' => $version,
- 'optional' => $optional);
- }
-
- /**
- * WARNING - do not use this function directly unless you know what you're doing
- */
- function setDeps($deps)
- {
- $this->_packageInfo['release_deps'] = $deps;
- }
-
- function hasDeps()
- {
- return isset($this->_packageInfo['release_deps']) &&
- count($this->_packageInfo['release_deps']);
- }
-
- function getDependencyGroup($group)
- {
- return false;
- }
-
- function isCompatible($pf)
- {
- return false;
- }
-
- function isSubpackageOf($p)
- {
- return $p->isSubpackage($this);
- }
-
- function isSubpackage($p)
- {
- return false;
- }
-
- function dependsOn($package, $channel)
- {
- if (strtolower($channel) != 'pear.php.net') {
- return false;
- }
- if (!($deps = $this->getDeps())) {
- return false;
- }
- foreach ($deps as $dep) {
- if ($dep['type'] != 'pkg') {
- continue;
- }
- if (strtolower($dep['name']) == strtolower($package)) {
- return true;
- }
- }
- return false;
- }
-
- function getConfigureOptions()
- {
- if (isset($this->_packageInfo['configure_options'])) {
- return $this->_packageInfo['configure_options'];
- }
- return false;
- }
-
- function hasConfigureOptions()
- {
- return isset($this->_packageInfo['configure_options']) &&
- count($this->_packageInfo['configure_options']);
- }
-
- function addConfigureOption($name, $prompt, $default = false)
- {
- $o = array('name' => $name, 'prompt' => $prompt);
- if ($default !== false) {
- $o['default'] = $default;
- }
- if (!isset($this->_packageInfo['configure_options'])) {
- $this->_packageInfo['configure_options'] = array();
- }
- $this->_packageInfo['configure_options'][] = $o;
- }
-
- function clearConfigureOptions()
- {
- unset($this->_packageInfo['configure_options']);
- }
-
- function getProvides()
- {
- if (isset($this->_packageInfo['provides'])) {
- return $this->_packageInfo['provides'];
- }
- return false;
- }
-
- function getProvidesExtension()
- {
- return false;
- }
-
- function addFile($dir, $file, $attrs)
- {
- $dir = preg_replace(array('!\\\\+!', '!/+!'), array('/', '/'), $dir);
- if ($dir == '/' || $dir == '') {
- $dir = '';
- } else {
- $dir .= '/';
- }
- $file = $dir . $file;
- $file = preg_replace('![\\/]+!', '/', $file);
- $this->_packageInfo['filelist'][$file] = $attrs;
- }
-
- function getInstallationFilelist()
- {
- return $this->getFilelist();
- }
-
- function getFilelist()
- {
- if (isset($this->_packageInfo['filelist'])) {
- return $this->_packageInfo['filelist'];
- }
- return false;
- }
-
- function setFileAttribute($file, $attr, $value)
- {
- $this->_packageInfo['filelist'][$file][$attr] = $value;
- }
-
- function resetFilelist()
- {
- $this->_packageInfo['filelist'] = array();
- }
-
- function setInstalledAs($file, $path)
- {
- if ($path) {
- return $this->_packageInfo['filelist'][$file]['installed_as'] = $path;
- }
- unset($this->_packageInfo['filelist'][$file]['installed_as']);
- }
-
- function installedFile($file, $atts)
- {
- if (isset($this->_packageInfo['filelist'][$file])) {
- $this->_packageInfo['filelist'][$file] =
- array_merge($this->_packageInfo['filelist'][$file], $atts);
- } else {
- $this->_packageInfo['filelist'][$file] = $atts;
- }
- }
-
- function getChangelog()
- {
- if (isset($this->_packageInfo['changelog'])) {
- return $this->_packageInfo['changelog'];
- }
- return false;
- }
-
- function getPackagexmlVersion()
- {
- return '1.0';
- }
-
- /**
- * Wrapper to {@link PEAR_ErrorStack::getErrors()}
- * @param boolean determines whether to purge the error stack after retrieving
- * @return array
- */
- function getValidationWarnings($purge = true)
- {
- return $this->_stack->getErrors($purge);
- }
-
- // }}}
- /**
- * Validation error. Also marks the object contents as invalid
- * @param error code
- * @param array error information
- * @access private
- */
- function _validateError($code, $params = array())
- {
- $this->_stack->push($code, 'error', $params, false, false, debug_backtrace());
- $this->_isValid = false;
- }
-
- /**
- * Validation warning. Does not mark the object contents invalid.
- * @param error code
- * @param array error information
- * @access private
- */
- function _validateWarning($code, $params = array())
- {
- $this->_stack->push($code, 'warning', $params, false, false, debug_backtrace());
- }
-
- /**
- * @param integer error code
- * @access protected
- */
- function _getErrorMessage()
- {
- return array(
- PEAR_PACKAGEFILE_ERROR_NO_NAME =>
- 'Missing Package Name',
- PEAR_PACKAGEFILE_ERROR_NO_SUMMARY =>
- 'No summary found',
- PEAR_PACKAGEFILE_ERROR_MULTILINE_SUMMARY =>
- 'Summary should be on one line',
- PEAR_PACKAGEFILE_ERROR_NO_DESCRIPTION =>
- 'Missing description',
- PEAR_PACKAGEFILE_ERROR_NO_LICENSE =>
- 'Missing license',
- PEAR_PACKAGEFILE_ERROR_NO_VERSION =>
- 'No release version found',
- PEAR_PACKAGEFILE_ERROR_NO_STATE =>
- 'No release state found',
- PEAR_PACKAGEFILE_ERROR_NO_DATE =>
- 'No release date found',
- PEAR_PACKAGEFILE_ERROR_NO_NOTES =>
- 'No release notes found',
- PEAR_PACKAGEFILE_ERROR_NO_LEAD =>
- 'Package must have at least one lead maintainer',
- PEAR_PACKAGEFILE_ERROR_NO_MAINTAINERS =>
- 'No maintainers found, at least one must be defined',
- PEAR_PACKAGEFILE_ERROR_NO_MAINTHANDLE =>
- 'Maintainer %index% has no handle (user ID at channel server)',
- PEAR_PACKAGEFILE_ERROR_NO_MAINTROLE =>
- 'Maintainer %index% has no role',
- PEAR_PACKAGEFILE_ERROR_NO_MAINTNAME =>
- 'Maintainer %index% has no name',
- PEAR_PACKAGEFILE_ERROR_NO_MAINTEMAIL =>
- 'Maintainer %index% has no email',
- PEAR_PACKAGEFILE_ERROR_NO_DEPNAME =>
- 'Dependency %index% is not a php dependency, and has no name',
- PEAR_PACKAGEFILE_ERROR_NO_DEPREL =>
- 'Dependency %index% has no relation (rel)',
- PEAR_PACKAGEFILE_ERROR_NO_DEPTYPE =>
- 'Dependency %index% has no type',
- PEAR_PACKAGEFILE_ERROR_DEPNAME_IGNORED =>
- 'PHP Dependency %index% has a name attribute of "%name%" which will be' .
- ' ignored!',
- PEAR_PACKAGEFILE_ERROR_NO_DEPVERSION =>
- 'Dependency %index% is not a rel="has" or rel="not" dependency, ' .
- 'and has no version',
- PEAR_PACKAGEFILE_ERROR_NO_DEPPHPVERSION =>
- 'Dependency %index% is a type="php" dependency, ' .
- 'and has no version',
- PEAR_PACKAGEFILE_ERROR_DEPVERSION_IGNORED =>
- 'Dependency %index% is a rel="%rel%" dependency, versioning is ignored',
- PEAR_PACKAGEFILE_ERROR_INVALID_DEPOPTIONAL =>
- 'Dependency %index% has invalid optional value "%opt%", should be yes or no',
- PEAR_PACKAGEFILE_PHP_NO_NOT =>
- 'Dependency %index%: php dependencies cannot use "not" rel, use "ne"' .
- ' to exclude specific versions',
- PEAR_PACKAGEFILE_ERROR_NO_CONFNAME =>
- 'Configure Option %index% has no name',
- PEAR_PACKAGEFILE_ERROR_NO_CONFPROMPT =>
- 'Configure Option %index% has no prompt',
- PEAR_PACKAGEFILE_ERROR_NO_FILES =>
- 'No files in <filelist> section of package.xml',
- PEAR_PACKAGEFILE_ERROR_NO_FILEROLE =>
- 'File "%file%" has no role, expecting one of "%roles%"',
- PEAR_PACKAGEFILE_ERROR_INVALID_FILEROLE =>
- 'File "%file%" has invalid role "%role%", expecting one of "%roles%"',
- PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME =>
- 'File "%file%" cannot start with ".", cannot package or install',
- PEAR_PACKAGEFILE_ERROR_INVALID_PHPFILE =>
- 'Parser error: invalid PHP found in file "%file%"',
- PEAR_PACKAGEFILE_ERROR_NO_PNAME_PREFIX =>
- 'in %file%: %type% "%name%" not prefixed with package name "%package%"',
- PEAR_PACKAGEFILE_ERROR_INVALID_FILE =>
- 'Parser error: invalid PHP file "%file%"',
- PEAR_PACKAGEFILE_ERROR_CHANNELVAL =>
- 'Channel validator error: field "%field%" - %reason%',
- PEAR_PACKAGEFILE_ERROR_PHP5 =>
- 'Error, PHP5 token encountered in %file%, analysis should be in PHP5',
- PEAR_PACKAGEFILE_ERROR_FILE_NOTFOUND =>
- 'File "%file%" in package.xml does not exist',
- PEAR_PACKAGEFILE_ERROR_NON_ISO_CHARS =>
- 'Package.xml contains non-ISO-8859-1 characters, and may not validate',
- );
- }
-
- /**
- * Validate XML package definition file.
- *
- * @access public
- * @return boolean
- */
- function validate($state = PEAR_VALIDATE_NORMAL, $nofilechecking = false)
- {
- if (($this->_isValid & $state) == $state) {
- return true;
- }
- $this->_isValid = true;
- $info = $this->_packageInfo;
- if (empty($info['package'])) {
- $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_NAME);
- $this->_packageName = $pn = 'unknown';
- } else {
- $this->_packageName = $pn = $info['package'];
- }
-
- if (empty($info['summary'])) {
- $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_SUMMARY);
- } elseif (strpos(trim($info['summary']), "\n") !== false) {
- $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_MULTILINE_SUMMARY,
- array('summary' => $info['summary']));
- }
- if (empty($info['description'])) {
- $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DESCRIPTION);
- }
- if (empty($info['release_license'])) {
- $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_LICENSE);
- }
- if (empty($info['version'])) {
- $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_VERSION);
- }
- if (empty($info['release_state'])) {
- $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_STATE);
- }
- if (empty($info['release_date'])) {
- $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DATE);
- }
- if (empty($info['release_notes'])) {
- $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_NOTES);
- }
- if (empty($info['maintainers'])) {
- $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTAINERS);
- } else {
- $haslead = false;
- $i = 1;
- foreach ($info['maintainers'] as $m) {
- if (empty($m['handle'])) {
- $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTHANDLE,
- array('index' => $i));
- }
- if (empty($m['role'])) {
- $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTROLE,
- array('index' => $i, 'roles' => PEAR_Common::getUserRoles()));
- } elseif ($m['role'] == 'lead') {
- $haslead = true;
- }
- if (empty($m['name'])) {
- $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTNAME,
- array('index' => $i));
- }
- if (empty($m['email'])) {
- $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTEMAIL,
- array('index' => $i));
- }
- $i++;
- }
- if (!$haslead) {
- $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_LEAD);
- }
- }
- if (!empty($info['release_deps'])) {
- $i = 1;
- foreach ($info['release_deps'] as $d) {
- if (!isset($d['type']) || empty($d['type'])) {
- $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPTYPE,
- array('index' => $i, 'types' => PEAR_Common::getDependencyTypes()));
- continue;
- }
- if (!isset($d['rel']) || empty($d['rel'])) {
- $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPREL,
- array('index' => $i, 'rels' => PEAR_Common::getDependencyRelations()));
- continue;
- }
- if (!empty($d['optional'])) {
- if (!in_array($d['optional'], array('yes', 'no'))) {
- $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_DEPOPTIONAL,
- array('index' => $i, 'opt' => $d['optional']));
- }
- }
- if ($d['rel'] != 'has' && $d['rel'] != 'not' && empty($d['version'])) {
- $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPVERSION,
- array('index' => $i));
- } elseif (($d['rel'] == 'has' || $d['rel'] == 'not') && !empty($d['version'])) {
- $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_DEPVERSION_IGNORED,
- array('index' => $i, 'rel' => $d['rel']));
- }
- if ($d['type'] == 'php' && !empty($d['name'])) {
- $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_DEPNAME_IGNORED,
- array('index' => $i, 'name' => $d['name']));
- } elseif ($d['type'] != 'php' && empty($d['name'])) {
- $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPNAME,
- array('index' => $i));
- }
- if ($d['type'] == 'php' && empty($d['version'])) {
- $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPPHPVERSION,
- array('index' => $i));
- }
- if (($d['rel'] == 'not') && ($d['type'] == 'php')) {
- $this->_validateError(PEAR_PACKAGEFILE_PHP_NO_NOT,
- array('index' => $i));
- }
- $i++;
- }
- }
- if (!empty($info['configure_options'])) {
- $i = 1;
- foreach ($info['configure_options'] as $c) {
- if (empty($c['name'])) {
- $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_CONFNAME,
- array('index' => $i));
- }
- if (empty($c['prompt'])) {
- $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_CONFPROMPT,
- array('index' => $i));
- }
- $i++;
- }
- }
- if (empty($info['filelist'])) {
- $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_FILES);
- $errors[] = 'no files';
- } else {
- foreach ($info['filelist'] as $file => $fa) {
- if (empty($fa['role'])) {
- $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_FILEROLE,
- array('file' => $file, 'roles' => PEAR_Common::getFileRoles()));
- continue;
- } elseif (!in_array($fa['role'], PEAR_Common::getFileRoles())) {
- $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_FILEROLE,
- array('file' => $file, 'role' => $fa['role'], 'roles' => PEAR_Common::getFileRoles()));
- }
- if (preg_match('~/\.\.?(/|\\z)|^\.\.?/~', str_replace('\\', '/', $file))) {
- // file contains .. parent directory or . cur directory references
- $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME,
- array('file' => $file));
- }
- if (isset($fa['install-as']) &&
- preg_match('~/\.\.?(/|\\z)|^\.\.?/~',
- str_replace('\\', '/', $fa['install-as']))) {
- // install-as contains .. parent directory or . cur directory references
- $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME,
- array('file' => $file . ' [installed as ' . $fa['install-as'] . ']'));
- }
- if (isset($fa['baseinstalldir']) &&
- preg_match('~/\.\.?(/|\\z)|^\.\.?/~',
- str_replace('\\', '/', $fa['baseinstalldir']))) {
- // install-as contains .. parent directory or . cur directory references
- $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME,
- array('file' => $file . ' [baseinstalldir ' . $fa['baseinstalldir'] . ']'));
- }
- }
- }
- if (isset($this->_registry) && $this->_isValid) {
- $chan = $this->_registry->getChannel('pear.php.net');
- if (PEAR::isError($chan)) {
- $this->_validateError(PEAR_PACKAGEFILE_ERROR_CHANNELVAL, $chan->getMessage());
- return $this->_isValid = 0;
- }
- $validator = $chan->getValidationObject();
- $validator->setPackageFile($this);
- $validator->validate($state);
- $failures = $validator->getFailures();
- foreach ($failures['errors'] as $error) {
- $this->_validateError(PEAR_PACKAGEFILE_ERROR_CHANNELVAL, $error);
- }
- foreach ($failures['warnings'] as $warning) {
- $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_CHANNELVAL, $warning);
- }
- }
- if ($this->_isValid && $state == PEAR_VALIDATE_PACKAGING && !$nofilechecking) {
- if ($this->_analyzePhpFiles()) {
- $this->_isValid = true;
- }
- }
- if ($this->_isValid) {
- return $this->_isValid = $state;
- }
- return $this->_isValid = 0;
- }
-
- function _analyzePhpFiles()
- {
- if (!$this->_isValid) {
- return false;
- }
- if (!isset($this->_packageFile)) {
- return false;
- }
- $dir_prefix = dirname($this->_packageFile);
- $common = new PEAR_Common;
- $log = isset($this->_logger) ? array(&$this->_logger, 'log') :
- array($common, 'log');
- $info = $this->getFilelist();
- foreach ($info as $file => $fa) {
- if (!file_exists($dir_prefix . DIRECTORY_SEPARATOR . $file)) {
- $this->_validateError(PEAR_PACKAGEFILE_ERROR_FILE_NOTFOUND,
- array('file' => realpath($dir_prefix) . DIRECTORY_SEPARATOR . $file));
- continue;
- }
- if ($fa['role'] == 'php' && $dir_prefix) {
- call_user_func_array($log, array(1, "Analyzing $file"));
- $srcinfo = $this->_analyzeSourceCode($dir_prefix . DIRECTORY_SEPARATOR . $file);
- if ($srcinfo) {
- $this->_buildProvidesArray($srcinfo);
- }
- }
- }
- $this->_packageName = $pn = $this->getPackage();
- $pnl = strlen($pn);
- if (isset($this->_packageInfo['provides'])) {
- foreach ((array) $this->_packageInfo['provides'] as $key => $what) {
- if (isset($what['explicit'])) {
- // skip conformance checks if the provides entry is
- // specified in the package.xml file
- continue;
- }
- extract($what);
- if ($type == 'class') {
- if (!strncasecmp($name, $pn, $pnl)) {
- continue;
- }
- $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_NO_PNAME_PREFIX,
- array('file' => $file, 'type' => $type, 'name' => $name, 'package' => $pn));
- } elseif ($type == 'function') {
- if (strstr($name, '::') || !strncasecmp($name, $pn, $pnl)) {
- continue;
- }
- $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_NO_PNAME_PREFIX,
- array('file' => $file, 'type' => $type, 'name' => $name, 'package' => $pn));
- }
- }
- }
- return $this->_isValid;
- }
-
- /**
- * Get the default xml generator object
- *
- * @return PEAR_PackageFile_Generator_v1
- */
- function &getDefaultGenerator()
- {
- if (!class_exists('PEAR_PackageFile_Generator_v1')) {
- require_once 'PEAR/PackageFile/Generator/v1.php';
- }
- $a = &new PEAR_PackageFile_Generator_v1($this);
- return $a;
- }
-
- /**
- * Get the contents of a file listed within the package.xml
- * @param string
- * @return string
- */
- function getFileContents($file)
- {
- if ($this->_archiveFile == $this->_packageFile) { // unpacked
- $dir = dirname($this->_packageFile);
- $file = $dir . DIRECTORY_SEPARATOR . $file;
- $file = str_replace(array('/', '\\'),
- array(DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR), $file);
- if (file_exists($file) && is_readable($file)) {
- return implode('', file($file));
- }
- } else { // tgz
- if (!class_exists('Archive_Tar')) {
- require_once 'Archive/Tar.php';
- }
- $tar = &new Archive_Tar($this->_archiveFile);
- $tar->pushErrorHandling(PEAR_ERROR_RETURN);
- if ($file != 'package.xml' && $file != 'package2.xml') {
- $file = $this->getPackage() . '-' . $this->getVersion() . '/' . $file;
- }
- $file = $tar->extractInString($file);
- $tar->popErrorHandling();
- if (PEAR::isError($file)) {
- return PEAR::raiseError("Cannot locate file '$file' in archive");
- }
- return $file;
- }
- }
-
- // {{{ analyzeSourceCode()
- /**
- * Analyze the source code of the given PHP file
- *
- * @param string Filename of the PHP file
- * @return mixed
- * @access private
- */
- function _analyzeSourceCode($file)
- {
- if (!function_exists("token_get_all")) {
- return false;
- }
- if (!defined('T_DOC_COMMENT')) {
- define('T_DOC_COMMENT', T_COMMENT);
- }
- if (!defined('T_INTERFACE')) {
- define('T_INTERFACE', -1);
- }
- if (!defined('T_IMPLEMENTS')) {
- define('T_IMPLEMENTS', -1);
- }
- if (!$fp = @fopen($file, "r")) {
- return false;
- }
- fclose($fp);
- $contents = file_get_contents($file);
- $tokens = token_get_all($contents);
-/*
- for ($i = 0; $i < sizeof($tokens); $i++) {
- @list($token, $data) = $tokens[$i];
- if (is_string($token)) {
- var_dump($token);
- } else {
- print token_name($token) . ' ';
- var_dump(rtrim($data));
- }
- }
-*/
- $look_for = 0;
- $paren_level = 0;
- $bracket_level = 0;
- $brace_level = 0;
- $lastphpdoc = '';
- $current_class = '';
- $current_interface = '';
- $current_class_level = -1;
- $current_function = '';
- $current_function_level = -1;
- $declared_classes = array();
- $declared_interfaces = array();
- $declared_functions = array();
- $declared_methods = array();
- $used_classes = array();
- $used_functions = array();
- $extends = array();
- $implements = array();
- $nodeps = array();
- $inquote = false;
- $interface = false;
- for ($i = 0; $i < sizeof($tokens); $i++) {
- if (is_array($tokens[$i])) {
- list($token, $data) = $tokens[$i];
- } else {
- $token = $tokens[$i];
- $data = '';
- }
- if ($inquote) {
- if ($token != '"' && $token != T_END_HEREDOC) {
- continue;
- } else {
- $inquote = false;
- continue;
- }
- }
- switch ($token) {
- case T_WHITESPACE :
- continue;
- case ';':
- if ($interface) {
- $current_function = '';
- $current_function_level = -1;
- }
- break;
- case '"':
- case T_START_HEREDOC:
- $inquote = true;
- break;
- case T_CURLY_OPEN:
- case T_DOLLAR_OPEN_CURLY_BRACES:
- case '{': $brace_level++; continue 2;
- case '}':
- $brace_level--;
- if ($current_class_level == $brace_level) {
- $current_class = '';
- $current_class_level = -1;
- }
- if ($current_function_level == $brace_level) {
- $current_function = '';
- $current_function_level = -1;
- }
- continue 2;
- case '[': $bracket_level++; continue 2;
- case ']': $bracket_level--; continue 2;
- case '(': $paren_level++; continue 2;
- case ')': $paren_level--; continue 2;
- case T_INTERFACE:
- $interface = true;
- case T_CLASS:
- if (($current_class_level != -1) || ($current_function_level != -1)) {
- $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_PHPFILE,
- array('file' => $file));
- return false;
- }
- case T_FUNCTION:
- case T_NEW:
- case T_EXTENDS:
- case T_IMPLEMENTS:
- $look_for = $token;
- continue 2;
- case T_STRING:
- if (version_compare(zend_version(), '2.0', '<')) {
- if (in_array(strtolower($data),
- array('public', 'private', 'protected', 'abstract',
- 'interface', 'implements', 'throw')
- )) {
- $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_PHP5,
- array($file));
- }
- }
- if ($look_for == T_CLASS) {
- $current_class = $data;
- $current_class_level = $brace_level;
- $declared_classes[] = $current_class;
- } elseif ($look_for == T_INTERFACE) {
- $current_interface = $data;
- $current_class_level = $brace_level;
- $declared_interfaces[] = $current_interface;
- } elseif ($look_for == T_IMPLEMENTS) {
- $implements[$current_class] = $data;
- } elseif ($look_for == T_EXTENDS) {
- $extends[$current_class] = $data;
- } elseif ($look_for == T_FUNCTION) {
- if ($current_class) {
- $current_function = "$current_class::$data";
- $declared_methods[$current_class][] = $data;
- } elseif ($current_interface) {
- $current_function = "$current_interface::$data";
- $declared_methods[$current_interface][] = $data;
- } else {
- $current_function = $data;
- $declared_functions[] = $current_function;
- }
- $current_function_level = $brace_level;
- $m = array();
- } elseif ($look_for == T_NEW) {
- $used_classes[$data] = true;
- }
- $look_for = 0;
- continue 2;
- case T_VARIABLE:
- $look_for = 0;
- continue 2;
- case T_DOC_COMMENT:
- case T_COMMENT:
- if (preg_match('!^/\*\*\s!', $data)) {
- $lastphpdoc = $data;
- if (preg_match_all('/@nodep\s+(\S+)/', $lastphpdoc, $m)) {
- $nodeps = array_merge($nodeps, $m[1]);
- }
- }
- continue 2;
- case T_DOUBLE_COLON:
- if (!($tokens[$i - 1][0] == T_WHITESPACE || $tokens[$i - 1][0] == T_STRING)) {
- $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_PHPFILE,
- array('file' => $file));
- return false;
- }
- $class = $tokens[$i - 1][1];
- if (strtolower($class) != 'parent') {
- $used_classes[$class] = true;
- }
- continue 2;
- }
- }
- return array(
- "source_file" => $file,
- "declared_classes" => $declared_classes,
- "declared_interfaces" => $declared_interfaces,
- "declared_methods" => $declared_methods,
- "declared_functions" => $declared_functions,
- "used_classes" => array_diff(array_keys($used_classes), $nodeps),
- "inheritance" => $extends,
- "implements" => $implements,
- );
- }
-
- /**
- * Build a "provides" array from data returned by
- * analyzeSourceCode(). The format of the built array is like
- * this:
- *
- * array(
- * 'class;MyClass' => 'array('type' => 'class', 'name' => 'MyClass'),
- * ...
- * )
- *
- *
- * @param array $srcinfo array with information about a source file
- * as returned by the analyzeSourceCode() method.
- *
- * @return void
- *
- * @access private
- *
- */
- function _buildProvidesArray($srcinfo)
- {
- if (!$this->_isValid) {
- return false;
- }
- $file = basename($srcinfo['source_file']);
- $pn = $this->getPackage();
- $pnl = strlen($pn);
- foreach ($srcinfo['declared_classes'] as $class) {
- $key = "class;$class";
- if (isset($this->_packageInfo['provides'][$key])) {
- continue;
- }
- $this->_packageInfo['provides'][$key] =
- array('file'=> $file, 'type' => 'class', 'name' => $class);
- if (isset($srcinfo['inheritance'][$class])) {
- $this->_packageInfo['provides'][$key]['extends'] =
- $srcinfo['inheritance'][$class];
- }
- }
- foreach ($srcinfo['declared_methods'] as $class => $methods) {
- foreach ($methods as $method) {
- $function = "$class::$method";
- $key = "function;$function";
- if ($method{0} == '_' || !strcasecmp($method, $class) ||
- isset($this->_packageInfo['provides'][$key])) {
- continue;
- }
- $this->_packageInfo['provides'][$key] =
- array('file'=> $file, 'type' => 'function', 'name' => $function);
- }
- }
-
- foreach ($srcinfo['declared_functions'] as $function) {
- $key = "function;$function";
- if ($function{0} == '_' || isset($this->_packageInfo['provides'][$key])) {
- continue;
- }
- if (!strstr($function, '::') && strncasecmp($function, $pn, $pnl)) {
- $warnings[] = "in1 " . $file . ": function \"$function\" not prefixed with package name \"$pn\"";
- }
- $this->_packageInfo['provides'][$key] =
- array('file'=> $file, 'type' => 'function', 'name' => $function);
- }
- }
-
- // }}}
-}
-?>
- +} +/** + * PEAR_PackageFile_v1, package.xml version 1.0 + * + * PHP versions 4 and 5 + * + * @category pear + * @package PEAR + * @author Greg Beaver <cellog@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: v1.php 276383 2009-02-24 23:39:37Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ +/** + * For error handling + */ +require_once 'PEAR/ErrorStack.php'; + +/** + * Error code if parsing is attempted with no xml extension + */ +define('PEAR_PACKAGEFILE_ERROR_NO_XML_EXT', 3); + +/** + * Error code if creating the xml parser resource fails + */ +define('PEAR_PACKAGEFILE_ERROR_CANT_MAKE_PARSER', 4); + +/** + * Error code used for all sax xml parsing errors + */ +define('PEAR_PACKAGEFILE_ERROR_PARSER_ERROR', 5); + +/** + * Error code used when there is no name + */ +define('PEAR_PACKAGEFILE_ERROR_NO_NAME', 6); + +/** + * Error code when a package name is not valid + */ +define('PEAR_PACKAGEFILE_ERROR_INVALID_NAME', 7); + +/** + * Error code used when no summary is parsed + */ +define('PEAR_PACKAGEFILE_ERROR_NO_SUMMARY', 8); + +/** + * Error code for summaries that are more than 1 line + */ +define('PEAR_PACKAGEFILE_ERROR_MULTILINE_SUMMARY', 9); + +/** + * Error code used when no description is present + */ +define('PEAR_PACKAGEFILE_ERROR_NO_DESCRIPTION', 10); + +/** + * Error code used when no license is present + */ +define('PEAR_PACKAGEFILE_ERROR_NO_LICENSE', 11); + +/** + * Error code used when a <version> version number is not present + */ +define('PEAR_PACKAGEFILE_ERROR_NO_VERSION', 12); + +/** + * Error code used when a <version> version number is invalid + */ +define('PEAR_PACKAGEFILE_ERROR_INVALID_VERSION', 13); + +/** + * Error code when release state is missing + */ +define('PEAR_PACKAGEFILE_ERROR_NO_STATE', 14); + +/** + * Error code when release state is invalid + */ +define('PEAR_PACKAGEFILE_ERROR_INVALID_STATE', 15); + +/** + * Error code when release state is missing + */ +define('PEAR_PACKAGEFILE_ERROR_NO_DATE', 16); + +/** + * Error code when release state is invalid + */ +define('PEAR_PACKAGEFILE_ERROR_INVALID_DATE', 17); + +/** + * Error code when no release notes are found + */ +define('PEAR_PACKAGEFILE_ERROR_NO_NOTES', 18); + +/** + * Error code when no maintainers are found + */ +define('PEAR_PACKAGEFILE_ERROR_NO_MAINTAINERS', 19); + +/** + * Error code when a maintainer has no handle + */ +define('PEAR_PACKAGEFILE_ERROR_NO_MAINTHANDLE', 20); + +/** + * Error code when a maintainer has no handle + */ +define('PEAR_PACKAGEFILE_ERROR_NO_MAINTROLE', 21); + +/** + * Error code when a maintainer has no name + */ +define('PEAR_PACKAGEFILE_ERROR_NO_MAINTNAME', 22); + +/** + * Error code when a maintainer has no email + */ +define('PEAR_PACKAGEFILE_ERROR_NO_MAINTEMAIL', 23); + +/** + * Error code when a maintainer has no handle + */ +define('PEAR_PACKAGEFILE_ERROR_INVALID_MAINTROLE', 24); + +/** + * Error code when a dependency is not a PHP dependency, but has no name + */ +define('PEAR_PACKAGEFILE_ERROR_NO_DEPNAME', 25); + +/** + * Error code when a dependency has no type (pkg, php, etc.) + */ +define('PEAR_PACKAGEFILE_ERROR_NO_DEPTYPE', 26); + +/** + * Error code when a dependency has no relation (lt, ge, has, etc.) + */ +define('PEAR_PACKAGEFILE_ERROR_NO_DEPREL', 27); + +/** + * Error code when a dependency is not a 'has' relation, but has no version + */ +define('PEAR_PACKAGEFILE_ERROR_NO_DEPVERSION', 28); + +/** + * Error code when a dependency has an invalid relation + */ +define('PEAR_PACKAGEFILE_ERROR_INVALID_DEPREL', 29); + +/** + * Error code when a dependency has an invalid type + */ +define('PEAR_PACKAGEFILE_ERROR_INVALID_DEPTYPE', 30); + +/** + * Error code when a dependency has an invalid optional option + */ +define('PEAR_PACKAGEFILE_ERROR_INVALID_DEPOPTIONAL', 31); + +/** + * Error code when a dependency is a pkg dependency, and has an invalid package name + */ +define('PEAR_PACKAGEFILE_ERROR_INVALID_DEPNAME', 32); + +/** + * Error code when a dependency has a channel="foo" attribute, and foo is not a registered channel + */ +define('PEAR_PACKAGEFILE_ERROR_UNKNOWN_DEPCHANNEL', 33); + +/** + * Error code when rel="has" and version attribute is present. + */ +define('PEAR_PACKAGEFILE_ERROR_DEPVERSION_IGNORED', 34); + +/** + * Error code when type="php" and dependency name is present + */ +define('PEAR_PACKAGEFILE_ERROR_DEPNAME_IGNORED', 35); + +/** + * Error code when a configure option has no name + */ +define('PEAR_PACKAGEFILE_ERROR_NO_CONFNAME', 36); + +/** + * Error code when a configure option has no name + */ +define('PEAR_PACKAGEFILE_ERROR_NO_CONFPROMPT', 37); + +/** + * Error code when a file in the filelist has an invalid role + */ +define('PEAR_PACKAGEFILE_ERROR_INVALID_FILEROLE', 38); + +/** + * Error code when a file in the filelist has no role + */ +define('PEAR_PACKAGEFILE_ERROR_NO_FILEROLE', 39); + +/** + * Error code when analyzing a php source file that has parse errors + */ +define('PEAR_PACKAGEFILE_ERROR_INVALID_PHPFILE', 40); + +/** + * Error code when analyzing a php source file reveals a source element + * without a package name prefix + */ +define('PEAR_PACKAGEFILE_ERROR_NO_PNAME_PREFIX', 41); + +/** + * Error code when an unknown channel is specified + */ +define('PEAR_PACKAGEFILE_ERROR_UNKNOWN_CHANNEL', 42); + +/** + * Error code when no files are found in the filelist + */ +define('PEAR_PACKAGEFILE_ERROR_NO_FILES', 43); + +/** + * Error code when a file is not valid php according to _analyzeSourceCode() + */ +define('PEAR_PACKAGEFILE_ERROR_INVALID_FILE', 44); + +/** + * Error code when the channel validator returns an error or warning + */ +define('PEAR_PACKAGEFILE_ERROR_CHANNELVAL', 45); + +/** + * Error code when a php5 package is packaged in php4 (analysis doesn't work) + */ +define('PEAR_PACKAGEFILE_ERROR_PHP5', 46); + +/** + * Error code when a file is listed in package.xml but does not exist + */ +define('PEAR_PACKAGEFILE_ERROR_FILE_NOTFOUND', 47); + +/** + * Error code when a <dep type="php" rel="not"... is encountered (use rel="ne") + */ +define('PEAR_PACKAGEFILE_PHP_NO_NOT', 48); + +/** + * Error code when a package.xml contains non-ISO-8859-1 characters + */ +define('PEAR_PACKAGEFILE_ERROR_NON_ISO_CHARS', 49); + +/** + * Error code when a dependency is not a 'has' relation, but has no version + */ +define('PEAR_PACKAGEFILE_ERROR_NO_DEPPHPVERSION', 50); + +/** + * Error code when a package has no lead developer + */ +define('PEAR_PACKAGEFILE_ERROR_NO_LEAD', 51); + +/** + * Error code when a filename begins with "." + */ +define('PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME', 52); +/** + * package.xml encapsulator + * @category pear + * @package PEAR + * @author Greg Beaver <cellog@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_PackageFile_v1 +{ + /** + * @access private + * @var PEAR_ErrorStack + * @access private + */ + var $_stack; + + /** + * A registry object, used to access the package name validation regex for non-standard channels + * @var PEAR_Registry + * @access private + */ + var $_registry; + + /** + * An object that contains a log method that matches PEAR_Common::log's signature + * @var object + * @access private + */ + var $_logger; + + /** + * Parsed package information + * @var array + * @access private + */ + var $_packageInfo; + + /** + * path to package.xml + * @var string + * @access private + */ + var $_packageFile; + + /** + * path to package .tgz or false if this is a local/extracted package.xml + * @var string + * @access private + */ + var $_archiveFile; + + /** + * @var int + * @access private + */ + var $_isValid = 0; + + /** + * Determines whether this packagefile was initialized only with partial package info + * + * If this package file was constructed via parsing REST, it will only contain + * + * - package name + * - channel name + * - dependencies + * @var boolean + * @access private + */ + var $_incomplete = true; + + /** + * @param bool determines whether to return a PEAR_Error object, or use the PEAR_ErrorStack + * @param string Name of Error Stack class to use. + */ + function PEAR_PackageFile_v1() + { + $this->_stack = &new PEAR_ErrorStack('PEAR_PackageFile_v1'); + $this->_stack->setErrorMessageTemplate($this->_getErrorMessage()); + $this->_isValid = 0; + } + + function installBinary($installer) + { + return false; + } + + function isExtension($name) + { + return false; + } + + function setConfig(&$config) + { + $this->_config = &$config; + $this->_registry = &$config->getRegistry(); + } + + function setRequestedGroup() + { + // placeholder + } + + /** + * For saving in the registry. + * + * Set the last version that was installed + * @param string + */ + function setLastInstalledVersion($version) + { + $this->_packageInfo['_lastversion'] = $version; + } + + /** + * @return string|false + */ + function getLastInstalledVersion() + { + if (isset($this->_packageInfo['_lastversion'])) { + return $this->_packageInfo['_lastversion']; + } + return false; + } + + function getInstalledBinary() + { + return false; + } + + function listPostinstallScripts() + { + return false; + } + + function initPostinstallScripts() + { + return false; + } + + function setLogger(&$logger) + { + if ($logger && (!is_object($logger) || !method_exists($logger, 'log'))) { + return PEAR::raiseError('Logger must be compatible with PEAR_Common::log'); + } + $this->_logger = &$logger; + } + + function setPackagefile($file, $archive = false) + { + $this->_packageFile = $file; + $this->_archiveFile = $archive ? $archive : $file; + } + + function getPackageFile() + { + return isset($this->_packageFile) ? $this->_packageFile : false; + } + + function getPackageType() + { + return 'php'; + } + + function getArchiveFile() + { + return $this->_archiveFile; + } + + function packageInfo($field) + { + if (!is_string($field) || empty($field) || + !isset($this->_packageInfo[$field])) { + return false; + } + return $this->_packageInfo[$field]; + } + + function setDirtree($path) + { + if (!isset($this->_packageInfo['dirtree'])) { + $this->_packageInfo['dirtree'] = array(); + } + $this->_packageInfo['dirtree'][$path] = true; + } + + function getDirtree() + { + if (isset($this->_packageInfo['dirtree']) && count($this->_packageInfo['dirtree'])) { + return $this->_packageInfo['dirtree']; + } + return false; + } + + function resetDirtree() + { + unset($this->_packageInfo['dirtree']); + } + + function fromArray($pinfo) + { + $this->_incomplete = false; + $this->_packageInfo = $pinfo; + } + + function isIncomplete() + { + return $this->_incomplete; + } + + function getChannel() + { + return 'pear.php.net'; + } + + function getUri() + { + return false; + } + + function getTime() + { + return false; + } + + function getExtends() + { + if (isset($this->_packageInfo['extends'])) { + return $this->_packageInfo['extends']; + } + return false; + } + + /** + * @return array + */ + function toArray() + { + if (!$this->validate(PEAR_VALIDATE_NORMAL)) { + return false; + } + return $this->getArray(); + } + + function getArray() + { + return $this->_packageInfo; + } + + function getName() + { + return $this->getPackage(); + } + + function getPackage() + { + if (isset($this->_packageInfo['package'])) { + return $this->_packageInfo['package']; + } + return false; + } + + /** + * WARNING - don't use this unless you know what you are doing + */ + function setRawPackage($package) + { + $this->_packageInfo['package'] = $package; + } + + function setPackage($package) + { + $this->_packageInfo['package'] = $package; + $this->_isValid = false; + } + + function getVersion() + { + if (isset($this->_packageInfo['version'])) { + return $this->_packageInfo['version']; + } + return false; + } + + function setVersion($version) + { + $this->_packageInfo['version'] = $version; + $this->_isValid = false; + } + + function clearMaintainers() + { + unset($this->_packageInfo['maintainers']); + } + + function getMaintainers() + { + if (isset($this->_packageInfo['maintainers'])) { + return $this->_packageInfo['maintainers']; + } + return false; + } + + /** + * Adds a new maintainer - no checking of duplicates is performed, use + * updatemaintainer for that purpose. + */ + function addMaintainer($role, $handle, $name, $email) + { + $this->_packageInfo['maintainers'][] = + array('handle' => $handle, 'role' => $role, 'email' => $email, 'name' => $name); + $this->_isValid = false; + } + + function updateMaintainer($role, $handle, $name, $email) + { + $found = false; + if (!isset($this->_packageInfo['maintainers']) || + !is_array($this->_packageInfo['maintainers'])) { + return $this->addMaintainer($role, $handle, $name, $email); + } + foreach ($this->_packageInfo['maintainers'] as $i => $maintainer) { + if ($maintainer['handle'] == $handle) { + $found = $i; + break; + } + } + if ($found !== false) { + unset($this->_packageInfo['maintainers'][$found]); + $this->_packageInfo['maintainers'] = + array_values($this->_packageInfo['maintainers']); + } + $this->addMaintainer($role, $handle, $name, $email); + } + + function deleteMaintainer($handle) + { + $found = false; + foreach ($this->_packageInfo['maintainers'] as $i => $maintainer) { + if ($maintainer['handle'] == $handle) { + $found = $i; + break; + } + } + if ($found !== false) { + unset($this->_packageInfo['maintainers'][$found]); + $this->_packageInfo['maintainers'] = + array_values($this->_packageInfo['maintainers']); + return true; + } + return false; + } + + function getState() + { + if (isset($this->_packageInfo['release_state'])) { + return $this->_packageInfo['release_state']; + } + return false; + } + + function setRawState($state) + { + $this->_packageInfo['release_state'] = $state; + } + + function setState($state) + { + $this->_packageInfo['release_state'] = $state; + $this->_isValid = false; + } + + function getDate() + { + if (isset($this->_packageInfo['release_date'])) { + return $this->_packageInfo['release_date']; + } + return false; + } + + function setDate($date) + { + $this->_packageInfo['release_date'] = $date; + $this->_isValid = false; + } + + function getLicense() + { + if (isset($this->_packageInfo['release_license'])) { + return $this->_packageInfo['release_license']; + } + return false; + } + + function setLicense($date) + { + $this->_packageInfo['release_license'] = $date; + $this->_isValid = false; + } + + function getSummary() + { + if (isset($this->_packageInfo['summary'])) { + return $this->_packageInfo['summary']; + } + return false; + } + + function setSummary($summary) + { + $this->_packageInfo['summary'] = $summary; + $this->_isValid = false; + } + + function getDescription() + { + if (isset($this->_packageInfo['description'])) { + return $this->_packageInfo['description']; + } + return false; + } + + function setDescription($desc) + { + $this->_packageInfo['description'] = $desc; + $this->_isValid = false; + } + + function getNotes() + { + if (isset($this->_packageInfo['release_notes'])) { + return $this->_packageInfo['release_notes']; + } + return false; + } + + function setNotes($notes) + { + $this->_packageInfo['release_notes'] = $notes; + $this->_isValid = false; + } + + function getDeps() + { + if (isset($this->_packageInfo['release_deps'])) { + return $this->_packageInfo['release_deps']; + } + return false; + } + + /** + * Reset dependencies prior to adding new ones + */ + function clearDeps() + { + unset($this->_packageInfo['release_deps']); + } + + function addPhpDep($version, $rel) + { + $this->_isValid = false; + $this->_packageInfo['release_deps'][] = + array('type' => 'php', + 'rel' => $rel, + 'version' => $version); + } + + function addPackageDep($name, $version, $rel, $optional = 'no') + { + $this->_isValid = false; + $dep = + array('type' => 'pkg', + 'name' => $name, + 'rel' => $rel, + 'optional' => $optional); + if ($rel != 'has' && $rel != 'not') { + $dep['version'] = $version; + } + $this->_packageInfo['release_deps'][] = $dep; + } + + function addExtensionDep($name, $version, $rel, $optional = 'no') + { + $this->_isValid = false; + $this->_packageInfo['release_deps'][] = + array('type' => 'ext', + 'name' => $name, + 'rel' => $rel, + 'version' => $version, + 'optional' => $optional); + } + + /** + * WARNING - do not use this function directly unless you know what you're doing + */ + function setDeps($deps) + { + $this->_packageInfo['release_deps'] = $deps; + } + + function hasDeps() + { + return isset($this->_packageInfo['release_deps']) && + count($this->_packageInfo['release_deps']); + } + + function getDependencyGroup($group) + { + return false; + } + + function isCompatible($pf) + { + return false; + } + + function isSubpackageOf($p) + { + return $p->isSubpackage($this); + } + + function isSubpackage($p) + { + return false; + } + + function dependsOn($package, $channel) + { + if (strtolower($channel) != 'pear.php.net') { + return false; + } + if (!($deps = $this->getDeps())) { + return false; + } + foreach ($deps as $dep) { + if ($dep['type'] != 'pkg') { + continue; + } + if (strtolower($dep['name']) == strtolower($package)) { + return true; + } + } + return false; + } + + function getConfigureOptions() + { + if (isset($this->_packageInfo['configure_options'])) { + return $this->_packageInfo['configure_options']; + } + return false; + } + + function hasConfigureOptions() + { + return isset($this->_packageInfo['configure_options']) && + count($this->_packageInfo['configure_options']); + } + + function addConfigureOption($name, $prompt, $default = false) + { + $o = array('name' => $name, 'prompt' => $prompt); + if ($default !== false) { + $o['default'] = $default; + } + if (!isset($this->_packageInfo['configure_options'])) { + $this->_packageInfo['configure_options'] = array(); + } + $this->_packageInfo['configure_options'][] = $o; + } + + function clearConfigureOptions() + { + unset($this->_packageInfo['configure_options']); + } + + function getProvides() + { + if (isset($this->_packageInfo['provides'])) { + return $this->_packageInfo['provides']; + } + return false; + } + + function getProvidesExtension() + { + return false; + } + + function addFile($dir, $file, $attrs) + { + $dir = preg_replace(array('!\\\\+!', '!/+!'), array('/', '/'), $dir); + if ($dir == '/' || $dir == '') { + $dir = ''; + } else { + $dir .= '/'; + } + $file = $dir . $file; + $file = preg_replace('![\\/]+!', '/', $file); + $this->_packageInfo['filelist'][$file] = $attrs; + } + + function getInstallationFilelist() + { + return $this->getFilelist(); + } + + function getFilelist() + { + if (isset($this->_packageInfo['filelist'])) { + return $this->_packageInfo['filelist']; + } + return false; + } + + function setFileAttribute($file, $attr, $value) + { + $this->_packageInfo['filelist'][$file][$attr] = $value; + } + + function resetFilelist() + { + $this->_packageInfo['filelist'] = array(); + } + + function setInstalledAs($file, $path) + { + if ($path) { + return $this->_packageInfo['filelist'][$file]['installed_as'] = $path; + } + unset($this->_packageInfo['filelist'][$file]['installed_as']); + } + + function installedFile($file, $atts) + { + if (isset($this->_packageInfo['filelist'][$file])) { + $this->_packageInfo['filelist'][$file] = + array_merge($this->_packageInfo['filelist'][$file], $atts); + } else { + $this->_packageInfo['filelist'][$file] = $atts; + } + } + + function getChangelog() + { + if (isset($this->_packageInfo['changelog'])) { + return $this->_packageInfo['changelog']; + } + return false; + } + + function getPackagexmlVersion() + { + return '1.0'; + } + + /** + * Wrapper to {@link PEAR_ErrorStack::getErrors()} + * @param boolean determines whether to purge the error stack after retrieving + * @return array + */ + function getValidationWarnings($purge = true) + { + return $this->_stack->getErrors($purge); + } + + // }}} + /** + * Validation error. Also marks the object contents as invalid + * @param error code + * @param array error information + * @access private + */ + function _validateError($code, $params = array()) + { + $this->_stack->push($code, 'error', $params, false, false, debug_backtrace()); + $this->_isValid = false; + } + + /** + * Validation warning. Does not mark the object contents invalid. + * @param error code + * @param array error information + * @access private + */ + function _validateWarning($code, $params = array()) + { + $this->_stack->push($code, 'warning', $params, false, false, debug_backtrace()); + } + + /** + * @param integer error code + * @access protected + */ + function _getErrorMessage() + { + return array( + PEAR_PACKAGEFILE_ERROR_NO_NAME => + 'Missing Package Name', + PEAR_PACKAGEFILE_ERROR_NO_SUMMARY => + 'No summary found', + PEAR_PACKAGEFILE_ERROR_MULTILINE_SUMMARY => + 'Summary should be on one line', + PEAR_PACKAGEFILE_ERROR_NO_DESCRIPTION => + 'Missing description', + PEAR_PACKAGEFILE_ERROR_NO_LICENSE => + 'Missing license', + PEAR_PACKAGEFILE_ERROR_NO_VERSION => + 'No release version found', + PEAR_PACKAGEFILE_ERROR_NO_STATE => + 'No release state found', + PEAR_PACKAGEFILE_ERROR_NO_DATE => + 'No release date found', + PEAR_PACKAGEFILE_ERROR_NO_NOTES => + 'No release notes found', + PEAR_PACKAGEFILE_ERROR_NO_LEAD => + 'Package must have at least one lead maintainer', + PEAR_PACKAGEFILE_ERROR_NO_MAINTAINERS => + 'No maintainers found, at least one must be defined', + PEAR_PACKAGEFILE_ERROR_NO_MAINTHANDLE => + 'Maintainer %index% has no handle (user ID at channel server)', + PEAR_PACKAGEFILE_ERROR_NO_MAINTROLE => + 'Maintainer %index% has no role', + PEAR_PACKAGEFILE_ERROR_NO_MAINTNAME => + 'Maintainer %index% has no name', + PEAR_PACKAGEFILE_ERROR_NO_MAINTEMAIL => + 'Maintainer %index% has no email', + PEAR_PACKAGEFILE_ERROR_NO_DEPNAME => + 'Dependency %index% is not a php dependency, and has no name', + PEAR_PACKAGEFILE_ERROR_NO_DEPREL => + 'Dependency %index% has no relation (rel)', + PEAR_PACKAGEFILE_ERROR_NO_DEPTYPE => + 'Dependency %index% has no type', + PEAR_PACKAGEFILE_ERROR_DEPNAME_IGNORED => + 'PHP Dependency %index% has a name attribute of "%name%" which will be' . + ' ignored!', + PEAR_PACKAGEFILE_ERROR_NO_DEPVERSION => + 'Dependency %index% is not a rel="has" or rel="not" dependency, ' . + 'and has no version', + PEAR_PACKAGEFILE_ERROR_NO_DEPPHPVERSION => + 'Dependency %index% is a type="php" dependency, ' . + 'and has no version', + PEAR_PACKAGEFILE_ERROR_DEPVERSION_IGNORED => + 'Dependency %index% is a rel="%rel%" dependency, versioning is ignored', + PEAR_PACKAGEFILE_ERROR_INVALID_DEPOPTIONAL => + 'Dependency %index% has invalid optional value "%opt%", should be yes or no', + PEAR_PACKAGEFILE_PHP_NO_NOT => + 'Dependency %index%: php dependencies cannot use "not" rel, use "ne"' . + ' to exclude specific versions', + PEAR_PACKAGEFILE_ERROR_NO_CONFNAME => + 'Configure Option %index% has no name', + PEAR_PACKAGEFILE_ERROR_NO_CONFPROMPT => + 'Configure Option %index% has no prompt', + PEAR_PACKAGEFILE_ERROR_NO_FILES => + 'No files in <filelist> section of package.xml', + PEAR_PACKAGEFILE_ERROR_NO_FILEROLE => + 'File "%file%" has no role, expecting one of "%roles%"', + PEAR_PACKAGEFILE_ERROR_INVALID_FILEROLE => + 'File "%file%" has invalid role "%role%", expecting one of "%roles%"', + PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME => + 'File "%file%" cannot start with ".", cannot package or install', + PEAR_PACKAGEFILE_ERROR_INVALID_PHPFILE => + 'Parser error: invalid PHP found in file "%file%"', + PEAR_PACKAGEFILE_ERROR_NO_PNAME_PREFIX => + 'in %file%: %type% "%name%" not prefixed with package name "%package%"', + PEAR_PACKAGEFILE_ERROR_INVALID_FILE => + 'Parser error: invalid PHP file "%file%"', + PEAR_PACKAGEFILE_ERROR_CHANNELVAL => + 'Channel validator error: field "%field%" - %reason%', + PEAR_PACKAGEFILE_ERROR_PHP5 => + 'Error, PHP5 token encountered in %file%, analysis should be in PHP5', + PEAR_PACKAGEFILE_ERROR_FILE_NOTFOUND => + 'File "%file%" in package.xml does not exist', + PEAR_PACKAGEFILE_ERROR_NON_ISO_CHARS => + 'Package.xml contains non-ISO-8859-1 characters, and may not validate', + ); + } + + /** + * Validate XML package definition file. + * + * @access public + * @return boolean + */ + function validate($state = PEAR_VALIDATE_NORMAL, $nofilechecking = false) + { + if (($this->_isValid & $state) == $state) { + return true; + } + $this->_isValid = true; + $info = $this->_packageInfo; + if (empty($info['package'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_NAME); + $this->_packageName = $pn = 'unknown'; + } else { + $this->_packageName = $pn = $info['package']; + } + + if (empty($info['summary'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_SUMMARY); + } elseif (strpos(trim($info['summary']), "\n") !== false) { + $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_MULTILINE_SUMMARY, + array('summary' => $info['summary'])); + } + if (empty($info['description'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DESCRIPTION); + } + if (empty($info['release_license'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_LICENSE); + } + if (empty($info['version'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_VERSION); + } + if (empty($info['release_state'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_STATE); + } + if (empty($info['release_date'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DATE); + } + if (empty($info['release_notes'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_NOTES); + } + if (empty($info['maintainers'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTAINERS); + } else { + $haslead = false; + $i = 1; + foreach ($info['maintainers'] as $m) { + if (empty($m['handle'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTHANDLE, + array('index' => $i)); + } + if (empty($m['role'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTROLE, + array('index' => $i, 'roles' => PEAR_Common::getUserRoles())); + } elseif ($m['role'] == 'lead') { + $haslead = true; + } + if (empty($m['name'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTNAME, + array('index' => $i)); + } + if (empty($m['email'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTEMAIL, + array('index' => $i)); + } + $i++; + } + if (!$haslead) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_LEAD); + } + } + if (!empty($info['release_deps'])) { + $i = 1; + foreach ($info['release_deps'] as $d) { + if (!isset($d['type']) || empty($d['type'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPTYPE, + array('index' => $i, 'types' => PEAR_Common::getDependencyTypes())); + continue; + } + if (!isset($d['rel']) || empty($d['rel'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPREL, + array('index' => $i, 'rels' => PEAR_Common::getDependencyRelations())); + continue; + } + if (!empty($d['optional'])) { + if (!in_array($d['optional'], array('yes', 'no'))) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_DEPOPTIONAL, + array('index' => $i, 'opt' => $d['optional'])); + } + } + if ($d['rel'] != 'has' && $d['rel'] != 'not' && empty($d['version'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPVERSION, + array('index' => $i)); + } elseif (($d['rel'] == 'has' || $d['rel'] == 'not') && !empty($d['version'])) { + $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_DEPVERSION_IGNORED, + array('index' => $i, 'rel' => $d['rel'])); + } + if ($d['type'] == 'php' && !empty($d['name'])) { + $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_DEPNAME_IGNORED, + array('index' => $i, 'name' => $d['name'])); + } elseif ($d['type'] != 'php' && empty($d['name'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPNAME, + array('index' => $i)); + } + if ($d['type'] == 'php' && empty($d['version'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPPHPVERSION, + array('index' => $i)); + } + if (($d['rel'] == 'not') && ($d['type'] == 'php')) { + $this->_validateError(PEAR_PACKAGEFILE_PHP_NO_NOT, + array('index' => $i)); + } + $i++; + } + } + if (!empty($info['configure_options'])) { + $i = 1; + foreach ($info['configure_options'] as $c) { + if (empty($c['name'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_CONFNAME, + array('index' => $i)); + } + if (empty($c['prompt'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_CONFPROMPT, + array('index' => $i)); + } + $i++; + } + } + if (empty($info['filelist'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_FILES); + $errors[] = 'no files'; + } else { + foreach ($info['filelist'] as $file => $fa) { + if (empty($fa['role'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_FILEROLE, + array('file' => $file, 'roles' => PEAR_Common::getFileRoles())); + continue; + } elseif (!in_array($fa['role'], PEAR_Common::getFileRoles())) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_FILEROLE, + array('file' => $file, 'role' => $fa['role'], 'roles' => PEAR_Common::getFileRoles())); + } + if (preg_match('~/\.\.?(/|\\z)|^\.\.?/~', str_replace('\\', '/', $file))) { + // file contains .. parent directory or . cur directory references + $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME, + array('file' => $file)); + } + if (isset($fa['install-as']) && + preg_match('~/\.\.?(/|\\z)|^\.\.?/~', + str_replace('\\', '/', $fa['install-as']))) { + // install-as contains .. parent directory or . cur directory references + $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME, + array('file' => $file . ' [installed as ' . $fa['install-as'] . ']')); + } + if (isset($fa['baseinstalldir']) && + preg_match('~/\.\.?(/|\\z)|^\.\.?/~', + str_replace('\\', '/', $fa['baseinstalldir']))) { + // install-as contains .. parent directory or . cur directory references + $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME, + array('file' => $file . ' [baseinstalldir ' . $fa['baseinstalldir'] . ']')); + } + } + } + if (isset($this->_registry) && $this->_isValid) { + $chan = $this->_registry->getChannel('pear.php.net'); + if (PEAR::isError($chan)) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_CHANNELVAL, $chan->getMessage()); + return $this->_isValid = 0; + } + $validator = $chan->getValidationObject(); + $validator->setPackageFile($this); + $validator->validate($state); + $failures = $validator->getFailures(); + foreach ($failures['errors'] as $error) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_CHANNELVAL, $error); + } + foreach ($failures['warnings'] as $warning) { + $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_CHANNELVAL, $warning); + } + } + if ($this->_isValid && $state == PEAR_VALIDATE_PACKAGING && !$nofilechecking) { + if ($this->_analyzePhpFiles()) { + $this->_isValid = true; + } + } + if ($this->_isValid) { + return $this->_isValid = $state; + } + return $this->_isValid = 0; + } + + function _analyzePhpFiles() + { + if (!$this->_isValid) { + return false; + } + if (!isset($this->_packageFile)) { + return false; + } + $dir_prefix = dirname($this->_packageFile); + $common = new PEAR_Common; + $log = isset($this->_logger) ? array(&$this->_logger, 'log') : + array($common, 'log'); + $info = $this->getFilelist(); + foreach ($info as $file => $fa) { + if (!file_exists($dir_prefix . DIRECTORY_SEPARATOR . $file)) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_FILE_NOTFOUND, + array('file' => realpath($dir_prefix) . DIRECTORY_SEPARATOR . $file)); + continue; + } + if ($fa['role'] == 'php' && $dir_prefix) { + call_user_func_array($log, array(1, "Analyzing $file")); + $srcinfo = $this->_analyzeSourceCode($dir_prefix . DIRECTORY_SEPARATOR . $file); + if ($srcinfo) { + $this->_buildProvidesArray($srcinfo); + } + } + } + $this->_packageName = $pn = $this->getPackage(); + $pnl = strlen($pn); + if (isset($this->_packageInfo['provides'])) { + foreach ((array) $this->_packageInfo['provides'] as $key => $what) { + if (isset($what['explicit'])) { + // skip conformance checks if the provides entry is + // specified in the package.xml file + continue; + } + extract($what); + if ($type == 'class') { + if (!strncasecmp($name, $pn, $pnl)) { + continue; + } + $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_NO_PNAME_PREFIX, + array('file' => $file, 'type' => $type, 'name' => $name, 'package' => $pn)); + } elseif ($type == 'function') { + if (strstr($name, '::') || !strncasecmp($name, $pn, $pnl)) { + continue; + } + $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_NO_PNAME_PREFIX, + array('file' => $file, 'type' => $type, 'name' => $name, 'package' => $pn)); + } + } + } + return $this->_isValid; + } + + /** + * Get the default xml generator object + * + * @return PEAR_PackageFile_Generator_v1 + */ + function &getDefaultGenerator() + { + if (!class_exists('PEAR_PackageFile_Generator_v1')) { + require_once 'PEAR/PackageFile/Generator/v1.php'; + } + $a = &new PEAR_PackageFile_Generator_v1($this); + return $a; + } + + /** + * Get the contents of a file listed within the package.xml + * @param string + * @return string + */ + function getFileContents($file) + { + if ($this->_archiveFile == $this->_packageFile) { // unpacked + $dir = dirname($this->_packageFile); + $file = $dir . DIRECTORY_SEPARATOR . $file; + $file = str_replace(array('/', '\\'), + array(DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR), $file); + if (file_exists($file) && is_readable($file)) { + return implode('', file($file)); + } + } else { // tgz + if (!class_exists('Archive_Tar')) { + require_once 'Archive/Tar.php'; + } + $tar = &new Archive_Tar($this->_archiveFile); + $tar->pushErrorHandling(PEAR_ERROR_RETURN); + if ($file != 'package.xml' && $file != 'package2.xml') { + $file = $this->getPackage() . '-' . $this->getVersion() . '/' . $file; + } + $file = $tar->extractInString($file); + $tar->popErrorHandling(); + if (PEAR::isError($file)) { + return PEAR::raiseError("Cannot locate file '$file' in archive"); + } + return $file; + } + } + + // {{{ analyzeSourceCode() + /** + * Analyze the source code of the given PHP file + * + * @param string Filename of the PHP file + * @return mixed + * @access private + */ + function _analyzeSourceCode($file) + { + if (!function_exists("token_get_all")) { + return false; + } + if (!defined('T_DOC_COMMENT')) { + define('T_DOC_COMMENT', T_COMMENT); + } + if (!defined('T_INTERFACE')) { + define('T_INTERFACE', -1); + } + if (!defined('T_IMPLEMENTS')) { + define('T_IMPLEMENTS', -1); + } + if (!$fp = @fopen($file, "r")) { + return false; + } + fclose($fp); + $contents = file_get_contents($file); + $tokens = token_get_all($contents); +/* + for ($i = 0; $i < sizeof($tokens); $i++) { + @list($token, $data) = $tokens[$i]; + if (is_string($token)) { + var_dump($token); + } else { + print token_name($token) . ' '; + var_dump(rtrim($data)); + } + } +*/ + $look_for = 0; + $paren_level = 0; + $bracket_level = 0; + $brace_level = 0; + $lastphpdoc = ''; + $current_class = ''; + $current_interface = ''; + $current_class_level = -1; + $current_function = ''; + $current_function_level = -1; + $declared_classes = array(); + $declared_interfaces = array(); + $declared_functions = array(); + $declared_methods = array(); + $used_classes = array(); + $used_functions = array(); + $extends = array(); + $implements = array(); + $nodeps = array(); + $inquote = false; + $interface = false; + for ($i = 0; $i < sizeof($tokens); $i++) { + if (is_array($tokens[$i])) { + list($token, $data) = $tokens[$i]; + } else { + $token = $tokens[$i]; + $data = ''; + } + if ($inquote) { + if ($token != '"' && $token != T_END_HEREDOC) { + continue; + } else { + $inquote = false; + continue; + } + } + switch ($token) { + case T_WHITESPACE : + continue; + case ';': + if ($interface) { + $current_function = ''; + $current_function_level = -1; + } + break; + case '"': + case T_START_HEREDOC: + $inquote = true; + break; + case T_CURLY_OPEN: + case T_DOLLAR_OPEN_CURLY_BRACES: + case '{': $brace_level++; continue 2; + case '}': + $brace_level--; + if ($current_class_level == $brace_level) { + $current_class = ''; + $current_class_level = -1; + } + if ($current_function_level == $brace_level) { + $current_function = ''; + $current_function_level = -1; + } + continue 2; + case '[': $bracket_level++; continue 2; + case ']': $bracket_level--; continue 2; + case '(': $paren_level++; continue 2; + case ')': $paren_level--; continue 2; + case T_INTERFACE: + $interface = true; + case T_CLASS: + if (($current_class_level != -1) || ($current_function_level != -1)) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_PHPFILE, + array('file' => $file)); + return false; + } + case T_FUNCTION: + case T_NEW: + case T_EXTENDS: + case T_IMPLEMENTS: + $look_for = $token; + continue 2; + case T_STRING: + if (version_compare(zend_version(), '2.0', '<')) { + if (in_array(strtolower($data), + array('public', 'private', 'protected', 'abstract', + 'interface', 'implements', 'throw') + )) { + $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_PHP5, + array($file)); + } + } + if ($look_for == T_CLASS) { + $current_class = $data; + $current_class_level = $brace_level; + $declared_classes[] = $current_class; + } elseif ($look_for == T_INTERFACE) { + $current_interface = $data; + $current_class_level = $brace_level; + $declared_interfaces[] = $current_interface; + } elseif ($look_for == T_IMPLEMENTS) { + $implements[$current_class] = $data; + } elseif ($look_for == T_EXTENDS) { + $extends[$current_class] = $data; + } elseif ($look_for == T_FUNCTION) { + if ($current_class) { + $current_function = "$current_class::$data"; + $declared_methods[$current_class][] = $data; + } elseif ($current_interface) { + $current_function = "$current_interface::$data"; + $declared_methods[$current_interface][] = $data; + } else { + $current_function = $data; + $declared_functions[] = $current_function; + } + $current_function_level = $brace_level; + $m = array(); + } elseif ($look_for == T_NEW) { + $used_classes[$data] = true; + } + $look_for = 0; + continue 2; + case T_VARIABLE: + $look_for = 0; + continue 2; + case T_DOC_COMMENT: + case T_COMMENT: + if (preg_match('!^/\*\*\s!', $data)) { + $lastphpdoc = $data; + if (preg_match_all('/@nodep\s+(\S+)/', $lastphpdoc, $m)) { + $nodeps = array_merge($nodeps, $m[1]); + } + } + continue 2; + case T_DOUBLE_COLON: + if (!($tokens[$i - 1][0] == T_WHITESPACE || $tokens[$i - 1][0] == T_STRING)) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_PHPFILE, + array('file' => $file)); + return false; + } + $class = $tokens[$i - 1][1]; + if (strtolower($class) != 'parent') { + $used_classes[$class] = true; + } + continue 2; + } + } + return array( + "source_file" => $file, + "declared_classes" => $declared_classes, + "declared_interfaces" => $declared_interfaces, + "declared_methods" => $declared_methods, + "declared_functions" => $declared_functions, + "used_classes" => array_diff(array_keys($used_classes), $nodeps), + "inheritance" => $extends, + "implements" => $implements, + ); + } + + /** + * Build a "provides" array from data returned by + * analyzeSourceCode(). The format of the built array is like + * this: + * + * array( + * 'class;MyClass' => 'array('type' => 'class', 'name' => 'MyClass'), + * ... + * ) + * + * + * @param array $srcinfo array with information about a source file + * as returned by the analyzeSourceCode() method. + * + * @return void + * + * @access private + * + */ + function _buildProvidesArray($srcinfo) + { + if (!$this->_isValid) { + return false; + } + $file = basename($srcinfo['source_file']); + $pn = $this->getPackage(); + $pnl = strlen($pn); + foreach ($srcinfo['declared_classes'] as $class) { + $key = "class;$class"; + if (isset($this->_packageInfo['provides'][$key])) { + continue; + } + $this->_packageInfo['provides'][$key] = + array('file'=> $file, 'type' => 'class', 'name' => $class); + if (isset($srcinfo['inheritance'][$class])) { + $this->_packageInfo['provides'][$key]['extends'] = + $srcinfo['inheritance'][$class]; + } + } + foreach ($srcinfo['declared_methods'] as $class => $methods) { + foreach ($methods as $method) { + $function = "$class::$method"; + $key = "function;$function"; + if ($method{0} == '_' || !strcasecmp($method, $class) || + isset($this->_packageInfo['provides'][$key])) { + continue; + } + $this->_packageInfo['provides'][$key] = + array('file'=> $file, 'type' => 'function', 'name' => $function); + } + } + + foreach ($srcinfo['declared_functions'] as $function) { + $key = "function;$function"; + if ($function{0} == '_' || isset($this->_packageInfo['provides'][$key])) { + continue; + } + if (!strstr($function, '::') && strncasecmp($function, $pn, $pnl)) { + $warnings[] = "in1 " . $file . ": function \"$function\" not prefixed with package name \"$pn\""; + } + $this->_packageInfo['provides'][$key] = + array('file'=> $file, 'type' => 'function', 'name' => $function); + } + } + + // }}} +} +?> + /** * PEAR_PackageFile_v2, package.xml version 2.0 * @@ -27690,7 +28197,7 @@ class PEAR_PackageFile_v1 * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: v2.php,v 1.145 2009/02/24 23:39:16 dufuz Exp $ + * @version CVS: $Id: v2.php 276383 2009-02-24 23:39:37Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ @@ -27704,7 +28211,7 @@ require_once 'PEAR/ErrorStack.php'; * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ @@ -29724,7 +30231,7 @@ class PEAR_PackageFile_v2 } } ?> - + /** * PEAR_REST_10 * @@ -29735,7 +30242,7 @@ class PEAR_PackageFile_v2 * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: 10.php,v 1.60 2009/03/07 23:09:56 dufuz Exp $ + * @version CVS: $Id: 10.php 287558 2009-08-21 22:21:28Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a12 */ @@ -29753,7 +30260,7 @@ require_once 'PEAR/REST.php'; * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a12 */ @@ -29787,16 +30294,18 @@ class PEAR_REST_10 */ function getDownloadURL($base, $packageinfo, $prefstate, $installed, $channel = false) { - $channel = $packageinfo['channel']; - $package = $packageinfo['package']; $states = $this->betterStates($prefstate, true); if (!$states) { return PEAR::raiseError('"' . $prefstate . '" is not a valid state'); } - $state = isset($packageinfo['state']) ? $packageinfo['state'] : null; - $version = isset($packageinfo['version']) ? $packageinfo['version'] : null; - $info = $this->_rest->retrieveData($base . 'r/' . strtolower($package) . '/allreleases.xml', false, false, $channel); + $channel = $packageinfo['channel']; + $package = $packageinfo['package']; + $state = isset($packageinfo['state']) ? $packageinfo['state'] : null; + $version = isset($packageinfo['version']) ? $packageinfo['version'] : null; + $restFile = $base . 'r/' . strtolower($package) . '/allreleases.xml'; + + $info = $this->_rest->retrieveData($restFile, false, false, $channel); if (PEAR::isError($info)) { return PEAR::raiseError('No releases available for package "' . $channel . '/' . $package . '"'); @@ -29848,22 +30357,27 @@ class PEAR_REST_10 function getDepDownloadURL($base, $xsdversion, $dependency, $deppackage, $prefstate = 'stable', $installed = false, $channel = false) { - $channel = $dependency['channel']; - $package = $dependency['name']; $states = $this->betterStates($prefstate, true); if (!$states) { return PEAR::raiseError('"' . $prefstate . '" is not a valid state'); } - $state = isset($dependency['state']) ? $dependency['state'] : null; - $version = isset($dependency['version']) ? $dependency['version'] : null; - $info = $this->_rest->retrieveData($base . 'r/' . strtolower($package) . '/allreleases.xml', false, false, $channel); + + $channel = $dependency['channel']; + $package = $dependency['name']; + $state = isset($dependency['state']) ? $dependency['state'] : null; + $version = isset($dependency['version']) ? $dependency['version'] : null; + $restFile = $base . 'r/' . strtolower($package) . '/allreleases.xml'; + + $info = $this->_rest->retrieveData($restFile, false, false, $channel); if (PEAR::isError($info)) { return PEAR::raiseError('Package "' . $deppackage['channel'] . '/' . $deppackage['package'] . '" dependency "' . $channel . '/' . $package . '" has no releases'); } + if (!is_array($info) || !isset($info['r'])) { return false; } + $exclude = array(); $min = $max = $recommended = false; if ($xsdversion == '1.0') { @@ -29981,19 +30495,23 @@ class PEAR_REST_10 if (!$found) { $release = $info['r'][0]; } - $pinfo = $this->_rest->retrieveCacheFirst($base . 'p/' . strtolower($package) . '/' . + + $packageLower = strtolower($package); + $pinfo = $this->_rest->retrieveCacheFirst($base . 'p/' . $packageLower . '/' . 'info.xml', false, false, $channel); if (PEAR::isError($pinfo)) { return PEAR::raiseError('Package "' . $package . '" does not have REST info xml available'); } - $releaseinfo = $this->_rest->retrieveCacheFirst($base . 'r/' . strtolower($package) . '/' . + + $releaseinfo = $this->_rest->retrieveCacheFirst($base . 'r/' . $packageLower . '/' . $release['v'] . '.xml', false, false, $channel); if (PEAR::isError($releaseinfo)) { return PEAR::raiseError('Package "' . $package . '" Version "' . $release['v'] . '" does not have REST xml available'); } - $packagexml = $this->_rest->retrieveCacheFirst($base . 'r/' . strtolower($package) . '/' . + + $packagexml = $this->_rest->retrieveCacheFirst($base . 'r/' . $packageLower . '/' . 'deps.' . $release['v'] . '.txt', false, true, $channel); if (PEAR::isError($packagexml)) { return PEAR::raiseError('Package "' . $package . '" Version "' . $release['v'] . @@ -30004,39 +30522,49 @@ class PEAR_REST_10 if (!$packagexml) { $packagexml = array(); } - $allinfo = $this->_rest->retrieveData($base . 'r/' . strtolower($package) . + + $allinfo = $this->_rest->retrieveData($base . 'r/' . $packageLower . '/allreleases.xml', false, false, $channel); if (!is_array($allinfo['r']) || !isset($allinfo['r'][0])) { $allinfo['r'] = array($allinfo['r']); } + $compatible = false; foreach ($allinfo['r'] as $release) { if ($release['v'] != $releaseinfo['v']) { continue; } + if (!isset($release['co'])) { break; } + $compatible = array(); if (!is_array($release['co']) || !isset($release['co'][0])) { $release['co'] = array($release['co']); } + foreach ($release['co'] as $entry) { $comp = array(); - $comp['name'] = $entry['p']; + $comp['name'] = $entry['p']; $comp['channel'] = $entry['c']; - $comp['min'] = $entry['min']; - $comp['max'] = $entry['max']; + $comp['min'] = $entry['min']; + $comp['max'] = $entry['max']; if (isset($entry['x']) && !is_array($entry['x'])) { $comp['exclude'] = $entry['x']; } + $compatible[] = $comp; } + if (count($compatible) == 1) { $compatible = $compatible[0]; } + break; } + + $deprecated = false; if (isset($pinfo['dc']) && isset($pinfo['dp'])) { if (is_array($pinfo['dp'])) { $deprecated = array('channel' => (string) $pinfo['dc'], @@ -30045,30 +30573,24 @@ class PEAR_REST_10 $deprecated = array('channel' => (string) $pinfo['dc'], 'package' => trim($pinfo['dp'])); } - } else { - $deprecated = false; } + + $return = array( + 'version' => $releaseinfo['v'], + 'info' => $packagexml, + 'package' => $releaseinfo['p']['_content'], + 'stability' => $releaseinfo['st'], + 'compatible' => $compatible, + 'deprecated' => $deprecated, + ); + if ($found) { - return - array('version' => $releaseinfo['v'], - 'info' => $packagexml, - 'package' => $releaseinfo['p']['_content'], - 'stability' => $releaseinfo['st'], - 'url' => $releaseinfo['g'], - 'compatible' => $compatible, - 'deprecated' => $deprecated, - ); - } else { - return - array('version' => $releaseinfo['v'], - 'package' => $releaseinfo['p']['_content'], - 'stability' => $releaseinfo['st'], - 'info' => $packagexml, - 'compatible' => $compatible, - 'deprecated' => $deprecated, - 'php' => $phpversion - ); + $return['url'] = $releaseinfo['g']; + return $return; } + + $return['php'] = $phpversion; + return $return; } function listPackages($base, $channel = false) @@ -30077,12 +30599,15 @@ class PEAR_REST_10 if (PEAR::isError($packagelist)) { return $packagelist; } + if (!is_array($packagelist) || !isset($packagelist['p'])) { return array(); } + if (!is_array($packagelist['p'])) { $packagelist['p'] = array($packagelist['p']); } + return $packagelist['p']; } @@ -30103,10 +30628,12 @@ class PEAR_REST_10 if (PEAR::isError($packagelist)) { return $packagelist; } + if (!is_array($packagelist) || !isset($packagelist['p'])) { $ret = array(); return $ret; } + if (!is_array($packagelist['p'])) { $packagelist['p'] = array($packagelist['p']); } @@ -30123,6 +30650,7 @@ class PEAR_REST_10 $categories[$cat] = $inf['ca']; } } + return array_values($categories); } @@ -30141,9 +30669,11 @@ class PEAR_REST_10 if (PEAR::isError($packagelist)) { return $packagelist; } + if (!is_array($packagelist) || !isset($packagelist['p'])) { return array(); } + if (!is_array($packagelist['p']) || !isset($packagelist['p'][0])) { // only 1 pkg $packagelist = array($packagelist['p']); @@ -30187,7 +30717,7 @@ class PEAR_REST_10 } if ($this->_rest->config->get('verbose') > 0) { $ui = &PEAR_Frontend::singleton(); - $ui->log('Retrieving data...0%', false); + $ui->log('Retrieving data...0%', true); } $ret = array(); if (!is_array($packagelist) || !isset($packagelist['p'])) { @@ -30567,621 +31097,645 @@ class PEAR_REST_10 return 1; } } -} -/**
- * PEAR_REST_11 - implement faster list-all/remote-list command
- *
- * PHP versions 4 and 5
- *
- * @category pear
- * @package PEAR
- * @author Greg Beaver <cellog@php.net>
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version CVS: $Id: 11.php,v 1.16 2009/02/24 23:39:22 dufuz Exp $
- * @link http://pear.php.net/package/PEAR
- * @since File available since Release 1.4.3
- */
-
-/**
- * For downloading REST xml/txt files
- */
-require_once 'PEAR/REST.php';
-
-/**
- * Implement REST 1.1
- *
- * @category pear
- * @package PEAR
- * @author Greg Beaver <cellog@php.net>
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.8.0
- * @link http://pear.php.net/package/PEAR
- * @since Class available since Release 1.4.3
- */
-class PEAR_REST_11
-{
- /**
- * @var PEAR_REST
- */
- var $_rest;
-
- function PEAR_REST_11($config, $options = array())
- {
- $this->_rest = &new PEAR_REST($config, $options);
- }
-
- function listAll($base, $dostable, $basic = true, $searchpackage = false, $searchsummary = false, $channel = false)
- {
- $categorylist = $this->_rest->retrieveData($base . 'c/categories.xml', false, false, $channel);
- if (PEAR::isError($categorylist)) {
- return $categorylist;
- }
-
- $ret = array();
- if (!is_array($categorylist['c']) || !isset($categorylist['c'][0])) {
- $categorylist['c'] = array($categorylist['c']);
- }
-
- PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
-
- foreach ($categorylist['c'] as $progress => $category) {
- $category = $category['_content'];
- $packagesinfo = $this->_rest->retrieveData($base .
- 'c/' . urlencode($category) . '/packagesinfo.xml', false, false, $channel);
-
- if (PEAR::isError($packagesinfo)) {
- continue;
- }
-
- if (!is_array($packagesinfo) || !isset($packagesinfo['pi'])) {
- continue;
- }
-
- if (!is_array($packagesinfo['pi']) || !isset($packagesinfo['pi'][0])) {
- $packagesinfo['pi'] = array($packagesinfo['pi']);
- }
-
- foreach ($packagesinfo['pi'] as $packageinfo) {
- if (empty($packageinfo)) {
- continue;
- }
-
- $info = $packageinfo['p'];
- $package = $info['n'];
- $releases = isset($packageinfo['a']) ? $packageinfo['a'] : false;
- unset($latest);
- unset($unstable);
- unset($stable);
- unset($state);
-
- if ($releases) {
- if (!isset($releases['r'][0])) {
- $releases['r'] = array($releases['r']);
- }
- foreach ($releases['r'] as $release) {
- if (!isset($latest)) {
- if ($dostable && $release['s'] == 'stable') {
- $latest = $release['v'];
- $state = 'stable';
- }
- if (!$dostable) {
- $latest = $release['v'];
- $state = $release['s'];
- }
- }
- if (!isset($stable) && $release['s'] == 'stable') {
- $stable = $release['v'];
- if (!isset($unstable)) {
- $unstable = $stable;
- }
- }
- if (!isset($unstable) && $release['s'] != 'stable') {
- $unstable = $release['v'];
- $state = $release['s'];
- }
- if (isset($latest) && !isset($state)) {
- $state = $release['s'];
- }
- if (isset($latest) && isset($stable) && isset($unstable)) {
- break;
- }
- }
- }
-
- if ($basic) { // remote-list command
- if (!isset($latest)) {
- $latest = false;
- }
- if ($dostable) {
- // $state is not set if there are no releases
- if (isset($state) && $state == 'stable') {
- $ret[$package] = array('stable' => $latest);
- } else {
- $ret[$package] = array('stable' => '-n/a-');
- }
- } else {
- $ret[$package] = array('stable' => $latest);
- }
- continue;
- }
-
- // list-all command
- $deps = array();
- if (!isset($unstable)) {
- $unstable = false;
- $state = 'stable';
- if (isset($stable)) {
- $latest = $unstable = $stable;
- }
- } else {
- $latest = $unstable;
- }
-
- if (!isset($latest)) {
- $latest = false;
- }
-
- if ($latest && isset($packageinfo['deps'])) {
- if (!is_array($packageinfo['deps']) ||
- !isset($packageinfo['deps'][0])) {
- $packageinfo['deps'] = array($packageinfo['deps']);
- }
- $d = false;
- foreach ($packageinfo['deps'] as $dep) {
- if ($dep['v'] == $latest) {
- $d = unserialize($dep['d']);
- }
- }
- if ($d) {
- if (isset($d['required'])) {
- if (!class_exists('PEAR_PackageFile_v2')) {
- require_once 'PEAR/PackageFile/v2.php';
- }
- if (!isset($pf)) {
- $pf = new PEAR_PackageFile_v2;
- }
- $pf->setDeps($d);
- $tdeps = $pf->getDeps();
- } else {
- $tdeps = $d;
- }
- foreach ($tdeps as $dep) {
- if ($dep['type'] !== 'pkg') {
- continue;
- }
- $deps[] = $dep;
- }
- }
- }
-
- $info = array('stable' => $latest, 'summary' => $info['s'],
- 'description' =>
- $info['d'], 'deps' => $deps, 'category' => $info['ca']['_content'],
- 'unstable' => $unstable, 'state' => $state);
- $ret[$package] = $info;
- }
- }
- PEAR::popErrorHandling();
- return $ret;
- }
-
- /**
- * List all categories of a REST server
- *
- * @param string $base base URL of the server
- * @return array of categorynames
- */
- function listCategories($base, $channel = false)
- {
- $categorylist = $this->_rest->retrieveData($base . 'c/categories.xml', false, false, $channel);
- if (PEAR::isError($categorylist)) {
- return $categorylist;
- }
- if (!is_array($categorylist) || !isset($categorylist['c'])) {
- return array();
- }
- if (isset($categorylist['c']['_content'])) {
- // only 1 category
- $categorylist['c'] = array($categorylist['c']);
- }
- return $categorylist['c'];
- }
-
- /**
- * List packages in a category of a REST server
- *
- * @param string $base base URL of the server
- * @param string $category name of the category
- * @param boolean $info also download full package info
- * @return array of packagenames
- */
- function listCategory($base, $category, $info = false, $channel = false)
- {
- if ($info == false) {
- $url = '%s'.'c/%s/packages.xml';
- } else {
- $url = '%s'.'c/%s/packagesinfo.xml';
- }
- $url = sprintf($url,
- $base,
- urlencode($category));
-
- // gives '404 Not Found' error when category doesn't exist
- $packagelist = $this->_rest->retrieveData($url, false, false, $channel);
- if (PEAR::isError($packagelist)) {
- return $packagelist;
- }
- if (!is_array($packagelist)) {
- return array();
- }
-
- if ($info == false) {
- if (!isset($packagelist['p'])) {
- return array();
- }
- if (!is_array($packagelist['p']) ||
- !isset($packagelist['p'][0])) { // only 1 pkg
- $packagelist = array($packagelist['p']);
- } else {
- $packagelist = $packagelist['p'];
- }
- return $packagelist;
- } else {
- // info == true
- if (!isset($packagelist['pi'])) {
- return array();
- }
- if (!is_array($packagelist['pi']) ||
- !isset($packagelist['pi'][0])) { // only 1 pkg
- $packagelist_pre = array($packagelist['pi']);
- } else {
- $packagelist_pre = $packagelist['pi'];
- }
-
- $packagelist = array();
- foreach ($packagelist_pre as $i => $item) {
- // compatibility with r/<latest.txt>.xml
- if (isset($item['a']['r'][0])) {
- // multiple releases
- $item['p']['v'] = $item['a']['r'][0]['v'];
- $item['p']['st'] = $item['a']['r'][0]['s'];
- } elseif (isset($item['a'])) {
- // first and only release
- $item['p']['v'] = $item['a']['r']['v'];
- $item['p']['st'] = $item['a']['r']['s'];
- }
-
- $packagelist[$i] = array('attribs' => $item['p']['r'],
- '_content' => $item['p']['n'],
- 'info' => $item['p']);
- }
- }
-
- return $packagelist;
- }
-
- /**
- * Return an array containing all of the states that are more stable than
- * or equal to the passed in state
- *
- * @param string Release state
- * @param boolean Determines whether to include $state in the list
- * @return false|array False if $state is not a valid release state
- */
- function betterStates($state, $include = false)
- {
- static $states = array('snapshot', 'devel', 'alpha', 'beta', 'stable');
- $i = array_search($state, $states);
- if ($i === false) {
- return false;
- }
- if ($include) {
- $i--;
- }
- return array_slice($states, $i + 1);
- }
-}
-?> -/**
- * PEAR_REST_13
- *
- * PHP versions 4 and 5
- *
- * @category pear
- * @package PEAR
- * @author Greg Beaver <cellog@php.net>
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version CVS: $Id: 13.php,v 1.8 2009/02/24 23:39:22 dufuz Exp $
- * @link http://pear.php.net/package/PEAR
- * @since File available since Release 1.4.0a12
- */
-
-/**
- * For downloading REST xml/txt files
- */
-require_once 'PEAR/REST.php';
-require_once 'PEAR/REST/10.php';
-
-/**
- * Implement REST 1.3
- *
- * @category pear
- * @package PEAR
- * @author Greg Beaver <cellog@php.net>
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.8.0
- * @link http://pear.php.net/package/PEAR
- * @since Class available since Release 1.4.0a12
- */
-class PEAR_REST_13 extends PEAR_REST_10
-{
- /**
- * Retrieve information about a remote package to be downloaded from a REST server
- *
- * This is smart enough to resolve the minimum PHP version dependency prior to download
- * @param string $base The uri to prepend to all REST calls
- * @param array $packageinfo an array of format:
- * <pre>
- * array(
- * 'package' => 'packagename',
- * 'channel' => 'channelname',
- * ['state' => 'alpha' (or valid state),]
- * -or-
- * ['version' => '1.whatever']
- * </pre>
- * @param string $prefstate Current preferred_state config variable value
- * @param bool $installed the installed version of this package to compare against
- * @return array|false|PEAR_Error see {@link _returnDownloadURL()}
- */
- function getDownloadURL($base, $packageinfo, $prefstate, $installed, $channel = false)
- {
- $channel = $packageinfo['channel'];
- $package = $packageinfo['package'];
- $states = $this->betterStates($prefstate, true);
- if (!$states) {
- return PEAR::raiseError('"' . $prefstate . '" is not a valid state');
- }
-
- $state = isset($packageinfo['state']) ? $packageinfo['state'] : null;
- $version = isset($packageinfo['version']) ? $packageinfo['version'] : null;
- $info = $this->_rest->retrieveData($base . 'r/' . strtolower($package) .
- '/allreleases2.xml');
- if (PEAR::isError($info)) {
- return PEAR::raiseError('No releases available for package "' .
- $channel . '/' . $package . '"');
- }
-
- if (!isset($info['r'])) {
- return false;
- }
-
- $release = $found = false;
- if (!is_array($info['r']) || !isset($info['r'][0])) {
- $info['r'] = array($info['r']);
- }
-
- $skippedphp = false;
- foreach ($info['r'] as $release) {
- if (!isset($this->_rest->_options['force']) && ($installed &&
- version_compare($release['v'], $installed, '<'))) {
- continue;
- }
-
- if (isset($state)) {
- // try our preferred state first
- if ($release['s'] == $state) {
- if (!isset($version) && version_compare($release['m'], phpversion(), '>')) {
- // skip releases that require a PHP version newer than our PHP version
- $skippedphp = $release;
- continue;
- }
- $found = true;
- break;
- }
-
- // see if there is something newer and more stable
- // bug #7221
- if (in_array($release['s'], $this->betterStates($state), true)) {
- if (!isset($version) && version_compare($release['m'], phpversion(), '>')) {
- // skip releases that require a PHP version newer than our PHP version
- $skippedphp = $release;
- continue;
- }
- $found = true;
- break;
- }
- } elseif (isset($version)) {
- if ($release['v'] == $version) {
- if (!isset($this->_rest->_options['force']) &&
- !isset($version) &&
- version_compare($release['m'], phpversion(), '>')) {
- // skip releases that require a PHP version newer than our PHP version
- $skippedphp = $release;
- continue;
- }
- $found = true;
- break;
- }
- } else {
- if (in_array($release['s'], $states)) {
- if (version_compare($release['m'], phpversion(), '>')) {
- // skip releases that require a PHP version newer than our PHP version
- $skippedphp = $release;
- continue;
- }
- $found = true;
- break;
- }
- }
- }
-
- if (!$found && $skippedphp) {
- $found = null;
- }
-
- return $this->_returnDownloadURL($base, $package, $release, $info, $found, $skippedphp, $channel);
- }
-
- function getDepDownloadURL($base, $xsdversion, $dependency, $deppackage,
- $prefstate = 'stable', $installed = false, $channel = false)
- {
- $channel = $dependency['channel'];
- $package = $dependency['name'];
- $states = $this->betterStates($prefstate, true);
- if (!$states) {
- return PEAR::raiseError('"' . $prefstate . '" is not a valid state');
- }
-
- $state = isset($dependency['state']) ? $dependency['state'] : null;
- $version = isset($dependency['version']) ? $dependency['version'] : null;
- $info = $this->_rest->retrieveData($base . 'r/' . strtolower($package) .
- '/allreleases2.xml');
- if (PEAR::isError($info)) {
- return PEAR::raiseError('Package "' . $deppackage['channel'] . '/' . $deppackage['package']
- . '" dependency "' . $channel . '/' . $package . '" has no releases');
- }
-
- if (!is_array($info) || !isset($info['r'])) {
- return false;
- }
-
- $exclude = array();
- $min = $max = $recommended = false;
- if ($xsdversion == '1.0') {
- $pinfo['package'] = $dependency['name'];
- $pinfo['channel'] = 'pear.php.net'; // this is always true - don't change this
- switch ($dependency['rel']) {
- case 'ge' :
- $min = $dependency['version'];
- break;
- case 'gt' :
- $min = $dependency['version'];
- $exclude = array($dependency['version']);
- break;
- case 'eq' :
- $recommended = $dependency['version'];
- break;
- case 'lt' :
- $max = $dependency['version'];
- $exclude = array($dependency['version']);
- break;
- case 'le' :
- $max = $dependency['version'];
- break;
- case 'ne' :
- $exclude = array($dependency['version']);
- break;
- }
- } else {
- $pinfo['package'] = $dependency['name'];
- $min = isset($dependency['min']) ? $dependency['min'] : false;
- $max = isset($dependency['max']) ? $dependency['max'] : false;
- $recommended = isset($dependency['recommended']) ?
- $dependency['recommended'] : false;
- if (isset($dependency['exclude'])) {
- if (!isset($dependency['exclude'][0])) {
- $exclude = array($dependency['exclude']);
- }
- }
- }
-
- $found = false;
- $release = false;
- $skippedphp = false;
- if (!is_array($info['r']) || !isset($info['r'][0])) {
- $info['r'] = array($info['r']);
- }
-
- foreach ($info['r'] as $release) {
- if (!isset($this->_rest->_options['force']) && ($installed &&
- version_compare($release['v'], $installed, '<'))) {
- continue;
- }
-
- if (in_array($release['v'], $exclude)) { // skip excluded versions
- continue;
- }
-
- // allow newer releases to say "I'm OK with the dependent package"
- if ($xsdversion == '2.0' && isset($release['co'])) {
- if (!is_array($release['co']) || !isset($release['co'][0])) {
- $release['co'] = array($release['co']);
- }
-
- foreach ($release['co'] as $entry) {
- if (isset($entry['x']) && !is_array($entry['x'])) {
- $entry['x'] = array($entry['x']);
- } elseif (!isset($entry['x'])) {
- $entry['x'] = array();
- }
-
- if ($entry['c'] == $deppackage['channel'] &&
- strtolower($entry['p']) == strtolower($deppackage['package']) &&
- version_compare($deppackage['version'], $entry['min'], '>=') &&
- version_compare($deppackage['version'], $entry['max'], '<=') &&
- !in_array($release['v'], $entry['x'])) {
- if (version_compare($release['m'], phpversion(), '>')) {
- // skip dependency releases that require a PHP version
- // newer than our PHP version
- $skippedphp = $release;
- continue;
- }
-
- $recommended = $release['v'];
- break;
- }
- }
- }
-
- if ($recommended) {
- if ($release['v'] != $recommended) { // if we want a specific
- // version, then skip all others
- continue;
- }
-
- if (!in_array($release['s'], $states)) {
- // the stability is too low, but we must return the
- // recommended version if possible
- return $this->_returnDownloadURL($base, $package, $release, $info, true, false, $channel);
- }
- }
-
- if ($min && version_compare($release['v'], $min, 'lt')) { // skip too old versions
- continue;
- }
-
- if ($max && version_compare($release['v'], $max, 'gt')) { // skip too new versions
- continue;
- }
-
- if ($installed && version_compare($release['v'], $installed, '<')) {
- continue;
- }
-
- if (in_array($release['s'], $states)) { // if in the preferred state...
- if (version_compare($release['m'], phpversion(), '>')) {
- // skip dependency releases that require a PHP version
- // newer than our PHP version
- $skippedphp = $release;
- continue;
- }
-
- $found = true; // ... then use it
- break;
- }
- }
-
- if (!$found && $skippedphp) {
- $found = null;
- }
-
- return $this->_returnDownloadURL($base, $package, $release, $info, $found, $skippedphp, $channel);
- }
-} +} +/** + * PEAR_REST_11 - implement faster list-all/remote-list command + * + * PHP versions 4 and 5 + * + * @category pear + * @package PEAR + * @author Greg Beaver <cellog@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: 11.php 286670 2009-08-02 14:16:06Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.3 + */ + +/** + * For downloading REST xml/txt files + */ +require_once 'PEAR/REST.php'; + +/** + * Implement REST 1.1 + * + * @category pear + * @package PEAR + * @author Greg Beaver <cellog@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.3 + */ +class PEAR_REST_11 +{ + /** + * @var PEAR_REST + */ + var $_rest; + + function PEAR_REST_11($config, $options = array()) + { + $this->_rest = &new PEAR_REST($config, $options); + } + + function listAll($base, $dostable, $basic = true, $searchpackage = false, $searchsummary = false, $channel = false) + { + $categorylist = $this->_rest->retrieveData($base . 'c/categories.xml', false, false, $channel); + if (PEAR::isError($categorylist)) { + return $categorylist; + } + + $ret = array(); + if (!is_array($categorylist['c']) || !isset($categorylist['c'][0])) { + $categorylist['c'] = array($categorylist['c']); + } + + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + + foreach ($categorylist['c'] as $progress => $category) { + $category = $category['_content']; + $packagesinfo = $this->_rest->retrieveData($base . + 'c/' . urlencode($category) . '/packagesinfo.xml', false, false, $channel); + + if (PEAR::isError($packagesinfo)) { + continue; + } + + if (!is_array($packagesinfo) || !isset($packagesinfo['pi'])) { + continue; + } + + if (!is_array($packagesinfo['pi']) || !isset($packagesinfo['pi'][0])) { + $packagesinfo['pi'] = array($packagesinfo['pi']); + } + + foreach ($packagesinfo['pi'] as $packageinfo) { + if (empty($packageinfo)) { + continue; + } + + $info = $packageinfo['p']; + $package = $info['n']; + $releases = isset($packageinfo['a']) ? $packageinfo['a'] : false; + unset($latest); + unset($unstable); + unset($stable); + unset($state); + + if ($releases) { + if (!isset($releases['r'][0])) { + $releases['r'] = array($releases['r']); + } + + foreach ($releases['r'] as $release) { + if (!isset($latest)) { + if ($dostable && $release['s'] == 'stable') { + $latest = $release['v']; + $state = 'stable'; + } + if (!$dostable) { + $latest = $release['v']; + $state = $release['s']; + } + } + + if (!isset($stable) && $release['s'] == 'stable') { + $stable = $release['v']; + if (!isset($unstable)) { + $unstable = $stable; + } + } + + if (!isset($unstable) && $release['s'] != 'stable') { + $unstable = $release['v']; + $state = $release['s']; + } + + if (isset($latest) && !isset($state)) { + $state = $release['s']; + } + + if (isset($latest) && isset($stable) && isset($unstable)) { + break; + } + } + } + + if ($basic) { // remote-list command + if (!isset($latest)) { + $latest = false; + } + + if ($dostable) { + // $state is not set if there are no releases + if (isset($state) && $state == 'stable') { + $ret[$package] = array('stable' => $latest); + } else { + $ret[$package] = array('stable' => '-n/a-'); + } + } else { + $ret[$package] = array('stable' => $latest); + } + + continue; + } + + // list-all command + if (!isset($unstable)) { + $unstable = false; + $state = 'stable'; + if (isset($stable)) { + $latest = $unstable = $stable; + } + } else { + $latest = $unstable; + } + + if (!isset($latest)) { + $latest = false; + } + + $deps = array(); + if ($latest && isset($packageinfo['deps'])) { + if (!is_array($packageinfo['deps']) || + !isset($packageinfo['deps'][0]) + ) { + $packageinfo['deps'] = array($packageinfo['deps']); + } + + $d = false; + foreach ($packageinfo['deps'] as $dep) { + if ($dep['v'] == $latest) { + $d = unserialize($dep['d']); + } + } + + if ($d) { + if (isset($d['required'])) { + if (!class_exists('PEAR_PackageFile_v2')) { + require_once 'PEAR/PackageFile/v2.php'; + } + + if (!isset($pf)) { + $pf = new PEAR_PackageFile_v2; + } + + $pf->setDeps($d); + $tdeps = $pf->getDeps(); + } else { + $tdeps = $d; + } + + foreach ($tdeps as $dep) { + if ($dep['type'] !== 'pkg') { + continue; + } + + $deps[] = $dep; + } + } + } + + $info = array( + 'stable' => $latest, + 'summary' => $info['s'], + 'description' => $info['d'], + 'deps' => $deps, + 'category' => $info['ca']['_content'], + 'unstable' => $unstable, + 'state' => $state + ); + $ret[$package] = $info; + } + } + + PEAR::popErrorHandling(); + return $ret; + } + + /** + * List all categories of a REST server + * + * @param string $base base URL of the server + * @return array of categorynames + */ + function listCategories($base, $channel = false) + { + $categorylist = $this->_rest->retrieveData($base . 'c/categories.xml', false, false, $channel); + if (PEAR::isError($categorylist)) { + return $categorylist; + } + + if (!is_array($categorylist) || !isset($categorylist['c'])) { + return array(); + } + + if (isset($categorylist['c']['_content'])) { + // only 1 category + $categorylist['c'] = array($categorylist['c']); + } + + return $categorylist['c']; + } + + /** + * List packages in a category of a REST server + * + * @param string $base base URL of the server + * @param string $category name of the category + * @param boolean $info also download full package info + * @return array of packagenames + */ + function listCategory($base, $category, $info = false, $channel = false) + { + if ($info == false) { + $url = '%s'.'c/%s/packages.xml'; + } else { + $url = '%s'.'c/%s/packagesinfo.xml'; + } + $url = sprintf($url, + $base, + urlencode($category)); + + // gives '404 Not Found' error when category doesn't exist + $packagelist = $this->_rest->retrieveData($url, false, false, $channel); + if (PEAR::isError($packagelist)) { + return $packagelist; + } + if (!is_array($packagelist)) { + return array(); + } + + if ($info == false) { + if (!isset($packagelist['p'])) { + return array(); + } + if (!is_array($packagelist['p']) || + !isset($packagelist['p'][0])) { // only 1 pkg + $packagelist = array($packagelist['p']); + } else { + $packagelist = $packagelist['p']; + } + return $packagelist; + } + + // info == true + if (!isset($packagelist['pi'])) { + return array(); + } + + if (!is_array($packagelist['pi']) || + !isset($packagelist['pi'][0])) { // only 1 pkg + $packagelist_pre = array($packagelist['pi']); + } else { + $packagelist_pre = $packagelist['pi']; + } + + $packagelist = array(); + foreach ($packagelist_pre as $i => $item) { + // compatibility with r/<latest.txt>.xml + if (isset($item['a']['r'][0])) { + // multiple releases + $item['p']['v'] = $item['a']['r'][0]['v']; + $item['p']['st'] = $item['a']['r'][0]['s']; + } elseif (isset($item['a'])) { + // first and only release + $item['p']['v'] = $item['a']['r']['v']; + $item['p']['st'] = $item['a']['r']['s']; + } + + $packagelist[$i] = array('attribs' => $item['p']['r'], + '_content' => $item['p']['n'], + 'info' => $item['p']); + } + + return $packagelist; + } + + /** + * Return an array containing all of the states that are more stable than + * or equal to the passed in state + * + * @param string Release state + * @param boolean Determines whether to include $state in the list + * @return false|array False if $state is not a valid release state + */ + function betterStates($state, $include = false) + { + static $states = array('snapshot', 'devel', 'alpha', 'beta', 'stable'); + $i = array_search($state, $states); + if ($i === false) { + return false; + } + if ($include) { + $i--; + } + return array_slice($states, $i + 1); + } +} +?> +/** + * PEAR_REST_13 + * + * PHP versions 4 and 5 + * + * @category pear + * @package PEAR + * @author Greg Beaver <cellog@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: 13.php 287110 2009-08-11 18:51:15Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a12 + */ + +/** + * For downloading REST xml/txt files + */ +require_once 'PEAR/REST.php'; +require_once 'PEAR/REST/10.php'; + +/** + * Implement REST 1.3 + * + * @category pear + * @package PEAR + * @author Greg Beaver <cellog@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a12 + */ +class PEAR_REST_13 extends PEAR_REST_10 +{ + /** + * Retrieve information about a remote package to be downloaded from a REST server + * + * This is smart enough to resolve the minimum PHP version dependency prior to download + * @param string $base The uri to prepend to all REST calls + * @param array $packageinfo an array of format: + * <pre> + * array( + * 'package' => 'packagename', + * 'channel' => 'channelname', + * ['state' => 'alpha' (or valid state),] + * -or- + * ['version' => '1.whatever'] + * </pre> + * @param string $prefstate Current preferred_state config variable value + * @param bool $installed the installed version of this package to compare against + * @return array|false|PEAR_Error see {@link _returnDownloadURL()} + */ + function getDownloadURL($base, $packageinfo, $prefstate, $installed, $channel = false) + { + $states = $this->betterStates($prefstate, true); + if (!$states) { + return PEAR::raiseError('"' . $prefstate . '" is not a valid state'); + } + + $channel = $packageinfo['channel']; + $package = $packageinfo['package']; + $state = isset($packageinfo['state']) ? $packageinfo['state'] : null; + $version = isset($packageinfo['version']) ? $packageinfo['version'] : null; + $restFile = $base . 'r/' . strtolower($package) . '/allreleases2.xml'; + + $info = $this->_rest->retrieveData($restFile, false, false, $channel); + if (PEAR::isError($info)) { + return PEAR::raiseError('No releases available for package "' . + $channel . '/' . $package . '"'); + } + + if (!isset($info['r'])) { + return false; + } + + $release = $found = false; + if (!is_array($info['r']) || !isset($info['r'][0])) { + $info['r'] = array($info['r']); + } + + $skippedphp = false; + foreach ($info['r'] as $release) { + if (!isset($this->_rest->_options['force']) && ($installed && + version_compare($release['v'], $installed, '<'))) { + continue; + } + + if (isset($state)) { + // try our preferred state first + if ($release['s'] == $state) { + if (!isset($version) && version_compare($release['m'], phpversion(), '>')) { + // skip releases that require a PHP version newer than our PHP version + $skippedphp = $release; + continue; + } + $found = true; + break; + } + + // see if there is something newer and more stable + // bug #7221 + if (in_array($release['s'], $this->betterStates($state), true)) { + if (!isset($version) && version_compare($release['m'], phpversion(), '>')) { + // skip releases that require a PHP version newer than our PHP version + $skippedphp = $release; + continue; + } + $found = true; + break; + } + } elseif (isset($version)) { + if ($release['v'] == $version) { + if (!isset($this->_rest->_options['force']) && + !isset($version) && + version_compare($release['m'], phpversion(), '>')) { + // skip releases that require a PHP version newer than our PHP version + $skippedphp = $release; + continue; + } + $found = true; + break; + } + } else { + if (in_array($release['s'], $states)) { + if (version_compare($release['m'], phpversion(), '>')) { + // skip releases that require a PHP version newer than our PHP version + $skippedphp = $release; + continue; + } + $found = true; + break; + } + } + } + + if (!$found && $skippedphp) { + $found = null; + } + + return $this->_returnDownloadURL($base, $package, $release, $info, $found, $skippedphp, $channel); + } + + function getDepDownloadURL($base, $xsdversion, $dependency, $deppackage, + $prefstate = 'stable', $installed = false, $channel = false) + { + $states = $this->betterStates($prefstate, true); + if (!$states) { + return PEAR::raiseError('"' . $prefstate . '" is not a valid state'); + } + + $channel = $dependency['channel']; + $package = $dependency['name']; + $state = isset($dependency['state']) ? $dependency['state'] : null; + $version = isset($dependency['version']) ? $dependency['version'] : null; + $restFile = $base . 'r/' . strtolower($package) .'/allreleases2.xml'; + + $info = $this->_rest->retrieveData($restFile, false, false, $channel); + if (PEAR::isError($info)) { + return PEAR::raiseError('Package "' . $deppackage['channel'] . '/' . $deppackage['package'] + . '" dependency "' . $channel . '/' . $package . '" has no releases'); + } + + if (!is_array($info) || !isset($info['r'])) { + return false; + } + + $exclude = array(); + $min = $max = $recommended = false; + if ($xsdversion == '1.0') { + $pinfo['package'] = $dependency['name']; + $pinfo['channel'] = 'pear.php.net'; // this is always true - don't change this + switch ($dependency['rel']) { + case 'ge' : + $min = $dependency['version']; + break; + case 'gt' : + $min = $dependency['version']; + $exclude = array($dependency['version']); + break; + case 'eq' : + $recommended = $dependency['version']; + break; + case 'lt' : + $max = $dependency['version']; + $exclude = array($dependency['version']); + break; + case 'le' : + $max = $dependency['version']; + break; + case 'ne' : + $exclude = array($dependency['version']); + break; + } + } else { + $pinfo['package'] = $dependency['name']; + $min = isset($dependency['min']) ? $dependency['min'] : false; + $max = isset($dependency['max']) ? $dependency['max'] : false; + $recommended = isset($dependency['recommended']) ? + $dependency['recommended'] : false; + if (isset($dependency['exclude'])) { + if (!isset($dependency['exclude'][0])) { + $exclude = array($dependency['exclude']); + } + } + } + + $skippedphp = $found = $release = false; + if (!is_array($info['r']) || !isset($info['r'][0])) { + $info['r'] = array($info['r']); + } + + foreach ($info['r'] as $release) { + if (!isset($this->_rest->_options['force']) && ($installed && + version_compare($release['v'], $installed, '<'))) { + continue; + } + + if (in_array($release['v'], $exclude)) { // skip excluded versions + continue; + } + + // allow newer releases to say "I'm OK with the dependent package" + if ($xsdversion == '2.0' && isset($release['co'])) { + if (!is_array($release['co']) || !isset($release['co'][0])) { + $release['co'] = array($release['co']); + } + + foreach ($release['co'] as $entry) { + if (isset($entry['x']) && !is_array($entry['x'])) { + $entry['x'] = array($entry['x']); + } elseif (!isset($entry['x'])) { + $entry['x'] = array(); + } + + if ($entry['c'] == $deppackage['channel'] && + strtolower($entry['p']) == strtolower($deppackage['package']) && + version_compare($deppackage['version'], $entry['min'], '>=') && + version_compare($deppackage['version'], $entry['max'], '<=') && + !in_array($release['v'], $entry['x'])) { + if (version_compare($release['m'], phpversion(), '>')) { + // skip dependency releases that require a PHP version + // newer than our PHP version + $skippedphp = $release; + continue; + } + + $recommended = $release['v']; + break; + } + } + } + + if ($recommended) { + if ($release['v'] != $recommended) { // if we want a specific + // version, then skip all others + continue; + } + + if (!in_array($release['s'], $states)) { + // the stability is too low, but we must return the + // recommended version if possible + return $this->_returnDownloadURL($base, $package, $release, $info, true, false, $channel); + } + } + + if ($min && version_compare($release['v'], $min, 'lt')) { // skip too old versions + continue; + } + + if ($max && version_compare($release['v'], $max, 'gt')) { // skip too new versions + continue; + } + + if ($installed && version_compare($release['v'], $installed, '<')) { + continue; + } + + if (in_array($release['s'], $states)) { // if in the preferred state... + if (version_compare($release['m'], phpversion(), '>')) { + // skip dependency releases that require a PHP version + // newer than our PHP version + $skippedphp = $release; + continue; + } + + $found = true; // ... then use it + break; + } + } + + if (!$found && $skippedphp) { + $found = null; + } + + return $this->_returnDownloadURL($base, $package, $release, $info, $found, $skippedphp, $channel); + } +} /** * <tasks:postinstallscript> - read/write version * @@ -31192,7 +31746,7 @@ class PEAR_REST_13 extends PEAR_REST_10 * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: rw.php,v 1.14 2009/02/24 23:45:32 dufuz Exp $ + * @version CVS: $Id: rw.php 276385 2009-02-24 23:46:03Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a10 */ @@ -31207,7 +31761,7 @@ require_once 'PEAR/Task/Postinstallscript.php'; * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a10 */ @@ -31349,177 +31903,177 @@ class PEAR_Task_Postinstallscript_rw extends PEAR_Task_Postinstallscript ); } } -?> -/**
- * <tasks:replace> - read/write version
- *
- * PHP versions 4 and 5
- *
- * @category pear
- * @package PEAR
- * @author Greg Beaver <cellog@php.net>
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version CVS: $Id: rw.php,v 1.5 2009/02/24 23:45:44 dufuz Exp $
- * @link http://pear.php.net/package/PEAR
- * @since File available since Release 1.4.0a10
- */
-/**
- * Base class
- */
-require_once 'PEAR/Task/Replace.php';
-/**
- * Abstracts the replace task xml.
- * @category pear
- * @package PEAR
- * @author Greg Beaver <cellog@php.net>
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.8.0
- * @link http://pear.php.net/package/PEAR
- * @since Class available since Release 1.4.0a10
- */
-class PEAR_Task_Replace_rw extends PEAR_Task_Replace
-{
- function PEAR_Task_Replace_rw(&$pkg, &$config, &$logger, $fileXml)
- {
- parent::PEAR_Task_Common($config, $logger, PEAR_TASK_PACKAGE);
- $this->_contents = $fileXml;
- $this->_pkg = &$pkg;
- $this->_params = array();
- }
-
- function validate()
- {
- return $this->validateXml($this->_pkg, $this->_params, $this->config, $this->_contents);
- }
-
- function setInfo($from, $to, $type)
- {
- $this->_params = array('attribs' => array('from' => $from, 'to' => $to, 'type' => $type));
- }
-
- function getName()
- {
- return 'replace';
- }
-
- function getXml()
- {
- return $this->_params;
- }
-}
-?> -/**
- * <tasks:unixeol> - read/write version
- *
- * PHP versions 4 and 5
- *
- * @category pear
- * @package PEAR
- * @author Greg Beaver <cellog@php.net>
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version CVS: $Id: rw.php,v 1.6 2009/02/24 23:45:30 dufuz Exp $
- * @link http://pear.php.net/package/PEAR
- * @since File available since Release 1.4.0a10
- */
-/**
- * Base class
- */
-require_once 'PEAR/Task/Unixeol.php';
-/**
- * Abstracts the unixeol task xml.
- * @category pear
- * @package PEAR
- * @author Greg Beaver <cellog@php.net>
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.8.0
- * @link http://pear.php.net/package/PEAR
- * @since Class available since Release 1.4.0a10
- */
-class PEAR_Task_Unixeol_rw extends PEAR_Task_Unixeol
-{
- function PEAR_Task_Unixeol_rw(&$pkg, &$config, &$logger, $fileXml)
- {
- parent::PEAR_Task_Common($config, $logger, PEAR_TASK_PACKAGE);
- $this->_contents = $fileXml;
- $this->_pkg = &$pkg;
- $this->_params = array();
- }
-
- function validate()
- {
- return true;
- }
-
- function getName()
- {
- return 'unixeol';
- }
-
- function getXml()
- {
- return '';
- }
-}
-?> -/**
- * <tasks:windowseol> - read/write version
- *
- * PHP versions 4 and 5
- *
- * @category pear
- * @package PEAR
- * @author Greg Beaver <cellog@php.net>
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version CVS: $Id: rw.php,v 1.6 2009/02/24 23:45:20 dufuz Exp $
- * @link http://pear.php.net/package/PEAR
- * @since File available since Release 1.4.0a10
- */
-/**
- * Base class
- */
-require_once 'PEAR/Task/Windowseol.php';
-/**
- * Abstracts the windowseol task xml.
- * @category pear
- * @package PEAR
- * @author Greg Beaver <cellog@php.net>
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.8.0
- * @link http://pear.php.net/package/PEAR
- * @since Class available since Release 1.4.0a10
- */
-class PEAR_Task_Windowseol_rw extends PEAR_Task_Windowseol
-{
- function PEAR_Task_Windowseol_rw(&$pkg, &$config, &$logger, $fileXml)
- {
- parent::PEAR_Task_Common($config, $logger, PEAR_TASK_PACKAGE);
- $this->_contents = $fileXml;
- $this->_pkg = &$pkg;
- $this->_params = array();
- }
-
- function validate()
- {
- return true;
- }
-
- function getName()
- {
- return 'windowseol';
- }
-
- function getXml()
- {
- return '';
- }
-}
-?> +?> +/** + * <tasks:replace> - read/write version + * + * PHP versions 4 and 5 + * + * @category pear + * @package PEAR + * @author Greg Beaver <cellog@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: rw.php 276385 2009-02-24 23:46:03Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a10 + */ +/** + * Base class + */ +require_once 'PEAR/Task/Replace.php'; +/** + * Abstracts the replace task xml. + * @category pear + * @package PEAR + * @author Greg Beaver <cellog@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a10 + */ +class PEAR_Task_Replace_rw extends PEAR_Task_Replace +{ + function PEAR_Task_Replace_rw(&$pkg, &$config, &$logger, $fileXml) + { + parent::PEAR_Task_Common($config, $logger, PEAR_TASK_PACKAGE); + $this->_contents = $fileXml; + $this->_pkg = &$pkg; + $this->_params = array(); + } + + function validate() + { + return $this->validateXml($this->_pkg, $this->_params, $this->config, $this->_contents); + } + + function setInfo($from, $to, $type) + { + $this->_params = array('attribs' => array('from' => $from, 'to' => $to, 'type' => $type)); + } + + function getName() + { + return 'replace'; + } + + function getXml() + { + return $this->_params; + } +} +?> +/** + * <tasks:unixeol> - read/write version + * + * PHP versions 4 and 5 + * + * @category pear + * @package PEAR + * @author Greg Beaver <cellog@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: rw.php 276385 2009-02-24 23:46:03Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a10 + */ +/** + * Base class + */ +require_once 'PEAR/Task/Unixeol.php'; +/** + * Abstracts the unixeol task xml. + * @category pear + * @package PEAR + * @author Greg Beaver <cellog@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a10 + */ +class PEAR_Task_Unixeol_rw extends PEAR_Task_Unixeol +{ + function PEAR_Task_Unixeol_rw(&$pkg, &$config, &$logger, $fileXml) + { + parent::PEAR_Task_Common($config, $logger, PEAR_TASK_PACKAGE); + $this->_contents = $fileXml; + $this->_pkg = &$pkg; + $this->_params = array(); + } + + function validate() + { + return true; + } + + function getName() + { + return 'unixeol'; + } + + function getXml() + { + return ''; + } +} +?> +/** + * <tasks:windowseol> - read/write version + * + * PHP versions 4 and 5 + * + * @category pear + * @package PEAR + * @author Greg Beaver <cellog@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: rw.php 276385 2009-02-24 23:46:03Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a10 + */ +/** + * Base class + */ +require_once 'PEAR/Task/Windowseol.php'; +/** + * Abstracts the windowseol task xml. + * @category pear + * @package PEAR + * @author Greg Beaver <cellog@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a10 + */ +class PEAR_Task_Windowseol_rw extends PEAR_Task_Windowseol +{ + function PEAR_Task_Windowseol_rw(&$pkg, &$config, &$logger, $fileXml) + { + parent::PEAR_Task_Common($config, $logger, PEAR_TASK_PACKAGE); + $this->_contents = $fileXml; + $this->_pkg = &$pkg; + $this->_params = array(); + } + + function validate() + { + return true; + } + + function getName() + { + return 'windowseol'; + } + + function getXml() + { + return ''; + } +} +?> /** * PEAR_Task_Common, base class for installer tasks * @@ -31530,7 +32084,7 @@ class PEAR_Task_Windowseol_rw extends PEAR_Task_Windowseol * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Common.php,v 1.20 2009/02/25 00:15:49 dufuz Exp $ + * @version CVS: $Id: Common.php 276394 2009-02-25 00:15:49Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ @@ -31568,7 +32122,7 @@ define('PEAR_TASK_PACKAGEANDINSTALL', 3); * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 * @abstract @@ -31720,7 +32274,7 @@ class PEAR_Task_Common return PEAR::raiseError($msg, $code); } } -?> +?> /** * <tasks:postinstallscript> * @@ -31731,7 +32285,7 @@ class PEAR_Task_Common * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Postinstallscript.php,v 1.22 2009/02/24 23:45:56 dufuz Exp $ + * @version CVS: $Id: Postinstallscript.php 276385 2009-02-24 23:46:03Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ @@ -31749,7 +32303,7 @@ require_once 'PEAR/Task/Common.php'; * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ @@ -32042,7 +32596,7 @@ class PEAR_Task_Postinstallscript extends PEAR_Task_Common { } } -?> +?> /** * <tasks:replace> * @@ -32053,7 +32607,7 @@ class PEAR_Task_Postinstallscript extends PEAR_Task_Common * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Replace.php,v 1.19 2009/02/25 00:15:49 dufuz Exp $ + * @version CVS: $Id: Replace.php 276394 2009-02-25 00:15:49Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ @@ -32068,7 +32622,7 @@ require_once 'PEAR/Task/Common.php'; * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ @@ -32217,7 +32771,7 @@ class PEAR_Task_Replace extends PEAR_Task_Common return $contents; } } -?> +?> /** * <tasks:unixeol> * @@ -32228,7 +32782,7 @@ class PEAR_Task_Replace extends PEAR_Task_Common * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Unixeol.php,v 1.12 2009/02/25 00:15:49 dufuz Exp $ + * @version CVS: $Id: Unixeol.php 276394 2009-02-25 00:15:49Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ @@ -32243,7 +32797,7 @@ require_once 'PEAR/Task/Common.php'; * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ @@ -32293,7 +32847,7 @@ class PEAR_Task_Unixeol extends PEAR_Task_Common return preg_replace("/\r\n|\n\r|\r|\n/", "\n", $contents); } } -?> +?> /** * <tasks:windowseol> * @@ -32304,7 +32858,7 @@ class PEAR_Task_Unixeol extends PEAR_Task_Common * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Windowseol.php,v 1.11 2009/02/25 00:15:49 dufuz Exp $ + * @version CVS: $Id: Windowseol.php 276394 2009-02-25 00:15:49Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ @@ -32319,7 +32873,7 @@ require_once 'PEAR/Task/Common.php'; * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ @@ -32369,7 +32923,7 @@ class PEAR_Task_Windowseol extends PEAR_Task_Common return preg_replace("/\r\n|\n\r|\r|\n/", "\r\n", $contents); } } -?> +?> /** * Channel Validator for the pecl.php.net channel * @@ -32380,7 +32934,7 @@ class PEAR_Task_Windowseol extends PEAR_Task_Common * @author Greg Beaver <cellog@php.net> * @copyright 1997-2006 The PHP Group * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: PECL.php,v 1.10 2009/02/24 23:39:19 dufuz Exp $ + * @version CVS: $Id: PECL.php 276383 2009-02-24 23:39:37Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a5 */ @@ -32395,7 +32949,7 @@ require_once 'PEAR/Validate.php'; * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a5 */ @@ -32431,225 +32985,225 @@ class PEAR_Validator_PECL extends PEAR_Validate return $ret; } } -?> -/**
- * Class auto-loader
- *
- * PHP versions 4
-
- *
- * @category pear
- * @package PEAR
- * @author Stig Bakken <ssb@php.net>
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version CVS: $Id: Autoloader.php,v 1.15 2009/02/24 23:38:22 dufuz Exp $
- * @link http://pear.php.net/manual/en/core.ppm.php#core.ppm.pear-autoloader
- * @since File available since Release 0.1
- * @deprecated File deprecated in Release 1.4.0a1
- */
-
-// /* vim: set expandtab tabstop=4 shiftwidth=4: */
-
-if (!extension_loaded("overload")) {
- // die hard without ext/overload
- die("Rebuild PHP with the `overload' extension to use PEAR_Autoloader");
-}
-
-/**
- * Include for PEAR_Error and PEAR classes
- */
-require_once "PEAR.php";
-
-/**
- * This class is for objects where you want to separate the code for
- * some methods into separate classes. This is useful if you have a
- * class with not-frequently-used methods that contain lots of code
- * that you would like to avoid always parsing.
- *
- * The PEAR_Autoloader class provides autoloading and aggregation.
- * The autoloading lets you set up in which classes the separated
- * methods are found. Aggregation is the technique used to import new
- * methods, an instance of each class providing separated methods is
- * stored and called every time the aggregated method is called.
- *
- * @category pear
- * @package PEAR
- * @author Stig Bakken <ssb@php.net>
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.8.0
- * @link http://pear.php.net/manual/en/core.ppm.php#core.ppm.pear-autoloader
- * @since File available since Release 0.1
- * @deprecated File deprecated in Release 1.4.0a1
- */
-class PEAR_Autoloader extends PEAR
-{
- // {{{ properties
-
- /**
- * Map of methods and classes where they are defined
- *
- * @var array
- *
- * @access private
- */
- var $_autoload_map = array();
-
- /**
- * Map of methods and aggregate objects
- *
- * @var array
- *
- * @access private
- */
- var $_method_map = array();
-
- // }}}
- // {{{ addAutoload()
-
- /**
- * Add one or more autoload entries.
- *
- * @param string $method which method to autoload
- *
- * @param string $classname (optional) which class to find the method in.
- * If the $method parameter is an array, this
- * parameter may be omitted (and will be ignored
- * if not), and the $method parameter will be
- * treated as an associative array with method
- * names as keys and class names as values.
- *
- * @return void
- *
- * @access public
- */
- function addAutoload($method, $classname = null)
- {
- if (is_array($method)) {
- array_walk($method, create_function('$a,&$b', '$b = strtolower($b);'));
- $this->_autoload_map = array_merge($this->_autoload_map, $method);
- } else {
- $this->_autoload_map[strtolower($method)] = $classname;
- }
- }
-
- // }}}
- // {{{ removeAutoload()
-
- /**
- * Remove an autoload entry.
- *
- * @param string $method which method to remove the autoload entry for
- *
- * @return bool TRUE if an entry was removed, FALSE if not
- *
- * @access public
- */
- function removeAutoload($method)
- {
- $method = strtolower($method);
- $ok = isset($this->_autoload_map[$method]);
- unset($this->_autoload_map[$method]);
- return $ok;
- }
-
- // }}}
- // {{{ addAggregateObject()
-
- /**
- * Add an aggregate object to this object. If the specified class
- * is not defined, loading it will be attempted following PEAR's
- * file naming scheme. All the methods in the class will be
- * aggregated, except private ones (name starting with an
- * underscore) and constructors.
- *
- * @param string $classname what class to instantiate for the object.
- *
- * @return void
- *
- * @access public
- */
- function addAggregateObject($classname)
- {
- $classname = strtolower($classname);
- if (!class_exists($classname)) {
- $include_file = preg_replace('/[^a-z0-9]/i', '_', $classname);
- include_once $include_file;
- }
- $obj =& new $classname;
- $methods = get_class_methods($classname);
- foreach ($methods as $method) {
- // don't import priviate methods and constructors
- if ($method{0} != '_' && $method != $classname) {
- $this->_method_map[$method] = $obj;
- }
- }
- }
-
- // }}}
- // {{{ removeAggregateObject()
-
- /**
- * Remove an aggregate object.
- *
- * @param string $classname the class of the object to remove
- *
- * @return bool TRUE if an object was removed, FALSE if not
- *
- * @access public
- */
- function removeAggregateObject($classname)
- {
- $ok = false;
- $classname = strtolower($classname);
- reset($this->_method_map);
- while (list($method, $obj) = each($this->_method_map)) {
- if (is_a($obj, $classname)) {
- unset($this->_method_map[$method]);
- $ok = true;
- }
- }
- return $ok;
- }
-
- // }}}
- // {{{ __call()
-
- /**
- * Overloaded object call handler, called each time an
- * undefined/aggregated method is invoked. This method repeats
- * the call in the right aggregate object and passes on the return
- * value.
- *
- * @param string $method which method that was called
- *
- * @param string $args An array of the parameters passed in the
- * original call
- *
- * @return mixed The return value from the aggregated method, or a PEAR
- * error if the called method was unknown.
- */
- function __call($method, $args, &$retval)
- {
- $method = strtolower($method);
- if (empty($this->_method_map[$method]) && isset($this->_autoload_map[$method])) {
- $this->addAggregateObject($this->_autoload_map[$method]);
- }
- if (isset($this->_method_map[$method])) {
- $retval = call_user_func_array(array($this->_method_map[$method], $method), $args);
- return true;
- }
- return false;
- }
-
- // }}}
-}
-
-overload("PEAR_Autoloader");
-
-?>
- +?> +/** + * Class auto-loader + * + * PHP versions 4 + + * + * @category pear + * @package PEAR + * @author Stig Bakken <ssb@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: Autoloader.php 276383 2009-02-24 23:39:37Z dufuz $ + * @link http://pear.php.net/manual/en/core.ppm.php#core.ppm.pear-autoloader + * @since File available since Release 0.1 + * @deprecated File deprecated in Release 1.4.0a1 + */ + +// /* vim: set expandtab tabstop=4 shiftwidth=4: */ + +if (!extension_loaded("overload")) { + // die hard without ext/overload + die("Rebuild PHP with the `overload' extension to use PEAR_Autoloader"); +} + +/** + * Include for PEAR_Error and PEAR classes + */ +require_once "PEAR.php"; + +/** + * This class is for objects where you want to separate the code for + * some methods into separate classes. This is useful if you have a + * class with not-frequently-used methods that contain lots of code + * that you would like to avoid always parsing. + * + * The PEAR_Autoloader class provides autoloading and aggregation. + * The autoloading lets you set up in which classes the separated + * methods are found. Aggregation is the technique used to import new + * methods, an instance of each class providing separated methods is + * stored and called every time the aggregated method is called. + * + * @category pear + * @package PEAR + * @author Stig Bakken <ssb@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/manual/en/core.ppm.php#core.ppm.pear-autoloader + * @since File available since Release 0.1 + * @deprecated File deprecated in Release 1.4.0a1 + */ +class PEAR_Autoloader extends PEAR +{ + // {{{ properties + + /** + * Map of methods and classes where they are defined + * + * @var array + * + * @access private + */ + var $_autoload_map = array(); + + /** + * Map of methods and aggregate objects + * + * @var array + * + * @access private + */ + var $_method_map = array(); + + // }}} + // {{{ addAutoload() + + /** + * Add one or more autoload entries. + * + * @param string $method which method to autoload + * + * @param string $classname (optional) which class to find the method in. + * If the $method parameter is an array, this + * parameter may be omitted (and will be ignored + * if not), and the $method parameter will be + * treated as an associative array with method + * names as keys and class names as values. + * + * @return void + * + * @access public + */ + function addAutoload($method, $classname = null) + { + if (is_array($method)) { + array_walk($method, create_function('$a,&$b', '$b = strtolower($b);')); + $this->_autoload_map = array_merge($this->_autoload_map, $method); + } else { + $this->_autoload_map[strtolower($method)] = $classname; + } + } + + // }}} + // {{{ removeAutoload() + + /** + * Remove an autoload entry. + * + * @param string $method which method to remove the autoload entry for + * + * @return bool TRUE if an entry was removed, FALSE if not + * + * @access public + */ + function removeAutoload($method) + { + $method = strtolower($method); + $ok = isset($this->_autoload_map[$method]); + unset($this->_autoload_map[$method]); + return $ok; + } + + // }}} + // {{{ addAggregateObject() + + /** + * Add an aggregate object to this object. If the specified class + * is not defined, loading it will be attempted following PEAR's + * file naming scheme. All the methods in the class will be + * aggregated, except private ones (name starting with an + * underscore) and constructors. + * + * @param string $classname what class to instantiate for the object. + * + * @return void + * + * @access public + */ + function addAggregateObject($classname) + { + $classname = strtolower($classname); + if (!class_exists($classname)) { + $include_file = preg_replace('/[^a-z0-9]/i', '_', $classname); + include_once $include_file; + } + $obj =& new $classname; + $methods = get_class_methods($classname); + foreach ($methods as $method) { + // don't import priviate methods and constructors + if ($method{0} != '_' && $method != $classname) { + $this->_method_map[$method] = $obj; + } + } + } + + // }}} + // {{{ removeAggregateObject() + + /** + * Remove an aggregate object. + * + * @param string $classname the class of the object to remove + * + * @return bool TRUE if an object was removed, FALSE if not + * + * @access public + */ + function removeAggregateObject($classname) + { + $ok = false; + $classname = strtolower($classname); + reset($this->_method_map); + while (list($method, $obj) = each($this->_method_map)) { + if (is_a($obj, $classname)) { + unset($this->_method_map[$method]); + $ok = true; + } + } + return $ok; + } + + // }}} + // {{{ __call() + + /** + * Overloaded object call handler, called each time an + * undefined/aggregated method is invoked. This method repeats + * the call in the right aggregate object and passes on the return + * value. + * + * @param string $method which method that was called + * + * @param string $args An array of the parameters passed in the + * original call + * + * @return mixed The return value from the aggregated method, or a PEAR + * error if the called method was unknown. + */ + function __call($method, $args, &$retval) + { + $method = strtolower($method); + if (empty($this->_method_map[$method]) && isset($this->_autoload_map[$method])) { + $this->addAggregateObject($this->_autoload_map[$method]); + } + if (isset($this->_method_map[$method])) { + $retval = call_user_func_array(array($this->_method_map[$method], $method), $args); + return true; + } + return false; + } + + // }}} +} + +overload("PEAR_Autoloader"); + +?> + /** * PEAR_Builder for building PHP extensions (PECL packages) * @@ -32661,7 +33215,7 @@ overload("PEAR_Autoloader"); * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Builder.php,v 1.38 2009/02/24 23:38:22 dufuz Exp $ + * @version CVS: $Id: Builder.php 276383 2009-02-24 23:39:37Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 0.1 * @@ -32684,7 +33238,7 @@ require_once 'PEAR/PackageFile.php'; * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since PHP 4.0.2 * @see http://pear.php.net/manual/en/core.ppm.pear-builder.php @@ -33011,7 +33565,7 @@ class PEAR_Builder extends PEAR_Common if (!file_exists($build_dir) || !is_dir($build_dir) || !chdir($build_dir)) { return $this->raiseError("could not chdir to $build_dir"); } - putenv('PHP_PEAR_VERSION=1.8.0'); + putenv('PHP_PEAR_VERSION=1.9.0'); foreach ($to_run as $cmd) { $err = $this->_runCommand($cmd, $callback); if (PEAR::isError($err)) { @@ -33122,7 +33676,7 @@ class PEAR_Builder extends PEAR_Common } return PEAR_Common::log($level, $msg); } -} +} /** * PEAR_ChannelFile, the channel handling class * @@ -33133,7 +33687,7 @@ class PEAR_Builder extends PEAR_Common * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: ChannelFile.php,v 1.84 2009/03/09 01:03:51 dufuz Exp $ + * @version CVS: $Id: ChannelFile.php 286951 2009-08-09 14:41:22Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ @@ -33270,7 +33824,7 @@ $GLOBALS['_PEAR_CHANNELS_MIRROR_TYPES'] = array('server'); * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ @@ -33622,12 +34176,15 @@ class PEAR_ChannelFile function _makeRestXml($info, $indent) { $ret = $indent . "<rest>\n"; - if (!isset($info['baseurl'][0])) { + if (isset($info['baseurl']) && !isset($info['baseurl'][0])) { $info['baseurl'] = array($info['baseurl']); } - foreach ($info['baseurl'] as $url) { - $ret .= "$indent <baseurl type=\"" . $url['attribs']['type'] . "\""; - $ret .= ">" . $url['_content'] . "</baseurl>\n"; + + if (isset($info['baseurl'])) { + foreach ($info['baseurl'] as $url) { + $ret .= "$indent <baseurl type=\"" . $url['attribs']['type'] . "\""; + $ret .= ">" . $url['_content'] . "</baseurl>\n"; + } } $ret .= $indent . "</rest>\n"; return $ret; @@ -33811,15 +34368,17 @@ class PEAR_ChannelFile if (!isset($functions[0])) { $functions = array($functions); } + foreach ($functions as $function) { if (!isset($function['_content']) || empty($function['_content'])) { $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_FUNCTIONNAME, array('parent' => $parent, 'protocol' => $protocol)); } + if ($protocol == 'rest') { if (!isset($function['attribs']['type']) || empty($function['attribs']['type'])) { - $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_BASEURLTYPE, + $this->_validateError(PEAR_CHANNELFILE_ERROR_NOBASEURLTYPE, array('parent' => $parent, 'protocol' => $protocol)); } } else { @@ -34143,6 +34702,14 @@ class PEAR_ChannelFile switch ($version) { case '1.0' : $this->resetREST($mirror); + + if (!isset($this->_channelInfo['servers'])) { + $this->_channelInfo['servers'] = array('primary' => + array('rest' => array())); + } elseif (!isset($this->_channelInfo['servers']['primary'])) { + $this->_channelInfo['servers']['primary'] = array('rest' => array()); + } + return true; break; default : @@ -34667,7 +35234,7 @@ class PEAR_ChannelFile return time(); } -} +} /** * PEAR_Command, command pattern class * @@ -34679,7 +35246,7 @@ class PEAR_ChannelFile * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Command.php,v 1.41 2009/02/24 23:38:22 dufuz Exp $ + * @version CVS: $Id: Command.php 286494 2009-07-29 06:57:11Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 0.1 */ @@ -34763,7 +35330,7 @@ $GLOBALS['_PEAR_Command_objects'] = array(); * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 0.1 */ @@ -34910,27 +35477,31 @@ class PEAR_Command if (!$merge) { $GLOBALS['_PEAR_Command_commandlist'] = array(); } - while ($entry = readdir($dp)) { - if ($entry{0} == '.' || substr($entry, -4) != '.xml') { + + while ($file = readdir($dp)) { + if ($file{0} == '.' || substr($file, -4) != '.xml') { continue; } - $class = "PEAR_Command_".substr($entry, 0, -4); - $file = "$dir/$entry"; - $parser->parse(file_get_contents($file)); - $implements = $parser->getData(); + + $f = substr($file, 0, -4); + $class = "PEAR_Command_" . $f; // List of commands if (empty($GLOBALS['_PEAR_Command_objects'][$class])) { - $GLOBALS['_PEAR_Command_objects'][$class] = "$dir/" . substr($entry, 0, -4) . - '.php'; + $GLOBALS['_PEAR_Command_objects'][$class] = "$dir/" . $f . '.php'; } + + $parser->parse(file_get_contents("$dir/$file")); + $implements = $parser->getData(); foreach ($implements as $command => $desc) { if ($command == 'attribs') { continue; } + if (isset($GLOBALS['_PEAR_Command_commandlist'][$command])) { return PEAR::raiseError('Command "' . $command . '" already registered in ' . 'class "' . $GLOBALS['_PEAR_Command_commandlist'][$command] . '"'); } + $GLOBALS['_PEAR_Command_commandlist'][$command] = $class; $GLOBALS['_PEAR_Command_commanddesc'][$command] = $desc['summary']; if (isset($desc['shortcut'])) { @@ -34942,6 +35513,7 @@ class PEAR_Command } $GLOBALS['_PEAR_Command_shortcuts'][$shortcut] = $command; } + if (isset($desc['options']) && $desc['options']) { foreach ($desc['options'] as $oname => $option) { if (isset($option['shortopt']) && strlen($option['shortopt']) > 1) { @@ -34954,6 +35526,7 @@ class PEAR_Command } } } + ksort($GLOBALS['_PEAR_Command_shortcuts']); ksort($GLOBALS['_PEAR_Command_commandlist']); @closedir($dp); @@ -35074,7 +35647,7 @@ class PEAR_Command return false; } // }}} -} +} /** * PEAR_Common, the base class for the PEAR Installer * @@ -35087,7 +35660,7 @@ class PEAR_Command * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Common.php,v 1.168 2009/03/27 19:35:47 dufuz Exp $ + * @version CVS: $Id: Common.php 282969 2009-06-28 23:09:27Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 0.1.0 * @deprecated File deprecated since Release 1.4.0a1 @@ -35194,7 +35767,7 @@ $GLOBALS['_PEAR_Common_script_phases'] = array('pre-install', 'post-install', 'p * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 * @deprecated This class will disappear, and its components will be spread @@ -35535,6 +36108,22 @@ class PEAR_Common extends PEAR return false; } + function _postProcessChecks($pf) + { + if (!PEAR::isError($pf)) { + return $this->_postProcessValidPackagexml($pf); + } + + $errs = $pf->getUserinfo(); + if (is_array($errs)) { + foreach ($errs as $error) { + $e = $this->raiseError($error['message'], $error['code'], null, null, $error); + } + } + + return $pf; + } + /** * Returns information about a package file. Expects the name of * a gzipped tar file as input. @@ -35551,18 +36140,7 @@ class PEAR_Common extends PEAR { $packagefile = &new PEAR_PackageFile($this->config); $pf = &$packagefile->fromTgzFile($file, PEAR_VALIDATE_NORMAL); - if (PEAR::isError($pf)) { - $errs = $pf->getUserinfo(); - if (is_array($errs)) { - foreach ($errs as $error) { - $e = $this->raiseError($error['message'], $error['code'], null, null, $error); - } - } - - return $pf; - } - - return $this->_postProcessValidPackagexml($pf); + return $this->_postProcessChecks($pf); } /** @@ -35581,18 +36159,7 @@ class PEAR_Common extends PEAR { $packagefile = &new PEAR_PackageFile($this->config); $pf = &$packagefile->fromPackageFile($descfile, PEAR_VALIDATE_NORMAL); - if (PEAR::isError($pf)) { - $errs = $pf->getUserinfo(); - if (is_array($errs)) { - foreach ($errs as $error) { - $e = $this->raiseError($error['message'], $error['code'], null, null, $error); - } - } - - return $pf; - } - - return $this->_postProcessValidPackagexml($pf); + return $this->_postProcessChecks($pf); } /** @@ -35611,18 +36178,7 @@ class PEAR_Common extends PEAR { $packagefile = &new PEAR_PackageFile($this->config); $pf = &$packagefile->fromXmlString($data, PEAR_VALIDATE_NORMAL, false); - if (PEAR::isError($pf)) { - $errs = $pf->getUserinfo(); - if (is_array($errs)) { - foreach ($errs as $error) { - $e = $this->raiseError($error['message'], $error['code'], null, null, $error); - } - } - - return $pf; - } - - return $this->_postProcessValidPackagexml($pf); + return $this->_postProcessChecks($pf); } /** @@ -35640,23 +36196,11 @@ class PEAR_Common extends PEAR // changelog is not converted to old format. $arr = $pf->toArray(true); $arr = array_merge($arr, $arr['old']); - unset($arr['old']); - unset($arr['xsdversion']); - unset($arr['contents']); - unset($arr['compatible']); - unset($arr['channel']); - unset($arr['uri']); - unset($arr['dependencies']); - unset($arr['phprelease']); - unset($arr['extsrcrelease']); - unset($arr['zendextsrcrelease']); - unset($arr['extbinrelease']); - unset($arr['zendextbinrelease']); - unset($arr['bundle']); - unset($arr['lead']); - unset($arr['developer']); - unset($arr['helper']); - unset($arr['contributor']); + unset($arr['old'], $arr['xsdversion'], $arr['contents'], $arr['compatible'], + $arr['channel'], $arr['uri'], $arr['dependencies'], $arr['phprelease'], + $arr['extsrcrelease'], $arr['zendextsrcrelease'], $arr['extbinrelease'], + $arr['zendextbinrelease'], $arr['bundle'], $arr['lead'], $arr['developer'], + $arr['helper'], $arr['contributor']); $arr['filelist'] = $pf->getFilelist(); $this->pkginfo = $arr; return $arr; @@ -35939,7 +36483,7 @@ class PEAR_Common extends PEAR } require_once 'PEAR/Config.php'; -require_once 'PEAR/PackageFile.php'; +require_once 'PEAR/PackageFile.php'; /** * PEAR_Config, customized configuration handling for the PEAR Installer * @@ -35951,7 +36495,7 @@ require_once 'PEAR/PackageFile.php'; * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Config.php,v 1.157 2009/02/25 00:23:26 dufuz Exp $ + * @version CVS: $Id: Config.php 286480 2009-07-29 02:50:02Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 0.1 */ @@ -36187,7 +36731,7 @@ if (getenv('PHP_PEAR_SIG_KEYDIR')) { * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 0.1 */ @@ -37772,13 +38316,17 @@ class PEAR_Config extends PEAR * * @param string config key * @param string (optional) config layer + * @param string (optional) channel (defaults to default channel) * @return bool TRUE on success, FALSE on failure * * @access public */ - function remove($key, $layer = 'user') + function remove($key, $layer = 'user', $channel = null) { - $channel = $this->getDefaultChannel(); + if ($channel === null) { + $channel = $this->getDefaultChannel(); + } + if ($channel !== 'pear.php.net') { if (isset($this->configuration[$layer]['__channels'][$channel][$key])) { unset($this->configuration[$layer]['__channels'][$channel][$key]); @@ -38032,7 +38580,7 @@ class PEAR_Config extends PEAR } } } - + /** * PEAR_DependencyDB, advanced installed packages dependency database * @@ -38044,7 +38592,7 @@ class PEAR_Config extends PEAR * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: DependencyDB.php,v 1.44 2009/03/21 15:15:26 dufuz Exp $ + * @version CVS: $Id: DependencyDB.php 286686 2009-08-02 17:38:57Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ @@ -38064,7 +38612,7 @@ $GLOBALS['_PEAR_DEPENDENCYDB_INSTANCE'] = array(); * @author Tomas V.V.Cox <cox@idec.net.com> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ @@ -38198,18 +38746,19 @@ class PEAR_DependencyDB { if (!is_file($this->_depdb)) { $this->rebuildDB(); - } else { - $depdb = $this->_getDepDB(); - // Datatype format has been changed, rebuild the Deps DB - if ($depdb['_version'] < $this->_version) { - $this->rebuildDB(); - } + return; + } - if ($depdb['_version']{0} > $this->_version{0}) { - return PEAR::raiseError('Dependency database is version ' . - $depdb['_version'] . ', and we are version ' . - $this->_version . ', cannot continue'); - } + $depdb = $this->_getDepDB(); + // Datatype format has been changed, rebuild the Deps DB + if ($depdb['_version'] < $this->_version) { + $this->rebuildDB(); + } + + if ($depdb['_version']{0} > $this->_version{0}) { + return PEAR::raiseError('Dependency database is version ' . + $depdb['_version'] . ', and we are version ' . + $this->_version . ', cannot continue'); } } @@ -38262,9 +38811,10 @@ class PEAR_DependencyDB foreach ($depend as $info) { $temp = $this->getDependencies($info); foreach ($temp as $dep) { - if (isset($dep['dep'], $dep['dep']['channel'], $dep['dep']['name']) && - strtolower($dep['dep']['channel']) == $channel && - strtolower($dep['dep']['name']) == $package + if ( + isset($dep['dep'], $dep['dep']['channel'], $dep['dep']['name']) && + strtolower($dep['dep']['channel']) == $channel && + strtolower($dep['dep']['name']) == $package ) { if (!isset($dependencies[$info['channel']])) { $dependencies[$info['channel']] = array(); @@ -38775,13 +39325,6 @@ class PEAR_DependencyDB break; } } - - if (!$found) { - $data['packages'][$depchannel][$dep['name']][] = array( - 'channel' => $channel, - 'package' => $package - ); - } } else { if (!isset($data['packages'])) { $data['packages'] = array(); @@ -38795,13 +39338,17 @@ class PEAR_DependencyDB $data['packages'][$depchannel][$dep['name']] = array(); } + $found = false; + } + + if (!$found) { $data['packages'][$depchannel][$dep['name']][] = array( 'channel' => $channel, 'package' => $package ); } } -} +} /** * PEAR_Dependency2, advanced dependency validation * @@ -38812,7 +39359,7 @@ class PEAR_DependencyDB * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Dependency2.php,v 1.59 2009/02/24 23:38:22 dufuz Exp $ + * @version CVS: $Id: Dependency2.php 286494 2009-07-29 06:57:11Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ @@ -38834,7 +39381,7 @@ require_once 'PEAR/Validate.php'; * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ @@ -39149,7 +39696,8 @@ class PEAR_Dependency2 } if (!isset($dep['min']) && !isset($dep['max']) && - !isset($dep['recommended']) && !isset($dep['exclude'])) { + !isset($dep['recommended']) && !isset($dep['exclude']) + ) { if ($loaded) { if (isset($dep['conflicts'])) { if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { @@ -39162,24 +39710,24 @@ class PEAR_Dependency2 } return true; - } else { - if (isset($dep['conflicts'])) { - return true; - } + } - if ($required) { - if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { - return $this->raiseError('%s requires PHP extension "' . - $dep['name'] . '"' . $extra); - } + if (isset($dep['conflicts'])) { + return true; + } - return $this->warning('warning: %s requires PHP extension "' . + if ($required) { + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('%s requires PHP extension "' . $dep['name'] . '"' . $extra); } - return $this->warning('%s can optionally use PHP extension "' . + return $this->warning('warning: %s requires PHP extension "' . $dep['name'] . '"' . $extra); } + + return $this->warning('%s can optionally use PHP extension "' . + $dep['name'] . '"' . $extra); } if (!$loaded) { @@ -39343,7 +39891,7 @@ class PEAR_Dependency2 */ function getPEARVersion() { - return '1.8.0'; + return '1.9.0'; } function validatePearinstallerDependency($dep) @@ -40157,7 +40705,7 @@ class PEAR_Dependency2 return array(sprintf($msg, $this->_registry->parsedPackageNameToString( $this->_currentPackage, true))); } -} +} /** * PEAR_Downloader, the PEAR Installer's download utility class * @@ -40171,7 +40719,7 @@ class PEAR_Dependency2 * @author Martin Jansen <mj@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Downloader.php,v 1.159 2009/03/08 04:01:08 dufuz Exp $ + * @version CVS: $Id: Downloader.php 287109 2009-08-11 18:50:30Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.3.0 */ @@ -40198,7 +40746,7 @@ define('PEAR_INSTALLER_ERROR_NO_PREF_STATE', 2); * @author Martin Jansen <mj@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.3.0 */ @@ -40298,7 +40846,6 @@ class PEAR_Downloader extends PEAR_Common * @var string */ var $_downloadDir; - // {{{ PEAR_Downloader() /** * @param PEAR_Frontend_* @@ -40466,7 +41013,8 @@ class PEAR_Downloader extends PEAR_Common } if ($params[$i] && !isset($channelschecked[$params[$i]->getChannel()]) && - !isset($this->_options['offline'])) { + !isset($this->_options['offline']) + ) { $channelschecked[$params[$i]->getChannel()] = true; PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); if (!class_exists('System')) { @@ -40484,10 +41032,9 @@ class PEAR_Downloader extends PEAR_Common break; } - $mirror = $this->config->get('preferred_mirror', null, - $params[$i]->getChannel()); - $a = $this->downloadHttp('http://' . $mirror . - '/channel.xml', $this->ui, $dir, null, $curchannel->lastModified()); + $mirror = $this->config->get('preferred_mirror', null, $params[$i]->getChannel()); + $url = 'http://' . $mirror . '/channel.xml'; + $a = $this->downloadHttp($url, $this->ui, $dir, null, $curchannel->lastModified()); PEAR::staticPopErrorHandling(); if (PEAR::isError($a) || !$a) { @@ -40916,8 +41463,6 @@ class PEAR_Downloader extends PEAR_Common $this->_downloadDir = $dir; } - // }}} - // {{{ configSet() function configSet($key, $value, $layer = 'user', $channel = false) { $this->config->set($key, $value, $layer, $channel); @@ -40928,8 +41473,6 @@ class PEAR_Downloader extends PEAR_Common } } - // }}} - // {{{ setOptions() function setOptions($options) { $this->_options = $options; @@ -40942,8 +41485,6 @@ class PEAR_Downloader extends PEAR_Common return $this->_options; } - // }}} - /** * For simpler unit-testing * @param PEAR_Config @@ -40959,8 +41500,6 @@ class PEAR_Downloader extends PEAR_Common return $a; } - // {{{ _getPackageDownloadUrl() - /** * @param array output of {@link parsePackageName()} * @access private @@ -41007,7 +41546,7 @@ class PEAR_Downloader extends PEAR_Common !($base = $chan->getBaseURL('REST1.0', $preferred_mirror)) ) ) { - return $this->raiseError($parr['channel'] . ' is using a unsupported protocal - This should never happen.'); + return $this->raiseError($parr['channel'] . ' is using a unsupported protocol - This should never happen.'); } if ($base2) { @@ -41017,14 +41556,15 @@ class PEAR_Downloader extends PEAR_Common $rest = &$this->config->getREST('1.0', $this->_options); } + $downloadVersion = false; if (!isset($parr['version']) && !isset($parr['state']) && $version && !PEAR::isError($version) - && !isset($this->_options['downloadonly'])) { - $url = $rest->getDownloadURL($base, $parr, $state, $version, $chan->getName()); - } else { - $url = $rest->getDownloadURL($base, $parr, $state, false, $chan->getName()); + && !isset($this->_options['downloadonly']) + ) { + $downloadVersion = $version; } + $url = $rest->getDownloadURL($base, $parr, $state, $downloadVersion, $chan->getName()); if (PEAR::isError($url)) { $this->configSet('default_channel', $curchannel); return $url; @@ -41095,8 +41635,6 @@ class PEAR_Downloader extends PEAR_Common return $url; } - // }}} - // {{{ getDepPackageDownloadUrl() /** * @param array dependency array @@ -41226,10 +41764,8 @@ class PEAR_Downloader extends PEAR_Common return $url; } - return $this->raiseError($parr['channel'] . ' is using a unsupported protocal - This should never happen.'); + return $this->raiseError($parr['channel'] . ' is using a unsupported protocol - This should never happen.'); } - // }}} - // {{{ getPackageDownloadUrl() /** * @deprecated in favor of _getPackageDownloadUrl @@ -41254,9 +41790,6 @@ class PEAR_Downloader extends PEAR_Common return $package; } - // }}} - // {{{ getDownloadedPackages() - /** * Retrieve a list of downloaded packages after a call to {@link download()}. * @@ -41271,9 +41804,6 @@ class PEAR_Downloader extends PEAR_Common return $ret; } - // }}} - // {{{ _downloadCallback() - function _downloadCallback($msg, $params = null) { switch ($msg) { @@ -41306,9 +41836,6 @@ class PEAR_Downloader extends PEAR_Common $this->ui->_downloadCallback($msg, $params); } - // }}} - // {{{ _prependPath($path, $prepend) - function _prependPath($path, $prepend) { if (strlen($prepend) > 0) { @@ -41325,8 +41852,6 @@ class PEAR_Downloader extends PEAR_Common } return $path; } - // }}} - // {{{ pushError($errmsg, $code) /** * @param string @@ -41337,9 +41862,6 @@ class PEAR_Downloader extends PEAR_Common array_push($this->_errorStack, array($errmsg, $code)); } - // }}} - // {{{ getErrorMsgs() - function getErrorMsgs() { $msgs = array(); @@ -41351,10 +41873,10 @@ class PEAR_Downloader extends PEAR_Common return $msgs; } - // }}} - /** * for BC + * + * @deprecated */ function sortPkgDeps(&$packages, $uninstall = false) { @@ -41513,7 +42035,7 @@ class PEAR_Downloader extends PEAR_Common $installOrder = Structures_Graph_Manipulator_TopologicalSorter::sort($depgraph); $ret = array(); - for ($i = 0; $i < count($installOrder); $i++) { + for ($i = 0, $count = count($installOrder); $i < $count; $i++) { foreach ($installOrder[$i] as $index => $sortedpackage) { $data = &$installOrder[$i][$index]->getData(); $ret[] = &$nodes[$reg->parsedPackageNameToString( @@ -41548,6 +42070,7 @@ class PEAR_Downloader extends PEAR_Common if (count($deplinks[$dep]) == 0) { unset($deplinks[$dep]); } + continue 3; } } @@ -41562,25 +42085,30 @@ class PEAR_Downloader extends PEAR_Common $visited = array(); return; } + // this happens when a parent has a dep cycle on another dependency // but the child is not part of the cycle if (isset($visited[$dep])) { return false; } + $visited[$dep] = 1; if ($test == $dep) { return true; } + if (isset($deplinks[$dep])) { if (in_array($test, array_keys($deplinks[$dep]), true)) { return true; } + foreach ($deplinks[$dep] as $parent => $unused) { if ($this->_testCycle($test, $deplinks, $parent)) { return true; } } } + return false; } @@ -41817,7 +42345,7 @@ class PEAR_Downloader extends PEAR_Common } $request .= $ifmodifiedsince . - "User-Agent: PEAR/1.8.0/PHP/" . PHP_VERSION . "\r\n"; + "User-Agent: PEAR/1.9.0/PHP/" . PHP_VERSION . "\r\n"; if (isset($this)) { // only pass in authentication for non-static calls $username = $config->get('username', null, $channel); @@ -41914,6 +42442,7 @@ class PEAR_Downloader extends PEAR_Common return PEAR::raiseError("$dest_file: write failed ($php_errormsg)"); } } + fclose($fp); fclose($wp); if ($callback) { @@ -41924,6 +42453,7 @@ class PEAR_Downloader extends PEAR_Common if (isset($headers['etag'])) { $lastmodified = array('ETag' => $headers['etag']); } + if (isset($headers['last-modified'])) { if (is_array($lastmodified)) { $lastmodified['Last-Modified'] = $headers['last-modified']; @@ -41936,1615 +42466,1615 @@ class PEAR_Downloader extends PEAR_Common return $dest_file; } } -// }}} -/**
- * Error Stack Implementation
- *
- * This is an incredibly simple implementation of a very complex error handling
- * facility. It contains the ability
- * to track multiple errors from multiple packages simultaneously. In addition,
- * it can track errors of many levels, save data along with the error, context
- * information such as the exact file, line number, class and function that
- * generated the error, and if necessary, it can raise a traditional PEAR_Error.
- * It has built-in support for PEAR::Log, to log errors as they occur
- *
- * Since version 0.2alpha, it is also possible to selectively ignore errors,
- * through the use of an error callback, see {@link pushCallback()}
- *
- * Since version 0.3alpha, it is possible to specify the exception class
- * returned from {@link push()}
- *
- * Since version PEAR1.3.2, ErrorStack no longer instantiates an exception class. This can
- * still be done quite handily in an error callback or by manipulating the returned array
- * @category Debugging
- * @package PEAR_ErrorStack
- * @author Greg Beaver <cellog@php.net>
- * @copyright 2004-2008 Greg Beaver
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version CVS: $Id: ErrorStack.php,v 1.29 2009/02/24 23:38:22 dufuz Exp $
- * @link http://pear.php.net/package/PEAR_ErrorStack
- */
-
-/**
- * Singleton storage
- *
- * Format:
- * <pre>
- * array(
- * 'package1' => PEAR_ErrorStack object,
- * 'package2' => PEAR_ErrorStack object,
- * ...
- * )
- * </pre>
- * @access private
- * @global array $GLOBALS['_PEAR_ERRORSTACK_SINGLETON']
- */
-$GLOBALS['_PEAR_ERRORSTACK_SINGLETON'] = array();
-
-/**
- * Global error callback (default)
- *
- * This is only used if set to non-false. * is the default callback for
- * all packages, whereas specific packages may set a default callback
- * for all instances, regardless of whether they are a singleton or not.
- *
- * To exclude non-singletons, only set the local callback for the singleton
- * @see PEAR_ErrorStack::setDefaultCallback()
- * @access private
- * @global array $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK']
- */
-$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'] = array(
- '*' => false,
-);
-
-/**
- * Global Log object (default)
- *
- * This is only used if set to non-false. Use to set a default log object for
- * all stacks, regardless of instantiation order or location
- * @see PEAR_ErrorStack::setDefaultLogger()
- * @access private
- * @global array $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER']
- */
-$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] = false;
-
-/**
- * Global Overriding Callback
- *
- * This callback will override any error callbacks that specific loggers have set.
- * Use with EXTREME caution
- * @see PEAR_ErrorStack::staticPushCallback()
- * @access private
- * @global array $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER']
- */
-$GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'] = array();
-
-/**#@+
- * One of four possible return values from the error Callback
- * @see PEAR_ErrorStack::_errorCallback()
- */
-/**
- * If this is returned, then the error will be both pushed onto the stack
- * and logged.
- */
-define('PEAR_ERRORSTACK_PUSHANDLOG', 1);
-/**
- * If this is returned, then the error will only be pushed onto the stack,
- * and not logged.
- */
-define('PEAR_ERRORSTACK_PUSH', 2);
-/**
- * If this is returned, then the error will only be logged, but not pushed
- * onto the error stack.
- */
-define('PEAR_ERRORSTACK_LOG', 3);
-/**
- * If this is returned, then the error is completely ignored.
- */
-define('PEAR_ERRORSTACK_IGNORE', 4);
-/**
- * If this is returned, then the error is logged and die() is called.
- */
-define('PEAR_ERRORSTACK_DIE', 5);
-/**#@-*/
-
-/**
- * Error code for an attempt to instantiate a non-class as a PEAR_ErrorStack in
- * the singleton method.
- */
-define('PEAR_ERRORSTACK_ERR_NONCLASS', 1);
-
-/**
- * Error code for an attempt to pass an object into {@link PEAR_ErrorStack::getMessage()}
- * that has no __toString() method
- */
-define('PEAR_ERRORSTACK_ERR_OBJTOSTRING', 2);
-/**
- * Error Stack Implementation
- *
- * Usage:
- * <code>
- * // global error stack
- * $global_stack = &PEAR_ErrorStack::singleton('MyPackage');
- * // local error stack
- * $local_stack = new PEAR_ErrorStack('MyPackage');
- * </code>
- * @author Greg Beaver <cellog@php.net>
- * @version 1.8.0
- * @package PEAR_ErrorStack
- * @category Debugging
- * @copyright 2004-2008 Greg Beaver
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version CVS: $Id: ErrorStack.php,v 1.29 2009/02/24 23:38:22 dufuz Exp $
- * @link http://pear.php.net/package/PEAR_ErrorStack
- */
-class PEAR_ErrorStack {
- /**
- * Errors are stored in the order that they are pushed on the stack.
- * @since 0.4alpha Errors are no longer organized by error level.
- * This renders pop() nearly unusable, and levels could be more easily
- * handled in a callback anyway
- * @var array
- * @access private
- */
- var $_errors = array();
-
- /**
- * Storage of errors by level.
- *
- * Allows easy retrieval and deletion of only errors from a particular level
- * @since PEAR 1.4.0dev
- * @var array
- * @access private
- */
- var $_errorsByLevel = array();
-
- /**
- * Package name this error stack represents
- * @var string
- * @access protected
- */
- var $_package;
-
- /**
- * Determines whether a PEAR_Error is thrown upon every error addition
- * @var boolean
- * @access private
- */
- var $_compat = false;
-
- /**
- * If set to a valid callback, this will be used to generate the error
- * message from the error code, otherwise the message passed in will be
- * used
- * @var false|string|array
- * @access private
- */
- var $_msgCallback = false;
-
- /**
- * If set to a valid callback, this will be used to generate the error
- * context for an error. For PHP-related errors, this will be a file
- * and line number as retrieved from debug_backtrace(), but can be
- * customized for other purposes. The error might actually be in a separate
- * configuration file, or in a database query.
- * @var false|string|array
- * @access protected
- */
- var $_contextCallback = false;
-
- /**
- * If set to a valid callback, this will be called every time an error
- * is pushed onto the stack. The return value will be used to determine
- * whether to allow an error to be pushed or logged.
- *
- * The return value must be one an PEAR_ERRORSTACK_* constant
- * @see PEAR_ERRORSTACK_PUSHANDLOG, PEAR_ERRORSTACK_PUSH, PEAR_ERRORSTACK_LOG
- * @var false|string|array
- * @access protected
- */
- var $_errorCallback = array();
-
- /**
- * PEAR::Log object for logging errors
- * @var false|Log
- * @access protected
- */
- var $_logger = false;
-
- /**
- * Error messages - designed to be overridden
- * @var array
- * @abstract
- */
- var $_errorMsgs = array();
-
- /**
- * Set up a new error stack
- *
- * @param string $package name of the package this error stack represents
- * @param callback $msgCallback callback used for error message generation
- * @param callback $contextCallback callback used for context generation,
- * defaults to {@link getFileLine()}
- * @param boolean $throwPEAR_Error
- */
- function PEAR_ErrorStack($package, $msgCallback = false, $contextCallback = false,
- $throwPEAR_Error = false)
- {
- $this->_package = $package;
- $this->setMessageCallback($msgCallback);
- $this->setContextCallback($contextCallback);
- $this->_compat = $throwPEAR_Error;
- }
-
- /**
- * Return a single error stack for this package.
- *
- * Note that all parameters are ignored if the stack for package $package
- * has already been instantiated
- * @param string $package name of the package this error stack represents
- * @param callback $msgCallback callback used for error message generation
- * @param callback $contextCallback callback used for context generation,
- * defaults to {@link getFileLine()}
- * @param boolean $throwPEAR_Error
- * @param string $stackClass class to instantiate
- * @static
- * @return PEAR_ErrorStack
- */
- function &singleton($package, $msgCallback = false, $contextCallback = false,
- $throwPEAR_Error = false, $stackClass = 'PEAR_ErrorStack')
- {
- if (isset($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package])) {
- return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package];
- }
- if (!class_exists($stackClass)) {
- if (function_exists('debug_backtrace')) {
- $trace = debug_backtrace();
- }
- PEAR_ErrorStack::staticPush('PEAR_ErrorStack', PEAR_ERRORSTACK_ERR_NONCLASS,
- 'exception', array('stackclass' => $stackClass),
- 'stack class "%stackclass%" is not a valid class name (should be like PEAR_ErrorStack)',
- false, $trace);
- }
- $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package] =
- new $stackClass($package, $msgCallback, $contextCallback, $throwPEAR_Error);
-
- return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package];
- }
-
- /**
- * Internal error handler for PEAR_ErrorStack class
- *
- * Dies if the error is an exception (and would have died anyway)
- * @access private
- */
- function _handleError($err)
- {
- if ($err['level'] == 'exception') {
- $message = $err['message'];
- if (isset($_SERVER['REQUEST_URI'])) {
- echo '<br />';
- } else {
- echo "\n";
- }
- var_dump($err['context']);
- die($message);
- }
- }
-
- /**
- * Set up a PEAR::Log object for all error stacks that don't have one
- * @param Log $log
- * @static
- */
- function setDefaultLogger(&$log)
- {
- if (is_object($log) && method_exists($log, 'log') ) {
- $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] = &$log;
- } elseif (is_callable($log)) {
- $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] = &$log;
- }
- }
-
- /**
- * Set up a PEAR::Log object for this error stack
- * @param Log $log
- */
- function setLogger(&$log)
- {
- if (is_object($log) && method_exists($log, 'log') ) {
- $this->_logger = &$log;
- } elseif (is_callable($log)) {
- $this->_logger = &$log;
- }
- }
-
- /**
- * Set an error code => error message mapping callback
- *
- * This method sets the callback that can be used to generate error
- * messages for any instance
- * @param array|string Callback function/method
- */
- function setMessageCallback($msgCallback)
- {
- if (!$msgCallback) {
- $this->_msgCallback = array(&$this, 'getErrorMessage');
- } else {
- if (is_callable($msgCallback)) {
- $this->_msgCallback = $msgCallback;
- }
- }
- }
-
- /**
- * Get an error code => error message mapping callback
- *
- * This method returns the current callback that can be used to generate error
- * messages
- * @return array|string|false Callback function/method or false if none
- */
- function getMessageCallback()
- {
- return $this->_msgCallback;
- }
-
- /**
- * Sets a default callback to be used by all error stacks
- *
- * This method sets the callback that can be used to generate error
- * messages for a singleton
- * @param array|string Callback function/method
- * @param string Package name, or false for all packages
- * @static
- */
- function setDefaultCallback($callback = false, $package = false)
- {
- if (!is_callable($callback)) {
- $callback = false;
- }
- $package = $package ? $package : '*';
- $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'][$package] = $callback;
- }
-
- /**
- * Set a callback that generates context information (location of error) for an error stack
- *
- * This method sets the callback that can be used to generate context
- * information for an error. Passing in NULL will disable context generation
- * and remove the expensive call to debug_backtrace()
- * @param array|string|null Callback function/method
- */
- function setContextCallback($contextCallback)
- {
- if ($contextCallback === null) {
- return $this->_contextCallback = false;
- }
- if (!$contextCallback) {
- $this->_contextCallback = array(&$this, 'getFileLine');
- } else {
- if (is_callable($contextCallback)) {
- $this->_contextCallback = $contextCallback;
- }
- }
- }
-
- /**
- * Set an error Callback
- * If set to a valid callback, this will be called every time an error
- * is pushed onto the stack. The return value will be used to determine
- * whether to allow an error to be pushed or logged.
- *
- * The return value must be one of the ERRORSTACK_* constants.
- *
- * This functionality can be used to emulate PEAR's pushErrorHandling, and
- * the PEAR_ERROR_CALLBACK mode, without affecting the integrity of
- * the error stack or logging
- * @see PEAR_ERRORSTACK_PUSHANDLOG, PEAR_ERRORSTACK_PUSH, PEAR_ERRORSTACK_LOG
- * @see popCallback()
- * @param string|array $cb
- */
- function pushCallback($cb)
- {
- array_push($this->_errorCallback, $cb);
- }
-
- /**
- * Remove a callback from the error callback stack
- * @see pushCallback()
- * @return array|string|false
- */
- function popCallback()
- {
- if (!count($this->_errorCallback)) {
- return false;
- }
- return array_pop($this->_errorCallback);
- }
-
- /**
- * Set a temporary overriding error callback for every package error stack
- *
- * Use this to temporarily disable all existing callbacks (can be used
- * to emulate the @ operator, for instance)
- * @see PEAR_ERRORSTACK_PUSHANDLOG, PEAR_ERRORSTACK_PUSH, PEAR_ERRORSTACK_LOG
- * @see staticPopCallback(), pushCallback()
- * @param string|array $cb
- * @static
- */
- function staticPushCallback($cb)
- {
- array_push($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'], $cb);
- }
-
- /**
- * Remove a temporary overriding error callback
- * @see staticPushCallback()
- * @return array|string|false
- * @static
- */
- function staticPopCallback()
- {
- $ret = array_pop($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK']);
- if (!is_array($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'])) {
- $GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'] = array();
- }
- return $ret;
- }
-
- /**
- * Add an error to the stack
- *
- * If the message generator exists, it is called with 2 parameters.
- * - the current Error Stack object
- * - an array that is in the same format as an error. Available indices
- * are 'code', 'package', 'time', 'params', 'level', and 'context'
- *
- * Next, if the error should contain context information, this is
- * handled by the context grabbing method.
- * Finally, the error is pushed onto the proper error stack
- * @param int $code Package-specific error code
- * @param string $level Error level. This is NOT spell-checked
- * @param array $params associative array of error parameters
- * @param string $msg Error message, or a portion of it if the message
- * is to be generated
- * @param array $repackage If this error re-packages an error pushed by
- * another package, place the array returned from
- * {@link pop()} in this parameter
- * @param array $backtrace Protected parameter: use this to pass in the
- * {@link debug_backtrace()} that should be used
- * to find error context
- * @return PEAR_Error|array if compatibility mode is on, a PEAR_Error is also
- * thrown. If a PEAR_Error is returned, the userinfo
- * property is set to the following array:
- *
- * <code>
- * array(
- * 'code' => $code,
- * 'params' => $params,
- * 'package' => $this->_package,
- * 'level' => $level,
- * 'time' => time(),
- * 'context' => $context,
- * 'message' => $msg,
- * //['repackage' => $err] repackaged error array/Exception class
- * );
- * </code>
- *
- * Normally, the previous array is returned.
- */
- function push($code, $level = 'error', $params = array(), $msg = false,
- $repackage = false, $backtrace = false)
- {
- $context = false;
- // grab error context
- if ($this->_contextCallback) {
- if (!$backtrace) {
- $backtrace = debug_backtrace();
- }
- $context = call_user_func($this->_contextCallback, $code, $params, $backtrace);
- }
-
- // save error
- $time = explode(' ', microtime());
- $time = $time[1] + $time[0];
- $err = array(
- 'code' => $code,
- 'params' => $params,
- 'package' => $this->_package,
- 'level' => $level,
- 'time' => $time,
- 'context' => $context,
- 'message' => $msg,
- );
-
- if ($repackage) {
- $err['repackage'] = $repackage;
- }
-
- // set up the error message, if necessary
- if ($this->_msgCallback) {
- $msg = call_user_func_array($this->_msgCallback,
- array(&$this, $err));
- $err['message'] = $msg;
- }
- $push = $log = true;
- $die = false;
- // try the overriding callback first
- $callback = $this->staticPopCallback();
- if ($callback) {
- $this->staticPushCallback($callback);
- }
- if (!is_callable($callback)) {
- // try the local callback next
- $callback = $this->popCallback();
- if (is_callable($callback)) {
- $this->pushCallback($callback);
- } else {
- // try the default callback
- $callback = isset($GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'][$this->_package]) ?
- $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'][$this->_package] :
- $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK']['*'];
- }
- }
- if (is_callable($callback)) {
- switch(call_user_func($callback, $err)){
- case PEAR_ERRORSTACK_IGNORE:
- return $err;
- break;
- case PEAR_ERRORSTACK_PUSH:
- $log = false;
- break;
- case PEAR_ERRORSTACK_LOG:
- $push = false;
- break;
- case PEAR_ERRORSTACK_DIE:
- $die = true;
- break;
- // anything else returned has the same effect as pushandlog
- }
- }
- if ($push) {
- array_unshift($this->_errors, $err);
- if (!isset($this->_errorsByLevel[$err['level']])) {
- $this->_errorsByLevel[$err['level']] = array();
- }
- $this->_errorsByLevel[$err['level']][] = &$this->_errors[0];
- }
- if ($log) {
- if ($this->_logger || $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER']) {
- $this->_log($err);
- }
- }
- if ($die) {
- die();
- }
- if ($this->_compat && $push) {
- return $this->raiseError($msg, $code, null, null, $err);
- }
- return $err;
- }
-
- /**
- * Static version of {@link push()}
- *
- * @param string $package Package name this error belongs to
- * @param int $code Package-specific error code
- * @param string $level Error level. This is NOT spell-checked
- * @param array $params associative array of error parameters
- * @param string $msg Error message, or a portion of it if the message
- * is to be generated
- * @param array $repackage If this error re-packages an error pushed by
- * another package, place the array returned from
- * {@link pop()} in this parameter
- * @param array $backtrace Protected parameter: use this to pass in the
- * {@link debug_backtrace()} that should be used
- * to find error context
- * @return PEAR_Error|array if compatibility mode is on, a PEAR_Error is also
- * thrown. see docs for {@link push()}
- * @static
- */
- function staticPush($package, $code, $level = 'error', $params = array(),
- $msg = false, $repackage = false, $backtrace = false)
- {
- $s = &PEAR_ErrorStack::singleton($package);
- if ($s->_contextCallback) {
- if (!$backtrace) {
- if (function_exists('debug_backtrace')) {
- $backtrace = debug_backtrace();
- }
- }
- }
- return $s->push($code, $level, $params, $msg, $repackage, $backtrace);
- }
-
- /**
- * Log an error using PEAR::Log
- * @param array $err Error array
- * @param array $levels Error level => Log constant map
- * @access protected
- */
- function _log($err)
- {
- if ($this->_logger) {
- $logger = &$this->_logger;
- } else {
- $logger = &$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'];
- }
- if (is_a($logger, 'Log')) {
- $levels = array(
- 'exception' => PEAR_LOG_CRIT,
- 'alert' => PEAR_LOG_ALERT,
- 'critical' => PEAR_LOG_CRIT,
- 'error' => PEAR_LOG_ERR,
- 'warning' => PEAR_LOG_WARNING,
- 'notice' => PEAR_LOG_NOTICE,
- 'info' => PEAR_LOG_INFO,
- 'debug' => PEAR_LOG_DEBUG);
- if (isset($levels[$err['level']])) {
- $level = $levels[$err['level']];
- } else {
- $level = PEAR_LOG_INFO;
- }
- $logger->log($err['message'], $level, $err);
- } else { // support non-standard logs
- call_user_func($logger, $err);
- }
- }
-
-
- /**
- * Pop an error off of the error stack
- *
- * @return false|array
- * @since 0.4alpha it is no longer possible to specify a specific error
- * level to return - the last error pushed will be returned, instead
- */
- function pop()
- {
- $err = @array_shift($this->_errors);
- if (!is_null($err)) {
- @array_pop($this->_errorsByLevel[$err['level']]);
- if (!count($this->_errorsByLevel[$err['level']])) {
- unset($this->_errorsByLevel[$err['level']]);
- }
- }
- return $err;
- }
-
- /**
- * Pop an error off of the error stack, static method
- *
- * @param string package name
- * @return boolean
- * @since PEAR1.5.0a1
- */
- function staticPop($package)
- {
- if ($package) {
- if (!isset($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package])) {
- return false;
- }
- return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]->pop();
- }
- }
-
- /**
- * Determine whether there are any errors on the stack
- * @param string|array Level name. Use to determine if any errors
- * of level (string), or levels (array) have been pushed
- * @return boolean
- */
- function hasErrors($level = false)
- {
- if ($level) {
- return isset($this->_errorsByLevel[$level]);
- }
- return count($this->_errors);
- }
-
- /**
- * Retrieve all errors since last purge
- *
- * @param boolean set in order to empty the error stack
- * @param string level name, to return only errors of a particular severity
- * @return array
- */
- function getErrors($purge = false, $level = false)
- {
- if (!$purge) {
- if ($level) {
- if (!isset($this->_errorsByLevel[$level])) {
- return array();
- } else {
- return $this->_errorsByLevel[$level];
- }
- } else {
- return $this->_errors;
- }
- }
- if ($level) {
- $ret = $this->_errorsByLevel[$level];
- foreach ($this->_errorsByLevel[$level] as $i => $unused) {
- // entries are references to the $_errors array
- $this->_errorsByLevel[$level][$i] = false;
- }
- // array_filter removes all entries === false
- $this->_errors = array_filter($this->_errors);
- unset($this->_errorsByLevel[$level]);
- return $ret;
- }
- $ret = $this->_errors;
- $this->_errors = array();
- $this->_errorsByLevel = array();
- return $ret;
- }
-
- /**
- * Determine whether there are any errors on a single error stack, or on any error stack
- *
- * The optional parameter can be used to test the existence of any errors without the need of
- * singleton instantiation
- * @param string|false Package name to check for errors
- * @param string Level name to check for a particular severity
- * @return boolean
- * @static
- */
- function staticHasErrors($package = false, $level = false)
- {
- if ($package) {
- if (!isset($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package])) {
- return false;
- }
- return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]->hasErrors($level);
- }
- foreach ($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'] as $package => $obj) {
- if ($obj->hasErrors($level)) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Get a list of all errors since last purge, organized by package
- * @since PEAR 1.4.0dev BC break! $level is now in the place $merge used to be
- * @param boolean $purge Set to purge the error stack of existing errors
- * @param string $level Set to a level name in order to retrieve only errors of a particular level
- * @param boolean $merge Set to return a flat array, not organized by package
- * @param array $sortfunc Function used to sort a merged array - default
- * sorts by time, and should be good for most cases
- * @static
- * @return array
- */
- function staticGetErrors($purge = false, $level = false, $merge = false,
- $sortfunc = array('PEAR_ErrorStack', '_sortErrors'))
- {
- $ret = array();
- if (!is_callable($sortfunc)) {
- $sortfunc = array('PEAR_ErrorStack', '_sortErrors');
- }
- foreach ($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'] as $package => $obj) {
- $test = $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]->getErrors($purge, $level);
- if ($test) {
- if ($merge) {
- $ret = array_merge($ret, $test);
- } else {
- $ret[$package] = $test;
- }
- }
- }
- if ($merge) {
- usort($ret, $sortfunc);
- }
- return $ret;
- }
-
- /**
- * Error sorting function, sorts by time
- * @access private
- */
- function _sortErrors($a, $b)
- {
- if ($a['time'] == $b['time']) {
- return 0;
- }
- if ($a['time'] < $b['time']) {
- return 1;
- }
- return -1;
- }
-
- /**
- * Standard file/line number/function/class context callback
- *
- * This function uses a backtrace generated from {@link debug_backtrace()}
- * and so will not work at all in PHP < 4.3.0. The frame should
- * reference the frame that contains the source of the error.
- * @return array|false either array('file' => file, 'line' => line,
- * 'function' => function name, 'class' => class name) or
- * if this doesn't work, then false
- * @param unused
- * @param integer backtrace frame.
- * @param array Results of debug_backtrace()
- * @static
- */
- function getFileLine($code, $params, $backtrace = null)
- {
- if ($backtrace === null) {
- return false;
- }
- $frame = 0;
- $functionframe = 1;
- if (!isset($backtrace[1])) {
- $functionframe = 0;
- } else {
- while (isset($backtrace[$functionframe]['function']) &&
- $backtrace[$functionframe]['function'] == 'eval' &&
- isset($backtrace[$functionframe + 1])) {
- $functionframe++;
- }
- }
- if (isset($backtrace[$frame])) {
- if (!isset($backtrace[$frame]['file'])) {
- $frame++;
- }
- $funcbacktrace = $backtrace[$functionframe];
- $filebacktrace = $backtrace[$frame];
- $ret = array('file' => $filebacktrace['file'],
- 'line' => $filebacktrace['line']);
- // rearrange for eval'd code or create function errors
- if (strpos($filebacktrace['file'], '(') &&
- preg_match(';^(.*?)\((\d+)\) : (.*?)\\z;', $filebacktrace['file'],
- $matches)) {
- $ret['file'] = $matches[1];
- $ret['line'] = $matches[2] + 0;
- }
- if (isset($funcbacktrace['function']) && isset($backtrace[1])) {
- if ($funcbacktrace['function'] != 'eval') {
- if ($funcbacktrace['function'] == '__lambda_func') {
- $ret['function'] = 'create_function() code';
- } else {
- $ret['function'] = $funcbacktrace['function'];
- }
- }
- }
- if (isset($funcbacktrace['class']) && isset($backtrace[1])) {
- $ret['class'] = $funcbacktrace['class'];
- }
- return $ret;
- }
- return false;
- }
-
- /**
- * Standard error message generation callback
- *
- * This method may also be called by a custom error message generator
- * to fill in template values from the params array, simply
- * set the third parameter to the error message template string to use
- *
- * The special variable %__msg% is reserved: use it only to specify
- * where a message passed in by the user should be placed in the template,
- * like so:
- *
- * Error message: %msg% - internal error
- *
- * If the message passed like so:
- *
- * <code>
- * $stack->push(ERROR_CODE, 'error', array(), 'server error 500');
- * </code>
- *
- * The returned error message will be "Error message: server error 500 -
- * internal error"
- * @param PEAR_ErrorStack
- * @param array
- * @param string|false Pre-generated error message template
- * @static
- * @return string
- */
- function getErrorMessage(&$stack, $err, $template = false)
- {
- if ($template) {
- $mainmsg = $template;
- } else {
- $mainmsg = $stack->getErrorMessageTemplate($err['code']);
- }
- $mainmsg = str_replace('%__msg%', $err['message'], $mainmsg);
- if (is_array($err['params']) && count($err['params'])) {
- foreach ($err['params'] as $name => $val) {
- if (is_array($val)) {
- // @ is needed in case $val is a multi-dimensional array
- $val = @implode(', ', $val);
- }
- if (is_object($val)) {
- if (method_exists($val, '__toString')) {
- $val = $val->__toString();
- } else {
- PEAR_ErrorStack::staticPush('PEAR_ErrorStack', PEAR_ERRORSTACK_ERR_OBJTOSTRING,
- 'warning', array('obj' => get_class($val)),
- 'object %obj% passed into getErrorMessage, but has no __toString() method');
- $val = 'Object';
- }
- }
- $mainmsg = str_replace('%' . $name . '%', $val, $mainmsg);
- }
- }
- return $mainmsg;
- }
-
- /**
- * Standard Error Message Template generator from code
- * @return string
- */
- function getErrorMessageTemplate($code)
- {
- if (!isset($this->_errorMsgs[$code])) {
- return '%__msg%';
- }
- return $this->_errorMsgs[$code];
- }
-
- /**
- * Set the Error Message Template array
- *
- * The array format must be:
- * <pre>
- * array(error code => 'message template',...)
- * </pre>
- *
- * Error message parameters passed into {@link push()} will be used as input
- * for the error message. If the template is 'message %foo% was %bar%', and the
- * parameters are array('foo' => 'one', 'bar' => 'six'), the error message returned will
- * be 'message one was six'
- * @return string
- */
- function setErrorMessageTemplate($template)
- {
- $this->_errorMsgs = $template;
- }
-
-
- /**
- * emulate PEAR::raiseError()
- *
- * @return PEAR_Error
- */
- function raiseError()
- {
- require_once 'PEAR.php';
- $args = func_get_args();
- return call_user_func_array(array('PEAR', 'raiseError'), $args);
- }
-}
-$stack = &PEAR_ErrorStack::singleton('PEAR_ErrorStack');
-$stack->pushCallback(array('PEAR_ErrorStack', '_handleError'));
-?>
- -/* vim: set expandtab tabstop=4 shiftwidth=4 foldmethod=marker: */
-/**
- * PEAR_Exception
- *
- * PHP versions 4 and 5
- *
- * @category pear
- * @package PEAR
- * @author Tomas V. V. Cox <cox@idecnet.com>
- * @author Hans Lellelid <hans@velum.net>
- * @author Bertrand Mansion <bmansion@mamasam.com>
- * @author Greg Beaver <cellog@php.net>
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version CVS: $Id: Exception.php,v 1.30 2009/02/24 23:38:22 dufuz Exp $
- * @link http://pear.php.net/package/PEAR
- * @since File available since Release 1.3.3
- */
-
-
-/**
- * Base PEAR_Exception Class
- *
- * 1) Features:
- *
- * - Nestable exceptions (throw new PEAR_Exception($msg, $prev_exception))
- * - Definable triggers, shot when exceptions occur
- * - Pretty and informative error messages
- * - Added more context info available (like class, method or cause)
- * - cause can be a PEAR_Exception or an array of mixed
- * PEAR_Exceptions/PEAR_ErrorStack warnings
- * - callbacks for specific exception classes and their children
- *
- * 2) Ideas:
- *
- * - Maybe a way to define a 'template' for the output
- *
- * 3) Inherited properties from PHP Exception Class:
- *
- * protected $message
- * protected $code
- * protected $line
- * protected $file
- * private $trace
- *
- * 4) Inherited methods from PHP Exception Class:
- *
- * __clone
- * __construct
- * getMessage
- * getCode
- * getFile
- * getLine
- * getTraceSafe
- * getTraceSafeAsString
- * __toString
- *
- * 5) Usage example
- *
- * <code>
- * require_once 'PEAR/Exception.php';
- *
- * class Test {
- * function foo() {
- * throw new PEAR_Exception('Error Message', ERROR_CODE);
- * }
- * }
- *
- * function myLogger($pear_exception) {
- * echo $pear_exception->getMessage();
- * }
- * // each time a exception is thrown the 'myLogger' will be called
- * // (its use is completely optional)
- * PEAR_Exception::addObserver('myLogger');
- * $test = new Test;
- * try {
- * $test->foo();
- * } catch (PEAR_Exception $e) {
- * print $e;
- * }
- * </code>
- *
- * @category pear
- * @package PEAR
- * @author Tomas V.V.Cox <cox@idecnet.com>
- * @author Hans Lellelid <hans@velum.net>
- * @author Bertrand Mansion <bmansion@mamasam.com>
- * @author Greg Beaver <cellog@php.net>
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.8.0
- * @link http://pear.php.net/package/PEAR
- * @since Class available since Release 1.3.3
- *
- */
-class PEAR_Exception extends Exception
-{
- const OBSERVER_PRINT = -2;
- const OBSERVER_TRIGGER = -4;
- const OBSERVER_DIE = -8;
- protected $cause;
- private static $_observers = array();
- private static $_uniqueid = 0;
- private $_trace;
-
- /**
- * Supported signatures:
- * - PEAR_Exception(string $message);
- * - PEAR_Exception(string $message, int $code);
- * - PEAR_Exception(string $message, Exception $cause);
- * - PEAR_Exception(string $message, Exception $cause, int $code);
- * - PEAR_Exception(string $message, PEAR_Error $cause);
- * - PEAR_Exception(string $message, PEAR_Error $cause, int $code);
- * - PEAR_Exception(string $message, array $causes);
- * - PEAR_Exception(string $message, array $causes, int $code);
- * @param string exception message
- * @param int|Exception|PEAR_Error|array|null exception cause
- * @param int|null exception code or null
- */
- public function __construct($message, $p2 = null, $p3 = null)
- {
- if (is_int($p2)) {
- $code = $p2;
- $this->cause = null;
- } elseif (is_object($p2) || is_array($p2)) {
- // using is_object allows both Exception and PEAR_Error
- if (is_object($p2) && !($p2 instanceof Exception)) {
- if (!class_exists('PEAR_Error') || !($p2 instanceof PEAR_Error)) {
- throw new PEAR_Exception('exception cause must be Exception, ' .
- 'array, or PEAR_Error');
- }
- }
- $code = $p3;
- if (is_array($p2) && isset($p2['message'])) {
- // fix potential problem of passing in a single warning
- $p2 = array($p2);
- }
- $this->cause = $p2;
- } else {
- $code = null;
- $this->cause = null;
- }
- parent::__construct($message, $code);
- $this->signal();
- }
-
- /**
- * @param mixed $callback - A valid php callback, see php func is_callable()
- * - A PEAR_Exception::OBSERVER_* constant
- * - An array(const PEAR_Exception::OBSERVER_*,
- * mixed $options)
- * @param string $label The name of the observer. Use this if you want
- * to remove it later with removeObserver()
- */
- public static function addObserver($callback, $label = 'default')
- {
- self::$_observers[$label] = $callback;
- }
-
- public static function removeObserver($label = 'default')
- {
- unset(self::$_observers[$label]);
- }
-
- /**
- * @return int unique identifier for an observer
- */
- public static function getUniqueId()
- {
- return self::$_uniqueid++;
- }
-
- private function signal()
- {
- foreach (self::$_observers as $func) {
- if (is_callable($func)) {
- call_user_func($func, $this);
- continue;
- }
- settype($func, 'array');
- switch ($func[0]) {
- case self::OBSERVER_PRINT :
- $f = (isset($func[1])) ? $func[1] : '%s';
- printf($f, $this->getMessage());
- break;
- case self::OBSERVER_TRIGGER :
- $f = (isset($func[1])) ? $func[1] : E_USER_NOTICE;
- trigger_error($this->getMessage(), $f);
- break;
- case self::OBSERVER_DIE :
- $f = (isset($func[1])) ? $func[1] : '%s';
- die(printf($f, $this->getMessage()));
- break;
- default:
- trigger_error('invalid observer type', E_USER_WARNING);
- }
- }
- }
-
- /**
- * Return specific error information that can be used for more detailed
- * error messages or translation.
- *
- * This method may be overridden in child exception classes in order
- * to add functionality not present in PEAR_Exception and is a placeholder
- * to define API
- *
- * The returned array must be an associative array of parameter => value like so:
- * <pre>
- * array('name' => $name, 'context' => array(...))
- * </pre>
- * @return array
- */
- public function getErrorData()
- {
- return array();
- }
-
- /**
- * Returns the exception that caused this exception to be thrown
- * @access public
- * @return Exception|array The context of the exception
- */
- public function getCause()
- {
- return $this->cause;
- }
-
- /**
- * Function must be public to call on caused exceptions
- * @param array
- */
- public function getCauseMessage(&$causes)
- {
- $trace = $this->getTraceSafe();
- $cause = array('class' => get_class($this),
- 'message' => $this->message,
- 'file' => 'unknown',
- 'line' => 'unknown');
- if (isset($trace[0])) {
- if (isset($trace[0]['file'])) {
- $cause['file'] = $trace[0]['file'];
- $cause['line'] = $trace[0]['line'];
- }
- }
- $causes[] = $cause;
- if ($this->cause instanceof PEAR_Exception) {
- $this->cause->getCauseMessage($causes);
- } elseif ($this->cause instanceof Exception) {
- $causes[] = array('class' => get_class($this->cause),
- 'message' => $this->cause->getMessage(),
- 'file' => $this->cause->getFile(),
- 'line' => $this->cause->getLine());
- } elseif (class_exists('PEAR_Error') && $this->cause instanceof PEAR_Error) {
- $causes[] = array('class' => get_class($this->cause),
- 'message' => $this->cause->getMessage(),
- 'file' => 'unknown',
- 'line' => 'unknown');
- } elseif (is_array($this->cause)) {
- foreach ($this->cause as $cause) {
- if ($cause instanceof PEAR_Exception) {
- $cause->getCauseMessage($causes);
- } elseif ($cause instanceof Exception) {
- $causes[] = array('class' => get_class($cause),
- 'message' => $cause->getMessage(),
- 'file' => $cause->getFile(),
- 'line' => $cause->getLine());
- } elseif (class_exists('PEAR_Error') && $cause instanceof PEAR_Error) {
- $causes[] = array('class' => get_class($cause),
- 'message' => $cause->getMessage(),
- 'file' => 'unknown',
- 'line' => 'unknown');
- } elseif (is_array($cause) && isset($cause['message'])) {
- // PEAR_ErrorStack warning
- $causes[] = array(
- 'class' => $cause['package'],
- 'message' => $cause['message'],
- 'file' => isset($cause['context']['file']) ?
- $cause['context']['file'] :
- 'unknown',
- 'line' => isset($cause['context']['line']) ?
- $cause['context']['line'] :
- 'unknown',
- );
- }
- }
- }
- }
-
- public function getTraceSafe()
- {
- if (!isset($this->_trace)) {
- $this->_trace = $this->getTrace();
- if (empty($this->_trace)) {
- $backtrace = debug_backtrace();
- $this->_trace = array($backtrace[count($backtrace)-1]);
- }
- }
- return $this->_trace;
- }
-
- public function getErrorClass()
- {
- $trace = $this->getTraceSafe();
- return $trace[0]['class'];
- }
-
- public function getErrorMethod()
- {
- $trace = $this->getTraceSafe();
- return $trace[0]['function'];
- }
-
- public function __toString()
- {
- if (isset($_SERVER['REQUEST_URI'])) {
- return $this->toHtml();
- }
- return $this->toText();
- }
-
- public function toHtml()
- {
- $trace = $this->getTraceSafe();
- $causes = array();
- $this->getCauseMessage($causes);
- $html = '<table border="1" cellspacing="0">' . "\n";
- foreach ($causes as $i => $cause) {
- $html .= '<tr><td colspan="3" bgcolor="#ff9999">'
- . str_repeat('-', $i) . ' <b>' . $cause['class'] . '</b>: '
- . htmlspecialchars($cause['message']) . ' in <b>' . $cause['file'] . '</b> '
- . 'on line <b>' . $cause['line'] . '</b>'
- . "</td></tr>\n";
- }
- $html .= '<tr><td colspan="3" bgcolor="#aaaaaa" align="center"><b>Exception trace</b></td></tr>' . "\n"
- . '<tr><td align="center" bgcolor="#cccccc" width="20"><b>#</b></td>'
- . '<td align="center" bgcolor="#cccccc"><b>Function</b></td>'
- . '<td align="center" bgcolor="#cccccc"><b>Location</b></td></tr>' . "\n";
-
- foreach ($trace as $k => $v) {
- $html .= '<tr><td align="center">' . $k . '</td>'
- . '<td>';
- if (!empty($v['class'])) {
- $html .= $v['class'] . $v['type'];
- }
- $html .= $v['function'];
- $args = array();
- if (!empty($v['args'])) {
- foreach ($v['args'] as $arg) {
- if (is_null($arg)) $args[] = 'null';
- elseif (is_array($arg)) $args[] = 'Array';
- elseif (is_object($arg)) $args[] = 'Object('.get_class($arg).')';
- elseif (is_bool($arg)) $args[] = $arg ? 'true' : 'false';
- elseif (is_int($arg) || is_double($arg)) $args[] = $arg;
- else {
- $arg = (string)$arg;
- $str = htmlspecialchars(substr($arg, 0, 16));
- if (strlen($arg) > 16) $str .= '…';
- $args[] = "'" . $str . "'";
- }
- }
- }
- $html .= '(' . implode(', ',$args) . ')'
- . '</td>'
- . '<td>' . (isset($v['file']) ? $v['file'] : 'unknown')
- . ':' . (isset($v['line']) ? $v['line'] : 'unknown')
- . '</td></tr>' . "\n";
- }
- $html .= '<tr><td align="center">' . ($k+1) . '</td>'
- . '<td>{main}</td>'
- . '<td> </td></tr>' . "\n"
- . '</table>';
- return $html;
- }
-
- public function toText()
- {
- $causes = array();
- $this->getCauseMessage($causes);
- $causeMsg = '';
- foreach ($causes as $i => $cause) {
- $causeMsg .= str_repeat(' ', $i) . $cause['class'] . ': '
- . $cause['message'] . ' in ' . $cause['file']
- . ' on line ' . $cause['line'] . "\n";
- }
- return $causeMsg . $this->getTraceAsString();
- }
-}
-
-?> +// }}} +/** + * Error Stack Implementation + * + * This is an incredibly simple implementation of a very complex error handling + * facility. It contains the ability + * to track multiple errors from multiple packages simultaneously. In addition, + * it can track errors of many levels, save data along with the error, context + * information such as the exact file, line number, class and function that + * generated the error, and if necessary, it can raise a traditional PEAR_Error. + * It has built-in support for PEAR::Log, to log errors as they occur + * + * Since version 0.2alpha, it is also possible to selectively ignore errors, + * through the use of an error callback, see {@link pushCallback()} + * + * Since version 0.3alpha, it is possible to specify the exception class + * returned from {@link push()} + * + * Since version PEAR1.3.2, ErrorStack no longer instantiates an exception class. This can + * still be done quite handily in an error callback or by manipulating the returned array + * @category Debugging + * @package PEAR_ErrorStack + * @author Greg Beaver <cellog@php.net> + * @copyright 2004-2008 Greg Beaver + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: ErrorStack.php 276383 2009-02-24 23:39:37Z dufuz $ + * @link http://pear.php.net/package/PEAR_ErrorStack + */ + +/** + * Singleton storage + * + * Format: + * <pre> + * array( + * 'package1' => PEAR_ErrorStack object, + * 'package2' => PEAR_ErrorStack object, + * ... + * ) + * </pre> + * @access private + * @global array $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'] + */ +$GLOBALS['_PEAR_ERRORSTACK_SINGLETON'] = array(); + +/** + * Global error callback (default) + * + * This is only used if set to non-false. * is the default callback for + * all packages, whereas specific packages may set a default callback + * for all instances, regardless of whether they are a singleton or not. + * + * To exclude non-singletons, only set the local callback for the singleton + * @see PEAR_ErrorStack::setDefaultCallback() + * @access private + * @global array $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'] + */ +$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'] = array( + '*' => false, +); + +/** + * Global Log object (default) + * + * This is only used if set to non-false. Use to set a default log object for + * all stacks, regardless of instantiation order or location + * @see PEAR_ErrorStack::setDefaultLogger() + * @access private + * @global array $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] + */ +$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] = false; + +/** + * Global Overriding Callback + * + * This callback will override any error callbacks that specific loggers have set. + * Use with EXTREME caution + * @see PEAR_ErrorStack::staticPushCallback() + * @access private + * @global array $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] + */ +$GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'] = array(); + +/**#@+ + * One of four possible return values from the error Callback + * @see PEAR_ErrorStack::_errorCallback() + */ +/** + * If this is returned, then the error will be both pushed onto the stack + * and logged. + */ +define('PEAR_ERRORSTACK_PUSHANDLOG', 1); +/** + * If this is returned, then the error will only be pushed onto the stack, + * and not logged. + */ +define('PEAR_ERRORSTACK_PUSH', 2); +/** + * If this is returned, then the error will only be logged, but not pushed + * onto the error stack. + */ +define('PEAR_ERRORSTACK_LOG', 3); +/** + * If this is returned, then the error is completely ignored. + */ +define('PEAR_ERRORSTACK_IGNORE', 4); +/** + * If this is returned, then the error is logged and die() is called. + */ +define('PEAR_ERRORSTACK_DIE', 5); +/**#@-*/ + +/** + * Error code for an attempt to instantiate a non-class as a PEAR_ErrorStack in + * the singleton method. + */ +define('PEAR_ERRORSTACK_ERR_NONCLASS', 1); + +/** + * Error code for an attempt to pass an object into {@link PEAR_ErrorStack::getMessage()} + * that has no __toString() method + */ +define('PEAR_ERRORSTACK_ERR_OBJTOSTRING', 2); +/** + * Error Stack Implementation + * + * Usage: + * <code> + * // global error stack + * $global_stack = &PEAR_ErrorStack::singleton('MyPackage'); + * // local error stack + * $local_stack = new PEAR_ErrorStack('MyPackage'); + * </code> + * @author Greg Beaver <cellog@php.net> + * @version 1.9.0 + * @package PEAR_ErrorStack + * @category Debugging + * @copyright 2004-2008 Greg Beaver + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: ErrorStack.php 276383 2009-02-24 23:39:37Z dufuz $ + * @link http://pear.php.net/package/PEAR_ErrorStack + */ +class PEAR_ErrorStack { + /** + * Errors are stored in the order that they are pushed on the stack. + * @since 0.4alpha Errors are no longer organized by error level. + * This renders pop() nearly unusable, and levels could be more easily + * handled in a callback anyway + * @var array + * @access private + */ + var $_errors = array(); + + /** + * Storage of errors by level. + * + * Allows easy retrieval and deletion of only errors from a particular level + * @since PEAR 1.4.0dev + * @var array + * @access private + */ + var $_errorsByLevel = array(); + + /** + * Package name this error stack represents + * @var string + * @access protected + */ + var $_package; + + /** + * Determines whether a PEAR_Error is thrown upon every error addition + * @var boolean + * @access private + */ + var $_compat = false; + + /** + * If set to a valid callback, this will be used to generate the error + * message from the error code, otherwise the message passed in will be + * used + * @var false|string|array + * @access private + */ + var $_msgCallback = false; + + /** + * If set to a valid callback, this will be used to generate the error + * context for an error. For PHP-related errors, this will be a file + * and line number as retrieved from debug_backtrace(), but can be + * customized for other purposes. The error might actually be in a separate + * configuration file, or in a database query. + * @var false|string|array + * @access protected + */ + var $_contextCallback = false; + + /** + * If set to a valid callback, this will be called every time an error + * is pushed onto the stack. The return value will be used to determine + * whether to allow an error to be pushed or logged. + * + * The return value must be one an PEAR_ERRORSTACK_* constant + * @see PEAR_ERRORSTACK_PUSHANDLOG, PEAR_ERRORSTACK_PUSH, PEAR_ERRORSTACK_LOG + * @var false|string|array + * @access protected + */ + var $_errorCallback = array(); + + /** + * PEAR::Log object for logging errors + * @var false|Log + * @access protected + */ + var $_logger = false; + + /** + * Error messages - designed to be overridden + * @var array + * @abstract + */ + var $_errorMsgs = array(); + + /** + * Set up a new error stack + * + * @param string $package name of the package this error stack represents + * @param callback $msgCallback callback used for error message generation + * @param callback $contextCallback callback used for context generation, + * defaults to {@link getFileLine()} + * @param boolean $throwPEAR_Error + */ + function PEAR_ErrorStack($package, $msgCallback = false, $contextCallback = false, + $throwPEAR_Error = false) + { + $this->_package = $package; + $this->setMessageCallback($msgCallback); + $this->setContextCallback($contextCallback); + $this->_compat = $throwPEAR_Error; + } + + /** + * Return a single error stack for this package. + * + * Note that all parameters are ignored if the stack for package $package + * has already been instantiated + * @param string $package name of the package this error stack represents + * @param callback $msgCallback callback used for error message generation + * @param callback $contextCallback callback used for context generation, + * defaults to {@link getFileLine()} + * @param boolean $throwPEAR_Error + * @param string $stackClass class to instantiate + * @static + * @return PEAR_ErrorStack + */ + function &singleton($package, $msgCallback = false, $contextCallback = false, + $throwPEAR_Error = false, $stackClass = 'PEAR_ErrorStack') + { + if (isset($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package])) { + return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]; + } + if (!class_exists($stackClass)) { + if (function_exists('debug_backtrace')) { + $trace = debug_backtrace(); + } + PEAR_ErrorStack::staticPush('PEAR_ErrorStack', PEAR_ERRORSTACK_ERR_NONCLASS, + 'exception', array('stackclass' => $stackClass), + 'stack class "%stackclass%" is not a valid class name (should be like PEAR_ErrorStack)', + false, $trace); + } + $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package] = + new $stackClass($package, $msgCallback, $contextCallback, $throwPEAR_Error); + + return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]; + } + + /** + * Internal error handler for PEAR_ErrorStack class + * + * Dies if the error is an exception (and would have died anyway) + * @access private + */ + function _handleError($err) + { + if ($err['level'] == 'exception') { + $message = $err['message']; + if (isset($_SERVER['REQUEST_URI'])) { + echo '<br />'; + } else { + echo "\n"; + } + var_dump($err['context']); + die($message); + } + } + + /** + * Set up a PEAR::Log object for all error stacks that don't have one + * @param Log $log + * @static + */ + function setDefaultLogger(&$log) + { + if (is_object($log) && method_exists($log, 'log') ) { + $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] = &$log; + } elseif (is_callable($log)) { + $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] = &$log; + } + } + + /** + * Set up a PEAR::Log object for this error stack + * @param Log $log + */ + function setLogger(&$log) + { + if (is_object($log) && method_exists($log, 'log') ) { + $this->_logger = &$log; + } elseif (is_callable($log)) { + $this->_logger = &$log; + } + } + + /** + * Set an error code => error message mapping callback + * + * This method sets the callback that can be used to generate error + * messages for any instance + * @param array|string Callback function/method + */ + function setMessageCallback($msgCallback) + { + if (!$msgCallback) { + $this->_msgCallback = array(&$this, 'getErrorMessage'); + } else { + if (is_callable($msgCallback)) { + $this->_msgCallback = $msgCallback; + } + } + } + + /** + * Get an error code => error message mapping callback + * + * This method returns the current callback that can be used to generate error + * messages + * @return array|string|false Callback function/method or false if none + */ + function getMessageCallback() + { + return $this->_msgCallback; + } + + /** + * Sets a default callback to be used by all error stacks + * + * This method sets the callback that can be used to generate error + * messages for a singleton + * @param array|string Callback function/method + * @param string Package name, or false for all packages + * @static + */ + function setDefaultCallback($callback = false, $package = false) + { + if (!is_callable($callback)) { + $callback = false; + } + $package = $package ? $package : '*'; + $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'][$package] = $callback; + } + + /** + * Set a callback that generates context information (location of error) for an error stack + * + * This method sets the callback that can be used to generate context + * information for an error. Passing in NULL will disable context generation + * and remove the expensive call to debug_backtrace() + * @param array|string|null Callback function/method + */ + function setContextCallback($contextCallback) + { + if ($contextCallback === null) { + return $this->_contextCallback = false; + } + if (!$contextCallback) { + $this->_contextCallback = array(&$this, 'getFileLine'); + } else { + if (is_callable($contextCallback)) { + $this->_contextCallback = $contextCallback; + } + } + } + + /** + * Set an error Callback + * If set to a valid callback, this will be called every time an error + * is pushed onto the stack. The return value will be used to determine + * whether to allow an error to be pushed or logged. + * + * The return value must be one of the ERRORSTACK_* constants. + * + * This functionality can be used to emulate PEAR's pushErrorHandling, and + * the PEAR_ERROR_CALLBACK mode, without affecting the integrity of + * the error stack or logging + * @see PEAR_ERRORSTACK_PUSHANDLOG, PEAR_ERRORSTACK_PUSH, PEAR_ERRORSTACK_LOG + * @see popCallback() + * @param string|array $cb + */ + function pushCallback($cb) + { + array_push($this->_errorCallback, $cb); + } + + /** + * Remove a callback from the error callback stack + * @see pushCallback() + * @return array|string|false + */ + function popCallback() + { + if (!count($this->_errorCallback)) { + return false; + } + return array_pop($this->_errorCallback); + } + + /** + * Set a temporary overriding error callback for every package error stack + * + * Use this to temporarily disable all existing callbacks (can be used + * to emulate the @ operator, for instance) + * @see PEAR_ERRORSTACK_PUSHANDLOG, PEAR_ERRORSTACK_PUSH, PEAR_ERRORSTACK_LOG + * @see staticPopCallback(), pushCallback() + * @param string|array $cb + * @static + */ + function staticPushCallback($cb) + { + array_push($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'], $cb); + } + + /** + * Remove a temporary overriding error callback + * @see staticPushCallback() + * @return array|string|false + * @static + */ + function staticPopCallback() + { + $ret = array_pop($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK']); + if (!is_array($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'])) { + $GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'] = array(); + } + return $ret; + } + + /** + * Add an error to the stack + * + * If the message generator exists, it is called with 2 parameters. + * - the current Error Stack object + * - an array that is in the same format as an error. Available indices + * are 'code', 'package', 'time', 'params', 'level', and 'context' + * + * Next, if the error should contain context information, this is + * handled by the context grabbing method. + * Finally, the error is pushed onto the proper error stack + * @param int $code Package-specific error code + * @param string $level Error level. This is NOT spell-checked + * @param array $params associative array of error parameters + * @param string $msg Error message, or a portion of it if the message + * is to be generated + * @param array $repackage If this error re-packages an error pushed by + * another package, place the array returned from + * {@link pop()} in this parameter + * @param array $backtrace Protected parameter: use this to pass in the + * {@link debug_backtrace()} that should be used + * to find error context + * @return PEAR_Error|array if compatibility mode is on, a PEAR_Error is also + * thrown. If a PEAR_Error is returned, the userinfo + * property is set to the following array: + * + * <code> + * array( + * 'code' => $code, + * 'params' => $params, + * 'package' => $this->_package, + * 'level' => $level, + * 'time' => time(), + * 'context' => $context, + * 'message' => $msg, + * //['repackage' => $err] repackaged error array/Exception class + * ); + * </code> + * + * Normally, the previous array is returned. + */ + function push($code, $level = 'error', $params = array(), $msg = false, + $repackage = false, $backtrace = false) + { + $context = false; + // grab error context + if ($this->_contextCallback) { + if (!$backtrace) { + $backtrace = debug_backtrace(); + } + $context = call_user_func($this->_contextCallback, $code, $params, $backtrace); + } + + // save error + $time = explode(' ', microtime()); + $time = $time[1] + $time[0]; + $err = array( + 'code' => $code, + 'params' => $params, + 'package' => $this->_package, + 'level' => $level, + 'time' => $time, + 'context' => $context, + 'message' => $msg, + ); + + if ($repackage) { + $err['repackage'] = $repackage; + } + + // set up the error message, if necessary + if ($this->_msgCallback) { + $msg = call_user_func_array($this->_msgCallback, + array(&$this, $err)); + $err['message'] = $msg; + } + $push = $log = true; + $die = false; + // try the overriding callback first + $callback = $this->staticPopCallback(); + if ($callback) { + $this->staticPushCallback($callback); + } + if (!is_callable($callback)) { + // try the local callback next + $callback = $this->popCallback(); + if (is_callable($callback)) { + $this->pushCallback($callback); + } else { + // try the default callback + $callback = isset($GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'][$this->_package]) ? + $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'][$this->_package] : + $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK']['*']; + } + } + if (is_callable($callback)) { + switch(call_user_func($callback, $err)){ + case PEAR_ERRORSTACK_IGNORE: + return $err; + break; + case PEAR_ERRORSTACK_PUSH: + $log = false; + break; + case PEAR_ERRORSTACK_LOG: + $push = false; + break; + case PEAR_ERRORSTACK_DIE: + $die = true; + break; + // anything else returned has the same effect as pushandlog + } + } + if ($push) { + array_unshift($this->_errors, $err); + if (!isset($this->_errorsByLevel[$err['level']])) { + $this->_errorsByLevel[$err['level']] = array(); + } + $this->_errorsByLevel[$err['level']][] = &$this->_errors[0]; + } + if ($log) { + if ($this->_logger || $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER']) { + $this->_log($err); + } + } + if ($die) { + die(); + } + if ($this->_compat && $push) { + return $this->raiseError($msg, $code, null, null, $err); + } + return $err; + } + + /** + * Static version of {@link push()} + * + * @param string $package Package name this error belongs to + * @param int $code Package-specific error code + * @param string $level Error level. This is NOT spell-checked + * @param array $params associative array of error parameters + * @param string $msg Error message, or a portion of it if the message + * is to be generated + * @param array $repackage If this error re-packages an error pushed by + * another package, place the array returned from + * {@link pop()} in this parameter + * @param array $backtrace Protected parameter: use this to pass in the + * {@link debug_backtrace()} that should be used + * to find error context + * @return PEAR_Error|array if compatibility mode is on, a PEAR_Error is also + * thrown. see docs for {@link push()} + * @static + */ + function staticPush($package, $code, $level = 'error', $params = array(), + $msg = false, $repackage = false, $backtrace = false) + { + $s = &PEAR_ErrorStack::singleton($package); + if ($s->_contextCallback) { + if (!$backtrace) { + if (function_exists('debug_backtrace')) { + $backtrace = debug_backtrace(); + } + } + } + return $s->push($code, $level, $params, $msg, $repackage, $backtrace); + } + + /** + * Log an error using PEAR::Log + * @param array $err Error array + * @param array $levels Error level => Log constant map + * @access protected + */ + function _log($err) + { + if ($this->_logger) { + $logger = &$this->_logger; + } else { + $logger = &$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER']; + } + if (is_a($logger, 'Log')) { + $levels = array( + 'exception' => PEAR_LOG_CRIT, + 'alert' => PEAR_LOG_ALERT, + 'critical' => PEAR_LOG_CRIT, + 'error' => PEAR_LOG_ERR, + 'warning' => PEAR_LOG_WARNING, + 'notice' => PEAR_LOG_NOTICE, + 'info' => PEAR_LOG_INFO, + 'debug' => PEAR_LOG_DEBUG); + if (isset($levels[$err['level']])) { + $level = $levels[$err['level']]; + } else { + $level = PEAR_LOG_INFO; + } + $logger->log($err['message'], $level, $err); + } else { // support non-standard logs + call_user_func($logger, $err); + } + } + + + /** + * Pop an error off of the error stack + * + * @return false|array + * @since 0.4alpha it is no longer possible to specify a specific error + * level to return - the last error pushed will be returned, instead + */ + function pop() + { + $err = @array_shift($this->_errors); + if (!is_null($err)) { + @array_pop($this->_errorsByLevel[$err['level']]); + if (!count($this->_errorsByLevel[$err['level']])) { + unset($this->_errorsByLevel[$err['level']]); + } + } + return $err; + } + + /** + * Pop an error off of the error stack, static method + * + * @param string package name + * @return boolean + * @since PEAR1.5.0a1 + */ + function staticPop($package) + { + if ($package) { + if (!isset($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package])) { + return false; + } + return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]->pop(); + } + } + + /** + * Determine whether there are any errors on the stack + * @param string|array Level name. Use to determine if any errors + * of level (string), or levels (array) have been pushed + * @return boolean + */ + function hasErrors($level = false) + { + if ($level) { + return isset($this->_errorsByLevel[$level]); + } + return count($this->_errors); + } + + /** + * Retrieve all errors since last purge + * + * @param boolean set in order to empty the error stack + * @param string level name, to return only errors of a particular severity + * @return array + */ + function getErrors($purge = false, $level = false) + { + if (!$purge) { + if ($level) { + if (!isset($this->_errorsByLevel[$level])) { + return array(); + } else { + return $this->_errorsByLevel[$level]; + } + } else { + return $this->_errors; + } + } + if ($level) { + $ret = $this->_errorsByLevel[$level]; + foreach ($this->_errorsByLevel[$level] as $i => $unused) { + // entries are references to the $_errors array + $this->_errorsByLevel[$level][$i] = false; + } + // array_filter removes all entries === false + $this->_errors = array_filter($this->_errors); + unset($this->_errorsByLevel[$level]); + return $ret; + } + $ret = $this->_errors; + $this->_errors = array(); + $this->_errorsByLevel = array(); + return $ret; + } + + /** + * Determine whether there are any errors on a single error stack, or on any error stack + * + * The optional parameter can be used to test the existence of any errors without the need of + * singleton instantiation + * @param string|false Package name to check for errors + * @param string Level name to check for a particular severity + * @return boolean + * @static + */ + function staticHasErrors($package = false, $level = false) + { + if ($package) { + if (!isset($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package])) { + return false; + } + return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]->hasErrors($level); + } + foreach ($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'] as $package => $obj) { + if ($obj->hasErrors($level)) { + return true; + } + } + return false; + } + + /** + * Get a list of all errors since last purge, organized by package + * @since PEAR 1.4.0dev BC break! $level is now in the place $merge used to be + * @param boolean $purge Set to purge the error stack of existing errors + * @param string $level Set to a level name in order to retrieve only errors of a particular level + * @param boolean $merge Set to return a flat array, not organized by package + * @param array $sortfunc Function used to sort a merged array - default + * sorts by time, and should be good for most cases + * @static + * @return array + */ + function staticGetErrors($purge = false, $level = false, $merge = false, + $sortfunc = array('PEAR_ErrorStack', '_sortErrors')) + { + $ret = array(); + if (!is_callable($sortfunc)) { + $sortfunc = array('PEAR_ErrorStack', '_sortErrors'); + } + foreach ($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'] as $package => $obj) { + $test = $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]->getErrors($purge, $level); + if ($test) { + if ($merge) { + $ret = array_merge($ret, $test); + } else { + $ret[$package] = $test; + } + } + } + if ($merge) { + usort($ret, $sortfunc); + } + return $ret; + } + + /** + * Error sorting function, sorts by time + * @access private + */ + function _sortErrors($a, $b) + { + if ($a['time'] == $b['time']) { + return 0; + } + if ($a['time'] < $b['time']) { + return 1; + } + return -1; + } + + /** + * Standard file/line number/function/class context callback + * + * This function uses a backtrace generated from {@link debug_backtrace()} + * and so will not work at all in PHP < 4.3.0. The frame should + * reference the frame that contains the source of the error. + * @return array|false either array('file' => file, 'line' => line, + * 'function' => function name, 'class' => class name) or + * if this doesn't work, then false + * @param unused + * @param integer backtrace frame. + * @param array Results of debug_backtrace() + * @static + */ + function getFileLine($code, $params, $backtrace = null) + { + if ($backtrace === null) { + return false; + } + $frame = 0; + $functionframe = 1; + if (!isset($backtrace[1])) { + $functionframe = 0; + } else { + while (isset($backtrace[$functionframe]['function']) && + $backtrace[$functionframe]['function'] == 'eval' && + isset($backtrace[$functionframe + 1])) { + $functionframe++; + } + } + if (isset($backtrace[$frame])) { + if (!isset($backtrace[$frame]['file'])) { + $frame++; + } + $funcbacktrace = $backtrace[$functionframe]; + $filebacktrace = $backtrace[$frame]; + $ret = array('file' => $filebacktrace['file'], + 'line' => $filebacktrace['line']); + // rearrange for eval'd code or create function errors + if (strpos($filebacktrace['file'], '(') && + preg_match(';^(.*?)\((\d+)\) : (.*?)\\z;', $filebacktrace['file'], + $matches)) { + $ret['file'] = $matches[1]; + $ret['line'] = $matches[2] + 0; + } + if (isset($funcbacktrace['function']) && isset($backtrace[1])) { + if ($funcbacktrace['function'] != 'eval') { + if ($funcbacktrace['function'] == '__lambda_func') { + $ret['function'] = 'create_function() code'; + } else { + $ret['function'] = $funcbacktrace['function']; + } + } + } + if (isset($funcbacktrace['class']) && isset($backtrace[1])) { + $ret['class'] = $funcbacktrace['class']; + } + return $ret; + } + return false; + } + + /** + * Standard error message generation callback + * + * This method may also be called by a custom error message generator + * to fill in template values from the params array, simply + * set the third parameter to the error message template string to use + * + * The special variable %__msg% is reserved: use it only to specify + * where a message passed in by the user should be placed in the template, + * like so: + * + * Error message: %msg% - internal error + * + * If the message passed like so: + * + * <code> + * $stack->push(ERROR_CODE, 'error', array(), 'server error 500'); + * </code> + * + * The returned error message will be "Error message: server error 500 - + * internal error" + * @param PEAR_ErrorStack + * @param array + * @param string|false Pre-generated error message template + * @static + * @return string + */ + function getErrorMessage(&$stack, $err, $template = false) + { + if ($template) { + $mainmsg = $template; + } else { + $mainmsg = $stack->getErrorMessageTemplate($err['code']); + } + $mainmsg = str_replace('%__msg%', $err['message'], $mainmsg); + if (is_array($err['params']) && count($err['params'])) { + foreach ($err['params'] as $name => $val) { + if (is_array($val)) { + // @ is needed in case $val is a multi-dimensional array + $val = @implode(', ', $val); + } + if (is_object($val)) { + if (method_exists($val, '__toString')) { + $val = $val->__toString(); + } else { + PEAR_ErrorStack::staticPush('PEAR_ErrorStack', PEAR_ERRORSTACK_ERR_OBJTOSTRING, + 'warning', array('obj' => get_class($val)), + 'object %obj% passed into getErrorMessage, but has no __toString() method'); + $val = 'Object'; + } + } + $mainmsg = str_replace('%' . $name . '%', $val, $mainmsg); + } + } + return $mainmsg; + } + + /** + * Standard Error Message Template generator from code + * @return string + */ + function getErrorMessageTemplate($code) + { + if (!isset($this->_errorMsgs[$code])) { + return '%__msg%'; + } + return $this->_errorMsgs[$code]; + } + + /** + * Set the Error Message Template array + * + * The array format must be: + * <pre> + * array(error code => 'message template',...) + * </pre> + * + * Error message parameters passed into {@link push()} will be used as input + * for the error message. If the template is 'message %foo% was %bar%', and the + * parameters are array('foo' => 'one', 'bar' => 'six'), the error message returned will + * be 'message one was six' + * @return string + */ + function setErrorMessageTemplate($template) + { + $this->_errorMsgs = $template; + } + + + /** + * emulate PEAR::raiseError() + * + * @return PEAR_Error + */ + function raiseError() + { + require_once 'PEAR.php'; + $args = func_get_args(); + return call_user_func_array(array('PEAR', 'raiseError'), $args); + } +} +$stack = &PEAR_ErrorStack::singleton('PEAR_ErrorStack'); +$stack->pushCallback(array('PEAR_ErrorStack', '_handleError')); +?> + +/* vim: set expandtab tabstop=4 shiftwidth=4 foldmethod=marker: */ +/** + * PEAR_Exception + * + * PHP versions 4 and 5 + * + * @category pear + * @package PEAR + * @author Tomas V. V. Cox <cox@idecnet.com> + * @author Hans Lellelid <hans@velum.net> + * @author Bertrand Mansion <bmansion@mamasam.com> + * @author Greg Beaver <cellog@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: Exception.php 276383 2009-02-24 23:39:37Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.3.3 + */ + + +/** + * Base PEAR_Exception Class + * + * 1) Features: + * + * - Nestable exceptions (throw new PEAR_Exception($msg, $prev_exception)) + * - Definable triggers, shot when exceptions occur + * - Pretty and informative error messages + * - Added more context info available (like class, method or cause) + * - cause can be a PEAR_Exception or an array of mixed + * PEAR_Exceptions/PEAR_ErrorStack warnings + * - callbacks for specific exception classes and their children + * + * 2) Ideas: + * + * - Maybe a way to define a 'template' for the output + * + * 3) Inherited properties from PHP Exception Class: + * + * protected $message + * protected $code + * protected $line + * protected $file + * private $trace + * + * 4) Inherited methods from PHP Exception Class: + * + * __clone + * __construct + * getMessage + * getCode + * getFile + * getLine + * getTraceSafe + * getTraceSafeAsString + * __toString + * + * 5) Usage example + * + * <code> + * require_once 'PEAR/Exception.php'; + * + * class Test { + * function foo() { + * throw new PEAR_Exception('Error Message', ERROR_CODE); + * } + * } + * + * function myLogger($pear_exception) { + * echo $pear_exception->getMessage(); + * } + * // each time a exception is thrown the 'myLogger' will be called + * // (its use is completely optional) + * PEAR_Exception::addObserver('myLogger'); + * $test = new Test; + * try { + * $test->foo(); + * } catch (PEAR_Exception $e) { + * print $e; + * } + * </code> + * + * @category pear + * @package PEAR + * @author Tomas V.V.Cox <cox@idecnet.com> + * @author Hans Lellelid <hans@velum.net> + * @author Bertrand Mansion <bmansion@mamasam.com> + * @author Greg Beaver <cellog@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.3.3 + * + */ +class PEAR_Exception extends Exception +{ + const OBSERVER_PRINT = -2; + const OBSERVER_TRIGGER = -4; + const OBSERVER_DIE = -8; + protected $cause; + private static $_observers = array(); + private static $_uniqueid = 0; + private $_trace; + + /** + * Supported signatures: + * - PEAR_Exception(string $message); + * - PEAR_Exception(string $message, int $code); + * - PEAR_Exception(string $message, Exception $cause); + * - PEAR_Exception(string $message, Exception $cause, int $code); + * - PEAR_Exception(string $message, PEAR_Error $cause); + * - PEAR_Exception(string $message, PEAR_Error $cause, int $code); + * - PEAR_Exception(string $message, array $causes); + * - PEAR_Exception(string $message, array $causes, int $code); + * @param string exception message + * @param int|Exception|PEAR_Error|array|null exception cause + * @param int|null exception code or null + */ + public function __construct($message, $p2 = null, $p3 = null) + { + if (is_int($p2)) { + $code = $p2; + $this->cause = null; + } elseif (is_object($p2) || is_array($p2)) { + // using is_object allows both Exception and PEAR_Error + if (is_object($p2) && !($p2 instanceof Exception)) { + if (!class_exists('PEAR_Error') || !($p2 instanceof PEAR_Error)) { + throw new PEAR_Exception('exception cause must be Exception, ' . + 'array, or PEAR_Error'); + } + } + $code = $p3; + if (is_array($p2) && isset($p2['message'])) { + // fix potential problem of passing in a single warning + $p2 = array($p2); + } + $this->cause = $p2; + } else { + $code = null; + $this->cause = null; + } + parent::__construct($message, $code); + $this->signal(); + } + + /** + * @param mixed $callback - A valid php callback, see php func is_callable() + * - A PEAR_Exception::OBSERVER_* constant + * - An array(const PEAR_Exception::OBSERVER_*, + * mixed $options) + * @param string $label The name of the observer. Use this if you want + * to remove it later with removeObserver() + */ + public static function addObserver($callback, $label = 'default') + { + self::$_observers[$label] = $callback; + } + + public static function removeObserver($label = 'default') + { + unset(self::$_observers[$label]); + } + + /** + * @return int unique identifier for an observer + */ + public static function getUniqueId() + { + return self::$_uniqueid++; + } + + private function signal() + { + foreach (self::$_observers as $func) { + if (is_callable($func)) { + call_user_func($func, $this); + continue; + } + settype($func, 'array'); + switch ($func[0]) { + case self::OBSERVER_PRINT : + $f = (isset($func[1])) ? $func[1] : '%s'; + printf($f, $this->getMessage()); + break; + case self::OBSERVER_TRIGGER : + $f = (isset($func[1])) ? $func[1] : E_USER_NOTICE; + trigger_error($this->getMessage(), $f); + break; + case self::OBSERVER_DIE : + $f = (isset($func[1])) ? $func[1] : '%s'; + die(printf($f, $this->getMessage())); + break; + default: + trigger_error('invalid observer type', E_USER_WARNING); + } + } + } + + /** + * Return specific error information that can be used for more detailed + * error messages or translation. + * + * This method may be overridden in child exception classes in order + * to add functionality not present in PEAR_Exception and is a placeholder + * to define API + * + * The returned array must be an associative array of parameter => value like so: + * <pre> + * array('name' => $name, 'context' => array(...)) + * </pre> + * @return array + */ + public function getErrorData() + { + return array(); + } + + /** + * Returns the exception that caused this exception to be thrown + * @access public + * @return Exception|array The context of the exception + */ + public function getCause() + { + return $this->cause; + } + + /** + * Function must be public to call on caused exceptions + * @param array + */ + public function getCauseMessage(&$causes) + { + $trace = $this->getTraceSafe(); + $cause = array('class' => get_class($this), + 'message' => $this->message, + 'file' => 'unknown', + 'line' => 'unknown'); + if (isset($trace[0])) { + if (isset($trace[0]['file'])) { + $cause['file'] = $trace[0]['file']; + $cause['line'] = $trace[0]['line']; + } + } + $causes[] = $cause; + if ($this->cause instanceof PEAR_Exception) { + $this->cause->getCauseMessage($causes); + } elseif ($this->cause instanceof Exception) { + $causes[] = array('class' => get_class($this->cause), + 'message' => $this->cause->getMessage(), + 'file' => $this->cause->getFile(), + 'line' => $this->cause->getLine()); + } elseif (class_exists('PEAR_Error') && $this->cause instanceof PEAR_Error) { + $causes[] = array('class' => get_class($this->cause), + 'message' => $this->cause->getMessage(), + 'file' => 'unknown', + 'line' => 'unknown'); + } elseif (is_array($this->cause)) { + foreach ($this->cause as $cause) { + if ($cause instanceof PEAR_Exception) { + $cause->getCauseMessage($causes); + } elseif ($cause instanceof Exception) { + $causes[] = array('class' => get_class($cause), + 'message' => $cause->getMessage(), + 'file' => $cause->getFile(), + 'line' => $cause->getLine()); + } elseif (class_exists('PEAR_Error') && $cause instanceof PEAR_Error) { + $causes[] = array('class' => get_class($cause), + 'message' => $cause->getMessage(), + 'file' => 'unknown', + 'line' => 'unknown'); + } elseif (is_array($cause) && isset($cause['message'])) { + // PEAR_ErrorStack warning + $causes[] = array( + 'class' => $cause['package'], + 'message' => $cause['message'], + 'file' => isset($cause['context']['file']) ? + $cause['context']['file'] : + 'unknown', + 'line' => isset($cause['context']['line']) ? + $cause['context']['line'] : + 'unknown', + ); + } + } + } + } + + public function getTraceSafe() + { + if (!isset($this->_trace)) { + $this->_trace = $this->getTrace(); + if (empty($this->_trace)) { + $backtrace = debug_backtrace(); + $this->_trace = array($backtrace[count($backtrace)-1]); + } + } + return $this->_trace; + } + + public function getErrorClass() + { + $trace = $this->getTraceSafe(); + return $trace[0]['class']; + } + + public function getErrorMethod() + { + $trace = $this->getTraceSafe(); + return $trace[0]['function']; + } + + public function __toString() + { + if (isset($_SERVER['REQUEST_URI'])) { + return $this->toHtml(); + } + return $this->toText(); + } + + public function toHtml() + { + $trace = $this->getTraceSafe(); + $causes = array(); + $this->getCauseMessage($causes); + $html = '<table border="1" cellspacing="0">' . "\n"; + foreach ($causes as $i => $cause) { + $html .= '<tr><td colspan="3" bgcolor="#ff9999">' + . str_repeat('-', $i) . ' <b>' . $cause['class'] . '</b>: ' + . htmlspecialchars($cause['message']) . ' in <b>' . $cause['file'] . '</b> ' + . 'on line <b>' . $cause['line'] . '</b>' + . "</td></tr>\n"; + } + $html .= '<tr><td colspan="3" bgcolor="#aaaaaa" align="center"><b>Exception trace</b></td></tr>' . "\n" + . '<tr><td align="center" bgcolor="#cccccc" width="20"><b>#</b></td>' + . '<td align="center" bgcolor="#cccccc"><b>Function</b></td>' + . '<td align="center" bgcolor="#cccccc"><b>Location</b></td></tr>' . "\n"; + + foreach ($trace as $k => $v) { + $html .= '<tr><td align="center">' . $k . '</td>' + . '<td>'; + if (!empty($v['class'])) { + $html .= $v['class'] . $v['type']; + } + $html .= $v['function']; + $args = array(); + if (!empty($v['args'])) { + foreach ($v['args'] as $arg) { + if (is_null($arg)) $args[] = 'null'; + elseif (is_array($arg)) $args[] = 'Array'; + elseif (is_object($arg)) $args[] = 'Object('.get_class($arg).')'; + elseif (is_bool($arg)) $args[] = $arg ? 'true' : 'false'; + elseif (is_int($arg) || is_double($arg)) $args[] = $arg; + else { + $arg = (string)$arg; + $str = htmlspecialchars(substr($arg, 0, 16)); + if (strlen($arg) > 16) $str .= '…'; + $args[] = "'" . $str . "'"; + } + } + } + $html .= '(' . implode(', ',$args) . ')' + . '</td>' + . '<td>' . (isset($v['file']) ? $v['file'] : 'unknown') + . ':' . (isset($v['line']) ? $v['line'] : 'unknown') + . '</td></tr>' . "\n"; + } + $html .= '<tr><td align="center">' . ($k+1) . '</td>' + . '<td>{main}</td>' + . '<td> </td></tr>' . "\n" + . '</table>'; + return $html; + } + + public function toText() + { + $causes = array(); + $this->getCauseMessage($causes); + $causeMsg = ''; + foreach ($causes as $i => $cause) { + $causeMsg .= str_repeat(' ', $i) . $cause['class'] . ': ' + . $cause['message'] . ' in ' . $cause['file'] + . ' on line ' . $cause['line'] . "\n"; + } + return $causeMsg . $this->getTraceAsString(); + } +} + +?> if ($skipmsg) { $a = &new $ec($code, $mode, $options, $userinfo); } else { $a = &new $ec($message, $code, $mode, $options, $userinfo); } -?> -/**
- * PEAR_Frontend, the singleton-based frontend for user input/output
- *
- * PHP versions 4 and 5
- *
- * @category pear
- * @package PEAR
- * @author Greg Beaver <cellog@php.net>
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version CVS: $Id: Frontend.php,v 1.18 2009/02/24 23:38:22 dufuz Exp $
- * @link http://pear.php.net/package/PEAR
- * @since File available since Release 1.4.0a1
- */
-
-/**
- * Include error handling
- */
-//require_once 'PEAR.php';
-
-/**
- * Which user interface class is being used.
- * @var string class name
- */
-$GLOBALS['_PEAR_FRONTEND_CLASS'] = 'PEAR_Frontend_CLI';
-
-/**
- * Instance of $_PEAR_Command_uiclass.
- * @var object
- */
-$GLOBALS['_PEAR_FRONTEND_SINGLETON'] = null;
-
-/**
- * Singleton-based frontend for PEAR user input/output
- *
- * @category pear
- * @package PEAR
- * @author Greg Beaver <cellog@php.net>
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.8.0
- * @link http://pear.php.net/package/PEAR
- * @since Class available since Release 1.4.0a1
- */
-class PEAR_Frontend extends PEAR
-{
- /**
- * Retrieve the frontend object
- * @return PEAR_Frontend_CLI|PEAR_Frontend_Web|PEAR_Frontend_Gtk
- * @static
- */
- function &singleton($type = null)
- {
- if ($type === null) {
- if (!isset($GLOBALS['_PEAR_FRONTEND_SINGLETON'])) {
- $a = false;
- return $a;
- }
- return $GLOBALS['_PEAR_FRONTEND_SINGLETON'];
- }
-
- $a = PEAR_Frontend::setFrontendClass($type);
- return $a;
- }
-
- /**
- * Set the frontend class that will be used by calls to {@link singleton()}
- *
- * Frontends are expected to conform to the PEAR naming standard of
- * _ => DIRECTORY_SEPARATOR (PEAR_Frontend_CLI is in PEAR/Frontend/CLI.php)
- * @param string $uiclass full class name
- * @return PEAR_Frontend
- * @static
- */
- function &setFrontendClass($uiclass)
- {
- if (is_object($GLOBALS['_PEAR_FRONTEND_SINGLETON']) &&
- is_a($GLOBALS['_PEAR_FRONTEND_SINGLETON'], $uiclass)) {
- return $GLOBALS['_PEAR_FRONTEND_SINGLETON'];
- }
-
- if (!class_exists($uiclass)) {
- $file = str_replace('_', '/', $uiclass) . '.php';
- if (PEAR_Frontend::isIncludeable($file)) {
- include_once $file;
- }
- }
-
- if (class_exists($uiclass)) {
- $obj = &new $uiclass;
- // quick test to see if this class implements a few of the most
- // important frontend methods
- if (is_a($obj, 'PEAR_Frontend')) {
- $GLOBALS['_PEAR_FRONTEND_SINGLETON'] = &$obj;
- $GLOBALS['_PEAR_FRONTEND_CLASS'] = $uiclass;
- return $obj;
- }
-
- $err = PEAR::raiseError("not a frontend class: $uiclass");
- return $err;
- }
-
- $err = PEAR::raiseError("no such class: $uiclass");
- return $err;
- }
-
- /**
- * Set the frontend class that will be used by calls to {@link singleton()}
- *
- * Frontends are expected to be a descendant of PEAR_Frontend
- * @param PEAR_Frontend
- * @return PEAR_Frontend
- * @static
- */
- function &setFrontendObject($uiobject)
- {
- if (is_object($GLOBALS['_PEAR_FRONTEND_SINGLETON']) &&
- is_a($GLOBALS['_PEAR_FRONTEND_SINGLETON'], get_class($uiobject))) {
- return $GLOBALS['_PEAR_FRONTEND_SINGLETON'];
- }
-
- if (!is_a($uiobject, 'PEAR_Frontend')) {
- $err = PEAR::raiseError('not a valid frontend class: (' .
- get_class($uiobject) . ')');
- return $err;
- }
-
- $GLOBALS['_PEAR_FRONTEND_SINGLETON'] = &$uiobject;
- $GLOBALS['_PEAR_FRONTEND_CLASS'] = get_class($uiobject);
- return $uiobject;
- }
-
- /**
- * @param string $path relative or absolute include path
- * @return boolean
- * @static
- */
- function isIncludeable($path)
- {
- if (file_exists($path) && is_readable($path)) {
- return true;
- }
-
- $fp = @fopen($path, 'r', true);
- if ($fp) {
- fclose($fp);
- return true;
- }
-
- return false;
- }
-
- /**
- * @param PEAR_Config
- */
- function setConfig(&$config)
- {
- }
-
- /**
- * This can be overridden to allow session-based temporary file management
- *
- * By default, all files are deleted at the end of a session. The web installer
- * needs to be able to sustain a list over many sessions in order to support
- * user interaction with install scripts
- */
- function addTempFile($file)
- {
- $GLOBALS['_PEAR_Common_tempfiles'][] = $file;
- }
-
- /**
- * Log an action
- *
- * @param string $msg the message to log
- * @param boolean $append_crlf
- * @return boolean true
- * @abstract
- */
- function log($msg, $append_crlf = true)
- {
- }
-
- /**
- * Run a post-installation script
- *
- * @param array $scripts array of post-install scripts
- * @abstract
- */
- function runPostinstallScripts(&$scripts)
- {
- }
-
- /**
- * Display human-friendly output formatted depending on the
- * $command parameter.
- *
- * This should be able to handle basic output data with no command
- * @param mixed $data data structure containing the information to display
- * @param string $command command from which this method was called
- * @abstract
- */
- function outputData($data, $command = '_default')
- {
- }
-
- /**
- * Display a modal form dialog and return the given input
- *
- * A frontend that requires multiple requests to retrieve and process
- * data must take these needs into account, and implement the request
- * handling code.
- * @param string $command command from which this method was called
- * @param array $prompts associative array. keys are the input field names
- * and values are the description
- * @param array $types array of input field types (text, password,
- * etc.) keys have to be the same like in $prompts
- * @param array $defaults array of default values. again keys have
- * to be the same like in $prompts. Do not depend
- * on a default value being set.
- * @return array input sent by the user
- * @abstract
- */
- function userDialog($command, $prompts, $types = array(), $defaults = array())
- {
- }
-} +?> +/** + * PEAR_Frontend, the singleton-based frontend for user input/output + * + * PHP versions 4 and 5 + * + * @category pear + * @package PEAR + * @author Greg Beaver <cellog@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: Frontend.php 276383 2009-02-24 23:39:37Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ + +/** + * Include error handling + */ +//require_once 'PEAR.php'; + +/** + * Which user interface class is being used. + * @var string class name + */ +$GLOBALS['_PEAR_FRONTEND_CLASS'] = 'PEAR_Frontend_CLI'; + +/** + * Instance of $_PEAR_Command_uiclass. + * @var object + */ +$GLOBALS['_PEAR_FRONTEND_SINGLETON'] = null; + +/** + * Singleton-based frontend for PEAR user input/output + * + * @category pear + * @package PEAR + * @author Greg Beaver <cellog@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_Frontend extends PEAR +{ + /** + * Retrieve the frontend object + * @return PEAR_Frontend_CLI|PEAR_Frontend_Web|PEAR_Frontend_Gtk + * @static + */ + function &singleton($type = null) + { + if ($type === null) { + if (!isset($GLOBALS['_PEAR_FRONTEND_SINGLETON'])) { + $a = false; + return $a; + } + return $GLOBALS['_PEAR_FRONTEND_SINGLETON']; + } + + $a = PEAR_Frontend::setFrontendClass($type); + return $a; + } + + /** + * Set the frontend class that will be used by calls to {@link singleton()} + * + * Frontends are expected to conform to the PEAR naming standard of + * _ => DIRECTORY_SEPARATOR (PEAR_Frontend_CLI is in PEAR/Frontend/CLI.php) + * @param string $uiclass full class name + * @return PEAR_Frontend + * @static + */ + function &setFrontendClass($uiclass) + { + if (is_object($GLOBALS['_PEAR_FRONTEND_SINGLETON']) && + is_a($GLOBALS['_PEAR_FRONTEND_SINGLETON'], $uiclass)) { + return $GLOBALS['_PEAR_FRONTEND_SINGLETON']; + } + + if (!class_exists($uiclass)) { + $file = str_replace('_', '/', $uiclass) . '.php'; + if (PEAR_Frontend::isIncludeable($file)) { + include_once $file; + } + } + + if (class_exists($uiclass)) { + $obj = &new $uiclass; + // quick test to see if this class implements a few of the most + // important frontend methods + if (is_a($obj, 'PEAR_Frontend')) { + $GLOBALS['_PEAR_FRONTEND_SINGLETON'] = &$obj; + $GLOBALS['_PEAR_FRONTEND_CLASS'] = $uiclass; + return $obj; + } + + $err = PEAR::raiseError("not a frontend class: $uiclass"); + return $err; + } + + $err = PEAR::raiseError("no such class: $uiclass"); + return $err; + } + + /** + * Set the frontend class that will be used by calls to {@link singleton()} + * + * Frontends are expected to be a descendant of PEAR_Frontend + * @param PEAR_Frontend + * @return PEAR_Frontend + * @static + */ + function &setFrontendObject($uiobject) + { + if (is_object($GLOBALS['_PEAR_FRONTEND_SINGLETON']) && + is_a($GLOBALS['_PEAR_FRONTEND_SINGLETON'], get_class($uiobject))) { + return $GLOBALS['_PEAR_FRONTEND_SINGLETON']; + } + + if (!is_a($uiobject, 'PEAR_Frontend')) { + $err = PEAR::raiseError('not a valid frontend class: (' . + get_class($uiobject) . ')'); + return $err; + } + + $GLOBALS['_PEAR_FRONTEND_SINGLETON'] = &$uiobject; + $GLOBALS['_PEAR_FRONTEND_CLASS'] = get_class($uiobject); + return $uiobject; + } + + /** + * @param string $path relative or absolute include path + * @return boolean + * @static + */ + function isIncludeable($path) + { + if (file_exists($path) && is_readable($path)) { + return true; + } + + $fp = @fopen($path, 'r', true); + if ($fp) { + fclose($fp); + return true; + } + + return false; + } + + /** + * @param PEAR_Config + */ + function setConfig(&$config) + { + } + + /** + * This can be overridden to allow session-based temporary file management + * + * By default, all files are deleted at the end of a session. The web installer + * needs to be able to sustain a list over many sessions in order to support + * user interaction with install scripts + */ + function addTempFile($file) + { + $GLOBALS['_PEAR_Common_tempfiles'][] = $file; + } + + /** + * Log an action + * + * @param string $msg the message to log + * @param boolean $append_crlf + * @return boolean true + * @abstract + */ + function log($msg, $append_crlf = true) + { + } + + /** + * Run a post-installation script + * + * @param array $scripts array of post-install scripts + * @abstract + */ + function runPostinstallScripts(&$scripts) + { + } + + /** + * Display human-friendly output formatted depending on the + * $command parameter. + * + * This should be able to handle basic output data with no command + * @param mixed $data data structure containing the information to display + * @param string $command command from which this method was called + * @abstract + */ + function outputData($data, $command = '_default') + { + } + + /** + * Display a modal form dialog and return the given input + * + * A frontend that requires multiple requests to retrieve and process + * data must take these needs into account, and implement the request + * handling code. + * @param string $command command from which this method was called + * @param array $prompts associative array. keys are the input field names + * and values are the description + * @param array $types array of input field types (text, password, + * etc.) keys have to be the same like in $prompts + * @param array $defaults array of default values. again keys have + * to be the same like in $prompts. Do not depend + * on a default value being set. + * @return array input sent by the user + * @abstract + */ + function userDialog($command, $prompts, $types = array(), $defaults = array()) + { + } +} /** * PEAR_Installer * @@ -43558,7 +44088,7 @@ class PEAR_Frontend extends PEAR * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Installer.php,v 1.259 2009/04/09 00:55:07 dufuz Exp $ + * @version CVS: $Id: Installer.php 287446 2009-08-18 11:45:05Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 0.1 */ @@ -43582,7 +44112,7 @@ define('PEAR_INSTALLER_NOBINARY', -240); * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 0.1 */ @@ -44672,7 +45202,6 @@ class PEAR_Installer extends PEAR_Downloader * * @return array|PEAR_Error package info if successful */ - function install($pkgfile, $options = array()) { $this->_options = $options; @@ -44686,7 +45215,7 @@ class PEAR_Installer extends PEAR_Downloader } else { $descfile = $pkgfile; $tmpdir = ''; - $pkg = &$this->_parsePackageXml($descfile, $tmpdir); + $pkg = $this->_parsePackageXml($descfile, $tmpdir); if (PEAR::isError($pkg)) { return $pkg; } @@ -44940,11 +45469,7 @@ class PEAR_Installer extends PEAR_Downloader } $p = &$installregistry->getPackage($pkgname, $channel); - if (empty($options['register-only']) && $p) { - $dirtree = $p->getDirTree(); - } else { - $dirtree = false; - } + $dirtree = (empty($options['register-only']) && $p) ? $p->getDirTree() : false; $pkg->resetFilelist(); $pkg->setLastInstalledVersion($installregistry->packageInfo($pkg->getPackage(), @@ -45117,11 +45642,8 @@ class PEAR_Installer extends PEAR_Downloader } $copyto = $this->_prependPath($dest, $packagingroot); - if ($copyto != $dest) { - $this->log(1, "Installing '$dest' as '$copyto'"); - } else { - $this->log(1, "Installing '$dest'"); - } + $extra = $copyto != $dest ? " as '$copyto'" : ''; + $this->log(1, "Installing '$dest'$extra"); $copydir = dirname($copyto); // pretty much nothing happens if we are only registering the install @@ -45150,24 +45672,20 @@ class PEAR_Installer extends PEAR_Downloader } } + + $data = array( + 'role' => $role, + 'name' => $bn, + 'installed_as' => $dest, + 'php_api' => $ext['php_api'], + 'zend_mod_api' => $ext['zend_mod_api'], + 'zend_ext_api' => $ext['zend_ext_api'], + ); + if ($filelist->getPackageXmlVersion() == '1.0') { - $filelist->installedFile($bn, array( - 'role' => $role, - 'name' => $bn, - 'installed_as' => $dest, - 'php_api' => $ext['php_api'], - 'zend_mod_api' => $ext['zend_mod_api'], - 'zend_ext_api' => $ext['zend_ext_api'], - )); + $filelist->installedFile($bn, $data); } else { - $filelist->installedFile($bn, array('attribs' => array( - 'role' => $role, - 'name' => $bn, - 'installed_as' => $dest, - 'php_api' => $ext['php_api'], - 'zend_mod_api' => $ext['zend_mod_api'], - 'zend_ext_api' => $ext['zend_ext_api'], - ))); + $filelist->installedFile($bn, array('attribs' => $data)); } } } @@ -45194,11 +45712,8 @@ class PEAR_Installer extends PEAR_Downloader */ function uninstall($package, $options = array()) { - if (isset($options['installroot'])) { - $this->config->setInstallRoot($options['installroot']); - } else { - $this->config->setInstallRoot(''); - } + $installRoot = isset($options['installroot']) ? $options['installroot'] : ''; + $this->config->setInstallRoot($installRoot); $this->installroot = ''; $this->_registry = &$this->config->getRegistry(); @@ -45291,17 +45806,18 @@ class PEAR_Installer extends PEAR_Downloader } } else { $this->startFileTransaction(); - if ($dirtree = $pkg->getDirTree()) { - // attempt to delete empty directories - uksort($dirtree, array($this, '_sortDirs')); - foreach($dirtree as $dir => $notused) { - $this->addFileOperation('rmdir', array($dir)); - } - } else { + $dirtree = $pkg->getDirTree(); + if ($dirtree === false) { $this->configSet('default_channel', $savechannel); return $this->_registry->deletePackage($package, $channel); } + // attempt to delete empty directories + uksort($dirtree, array($this, '_sortDirs')); + foreach($dirtree as $dir => $notused) { + $this->addFileOperation('rmdir', array($dir)); + } + if (!$this->commitFileTransaction()) { $this->rollbackFileTransaction(); if (!isset($options['ignore-errors'])) { @@ -45380,7 +45896,7 @@ class PEAR_Installer extends PEAR_Downloader } // }}} -} +} /** * PEAR_PackageFile, package.xml parsing utility class * @@ -45391,7 +45907,7 @@ class PEAR_Installer extends PEAR_Downloader * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: PackageFile.php,v 1.48 2009/04/09 22:16:26 dufuz Exp $ + * @version CVS: $Id: PackageFile.php 286670 2009-08-02 14:16:06Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ @@ -45417,7 +45933,7 @@ define('PEAR_PACKAGEFILE_ERROR_INVALID_PACKAGEVERSION', 2); * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ @@ -45587,9 +46103,10 @@ class PEAR_PackageFile return $pf; } - if (!$pf->validate($state)) { + if (!$pf->validate($state)) {; if ($this->_config->get('verbose') > 0 - && $this->_logger && $pf->getValidationWarnings(false)) { + && $this->_logger && $pf->getValidationWarnings(false) + ) { foreach ($pf->getValidationWarnings(false) as $warning) { $this->_logger->log(0, 'ERROR: ' . $warning['message']); } @@ -45705,11 +46222,11 @@ class PEAR_PackageFile $ret = PEAR::raiseError("Could not get contents of package \"$file\"". '. Invalid tgz file.'); return $ret; - } else { - if (!count($content) && !@is_file($file)) { - $ret = PEAR::raiseError("could not open file \"$file\""); - return $ret; - } + } + + if (!count($content) && !@is_file($file)) { + $ret = PEAR::raiseError("could not open file \"$file\""); + return $ret; } $xml = null; @@ -45879,7 +46396,7 @@ class PEAR_PackageFile $info = PEAR::raiseError("Cannot open '$info' for parsing"); return $info; } -} +} /** * PEAR_Packager for generating releases * @@ -45892,7 +46409,7 @@ class PEAR_PackageFile * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Packager.php,v 1.75 2009/02/24 23:38:22 dufuz Exp $ + * @version CVS: $Id: Packager.php 286809 2009-08-04 15:10:26Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 0.1 */ @@ -45912,7 +46429,7 @@ require_once 'System.php'; * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 0.1 */ @@ -46044,6 +46561,12 @@ class PEAR_Packager extends PEAR_Common $this->log(1, 'Tag the released code with "pear cvstag ' . $main->getPackageFile() . '"'); $this->log(1, "(or set the CVS tag $cvstag by hand)"); + } elseif (file_exists("$pkgdir/.svn")) { + $svnversion = preg_replace('/[^a-z0-9]/i', '.', $pf->getVersion()); + $svntag = $pf->getName() . "-$svnversion"; + $this->log(1, 'Tag the released code with "pear svntag ' . + $main->getPackageFile() . '"'); + $this->log(1, "(or set the SVN tag $svntag by hand)"); } } else { // this branch is executed for single packagefile packaging $gen = &$pf->getDefaultGenerator(); @@ -46063,2363 +46586,2411 @@ class PEAR_Packager extends PEAR_Common $cvstag = "RELEASE_$cvsversion"; $this->log(1, "Tag the released code with `pear cvstag $pkgfile'"); $this->log(1, "(or set the CVS tag $cvstag by hand)"); + } elseif (file_exists("$pkgdir/.svn")) { + $svnversion = preg_replace('/[^a-z0-9]/i', '.', $pf->getVersion()); + $svntag = $pf->getName() . "-$svnversion"; + $this->log(1, "Tag the released code with `pear svntag $pkgfile'"); + $this->log(1, "(or set the SVN tag $svntag by hand)"); } } return $dest_package; } -} -/**
- * PEAR_Registry
- *
- * PHP versions 4 and 5
- *
- * @category pear
- * @package PEAR
- * @author Stig Bakken <ssb@php.net>
- * @author Tomas V. V. Cox <cox@idecnet.com>
- * @author Greg Beaver <cellog@php.net>
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version CVS: $Id: Registry.php,v 1.179 2009/04/10 19:42:18 dufuz Exp $
- * @link http://pear.php.net/package/PEAR
- * @since File available since Release 0.1
- */
-
-/**
- * for PEAR_Error
- */
-require_once 'PEAR.php';
-require_once 'PEAR/DependencyDB.php';
-
-define('PEAR_REGISTRY_ERROR_LOCK', -2);
-define('PEAR_REGISTRY_ERROR_FORMAT', -3);
-define('PEAR_REGISTRY_ERROR_FILE', -4);
-define('PEAR_REGISTRY_ERROR_CONFLICT', -5);
-define('PEAR_REGISTRY_ERROR_CHANNEL_FILE', -6);
-
-/**
- * Administration class used to maintain the installed package database.
- * @category pear
- * @package PEAR
- * @author Stig Bakken <ssb@php.net>
- * @author Tomas V. V. Cox <cox@idecnet.com>
- * @author Greg Beaver <cellog@php.net>
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.8.0
- * @link http://pear.php.net/package/PEAR
- * @since Class available since Release 1.4.0a1
- */
-class PEAR_Registry extends PEAR
-{
- /**
- * File containing all channel information.
- * @var string
- */
- var $channels = '';
-
- /** Directory where registry files are stored.
- * @var string
- */
- var $statedir = '';
-
- /** File where the file map is stored
- * @var string
- */
- var $filemap = '';
-
- /** Directory where registry files for channels are stored.
- * @var string
- */
- var $channelsdir = '';
-
- /** Name of file used for locking the registry
- * @var string
- */
- var $lockfile = '';
-
- /** File descriptor used during locking
- * @var resource
- */
- var $lock_fp = null;
-
- /** Mode used during locking
- * @var int
- */
- var $lock_mode = 0; // XXX UNUSED
-
- /** Cache of package information. Structure:
- * array(
- * 'package' => array('id' => ... ),
- * ... )
- * @var array
- */
- var $pkginfo_cache = array();
-
- /** Cache of file map. Structure:
- * array( '/path/to/file' => 'package', ... )
- * @var array
- */
- var $filemap_cache = array();
-
- /**
- * @var false|PEAR_ChannelFile
- */
- var $_pearChannel;
-
- /**
- * @var false|PEAR_ChannelFile
- */
- var $_peclChannel;
-
- /**
- * @var false|PEAR_ChannelFile
- */
- var $_docChannel;
-
- /**
- * @var PEAR_DependencyDB
- */
- var $_dependencyDB;
-
- /**
- * @var PEAR_Config
- */
- var $_config;
-
- /**
- * PEAR_Registry constructor.
- *
- * @param string (optional) PEAR install directory (for .php files)
- * @param PEAR_ChannelFile PEAR_ChannelFile object representing the PEAR channel, if
- * default values are not desired. Only used the very first time a PEAR
- * repository is initialized
- * @param PEAR_ChannelFile PEAR_ChannelFile object representing the PECL channel, if
- * default values are not desired. Only used the very first time a PEAR
- * repository is initialized
- *
- * @access public
- */
- function PEAR_Registry($pear_install_dir = PEAR_INSTALL_DIR, $pear_channel = false,
- $pecl_channel = false)
- {
- parent::PEAR();
- $this->setInstallDir($pear_install_dir);
- $this->_pearChannel = $pear_channel;
- $this->_peclChannel = $pecl_channel;
- $this->_config = false;
- }
-
- function setInstallDir($pear_install_dir = PEAR_INSTALL_DIR)
- {
- $ds = DIRECTORY_SEPARATOR;
- $this->install_dir = $pear_install_dir;
- $this->channelsdir = $pear_install_dir.$ds.'.channels';
- $this->statedir = $pear_install_dir.$ds.'.registry';
- $this->filemap = $pear_install_dir.$ds.'.filemap';
- $this->lockfile = $pear_install_dir.$ds.'.lock';
- }
-
- function hasWriteAccess()
- {
- if (!file_exists($this->install_dir)) {
- $dir = $this->install_dir;
- while ($dir && $dir != '.') {
- $olddir = $dir;
- $dir = dirname($dir);
- if ($dir != '.' && file_exists($dir)) {
- if (is_writeable($dir)) {
- return true;
- }
-
- return false;
- }
-
- if ($dir == $olddir) { // this can happen in safe mode
- return @is_writable($dir);
- }
- }
-
- return false;
- }
-
- return is_writeable($this->install_dir);
- }
-
- function setConfig(&$config, $resetInstallDir = true)
- {
- $this->_config = &$config;
- if ($resetInstallDir) {
- $this->setInstallDir($config->get('php_dir'));
- }
- }
-
- function _initializeChannelDirs()
- {
- static $running = false;
- if (!$running) {
- $running = true;
- $ds = DIRECTORY_SEPARATOR;
- if (!is_dir($this->channelsdir) ||
- !file_exists($this->channelsdir . $ds . 'pear.php.net.reg') ||
- !file_exists($this->channelsdir . $ds . 'pecl.php.net.reg') ||
- !file_exists($this->channelsdir . $ds . 'doc.php.net.reg') ||
- !file_exists($this->channelsdir . $ds . '__uri.reg')) {
- if (!file_exists($this->channelsdir . $ds . 'pear.php.net.reg')) {
- $pear_channel = $this->_pearChannel;
- if (!is_a($pear_channel, 'PEAR_ChannelFile') || !$pear_channel->validate()) {
- if (!class_exists('PEAR_ChannelFile')) {
- require_once 'PEAR/ChannelFile.php';
- }
-
- $pear_channel = new PEAR_ChannelFile;
- $pear_channel->setName('pear.php.net');
- $pear_channel->setAlias('pear');
- $pear_channel->setServer('pear.php.net');
- $pear_channel->setSummary('PHP Extension and Application Repository');
- $pear_channel->setDefaultPEARProtocols();
- $pear_channel->setBaseURL('REST1.0', 'http://pear.php.net/rest/');
- $pear_channel->setBaseURL('REST1.1', 'http://pear.php.net/rest/');
- } else {
- $pear_channel->setName('pear.php.net');
- $pear_channel->setAlias('pear');
- }
-
- $pear_channel->validate();
- $this->_addChannel($pear_channel);
- }
-
- if (!file_exists($this->channelsdir . $ds . 'pecl.php.net.reg')) {
- $pecl_channel = $this->_peclChannel;
- if (!is_a($pecl_channel, 'PEAR_ChannelFile') || !$pecl_channel->validate()) {
- if (!class_exists('PEAR_ChannelFile')) {
- require_once 'PEAR/ChannelFile.php';
- }
-
- $pecl_channel = new PEAR_ChannelFile;
- $pecl_channel->setName('pecl.php.net');
- $pecl_channel->setAlias('pecl');
- $pecl_channel->setServer('pecl.php.net');
- $pecl_channel->setSummary('PHP Extension Community Library');
- $pecl_channel->setDefaultPEARProtocols();
- $pecl_channel->setBaseURL('REST1.0', 'http://pecl.php.net/rest/');
- $pecl_channel->setBaseURL('REST1.1', 'http://pecl.php.net/rest/');
- $pecl_channel->setValidationPackage('PEAR_Validator_PECL', '1.0');
- } else {
- $pecl_channel->setName('pecl.php.net');
- $pecl_channel->setAlias('pecl');
- }
-
- $pecl_channel->validate();
- $this->_addChannel($pecl_channel);
- }
-
- if (!file_exists($this->channelsdir . $ds . 'doc.php.net.reg')) {
- $doc_channel = $this->_docChannel;
- if (!is_a($doc_channel, 'PEAR_ChannelFile') || !$doc_channel->validate()) {
- if (!class_exists('PEAR_ChannelFile')) {
- require_once 'PEAR/ChannelFile.php';
- }
-
- $doc_channel = new PEAR_ChannelFile;
- $doc_channel->setName('doc.php.net');
- $doc_channel->setAlias('phpdocs');
- $doc_channel->setServer('doc.php.net');
- $doc_channel->setSummary('PHP Documentation Team');
- $doc_channel->setDefaultPEARProtocols();
- $doc_channel->setBaseURL('REST1.0', 'http://doc.php.net/Chiara_PEAR_Server_REST/');
- $doc_channel->setBaseURL('REST1.1', 'http://doc.php.net/Chiara_PEAR_Server_REST/');
- } else {
- $doc_channel->setName('doc.php.net');
- $doc_channel->setAlias('doc');
- }
-
- $doc_channel->validate();
- $this->_addChannel($doc_channel);
- }
-
- if (!file_exists($this->channelsdir . $ds . '__uri.reg')) {
- if (!class_exists('PEAR_ChannelFile')) {
- require_once 'PEAR/ChannelFile.php';
- }
-
- $private = new PEAR_ChannelFile;
- $private->setName('__uri');
- $private->setDefaultPEARProtocols();
- $private->setBaseURL('REST1.0', '****');
- $private->setSummary('Pseudo-channel for static packages');
- $this->_addChannel($private);
- }
- $this->_rebuildFileMap();
- }
-
- $running = false;
- }
- }
-
- function _initializeDirs()
- {
- $ds = DIRECTORY_SEPARATOR;
- // XXX Compatibility code should be removed in the future
- // rename all registry files if any to lowercase
- if (!OS_WINDOWS && file_exists($this->statedir) && is_dir($this->statedir) &&
- $handle = opendir($this->statedir)) {
- $dest = $this->statedir . $ds;
- while (false !== ($file = readdir($handle))) {
- if (preg_match('/^.*[A-Z].*\.reg\\z/', $file)) {
- rename($dest . $file, $dest . strtolower($file));
- }
- }
- closedir($handle);
- }
-
- $this->_initializeChannelDirs();
- if (!file_exists($this->filemap)) {
- $this->_rebuildFileMap();
- }
- $this->_initializeDepDB();
- }
-
- function _initializeDepDB()
- {
- if (!isset($this->_dependencyDB)) {
- static $initializing = false;
- if (!$initializing) {
- $initializing = true;
- if (!$this->_config) { // never used?
- $file = OS_WINDOWS ? 'pear.ini' : '.pearrc';
- $this->_config = &new PEAR_Config($this->statedir . DIRECTORY_SEPARATOR .
- $file);
- $this->_config->setRegistry($this);
- $this->_config->set('php_dir', $this->install_dir);
- }
-
- $this->_dependencyDB = &PEAR_DependencyDB::singleton($this->_config);
- if (PEAR::isError($this->_dependencyDB)) {
- // attempt to recover by removing the dep db
- if (file_exists($this->_config->get('php_dir', null, 'pear.php.net') .
- DIRECTORY_SEPARATOR . '.depdb')) {
- @unlink($this->_config->get('php_dir', null, 'pear.php.net') .
- DIRECTORY_SEPARATOR . '.depdb');
- }
-
- $this->_dependencyDB = &PEAR_DependencyDB::singleton($this->_config);
- if (PEAR::isError($this->_dependencyDB)) {
- echo $this->_dependencyDB->getMessage();
- echo 'Unrecoverable error';
- exit(1);
- }
- }
-
- $initializing = false;
- }
- }
- }
-
- /**
- * PEAR_Registry destructor. Makes sure no locks are forgotten.
- *
- * @access private
- */
- function _PEAR_Registry()
- {
- parent::_PEAR();
- if (is_resource($this->lock_fp)) {
- $this->_unlock();
- }
- }
-
- /**
- * Make sure the directory where we keep registry files exists.
- *
- * @return bool TRUE if directory exists, FALSE if it could not be
- * created
- *
- * @access private
- */
- function _assertStateDir($channel = false)
- {
- if ($channel && $this->_getChannelFromAlias($channel) != 'pear.php.net') {
- return $this->_assertChannelStateDir($channel);
- }
-
- static $init = false;
- if (!file_exists($this->statedir)) {
- if (!$this->hasWriteAccess()) {
- return false;
- }
-
- require_once 'System.php';
- if (!System::mkdir(array('-p', $this->statedir))) {
- return $this->raiseError("could not create directory '{$this->statedir}'");
- }
- $init = true;
- } elseif (!is_dir($this->statedir)) {
- return $this->raiseError('Cannot create directory ' . $this->statedir . ', ' .
- 'it already exists and is not a directory');
- }
-
- $ds = DIRECTORY_SEPARATOR;
- if (!file_exists($this->channelsdir)) {
- if (!file_exists($this->channelsdir . $ds . 'pear.php.net.reg') ||
- !file_exists($this->channelsdir . $ds . 'pecl.php.net.reg') ||
- !file_exists($this->channelsdir . $ds . 'doc.php.net.reg') ||
- !file_exists($this->channelsdir . $ds . '__uri.reg')) {
- $init = true;
- }
- } elseif (!is_dir($this->channelsdir)) {
- return $this->raiseError('Cannot create directory ' . $this->channelsdir . ', ' .
- 'it already exists and is not a directory');
- }
-
- if ($init) {
- static $running = false;
- if (!$running) {
- $running = true;
- $this->_initializeDirs();
- $running = false;
- $init = false;
- }
- } else {
- $this->_initializeDepDB();
- }
-
- return true;
- }
-
- /**
- * Make sure the directory where we keep registry files exists for a non-standard channel.
- *
- * @param string channel name
- * @return bool TRUE if directory exists, FALSE if it could not be
- * created
- *
- * @access private
- */
- function _assertChannelStateDir($channel)
- {
- $ds = DIRECTORY_SEPARATOR;
- if (!$channel || $this->_getChannelFromAlias($channel) == 'pear.php.net') {
- if (!file_exists($this->channelsdir . $ds . 'pear.php.net.reg')) {
- $this->_initializeChannelDirs();
- }
- return $this->_assertStateDir($channel);
- }
-
- $channelDir = $this->_channelDirectoryName($channel);
- if (!is_dir($this->channelsdir) ||
- !file_exists($this->channelsdir . $ds . 'pear.php.net.reg')) {
- $this->_initializeChannelDirs();
- }
-
- if (!file_exists($channelDir)) {
- if (!$this->hasWriteAccess()) {
- return false;
- }
-
- require_once 'System.php';
- if (!System::mkdir(array('-p', $channelDir))) {
- return $this->raiseError("could not create directory '" . $channelDir .
- "'");
- }
- } elseif (!is_dir($channelDir)) {
- return $this->raiseError("could not create directory '" . $channelDir .
- "', already exists and is not a directory");
- }
-
- return true;
- }
-
- /**
- * Make sure the directory where we keep registry files for channels exists
- *
- * @return bool TRUE if directory exists, FALSE if it could not be
- * created
- *
- * @access private
- */
- function _assertChannelDir()
- {
- if (!file_exists($this->channelsdir)) {
- if (!$this->hasWriteAccess()) {
- return false;
- }
-
- require_once 'System.php';
- if (!System::mkdir(array('-p', $this->channelsdir))) {
- return $this->raiseError("could not create directory '{$this->channelsdir}'");
- }
- } elseif (!is_dir($this->channelsdir)) {
- return $this->raiseError("could not create directory '{$this->channelsdir}" .
- "', it already exists and is not a directory");
- }
-
- if (!file_exists($this->channelsdir . DIRECTORY_SEPARATOR . '.alias')) {
- if (!$this->hasWriteAccess()) {
- return false;
- }
-
- require_once 'System.php';
- if (!System::mkdir(array('-p', $this->channelsdir . DIRECTORY_SEPARATOR . '.alias'))) {
- return $this->raiseError("could not create directory '{$this->channelsdir}/.alias'");
- }
- } elseif (!is_dir($this->channelsdir . DIRECTORY_SEPARATOR . '.alias')) {
- return $this->raiseError("could not create directory '{$this->channelsdir}" .
- "/.alias', it already exists and is not a directory");
- }
-
- return true;
- }
-
- /**
- * Get the name of the file where data for a given package is stored.
- *
- * @param string channel name, or false if this is a PEAR package
- * @param string package name
- *
- * @return string registry file name
- *
- * @access public
- */
- function _packageFileName($package, $channel = false)
- {
- if ($channel && $this->_getChannelFromAlias($channel) != 'pear.php.net') {
- return $this->_channelDirectoryName($channel) . DIRECTORY_SEPARATOR .
- strtolower($package) . '.reg';
- }
-
- return $this->statedir . DIRECTORY_SEPARATOR . strtolower($package) . '.reg';
- }
-
- /**
- * Get the name of the file where data for a given channel is stored.
- * @param string channel name
- * @return string registry file name
- */
- function _channelFileName($channel, $noaliases = false)
- {
- if (!$noaliases) {
- if (file_exists($this->_getChannelAliasFileName($channel))) {
- $channel = implode('', file($this->_getChannelAliasFileName($channel)));
- }
- }
- return $this->channelsdir . DIRECTORY_SEPARATOR . str_replace('/', '_',
- strtolower($channel)) . '.reg';
- }
-
- /**
- * @param string
- * @return string
- */
- function _getChannelAliasFileName($alias)
- {
- return $this->channelsdir . DIRECTORY_SEPARATOR . '.alias' .
- DIRECTORY_SEPARATOR . str_replace('/', '_', strtolower($alias)) . '.txt';
- }
-
- /**
- * Get the name of a channel from its alias
- */
- function _getChannelFromAlias($channel)
- {
- if (!$this->_channelExists($channel)) {
- if ($channel == 'pear.php.net') {
- return 'pear.php.net';
- }
-
- if ($channel == 'pecl.php.net') {
- return 'pecl.php.net';
- }
-
- if ($channel == 'doc.php.net') {
- return 'doc.php.net';
- }
-
- if ($channel == '__uri') {
- return '__uri';
- }
-
- return false;
- }
-
- $channel = strtolower($channel);
- if (file_exists($this->_getChannelAliasFileName($channel))) {
- // translate an alias to an actual channel
- return implode('', file($this->_getChannelAliasFileName($channel)));
- }
-
- return $channel;
- }
-
- /**
- * Get the alias of a channel from its alias or its name
- */
- function _getAlias($channel)
- {
- if (!$this->_channelExists($channel)) {
- if ($channel == 'pear.php.net') {
- return 'pear';
- }
-
- if ($channel == 'pecl.php.net') {
- return 'pecl';
- }
-
- if ($channel == 'doc.php.net') {
- return 'phpdocs';
- }
-
- return false;
- }
-
- $channel = $this->_getChannel($channel);
- if (PEAR::isError($channel)) {
- return $channel;
- }
-
- return $channel->getAlias();
- }
-
- /**
- * Get the name of the file where data for a given package is stored.
- *
- * @param string channel name, or false if this is a PEAR package
- * @param string package name
- *
- * @return string registry file name
- *
- * @access public
- */
- function _channelDirectoryName($channel)
- {
- if (!$channel || $this->_getChannelFromAlias($channel) == 'pear.php.net') {
- return $this->statedir;
- }
-
- $ch = $this->_getChannelFromAlias($channel);
- if (!$ch) {
- $ch = $channel;
- }
-
- return $this->statedir . DIRECTORY_SEPARATOR . strtolower('.channel.' .
- str_replace('/', '_', $ch));
- }
-
- function _openPackageFile($package, $mode, $channel = false)
- {
- if (!$this->_assertStateDir($channel)) {
- return null;
- }
-
- if (!in_array($mode, array('r', 'rb')) && !$this->hasWriteAccess()) {
- return null;
- }
-
- $file = $this->_packageFileName($package, $channel);
- if (!file_exists($file) && $mode == 'r' || $mode == 'rb') {
- return null;
- }
-
- $fp = @fopen($file, $mode);
- if (!$fp) {
- return null;
- }
-
- return $fp;
- }
-
- function _closePackageFile($fp)
- {
- fclose($fp);
- }
-
- function _openChannelFile($channel, $mode)
- {
- if (!$this->_assertChannelDir()) {
- return null;
- }
-
- if (!in_array($mode, array('r', 'rb')) && !$this->hasWriteAccess()) {
- return null;
- }
-
- $file = $this->_channelFileName($channel);
- if (!file_exists($file) && $mode == 'r' || $mode == 'rb') {
- return null;
- }
-
- $fp = @fopen($file, $mode);
- if (!$fp) {
- return null;
- }
-
- return $fp;
- }
-
- function _closeChannelFile($fp)
- {
- fclose($fp);
- }
-
- function _rebuildFileMap()
- {
- if (!class_exists('PEAR_Installer_Role')) {
- require_once 'PEAR/Installer/Role.php';
- }
-
- $channels = $this->_listAllPackages();
- $files = array();
- foreach ($channels as $channel => $packages) {
- foreach ($packages as $package) {
- $version = $this->_packageInfo($package, 'version', $channel);
- $filelist = $this->_packageInfo($package, 'filelist', $channel);
- if (!is_array($filelist)) {
- continue;
- }
-
- foreach ($filelist as $name => $attrs) {
- if (isset($attrs['attribs'])) {
- $attrs = $attrs['attribs'];
- }
-
- // it is possible for conflicting packages in different channels to
- // conflict with data files/doc files
- if ($name == 'dirtree') {
- continue;
- }
-
- if (isset($attrs['role']) && !in_array($attrs['role'],
- PEAR_Installer_Role::getInstallableRoles())) {
- // these are not installed
- continue;
- }
-
- if (isset($attrs['role']) && !in_array($attrs['role'],
- PEAR_Installer_Role::getBaseinstallRoles())) {
- $attrs['baseinstalldir'] = $package;
- }
-
- if (isset($attrs['baseinstalldir'])) {
- $file = $attrs['baseinstalldir'].DIRECTORY_SEPARATOR.$name;
- } else {
- $file = $name;
- }
-
- $file = preg_replace(',^/+,', '', $file);
- if ($channel != 'pear.php.net') {
- if (!isset($files[$attrs['role']])) {
- $files[$attrs['role']] = array();
- }
- $files[$attrs['role']][$file] = array(strtolower($channel),
- strtolower($package));
- } else {
- if (!isset($files[$attrs['role']])) {
- $files[$attrs['role']] = array();
- }
- $files[$attrs['role']][$file] = strtolower($package);
- }
- }
- }
- }
-
-
- $this->_assertStateDir();
- if (!$this->hasWriteAccess()) {
- return false;
- }
-
- $fp = @fopen($this->filemap, 'wb');
- if (!$fp) {
- return false;
- }
-
- $this->filemap_cache = $files;
- fwrite($fp, serialize($files));
- fclose($fp);
- return true;
- }
-
- function _readFileMap()
- {
- if (!file_exists($this->filemap)) {
- return array();
- }
-
- $fp = @fopen($this->filemap, 'r');
- if (!$fp) {
- return $this->raiseError('PEAR_Registry: could not open filemap "' . $this->filemap . '"', PEAR_REGISTRY_ERROR_FILE, null, null, $php_errormsg);
- }
-
- clearstatcache();
- $rt = get_magic_quotes_runtime();
- set_magic_quotes_runtime(0);
- $fsize = filesize($this->filemap);
- fclose($fp);
- $data = file_get_contents($this->filemap);
- set_magic_quotes_runtime($rt);
- $tmp = unserialize($data);
- if (!$tmp && $fsize > 7) {
- return $this->raiseError('PEAR_Registry: invalid filemap data', PEAR_REGISTRY_ERROR_FORMAT, null, null, $data);
- }
-
- $this->filemap_cache = $tmp;
- return true;
- }
-
- /**
- * Lock the registry.
- *
- * @param integer lock mode, one of LOCK_EX, LOCK_SH or LOCK_UN.
- * See flock manual for more information.
- *
- * @return bool TRUE on success, FALSE if locking failed, or a
- * PEAR error if some other error occurs (such as the
- * lock file not being writable).
- *
- * @access private
- */
- function _lock($mode = LOCK_EX)
- {
- if (stristr(php_uname(), 'Windows 9')) {
- return true;
- }
-
- if ($mode != LOCK_UN && is_resource($this->lock_fp)) {
- // XXX does not check type of lock (LOCK_SH/LOCK_EX)
- return true;
- }
-
- if (!$this->_assertStateDir()) {
- if ($mode == LOCK_EX) {
- return $this->raiseError('Registry directory is not writeable by the current user');
- }
-
- return true;
- }
-
- $open_mode = 'w';
- // XXX People reported problems with LOCK_SH and 'w'
- if ($mode === LOCK_SH || $mode === LOCK_UN) {
- if (!file_exists($this->lockfile)) {
- touch($this->lockfile);
- }
- $open_mode = 'r';
- }
-
- if (!is_resource($this->lock_fp)) {
- $this->lock_fp = @fopen($this->lockfile, $open_mode);
- }
-
- if (!is_resource($this->lock_fp)) {
- $this->lock_fp = null;
- return $this->raiseError("could not create lock file" .
- (isset($php_errormsg) ? ": " . $php_errormsg : ""));
- }
-
- if (!(int)flock($this->lock_fp, $mode)) {
- switch ($mode) {
- case LOCK_SH: $str = 'shared'; break;
- case LOCK_EX: $str = 'exclusive'; break;
- case LOCK_UN: $str = 'unlock'; break;
- default: $str = 'unknown'; break;
- }
-
- //is resource at this point, close it on error.
- fclose($this->lock_fp);
- $this->lock_fp = null;
- return $this->raiseError("could not acquire $str lock ($this->lockfile)",
- PEAR_REGISTRY_ERROR_LOCK);
- }
-
- return true;
- }
-
- function _unlock()
- {
- $ret = $this->_lock(LOCK_UN);
- if (is_resource($this->lock_fp)) {
- fclose($this->lock_fp);
- }
-
- $this->lock_fp = null;
- return $ret;
- }
-
- function _packageExists($package, $channel = false)
- {
- return file_exists($this->_packageFileName($package, $channel));
- }
-
- /**
- * Determine whether a channel exists in the registry
- * @param string Channel name
- * @param bool if true, then aliases will be ignored
- * @return boolean
- */
- function _channelExists($channel, $noaliases = false)
- {
- $a = file_exists($this->_channelFileName($channel, $noaliases));
- if (!$a && $channel == 'pear.php.net') {
- return true;
- }
-
- if (!$a && $channel == 'pecl.php.net') {
- return true;
- }
-
- if (!$a && $channel == 'doc.php.net') {
- return true;
- }
-
- return $a;
- }
-
- /**
- * @param PEAR_ChannelFile Channel object
- * @param donotuse
- * @param string Last-Modified HTTP tag from remote request
- * @return boolean|PEAR_Error True on creation, false if it already exists
- */
- function _addChannel($channel, $update = false, $lastmodified = false)
- {
- if (!is_a($channel, 'PEAR_ChannelFile')) {
- return false;
- }
-
- if (!$channel->validate()) {
- return false;
- }
-
- if (file_exists($this->_channelFileName($channel->getName()))) {
- if (!$update) {
- return false;
- }
-
- $checker = $this->_getChannel($channel->getName());
- if (PEAR::isError($checker)) {
- return $checker;
- }
-
- if ($channel->getAlias() != $checker->getAlias()) {
- if (file_exists($this->_getChannelAliasFileName($checker->getAlias()))) {
- @unlink($this->_getChannelAliasFileName($checker->getAlias()));
- }
- }
- } else {
- if ($update && !in_array($channel->getName(), array('pear.php.net', 'pecl.php.net', 'doc.php.net'))) {
- return false;
- }
- }
-
- $ret = $this->_assertChannelDir();
- if (PEAR::isError($ret)) {
- return $ret;
- }
-
- $ret = $this->_assertChannelStateDir($channel->getName());
- if (PEAR::isError($ret)) {
- return $ret;
- }
-
- if ($channel->getAlias() != $channel->getName()) {
- if (file_exists($this->_getChannelAliasFileName($channel->getAlias())) &&
- $this->_getChannelFromAlias($channel->getAlias()) != $channel->getName()) {
- $channel->setAlias($channel->getName());
- }
-
- if (!$this->hasWriteAccess()) {
- return false;
- }
-
- $fp = @fopen($this->_getChannelAliasFileName($channel->getAlias()), 'w');
- if (!$fp) {
- return false;
- }
-
- fwrite($fp, $channel->getName());
- fclose($fp);
- }
-
- if (!$this->hasWriteAccess()) {
- return false;
- }
-
- $fp = @fopen($this->_channelFileName($channel->getName()), 'wb');
- if (!$fp) {
- return false;
- }
-
- $info = $channel->toArray();
- if ($lastmodified) {
- $info['_lastmodified'] = $lastmodified;
- } else {
- $info['_lastmodified'] = date('r');
- }
-
- fwrite($fp, serialize($info));
- fclose($fp);
- return true;
- }
-
- /**
- * Deletion fails if there are any packages installed from the channel
- * @param string|PEAR_ChannelFile channel name
- * @return boolean|PEAR_Error True on deletion, false if it doesn't exist
- */
- function _deleteChannel($channel)
- {
- if (!is_string($channel)) {
- if (!is_a($channel, 'PEAR_ChannelFile')) {
- return false;
- }
-
- if (!$channel->validate()) {
- return false;
- }
- $channel = $channel->getName();
- }
-
- if ($this->_getChannelFromAlias($channel) == '__uri') {
- return false;
- }
-
- if ($this->_getChannelFromAlias($channel) == 'pecl.php.net') {
- return false;
- }
-
- if ($this->_getChannelFromAlias($channel) == 'doc.php.net') {
- return false;
- }
-
- if (!$this->_channelExists($channel)) {
- return false;
- }
-
- if (!$channel || $this->_getChannelFromAlias($channel) == 'pear.php.net') {
- return false;
- }
-
- $channel = $this->_getChannelFromAlias($channel);
- if ($channel == 'pear.php.net') {
- return false;
- }
-
- $test = $this->_listChannelPackages($channel);
- if (count($test)) {
- return false;
- }
-
- $test = @rmdir($this->_channelDirectoryName($channel));
- if (!$test) {
- return false;
- }
-
- $file = $this->_getChannelAliasFileName($this->_getAlias($channel));
- if (file_exists($file)) {
- $test = @unlink($file);
- if (!$test) {
- return false;
- }
- }
-
- $file = $this->_channelFileName($channel);
- $ret = true;
- if (file_exists($file)) {
- $ret = @unlink($file);
- }
-
- return $ret;
- }
-
- /**
- * Determine whether a channel exists in the registry
- * @param string Channel Alias
- * @return boolean
- */
- function _isChannelAlias($alias)
- {
- return file_exists($this->_getChannelAliasFileName($alias));
- }
-
- /**
- * @param string|null
- * @param string|null
- * @param string|null
- * @return array|null
- * @access private
- */
- function _packageInfo($package = null, $key = null, $channel = 'pear.php.net')
- {
- if ($package === null) {
- if ($channel === null) {
- $channels = $this->_listChannels();
- $ret = array();
- foreach ($channels as $channel) {
- $channel = strtolower($channel);
- $ret[$channel] = array();
- $packages = $this->_listPackages($channel);
- foreach ($packages as $package) {
- $ret[$channel][] = $this->_packageInfo($package, null, $channel);
- }
- }
-
- return $ret;
- }
-
- $ps = $this->_listPackages($channel);
- if (!count($ps)) {
- return array();
- }
- return array_map(array(&$this, '_packageInfo'),
- $ps, array_fill(0, count($ps), null),
- array_fill(0, count($ps), $channel));
- }
-
- $fp = $this->_openPackageFile($package, 'r', $channel);
- if ($fp === null) {
- return null;
- }
-
- $rt = get_magic_quotes_runtime();
- set_magic_quotes_runtime(0);
- clearstatcache();
- $this->_closePackageFile($fp);
- $data = file_get_contents($this->_packageFileName($package, $channel));
- set_magic_quotes_runtime($rt);
- $data = unserialize($data);
- if ($key === null) {
- return $data;
- }
-
- // compatibility for package.xml version 2.0
- if (isset($data['old'][$key])) {
- return $data['old'][$key];
- }
-
- if (isset($data[$key])) {
- return $data[$key];
- }
-
- return null;
- }
-
- /**
- * @param string Channel name
- * @param bool whether to strictly retrieve info of channels, not just aliases
- * @return array|null
- */
- function _channelInfo($channel, $noaliases = false)
- {
- if (!$this->_channelExists($channel, $noaliases)) {
- return null;
- }
-
- $fp = $this->_openChannelFile($channel, 'r');
- if ($fp === null) {
- return null;
- }
-
- $rt = get_magic_quotes_runtime();
- set_magic_quotes_runtime(0);
- clearstatcache();
- $this->_closeChannelFile($fp);
- $data = file_get_contents($this->_channelFileName($channel));
- set_magic_quotes_runtime($rt);
- $data = unserialize($data);
- return $data;
- }
-
- function _listChannels()
- {
- $channellist = array();
- if (!file_exists($this->channelsdir) || !is_dir($this->channelsdir)) {
- return array('pear.php.net', 'pecl.php.net', 'doc.php.net', '__uri');
- }
-
- $dp = opendir($this->channelsdir);
- while ($ent = readdir($dp)) {
- if ($ent{0} == '.' || substr($ent, -4) != '.reg') {
- continue;
- }
-
- if ($ent == '__uri.reg') {
- $channellist[] = '__uri';
- continue;
- }
-
- $channellist[] = str_replace('_', '/', substr($ent, 0, -4));
- }
-
- closedir($dp);
- if (!in_array('pear.php.net', $channellist)) {
- $channellist[] = 'pear.php.net';
- }
-
- if (!in_array('pecl.php.net', $channellist)) {
- $channellist[] = 'pecl.php.net';
- }
-
- if (!in_array('doc.php.net', $channellist)) {
- $channellist[] = 'doc.php.net';
- }
-
-
- if (!in_array('__uri', $channellist)) {
- $channellist[] = '__uri';
- }
-
- natsort($channellist);
- return $channellist;
- }
-
- function _listPackages($channel = false)
- {
- if ($channel && $this->_getChannelFromAlias($channel) != 'pear.php.net') {
- return $this->_listChannelPackages($channel);
- }
-
- if (!file_exists($this->statedir) || !is_dir($this->statedir)) {
- return array();
- }
-
- $pkglist = array();
- $dp = opendir($this->statedir);
- if (!$dp) {
- return $pkglist;
- }
-
- while ($ent = readdir($dp)) {
- if ($ent{0} == '.' || substr($ent, -4) != '.reg') {
- continue;
- }
-
- $pkglist[] = substr($ent, 0, -4);
- }
- closedir($dp);
- return $pkglist;
- }
-
- function _listChannelPackages($channel)
- {
- $pkglist = array();
- if (!file_exists($this->_channelDirectoryName($channel)) ||
- !is_dir($this->_channelDirectoryName($channel))) {
- return array();
- }
-
- $dp = opendir($this->_channelDirectoryName($channel));
- if (!$dp) {
- return $pkglist;
- }
-
- while ($ent = readdir($dp)) {
- if ($ent{0} == '.' || substr($ent, -4) != '.reg') {
- continue;
- }
- $pkglist[] = substr($ent, 0, -4);
- }
-
- closedir($dp);
- return $pkglist;
- }
-
- function _listAllPackages()
- {
- $ret = array();
- foreach ($this->_listChannels() as $channel) {
- $ret[$channel] = $this->_listPackages($channel);
- }
-
- return $ret;
- }
-
- /**
- * Add an installed package to the registry
- * @param string package name
- * @param array package info (parsed by PEAR_Common::infoFrom*() methods)
- * @return bool success of saving
- * @access private
- */
- function _addPackage($package, $info)
- {
- if ($this->_packageExists($package)) {
- return false;
- }
-
- $fp = $this->_openPackageFile($package, 'wb');
- if ($fp === null) {
- return false;
- }
-
- $info['_lastmodified'] = time();
- fwrite($fp, serialize($info));
- $this->_closePackageFile($fp);
- if (isset($info['filelist'])) {
- $this->_rebuildFileMap();
- }
-
- return true;
- }
-
- /**
- * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2
- * @return bool
- * @access private
- */
- function _addPackage2($info)
- {
- if (!is_a($info, 'PEAR_PackageFile_v1') && !is_a($info, 'PEAR_PackageFile_v2')) {
- return false;
- }
-
- if (!$info->validate()) {
- if (class_exists('PEAR_Common')) {
- $ui = PEAR_Frontend::singleton();
- if ($ui) {
- foreach ($info->getValidationWarnings() as $err) {
- $ui->log($err['message'], true);
- }
- }
- }
- return false;
- }
-
- $channel = $info->getChannel();
- $package = $info->getPackage();
- $save = $info;
- if ($this->_packageExists($package, $channel)) {
- return false;
- }
-
- if (!$this->_channelExists($channel, true)) {
- return false;
- }
-
- $info = $info->toArray(true);
- if (!$info) {
- return false;
- }
-
- $fp = $this->_openPackageFile($package, 'wb', $channel);
- if ($fp === null) {
- return false;
- }
-
- $info['_lastmodified'] = time();
- fwrite($fp, serialize($info));
- $this->_closePackageFile($fp);
- $this->_rebuildFileMap();
- return true;
- }
-
- /**
- * @param string Package name
- * @param array parsed package.xml 1.0
- * @param bool this parameter is only here for BC. Don't use it.
- * @access private
- */
- function _updatePackage($package, $info, $merge = true)
- {
- $oldinfo = $this->_packageInfo($package);
- if (empty($oldinfo)) {
- return false;
- }
-
- $fp = $this->_openPackageFile($package, 'w');
- if ($fp === null) {
- return false;
- }
-
- if (is_object($info)) {
- $info = $info->toArray();
- }
- $info['_lastmodified'] = time();
-
- $newinfo = $info;
- if ($merge) {
- $info = array_merge($oldinfo, $info);
- } else {
- $diff = $info;
- }
-
- fwrite($fp, serialize($info));
- $this->_closePackageFile($fp);
- if (isset($newinfo['filelist'])) {
- $this->_rebuildFileMap();
- }
-
- return true;
- }
-
- /**
- * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2
- * @return bool
- * @access private
- */
- function _updatePackage2($info)
- {
- if (!$this->_packageExists($info->getPackage(), $info->getChannel())) {
- return false;
- }
-
- $fp = $this->_openPackageFile($info->getPackage(), 'w', $info->getChannel());
- if ($fp === null) {
- return false;
- }
-
- $save = $info;
- $info = $save->getArray(true);
- $info['_lastmodified'] = time();
- fwrite($fp, serialize($info));
- $this->_closePackageFile($fp);
- $this->_rebuildFileMap();
- return true;
- }
-
- /**
- * @param string Package name
- * @param string Channel name
- * @return PEAR_PackageFile_v1|PEAR_PackageFile_v2|null
- * @access private
- */
- function &_getPackage($package, $channel = 'pear.php.net')
- {
- $info = $this->_packageInfo($package, null, $channel);
- if ($info === null) {
- return $info;
- }
-
- $a = $this->_config;
- if (!$a) {
- $this->_config = &new PEAR_Config;
- $this->_config->set('php_dir', $this->statedir);
- }
-
- if (!class_exists('PEAR_PackageFile')) {
- require_once 'PEAR/PackageFile.php';
- }
-
- $pkg = &new PEAR_PackageFile($this->_config);
- $pf = &$pkg->fromArray($info);
- return $pf;
- }
-
- /**
- * @param string channel name
- * @param bool whether to strictly retrieve channel names
- * @return PEAR_ChannelFile|PEAR_Error
- * @access private
- */
- function &_getChannel($channel, $noaliases = false)
- {
- $ch = false;
- if ($this->_channelExists($channel, $noaliases)) {
- $chinfo = $this->_channelInfo($channel, $noaliases);
- if ($chinfo) {
- if (!class_exists('PEAR_ChannelFile')) {
- require_once 'PEAR/ChannelFile.php';
- }
-
- $ch = &PEAR_ChannelFile::fromArrayWithErrors($chinfo);
- }
- }
-
- if ($ch) {
- if ($ch->validate()) {
- return $ch;
- }
-
- foreach ($ch->getErrors(true) as $err) {
- $message = $err['message'] . "\n";
- }
-
- $ch = PEAR::raiseError($message);
- return $ch;
- }
-
- if ($this->_getChannelFromAlias($channel) == 'pear.php.net') {
- // the registry is not properly set up, so use defaults
- if (!class_exists('PEAR_ChannelFile')) {
- require_once 'PEAR/ChannelFile.php';
- }
-
- $pear_channel = new PEAR_ChannelFile;
- $pear_channel->setName('pear.php.net');
- $pear_channel->setAlias('pear');
- $pear_channel->setSummary('PHP Extension and Application Repository');
- $pear_channel->setDefaultPEARProtocols();
- $pear_channel->setBaseURL('REST1.0', 'http://pear.php.net/rest/');
- $pear_channel->setBaseURL('REST1.1', 'http://pear.php.net/rest/');
- return $pear_channel;
- }
-
- if ($this->_getChannelFromAlias($channel) == 'pecl.php.net') {
- // the registry is not properly set up, so use defaults
- if (!class_exists('PEAR_ChannelFile')) {
- require_once 'PEAR/ChannelFile.php';
- }
- $pear_channel = new PEAR_ChannelFile;
- $pear_channel->setName('pecl.php.net');
- $pear_channel->setAlias('pecl');
- $pear_channel->setSummary('PHP Extension Community Library');
- $pear_channel->setDefaultPEARProtocols();
- $pear_channel->setBaseURL('REST1.0', 'http://pecl.php.net/rest/');
- $pear_channel->setBaseURL('REST1.1', 'http://pecl.php.net/rest/');
- $pear_channel->setValidationPackage('PEAR_Validator_PECL', '1.0');
- return $pear_channel;
- }
-
- if ($this->_getChannelFromAlias($channel) == 'doc.php.net') {
- // the registry is not properly set up, so use defaults
- if (!class_exists('PEAR_ChannelFile')) {
- require_once 'PEAR/ChannelFile.php';
- }
-
- $doc_channel = new PEAR_ChannelFile;
- $doc_channel->setName('doc.php.net');
- $doc_channel->setAlias('phpdocs');
- $doc_channel->setSummary('PHP Documentation Team');
- $doc_channel->setDefaultPEARProtocols();
- $doc_channel->setBaseURL('REST1.0', 'http://doc.php.net/Chiara_PEAR_Server_REST/');
- $doc_channel->setBaseURL('REST1.1', 'http://doc.php.net/Chiara_PEAR_Server_REST/');
- return $doc_channel;
- }
-
-
- if ($this->_getChannelFromAlias($channel) == '__uri') {
- // the registry is not properly set up, so use defaults
- if (!class_exists('PEAR_ChannelFile')) {
- require_once 'PEAR/ChannelFile.php';
- }
-
- $private = new PEAR_ChannelFile;
- $private->setName('__uri');
- $private->setDefaultPEARProtocols();
- $private->setBaseURL('REST1.0', '****');
- $private->setSummary('Pseudo-channel for static packages');
- return $private;
- }
-
- return $ch;
- }
-
- /**
- * @param string Package name
- * @param string Channel name
- * @return bool
- */
- function packageExists($package, $channel = 'pear.php.net')
- {
- if (PEAR::isError($e = $this->_lock(LOCK_SH))) {
- return $e;
- }
- $ret = $this->_packageExists($package, $channel);
- $this->_unlock();
- return $ret;
- }
-
- // }}}
-
- // {{{ channelExists()
-
- /**
- * @param string channel name
- * @param bool if true, then aliases will be ignored
- * @return bool
- */
- function channelExists($channel, $noaliases = false)
- {
- if (PEAR::isError($e = $this->_lock(LOCK_SH))) {
- return $e;
- }
- $ret = $this->_channelExists($channel, $noaliases);
- $this->_unlock();
- return $ret;
- }
-
- // }}}
-
- // {{{ isAlias()
-
- /**
- * Determines whether the parameter is an alias of a channel
- * @param string
- * @return bool
- */
- function isAlias($alias)
- {
- if (PEAR::isError($e = $this->_lock(LOCK_SH))) {
- return $e;
- }
- $ret = $this->_isChannelAlias($alias);
- $this->_unlock();
- return $ret;
- }
-
- // }}}
- // {{{ packageInfo()
-
- /**
- * @param string|null
- * @param string|null
- * @param string
- * @return array|null
- */
- function packageInfo($package = null, $key = null, $channel = 'pear.php.net')
- {
- if (PEAR::isError($e = $this->_lock(LOCK_SH))) {
- return $e;
- }
- $ret = $this->_packageInfo($package, $key, $channel);
- $this->_unlock();
- return $ret;
- }
-
- // }}}
- // {{{ channelInfo()
-
- /**
- * Retrieve a raw array of channel data.
- *
- * Do not use this, instead use {@link getChannel()} for normal
- * operations. Array structure is undefined in this method
- * @param string channel name
- * @param bool whether to strictly retrieve information only on non-aliases
- * @return array|null|PEAR_Error
- */
- function channelInfo($channel = null, $noaliases = false)
- {
- if (PEAR::isError($e = $this->_lock(LOCK_SH))) {
- return $e;
- }
- $ret = $this->_channelInfo($channel, $noaliases);
- $this->_unlock();
- return $ret;
- }
-
- // }}}
-
- /**
- * @param string
- */
- function channelName($channel)
- {
- if (PEAR::isError($e = $this->_lock(LOCK_SH))) {
- return $e;
- }
- $ret = $this->_getChannelFromAlias($channel);
- $this->_unlock();
- return $ret;
- }
-
- /**
- * @param string
- */
- function channelAlias($channel)
- {
- if (PEAR::isError($e = $this->_lock(LOCK_SH))) {
- return $e;
- }
- $ret = $this->_getAlias($channel);
- $this->_unlock();
- return $ret;
- }
- // {{{ listPackages()
-
- function listPackages($channel = false)
- {
- if (PEAR::isError($e = $this->_lock(LOCK_SH))) {
- return $e;
- }
- $ret = $this->_listPackages($channel);
- $this->_unlock();
- return $ret;
- }
-
- // }}}
- // {{{ listAllPackages()
-
- function listAllPackages()
- {
- if (PEAR::isError($e = $this->_lock(LOCK_SH))) {
- return $e;
- }
- $ret = $this->_listAllPackages();
- $this->_unlock();
- return $ret;
- }
-
- // }}}
- // {{{ listChannel()
-
- function listChannels()
- {
- if (PEAR::isError($e = $this->_lock(LOCK_SH))) {
- return $e;
- }
- $ret = $this->_listChannels();
- $this->_unlock();
- return $ret;
- }
-
- // }}}
- // {{{ addPackage()
-
- /**
- * Add an installed package to the registry
- * @param string|PEAR_PackageFile_v1|PEAR_PackageFile_v2 package name or object
- * that will be passed to {@link addPackage2()}
- * @param array package info (parsed by PEAR_Common::infoFrom*() methods)
- * @return bool success of saving
- */
- function addPackage($package, $info)
- {
- if (is_object($info)) {
- return $this->addPackage2($info);
- }
- if (PEAR::isError($e = $this->_lock(LOCK_EX))) {
- return $e;
- }
- $ret = $this->_addPackage($package, $info);
- $this->_unlock();
- if ($ret) {
- if (!class_exists('PEAR_PackageFile_v1')) {
- require_once 'PEAR/PackageFile/v1.php';
- }
- $pf = new PEAR_PackageFile_v1;
- $pf->setConfig($this->_config);
- $pf->fromArray($info);
- $this->_dependencyDB->uninstallPackage($pf);
- $this->_dependencyDB->installPackage($pf);
- }
- return $ret;
- }
-
- // }}}
- // {{{ addPackage2()
-
- function addPackage2($info)
- {
- if (!is_object($info)) {
- return $this->addPackage($info['package'], $info);
- }
- if (PEAR::isError($e = $this->_lock(LOCK_EX))) {
- return $e;
- }
- $ret = $this->_addPackage2($info);
- $this->_unlock();
- if ($ret) {
- $this->_dependencyDB->uninstallPackage($info);
- $this->_dependencyDB->installPackage($info);
- }
- return $ret;
- }
-
- // }}}
- // {{{ updateChannel()
-
- /**
- * For future expandibility purposes, separate this
- * @param PEAR_ChannelFile
- */
- function updateChannel($channel, $lastmodified = null)
- {
- if ($channel->getName() == '__uri') {
- return false;
- }
- return $this->addChannel($channel, $lastmodified, true);
- }
-
- // }}}
- // {{{ deleteChannel()
-
- /**
- * Deletion fails if there are any packages installed from the channel
- * @param string|PEAR_ChannelFile channel name
- * @return boolean|PEAR_Error True on deletion, false if it doesn't exist
- */
- function deleteChannel($channel)
- {
- if (PEAR::isError($e = $this->_lock(LOCK_EX))) {
- return $e;
- }
- $ret = $this->_deleteChannel($channel);
- $this->_unlock();
- if ($ret && is_a($this->_config, 'PEAR_Config')) {
- $this->_config->setChannels($this->listChannels());
- }
- return $ret;
- }
-
- // }}}
- // {{{ addChannel()
-
- /**
- * @param PEAR_ChannelFile Channel object
- * @param string Last-Modified header from HTTP for caching
- * @return boolean|PEAR_Error True on creation, false if it already exists
- */
- function addChannel($channel, $lastmodified = false, $update = false)
- {
- if (!is_a($channel, 'PEAR_ChannelFile')) {
- return false;
- }
- if (!$channel->validate()) {
- return false;
- }
- if (PEAR::isError($e = $this->_lock(LOCK_EX))) {
- return $e;
- }
- $ret = $this->_addChannel($channel, $update, $lastmodified);
- $this->_unlock();
- if (!$update && $ret && is_a($this->_config, 'PEAR_Config')) {
- $this->_config->setChannels($this->listChannels());
- }
- return $ret;
- }
-
- // }}}
- // {{{ deletePackage()
-
- function deletePackage($package, $channel = 'pear.php.net')
- {
- if (PEAR::isError($e = $this->_lock(LOCK_EX))) {
- return $e;
- }
- $file = $this->_packageFileName($package, $channel);
- if (file_exists($file)) {
- $ret = @unlink($file);
- } else {
- $ret = false;
- }
- $this->_rebuildFileMap();
- $this->_unlock();
- $p = array('channel' => $channel, 'package' => $package);
- $this->_dependencyDB->uninstallPackage($p);
- return $ret;
- }
-
- // }}}
- // {{{ updatePackage()
-
- function updatePackage($package, $info, $merge = true)
- {
- if (is_object($info)) {
- return $this->updatePackage2($info, $merge);
- }
- if (PEAR::isError($e = $this->_lock(LOCK_EX))) {
- return $e;
- }
- $ret = $this->_updatePackage($package, $info, $merge);
- $this->_unlock();
- if ($ret) {
- if (!class_exists('PEAR_PackageFile_v1')) {
- require_once 'PEAR/PackageFile/v1.php';
- }
- $pf = new PEAR_PackageFile_v1;
- $pf->setConfig($this->_config);
- $pf->fromArray($this->packageInfo($package));
- $this->_dependencyDB->uninstallPackage($pf);
- $this->_dependencyDB->installPackage($pf);
- }
- return $ret;
- }
-
- // }}}
- // {{{ updatePackage2()
-
- function updatePackage2($info)
- {
-
- if (!is_object($info)) {
- return $this->updatePackage($info['package'], $info, $merge);
- }
-
- if (!$info->validate(PEAR_VALIDATE_DOWNLOADING)) {
- return false;
- }
-
- if (PEAR::isError($e = $this->_lock(LOCK_EX))) {
- return $e;
- }
-
- $ret = $this->_updatePackage2($info);
- $this->_unlock();
- if ($ret) {
- $this->_dependencyDB->uninstallPackage($info);
- $this->_dependencyDB->installPackage($info);
- }
-
- return $ret;
- }
-
- // }}}
- // {{{ getChannel()
- /**
- * @param string channel name
- * @param bool whether to strictly return raw channels (no aliases)
- * @return PEAR_ChannelFile|PEAR_Error
- */
- function &getChannel($channel, $noaliases = false)
- {
- if (PEAR::isError($e = $this->_lock(LOCK_SH))) {
- return $e;
- }
- $ret = &$this->_getChannel($channel, $noaliases);
- $this->_unlock();
- if (!$ret) {
- return PEAR::raiseError('Unknown channel: ' . $channel);
- }
- return $ret;
- }
-
- // }}}
- // {{{ getPackage()
- /**
- * @param string package name
- * @param string channel name
- * @return PEAR_PackageFile_v1|PEAR_PackageFile_v2|null
- */
- function &getPackage($package, $channel = 'pear.php.net')
- {
- if (PEAR::isError($e = $this->_lock(LOCK_SH))) {
- return $e;
- }
- $pf = &$this->_getPackage($package, $channel);
- $this->_unlock();
- return $pf;
- }
-
- // }}}
-
- /**
- * Get PEAR_PackageFile_v[1/2] objects representing the contents of
- * a dependency group that are installed.
- *
- * This is used at uninstall-time
- * @param array
- * @return array|false
- */
- function getInstalledGroup($group)
- {
- $ret = array();
- if (isset($group['package'])) {
- if (!isset($group['package'][0])) {
- $group['package'] = array($group['package']);
- }
- foreach ($group['package'] as $package) {
- $depchannel = isset($package['channel']) ? $package['channel'] : '__uri';
- $p = &$this->getPackage($package['name'], $depchannel);
- if ($p) {
- $save = &$p;
- $ret[] = &$save;
- }
- }
- }
- if (isset($group['subpackage'])) {
- if (!isset($group['subpackage'][0])) {
- $group['subpackage'] = array($group['subpackage']);
- }
- foreach ($group['subpackage'] as $package) {
- $depchannel = isset($package['channel']) ? $package['channel'] : '__uri';
- $p = &$this->getPackage($package['name'], $depchannel);
- if ($p) {
- $save = &$p;
- $ret[] = &$save;
- }
- }
- }
- if (!count($ret)) {
- return false;
- }
- return $ret;
- }
-
- // {{{ getChannelValidator()
- /**
- * @param string channel name
- * @return PEAR_Validate|false
- */
- function &getChannelValidator($channel)
- {
- $chan = $this->getChannel($channel);
- if (PEAR::isError($chan)) {
- return $chan;
- }
- $val = $chan->getValidationObject();
- return $val;
- }
- // }}}
- // {{{ getChannels()
- /**
- * @param string channel name
- * @return array an array of PEAR_ChannelFile objects representing every installed channel
- */
- function &getChannels()
- {
- $ret = array();
- if (PEAR::isError($e = $this->_lock(LOCK_SH))) {
- return $e;
- }
- foreach ($this->_listChannels() as $channel) {
- $e = &$this->_getChannel($channel);
- if (!$e || PEAR::isError($e)) {
- continue;
- }
- $ret[] = $e;
- }
- $this->_unlock();
- return $ret;
- }
-
- // }}}
- // {{{ checkFileMap()
-
- /**
- * Test whether a file or set of files belongs to a package.
- *
- * If an array is passed in
- * @param string|array file path, absolute or relative to the pear
- * install dir
- * @param string|array name of PEAR package or array('package' => name, 'channel' =>
- * channel) of a package that will be ignored
- * @param string API version - 1.1 will exclude any files belonging to a package
- * @param array private recursion variable
- * @return array|false which package and channel the file belongs to, or an empty
- * string if the file does not belong to an installed package,
- * or belongs to the second parameter's package
- */
- function checkFileMap($path, $package = false, $api = '1.0', $attrs = false)
- {
- if (is_array($path)) {
- static $notempty;
- if (empty($notempty)) {
- if (!class_exists('PEAR_Installer_Role')) {
- require_once 'PEAR/Installer/Role.php';
- }
- $notempty = create_function('$a','return !empty($a);');
- }
- $package = is_array($package) ? array(strtolower($package[0]), strtolower($package[1]))
- : strtolower($package);
- $pkgs = array();
- foreach ($path as $name => $attrs) {
- if (is_array($attrs)) {
- if (isset($attrs['install-as'])) {
- $name = $attrs['install-as'];
- }
- if (!in_array($attrs['role'], PEAR_Installer_Role::getInstallableRoles())) {
- // these are not installed
- continue;
- }
- if (!in_array($attrs['role'], PEAR_Installer_Role::getBaseinstallRoles())) {
- $attrs['baseinstalldir'] = is_array($package) ? $package[1] : $package;
- }
- if (isset($attrs['baseinstalldir'])) {
- $name = $attrs['baseinstalldir'] . DIRECTORY_SEPARATOR . $name;
- }
- }
- $pkgs[$name] = $this->checkFileMap($name, $package, $api, $attrs);
- if (PEAR::isError($pkgs[$name])) {
- return $pkgs[$name];
- }
- }
- return array_filter($pkgs, $notempty);
- }
- if (empty($this->filemap_cache)) {
- if (PEAR::isError($e = $this->_lock(LOCK_SH))) {
- return $e;
- }
- $err = $this->_readFileMap();
- $this->_unlock();
- if (PEAR::isError($err)) {
- return $err;
- }
- }
- if (!$attrs) {
- $attrs = array('role' => 'php'); // any old call would be for PHP role only
- }
- if (isset($this->filemap_cache[$attrs['role']][$path])) {
- if ($api >= '1.1' && $this->filemap_cache[$attrs['role']][$path] == $package) {
- return false;
- }
- return $this->filemap_cache[$attrs['role']][$path];
- }
- $l = strlen($this->install_dir);
- if (substr($path, 0, $l) == $this->install_dir) {
- $path = preg_replace('!^'.DIRECTORY_SEPARATOR.'+!', '', substr($path, $l));
- }
- if (isset($this->filemap_cache[$attrs['role']][$path])) {
- if ($api >= '1.1' && $this->filemap_cache[$attrs['role']][$path] == $package) {
- return false;
- }
- return $this->filemap_cache[$attrs['role']][$path];
- }
- return false;
- }
-
- // }}}
- // {{{ flush()
- /**
- * Force a reload of the filemap
- * @since 1.5.0RC3
- */
- function flushFileMap()
- {
- $this->filemap_cache = null;
- clearstatcache(); // ensure that the next read gets the full, current filemap
- }
-
- // }}}
- // {{{ apiVersion()
- /**
- * Get the expected API version. Channels API is version 1.1, as it is backwards
- * compatible with 1.0
- * @return string
- */
- function apiVersion()
- {
- return '1.1';
- }
- // }}}
-
-
- /**
- * Parse a package name, or validate a parsed package name array
- * @param string|array pass in an array of format
- * array(
- * 'package' => 'pname',
- * ['channel' => 'channame',]
- * ['version' => 'version',]
- * ['state' => 'state',]
- * ['group' => 'groupname'])
- * or a string of format
- * [channel://][channame/]pname[-version|-state][/group=groupname]
- * @return array|PEAR_Error
- */
- function parsePackageName($param, $defaultchannel = 'pear.php.net')
- {
- $saveparam = $param;
- if (is_array($param)) {
- // convert to string for error messages
- $saveparam = $this->parsedPackageNameToString($param);
- // process the array
- if (!isset($param['package'])) {
- return PEAR::raiseError('parsePackageName(): array $param ' .
- 'must contain a valid package name in index "param"',
- 'package', null, null, $param);
- }
- if (!isset($param['uri'])) {
- if (!isset($param['channel'])) {
- $param['channel'] = $defaultchannel;
- }
- } else {
- $param['channel'] = '__uri';
- }
- } else {
- $components = @parse_url((string) $param);
- if (isset($components['scheme'])) {
- if ($components['scheme'] == 'http') {
- // uri package
- $param = array('uri' => $param, 'channel' => '__uri');
- } elseif($components['scheme'] != 'channel') {
- return PEAR::raiseError('parsePackageName(): only channel:// uris may ' .
- 'be downloaded, not "' . $param . '"', 'invalid', null, null, $param);
- }
- }
- if (!isset($components['path'])) {
- return PEAR::raiseError('parsePackageName(): array $param ' .
- 'must contain a valid package name in "' . $param . '"',
- 'package', null, null, $param);
- }
- if (isset($components['host'])) {
- // remove the leading "/"
- $components['path'] = substr($components['path'], 1);
- }
- if (!isset($components['scheme'])) {
- if (strpos($components['path'], '/') !== false) {
- if ($components['path']{0} == '/') {
- return PEAR::raiseError('parsePackageName(): this is not ' .
- 'a package name, it begins with "/" in "' . $param . '"',
- 'invalid', null, null, $param);
- }
- $parts = explode('/', $components['path']);
- $components['host'] = array_shift($parts);
- if (count($parts) > 1) {
- $components['path'] = array_pop($parts);
- $components['host'] .= '/' . implode('/', $parts);
- } else {
- $components['path'] = implode('/', $parts);
- }
- } else {
- $components['host'] = $defaultchannel;
- }
- } else {
- if (strpos($components['path'], '/')) {
- $parts = explode('/', $components['path']);
- $components['path'] = array_pop($parts);
- $components['host'] .= '/' . implode('/', $parts);
- }
- }
-
- if (is_array($param)) {
- $param['package'] = $components['path'];
- } else {
- $param = array(
- 'package' => $components['path']
- );
- if (isset($components['host'])) {
- $param['channel'] = $components['host'];
- }
- }
- if (isset($components['fragment'])) {
- $param['group'] = $components['fragment'];
- }
- if (isset($components['user'])) {
- $param['user'] = $components['user'];
- }
- if (isset($components['pass'])) {
- $param['pass'] = $components['pass'];
- }
- if (isset($components['query'])) {
- parse_str($components['query'], $param['opts']);
- }
- // check for extension
- $pathinfo = pathinfo($param['package']);
- if (isset($pathinfo['extension']) &&
- in_array(strtolower($pathinfo['extension']), array('tgz', 'tar'))) {
- $param['extension'] = $pathinfo['extension'];
- $param['package'] = substr($pathinfo['basename'], 0,
- strlen($pathinfo['basename']) - 4);
- }
- // check for version
- if (strpos($param['package'], '-')) {
- $test = explode('-', $param['package']);
- if (count($test) != 2) {
- return PEAR::raiseError('parsePackageName(): only one version/state ' .
- 'delimiter "-" is allowed in "' . $saveparam . '"',
- 'version', null, null, $param);
- }
- list($param['package'], $param['version']) = $test;
- }
- }
- // validation
- $info = $this->channelExists($param['channel']);
- if (PEAR::isError($info)) {
- return $info;
- }
- if (!$info) {
- return PEAR::raiseError('unknown channel "' . $param['channel'] .
- '" in "' . $saveparam . '"', 'channel', null, null, $param);
- }
- $chan = $this->getChannel($param['channel']);
- if (PEAR::isError($chan)) {
- return $chan;
- }
- if (!$chan) {
- return PEAR::raiseError("Exception: corrupt registry, could not " .
- "retrieve channel " . $param['channel'] . " information",
- 'registry', null, null, $param);
- }
- $param['channel'] = $chan->getName();
- $validate = $chan->getValidationObject();
- $vpackage = $chan->getValidationPackage();
- // validate package name
- if (!$validate->validPackageName($param['package'], $vpackage['_content'])) {
- return PEAR::raiseError('parsePackageName(): invalid package name "' .
- $param['package'] . '" in "' . $saveparam . '"',
- 'package', null, null, $param);
- }
- if (isset($param['group'])) {
- if (!PEAR_Validate::validGroupName($param['group'])) {
- return PEAR::raiseError('parsePackageName(): dependency group "' . $param['group'] .
- '" is not a valid group name in "' . $saveparam . '"', 'group', null, null,
- $param);
- }
- }
- if (isset($param['state'])) {
- if (!in_array(strtolower($param['state']), $validate->getValidStates())) {
- return PEAR::raiseError('parsePackageName(): state "' . $param['state']
- . '" is not a valid state in "' . $saveparam . '"',
- 'state', null, null, $param);
- }
- }
- if (isset($param['version'])) {
- if (isset($param['state'])) {
- return PEAR::raiseError('parsePackageName(): cannot contain both ' .
- 'a version and a stability (state) in "' . $saveparam . '"',
- 'version/state', null, null, $param);
- }
- // check whether version is actually a state
- if (in_array(strtolower($param['version']), $validate->getValidStates())) {
- $param['state'] = strtolower($param['version']);
- unset($param['version']);
- } else {
- if (!$validate->validVersion($param['version'])) {
- return PEAR::raiseError('parsePackageName(): "' . $param['version'] .
- '" is neither a valid version nor a valid state in "' .
- $saveparam . '"', 'version/state', null, null, $param);
- }
- }
- }
- return $param;
- }
-
- /**
- * @param array
- * @return string
- */
- function parsedPackageNameToString($parsed, $brief = false)
- {
- if (is_string($parsed)) {
- return $parsed;
- }
- if (is_object($parsed)) {
- $p = $parsed;
- $parsed = array(
- 'package' => $p->getPackage(),
- 'channel' => $p->getChannel(),
- 'version' => $p->getVersion(),
- );
- }
- if (isset($parsed['uri'])) {
- return $parsed['uri'];
- }
- if ($brief) {
- if ($channel = $this->channelAlias($parsed['channel'])) {
- return $channel . '/' . $parsed['package'];
- }
- }
- $upass = '';
- if (isset($parsed['user'])) {
- $upass = $parsed['user'];
- if (isset($parsed['pass'])) {
- $upass .= ':' . $parsed['pass'];
- }
- $upass = "$upass@";
- }
- $ret = 'channel://' . $upass . $parsed['channel'] . '/' . $parsed['package'];
- if (isset($parsed['version']) || isset($parsed['state'])) {
- $ver = isset($parsed['version']) ? $parsed['version'] : '';
- $ver .= isset($parsed['state']) ? $parsed['state'] : '';
- $ret .= '-' . $ver;
- }
- if (isset($parsed['extension'])) {
- $ret .= '.' . $parsed['extension'];
- }
- if (isset($parsed['opts'])) {
- $ret .= '?';
- foreach ($parsed['opts'] as $name => $value) {
- $parsed['opts'][$name] = "$name=$value";
- }
- $ret .= implode('&', $parsed['opts']);
- }
- if (isset($parsed['group'])) {
- $ret .= '#' . $parsed['group'];
- }
- return $ret;
- }
-} +} +/** + * PEAR_Registry + * + * PHP versions 4 and 5 + * + * @category pear + * @package PEAR + * @author Stig Bakken <ssb@php.net> + * @author Tomas V. V. Cox <cox@idecnet.com> + * @author Greg Beaver <cellog@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: Registry.php 287555 2009-08-21 21:27:27Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 0.1 + */ + +/** + * for PEAR_Error + */ +require_once 'PEAR.php'; +require_once 'PEAR/DependencyDB.php'; + +define('PEAR_REGISTRY_ERROR_LOCK', -2); +define('PEAR_REGISTRY_ERROR_FORMAT', -3); +define('PEAR_REGISTRY_ERROR_FILE', -4); +define('PEAR_REGISTRY_ERROR_CONFLICT', -5); +define('PEAR_REGISTRY_ERROR_CHANNEL_FILE', -6); + +/** + * Administration class used to maintain the installed package database. + * @category pear + * @package PEAR + * @author Stig Bakken <ssb@php.net> + * @author Tomas V. V. Cox <cox@idecnet.com> + * @author Greg Beaver <cellog@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_Registry extends PEAR +{ + /** + * File containing all channel information. + * @var string + */ + var $channels = ''; + + /** Directory where registry files are stored. + * @var string + */ + var $statedir = ''; + + /** File where the file map is stored + * @var string + */ + var $filemap = ''; + + /** Directory where registry files for channels are stored. + * @var string + */ + var $channelsdir = ''; + + /** Name of file used for locking the registry + * @var string + */ + var $lockfile = ''; + + /** File descriptor used during locking + * @var resource + */ + var $lock_fp = null; + + /** Mode used during locking + * @var int + */ + var $lock_mode = 0; // XXX UNUSED + + /** Cache of package information. Structure: + * array( + * 'package' => array('id' => ... ), + * ... ) + * @var array + */ + var $pkginfo_cache = array(); + + /** Cache of file map. Structure: + * array( '/path/to/file' => 'package', ... ) + * @var array + */ + var $filemap_cache = array(); + + /** + * @var false|PEAR_ChannelFile + */ + var $_pearChannel; + + /** + * @var false|PEAR_ChannelFile + */ + var $_peclChannel; + + /** + * @var false|PEAR_ChannelFile + */ + var $_docChannel; + + /** + * @var PEAR_DependencyDB + */ + var $_dependencyDB; + + /** + * @var PEAR_Config + */ + var $_config; + + /** + * PEAR_Registry constructor. + * + * @param string (optional) PEAR install directory (for .php files) + * @param PEAR_ChannelFile PEAR_ChannelFile object representing the PEAR channel, if + * default values are not desired. Only used the very first time a PEAR + * repository is initialized + * @param PEAR_ChannelFile PEAR_ChannelFile object representing the PECL channel, if + * default values are not desired. Only used the very first time a PEAR + * repository is initialized + * + * @access public + */ + function PEAR_Registry($pear_install_dir = PEAR_INSTALL_DIR, $pear_channel = false, + $pecl_channel = false) + { + parent::PEAR(); + $this->setInstallDir($pear_install_dir); + $this->_pearChannel = $pear_channel; + $this->_peclChannel = $pecl_channel; + $this->_config = false; + } + + function setInstallDir($pear_install_dir = PEAR_INSTALL_DIR) + { + $ds = DIRECTORY_SEPARATOR; + $this->install_dir = $pear_install_dir; + $this->channelsdir = $pear_install_dir.$ds.'.channels'; + $this->statedir = $pear_install_dir.$ds.'.registry'; + $this->filemap = $pear_install_dir.$ds.'.filemap'; + $this->lockfile = $pear_install_dir.$ds.'.lock'; + } + + function hasWriteAccess() + { + if (!file_exists($this->install_dir)) { + $dir = $this->install_dir; + while ($dir && $dir != '.') { + $olddir = $dir; + $dir = dirname($dir); + if ($dir != '.' && file_exists($dir)) { + if (is_writeable($dir)) { + return true; + } + + return false; + } + + if ($dir == $olddir) { // this can happen in safe mode + return @is_writable($dir); + } + } + + return false; + } + + return is_writeable($this->install_dir); + } + + function setConfig(&$config, $resetInstallDir = true) + { + $this->_config = &$config; + if ($resetInstallDir) { + $this->setInstallDir($config->get('php_dir')); + } + } + + function _initializeChannelDirs() + { + static $running = false; + if (!$running) { + $running = true; + $ds = DIRECTORY_SEPARATOR; + if (!is_dir($this->channelsdir) || + !file_exists($this->channelsdir . $ds . 'pear.php.net.reg') || + !file_exists($this->channelsdir . $ds . 'pecl.php.net.reg') || + !file_exists($this->channelsdir . $ds . 'doc.php.net.reg') || + !file_exists($this->channelsdir . $ds . '__uri.reg')) { + if (!file_exists($this->channelsdir . $ds . 'pear.php.net.reg')) { + $pear_channel = $this->_pearChannel; + if (!is_a($pear_channel, 'PEAR_ChannelFile') || !$pear_channel->validate()) { + if (!class_exists('PEAR_ChannelFile')) { + require_once 'PEAR/ChannelFile.php'; + } + + $pear_channel = new PEAR_ChannelFile; + $pear_channel->setAlias('pear'); + $pear_channel->setServer('pear.php.net'); + $pear_channel->setSummary('PHP Extension and Application Repository'); + $pear_channel->setDefaultPEARProtocols(); + $pear_channel->setBaseURL('REST1.0', 'http://pear.php.net/rest/'); + $pear_channel->setBaseURL('REST1.1', 'http://pear.php.net/rest/'); + $pear_channel->setBaseURL('REST1.3', 'http://pear.php.net/rest/'); + //$pear_channel->setBaseURL('REST1.4', 'http://pear.php.net/rest/'); + } else { + $pear_channel->setServer('pear.php.net'); + $pear_channel->setAlias('pear'); + } + + $pear_channel->validate(); + $this->_addChannel($pear_channel); + } + + if (!file_exists($this->channelsdir . $ds . 'pecl.php.net.reg')) { + $pecl_channel = $this->_peclChannel; + if (!is_a($pecl_channel, 'PEAR_ChannelFile') || !$pecl_channel->validate()) { + if (!class_exists('PEAR_ChannelFile')) { + require_once 'PEAR/ChannelFile.php'; + } + + $pecl_channel = new PEAR_ChannelFile; + $pecl_channel->setAlias('pecl'); + $pecl_channel->setServer('pecl.php.net'); + $pecl_channel->setSummary('PHP Extension Community Library'); + $pecl_channel->setDefaultPEARProtocols(); + $pecl_channel->setBaseURL('REST1.0', 'http://pecl.php.net/rest/'); + $pecl_channel->setBaseURL('REST1.1', 'http://pecl.php.net/rest/'); + $pecl_channel->setValidationPackage('PEAR_Validator_PECL', '1.0'); + } else { + $pecl_channel->setServer('pecl.php.net'); + $pecl_channel->setAlias('pecl'); + } + + $pecl_channel->validate(); + $this->_addChannel($pecl_channel); + } + + if (!file_exists($this->channelsdir . $ds . 'doc.php.net.reg')) { + $doc_channel = $this->_docChannel; + if (!is_a($doc_channel, 'PEAR_ChannelFile') || !$doc_channel->validate()) { + if (!class_exists('PEAR_ChannelFile')) { + require_once 'PEAR/ChannelFile.php'; + } + + $doc_channel = new PEAR_ChannelFile; + $doc_channel->setAlias('phpdocs'); + $doc_channel->setServer('doc.php.net'); + $doc_channel->setSummary('PHP Documentation Team'); + $doc_channel->setDefaultPEARProtocols(); + $doc_channel->setBaseURL('REST1.0', 'http://doc.php.net/rest/'); + $doc_channel->setBaseURL('REST1.1', 'http://doc.php.net/rest/'); + $doc_channel->setBaseURL('REST1.3', 'http://doc.php.net/rest/'); + } else { + $doc_channel->setServer('doc.php.net'); + $doc_channel->setAlias('doc'); + } + + $doc_channel->validate(); + $this->_addChannel($doc_channel); + } + + if (!file_exists($this->channelsdir . $ds . '__uri.reg')) { + if (!class_exists('PEAR_ChannelFile')) { + require_once 'PEAR/ChannelFile.php'; + } + + $private = new PEAR_ChannelFile; + $private->setName('__uri'); + $private->setDefaultPEARProtocols(); + $private->setBaseURL('REST1.0', '****'); + $private->setSummary('Pseudo-channel for static packages'); + $this->_addChannel($private); + } + $this->_rebuildFileMap(); + } + + $running = false; + } + } + + function _initializeDirs() + { + $ds = DIRECTORY_SEPARATOR; + // XXX Compatibility code should be removed in the future + // rename all registry files if any to lowercase + if (!OS_WINDOWS && file_exists($this->statedir) && is_dir($this->statedir) && + $handle = opendir($this->statedir)) { + $dest = $this->statedir . $ds; + while (false !== ($file = readdir($handle))) { + if (preg_match('/^.*[A-Z].*\.reg\\z/', $file)) { + rename($dest . $file, $dest . strtolower($file)); + } + } + closedir($handle); + } + + $this->_initializeChannelDirs(); + if (!file_exists($this->filemap)) { + $this->_rebuildFileMap(); + } + $this->_initializeDepDB(); + } + + function _initializeDepDB() + { + if (!isset($this->_dependencyDB)) { + static $initializing = false; + if (!$initializing) { + $initializing = true; + if (!$this->_config) { // never used? + $file = OS_WINDOWS ? 'pear.ini' : '.pearrc'; + $this->_config = &new PEAR_Config($this->statedir . DIRECTORY_SEPARATOR . + $file); + $this->_config->setRegistry($this); + $this->_config->set('php_dir', $this->install_dir); + } + + $this->_dependencyDB = &PEAR_DependencyDB::singleton($this->_config); + if (PEAR::isError($this->_dependencyDB)) { + // attempt to recover by removing the dep db + if (file_exists($this->_config->get('php_dir', null, 'pear.php.net') . + DIRECTORY_SEPARATOR . '.depdb')) { + @unlink($this->_config->get('php_dir', null, 'pear.php.net') . + DIRECTORY_SEPARATOR . '.depdb'); + } + + $this->_dependencyDB = &PEAR_DependencyDB::singleton($this->_config); + if (PEAR::isError($this->_dependencyDB)) { + echo $this->_dependencyDB->getMessage(); + echo 'Unrecoverable error'; + exit(1); + } + } + + $initializing = false; + } + } + } + + /** + * PEAR_Registry destructor. Makes sure no locks are forgotten. + * + * @access private + */ + function _PEAR_Registry() + { + parent::_PEAR(); + if (is_resource($this->lock_fp)) { + $this->_unlock(); + } + } + + /** + * Make sure the directory where we keep registry files exists. + * + * @return bool TRUE if directory exists, FALSE if it could not be + * created + * + * @access private + */ + function _assertStateDir($channel = false) + { + if ($channel && $this->_getChannelFromAlias($channel) != 'pear.php.net') { + return $this->_assertChannelStateDir($channel); + } + + static $init = false; + if (!file_exists($this->statedir)) { + if (!$this->hasWriteAccess()) { + return false; + } + + require_once 'System.php'; + if (!System::mkdir(array('-p', $this->statedir))) { + return $this->raiseError("could not create directory '{$this->statedir}'"); + } + $init = true; + } elseif (!is_dir($this->statedir)) { + return $this->raiseError('Cannot create directory ' . $this->statedir . ', ' . + 'it already exists and is not a directory'); + } + + $ds = DIRECTORY_SEPARATOR; + if (!file_exists($this->channelsdir)) { + if (!file_exists($this->channelsdir . $ds . 'pear.php.net.reg') || + !file_exists($this->channelsdir . $ds . 'pecl.php.net.reg') || + !file_exists($this->channelsdir . $ds . 'doc.php.net.reg') || + !file_exists($this->channelsdir . $ds . '__uri.reg')) { + $init = true; + } + } elseif (!is_dir($this->channelsdir)) { + return $this->raiseError('Cannot create directory ' . $this->channelsdir . ', ' . + 'it already exists and is not a directory'); + } + + if ($init) { + static $running = false; + if (!$running) { + $running = true; + $this->_initializeDirs(); + $running = false; + $init = false; + } + } else { + $this->_initializeDepDB(); + } + + return true; + } + + /** + * Make sure the directory where we keep registry files exists for a non-standard channel. + * + * @param string channel name + * @return bool TRUE if directory exists, FALSE if it could not be + * created + * + * @access private + */ + function _assertChannelStateDir($channel) + { + $ds = DIRECTORY_SEPARATOR; + if (!$channel || $this->_getChannelFromAlias($channel) == 'pear.php.net') { + if (!file_exists($this->channelsdir . $ds . 'pear.php.net.reg')) { + $this->_initializeChannelDirs(); + } + return $this->_assertStateDir($channel); + } + + $channelDir = $this->_channelDirectoryName($channel); + if (!is_dir($this->channelsdir) || + !file_exists($this->channelsdir . $ds . 'pear.php.net.reg')) { + $this->_initializeChannelDirs(); + } + + if (!file_exists($channelDir)) { + if (!$this->hasWriteAccess()) { + return false; + } + + require_once 'System.php'; + if (!System::mkdir(array('-p', $channelDir))) { + return $this->raiseError("could not create directory '" . $channelDir . + "'"); + } + } elseif (!is_dir($channelDir)) { + return $this->raiseError("could not create directory '" . $channelDir . + "', already exists and is not a directory"); + } + + return true; + } + + /** + * Make sure the directory where we keep registry files for channels exists + * + * @return bool TRUE if directory exists, FALSE if it could not be + * created + * + * @access private + */ + function _assertChannelDir() + { + if (!file_exists($this->channelsdir)) { + if (!$this->hasWriteAccess()) { + return false; + } + + require_once 'System.php'; + if (!System::mkdir(array('-p', $this->channelsdir))) { + return $this->raiseError("could not create directory '{$this->channelsdir}'"); + } + } elseif (!is_dir($this->channelsdir)) { + return $this->raiseError("could not create directory '{$this->channelsdir}" . + "', it already exists and is not a directory"); + } + + if (!file_exists($this->channelsdir . DIRECTORY_SEPARATOR . '.alias')) { + if (!$this->hasWriteAccess()) { + return false; + } + + require_once 'System.php'; + if (!System::mkdir(array('-p', $this->channelsdir . DIRECTORY_SEPARATOR . '.alias'))) { + return $this->raiseError("could not create directory '{$this->channelsdir}/.alias'"); + } + } elseif (!is_dir($this->channelsdir . DIRECTORY_SEPARATOR . '.alias')) { + return $this->raiseError("could not create directory '{$this->channelsdir}" . + "/.alias', it already exists and is not a directory"); + } + + return true; + } + + /** + * Get the name of the file where data for a given package is stored. + * + * @param string channel name, or false if this is a PEAR package + * @param string package name + * + * @return string registry file name + * + * @access public + */ + function _packageFileName($package, $channel = false) + { + if ($channel && $this->_getChannelFromAlias($channel) != 'pear.php.net') { + return $this->_channelDirectoryName($channel) . DIRECTORY_SEPARATOR . + strtolower($package) . '.reg'; + } + + return $this->statedir . DIRECTORY_SEPARATOR . strtolower($package) . '.reg'; + } + + /** + * Get the name of the file where data for a given channel is stored. + * @param string channel name + * @return string registry file name + */ + function _channelFileName($channel, $noaliases = false) + { + if (!$noaliases) { + if (file_exists($this->_getChannelAliasFileName($channel))) { + $channel = implode('', file($this->_getChannelAliasFileName($channel))); + } + } + return $this->channelsdir . DIRECTORY_SEPARATOR . str_replace('/', '_', + strtolower($channel)) . '.reg'; + } + + /** + * @param string + * @return string + */ + function _getChannelAliasFileName($alias) + { + return $this->channelsdir . DIRECTORY_SEPARATOR . '.alias' . + DIRECTORY_SEPARATOR . str_replace('/', '_', strtolower($alias)) . '.txt'; + } + + /** + * Get the name of a channel from its alias + */ + function _getChannelFromAlias($channel) + { + if (!$this->_channelExists($channel)) { + if ($channel == 'pear.php.net') { + return 'pear.php.net'; + } + + if ($channel == 'pecl.php.net') { + return 'pecl.php.net'; + } + + if ($channel == 'doc.php.net') { + return 'doc.php.net'; + } + + if ($channel == '__uri') { + return '__uri'; + } + + return false; + } + + $channel = strtolower($channel); + if (file_exists($this->_getChannelAliasFileName($channel))) { + // translate an alias to an actual channel + return implode('', file($this->_getChannelAliasFileName($channel))); + } + + return $channel; + } + + /** + * Get the alias of a channel from its alias or its name + */ + function _getAlias($channel) + { + if (!$this->_channelExists($channel)) { + if ($channel == 'pear.php.net') { + return 'pear'; + } + + if ($channel == 'pecl.php.net') { + return 'pecl'; + } + + if ($channel == 'doc.php.net') { + return 'phpdocs'; + } + + return false; + } + + $channel = $this->_getChannel($channel); + if (PEAR::isError($channel)) { + return $channel; + } + + return $channel->getAlias(); + } + + /** + * Get the name of the file where data for a given package is stored. + * + * @param string channel name, or false if this is a PEAR package + * @param string package name + * + * @return string registry file name + * + * @access public + */ + function _channelDirectoryName($channel) + { + if (!$channel || $this->_getChannelFromAlias($channel) == 'pear.php.net') { + return $this->statedir; + } + + $ch = $this->_getChannelFromAlias($channel); + if (!$ch) { + $ch = $channel; + } + + return $this->statedir . DIRECTORY_SEPARATOR . strtolower('.channel.' . + str_replace('/', '_', $ch)); + } + + function _openPackageFile($package, $mode, $channel = false) + { + if (!$this->_assertStateDir($channel)) { + return null; + } + + if (!in_array($mode, array('r', 'rb')) && !$this->hasWriteAccess()) { + return null; + } + + $file = $this->_packageFileName($package, $channel); + if (!file_exists($file) && $mode == 'r' || $mode == 'rb') { + return null; + } + + $fp = @fopen($file, $mode); + if (!$fp) { + return null; + } + + return $fp; + } + + function _closePackageFile($fp) + { + fclose($fp); + } + + function _openChannelFile($channel, $mode) + { + if (!$this->_assertChannelDir()) { + return null; + } + + if (!in_array($mode, array('r', 'rb')) && !$this->hasWriteAccess()) { + return null; + } + + $file = $this->_channelFileName($channel); + if (!file_exists($file) && $mode == 'r' || $mode == 'rb') { + return null; + } + + $fp = @fopen($file, $mode); + if (!$fp) { + return null; + } + + return $fp; + } + + function _closeChannelFile($fp) + { + fclose($fp); + } + + function _rebuildFileMap() + { + if (!class_exists('PEAR_Installer_Role')) { + require_once 'PEAR/Installer/Role.php'; + } + + $channels = $this->_listAllPackages(); + $files = array(); + foreach ($channels as $channel => $packages) { + foreach ($packages as $package) { + $version = $this->_packageInfo($package, 'version', $channel); + $filelist = $this->_packageInfo($package, 'filelist', $channel); + if (!is_array($filelist)) { + continue; + } + + foreach ($filelist as $name => $attrs) { + if (isset($attrs['attribs'])) { + $attrs = $attrs['attribs']; + } + + // it is possible for conflicting packages in different channels to + // conflict with data files/doc files + if ($name == 'dirtree') { + continue; + } + + if (isset($attrs['role']) && !in_array($attrs['role'], + PEAR_Installer_Role::getInstallableRoles())) { + // these are not installed + continue; + } + + if (isset($attrs['role']) && !in_array($attrs['role'], + PEAR_Installer_Role::getBaseinstallRoles())) { + $attrs['baseinstalldir'] = $package; + } + + if (isset($attrs['baseinstalldir'])) { + $file = $attrs['baseinstalldir'].DIRECTORY_SEPARATOR.$name; + } else { + $file = $name; + } + + $file = preg_replace(',^/+,', '', $file); + if ($channel != 'pear.php.net') { + if (!isset($files[$attrs['role']])) { + $files[$attrs['role']] = array(); + } + $files[$attrs['role']][$file] = array(strtolower($channel), + strtolower($package)); + } else { + if (!isset($files[$attrs['role']])) { + $files[$attrs['role']] = array(); + } + $files[$attrs['role']][$file] = strtolower($package); + } + } + } + } + + + $this->_assertStateDir(); + if (!$this->hasWriteAccess()) { + return false; + } + + $fp = @fopen($this->filemap, 'wb'); + if (!$fp) { + return false; + } + + $this->filemap_cache = $files; + fwrite($fp, serialize($files)); + fclose($fp); + return true; + } + + function _readFileMap() + { + if (!file_exists($this->filemap)) { + return array(); + } + + $fp = @fopen($this->filemap, 'r'); + if (!$fp) { + return $this->raiseError('PEAR_Registry: could not open filemap "' . $this->filemap . '"', PEAR_REGISTRY_ERROR_FILE, null, null, $php_errormsg); + } + + clearstatcache(); + $rt = get_magic_quotes_runtime(); + set_magic_quotes_runtime(0); + $fsize = filesize($this->filemap); + fclose($fp); + $data = file_get_contents($this->filemap); + set_magic_quotes_runtime($rt); + $tmp = unserialize($data); + if (!$tmp && $fsize > 7) { + return $this->raiseError('PEAR_Registry: invalid filemap data', PEAR_REGISTRY_ERROR_FORMAT, null, null, $data); + } + + $this->filemap_cache = $tmp; + return true; + } + + /** + * Lock the registry. + * + * @param integer lock mode, one of LOCK_EX, LOCK_SH or LOCK_UN. + * See flock manual for more information. + * + * @return bool TRUE on success, FALSE if locking failed, or a + * PEAR error if some other error occurs (such as the + * lock file not being writable). + * + * @access private + */ + function _lock($mode = LOCK_EX) + { + if (stristr(php_uname(), 'Windows 9')) { + return true; + } + + if ($mode != LOCK_UN && is_resource($this->lock_fp)) { + // XXX does not check type of lock (LOCK_SH/LOCK_EX) + return true; + } + + if (!$this->_assertStateDir()) { + if ($mode == LOCK_EX) { + return $this->raiseError('Registry directory is not writeable by the current user'); + } + + return true; + } + + $open_mode = 'w'; + // XXX People reported problems with LOCK_SH and 'w' + if ($mode === LOCK_SH || $mode === LOCK_UN) { + if (!file_exists($this->lockfile)) { + touch($this->lockfile); + } + $open_mode = 'r'; + } + + if (!is_resource($this->lock_fp)) { + $this->lock_fp = @fopen($this->lockfile, $open_mode); + } + + if (!is_resource($this->lock_fp)) { + $this->lock_fp = null; + return $this->raiseError("could not create lock file" . + (isset($php_errormsg) ? ": " . $php_errormsg : "")); + } + + if (!(int)flock($this->lock_fp, $mode)) { + switch ($mode) { + case LOCK_SH: $str = 'shared'; break; + case LOCK_EX: $str = 'exclusive'; break; + case LOCK_UN: $str = 'unlock'; break; + default: $str = 'unknown'; break; + } + + //is resource at this point, close it on error. + fclose($this->lock_fp); + $this->lock_fp = null; + return $this->raiseError("could not acquire $str lock ($this->lockfile)", + PEAR_REGISTRY_ERROR_LOCK); + } + + return true; + } + + function _unlock() + { + $ret = $this->_lock(LOCK_UN); + if (is_resource($this->lock_fp)) { + fclose($this->lock_fp); + } + + $this->lock_fp = null; + return $ret; + } + + function _packageExists($package, $channel = false) + { + return file_exists($this->_packageFileName($package, $channel)); + } + + /** + * Determine whether a channel exists in the registry + * + * @param string Channel name + * @param bool if true, then aliases will be ignored + * @return boolean + */ + function _channelExists($channel, $noaliases = false) + { + $a = file_exists($this->_channelFileName($channel, $noaliases)); + if (!$a && $channel == 'pear.php.net') { + return true; + } + + if (!$a && $channel == 'pecl.php.net') { + return true; + } + + if (!$a && $channel == 'doc.php.net') { + return true; + } + + return $a; + } + + /** + * Determine whether a mirror exists within the deafult channel in the registry + * + * @param string Channel name + * @param string Mirror name + * + * @return boolean + */ + function _mirrorExists($channel, $mirror) + { + $data = $this->_channelInfo($channel); + if (!isset($data['servers']['mirror'])) { + return false; + } + + foreach ($data['servers']['mirror'] as $m) { + if ($m['attribs']['host'] == $mirror) { + return true; + } + } + + return false; + } + + /** + * @param PEAR_ChannelFile Channel object + * @param donotuse + * @param string Last-Modified HTTP tag from remote request + * @return boolean|PEAR_Error True on creation, false if it already exists + */ + function _addChannel($channel, $update = false, $lastmodified = false) + { + if (!is_a($channel, 'PEAR_ChannelFile')) { + return false; + } + + if (!$channel->validate()) { + return false; + } + + if (file_exists($this->_channelFileName($channel->getName()))) { + if (!$update) { + return false; + } + + $checker = $this->_getChannel($channel->getName()); + if (PEAR::isError($checker)) { + return $checker; + } + + if ($channel->getAlias() != $checker->getAlias()) { + if (file_exists($this->_getChannelAliasFileName($checker->getAlias()))) { + @unlink($this->_getChannelAliasFileName($checker->getAlias())); + } + } + } else { + if ($update && !in_array($channel->getName(), array('pear.php.net', 'pecl.php.net', 'doc.php.net'))) { + return false; + } + } + + $ret = $this->_assertChannelDir(); + if (PEAR::isError($ret)) { + return $ret; + } + + $ret = $this->_assertChannelStateDir($channel->getName()); + if (PEAR::isError($ret)) { + return $ret; + } + + if ($channel->getAlias() != $channel->getName()) { + if (file_exists($this->_getChannelAliasFileName($channel->getAlias())) && + $this->_getChannelFromAlias($channel->getAlias()) != $channel->getName()) { + $channel->setAlias($channel->getName()); + } + + if (!$this->hasWriteAccess()) { + return false; + } + + $fp = @fopen($this->_getChannelAliasFileName($channel->getAlias()), 'w'); + if (!$fp) { + return false; + } + + fwrite($fp, $channel->getName()); + fclose($fp); + } + + if (!$this->hasWriteAccess()) { + return false; + } + + $fp = @fopen($this->_channelFileName($channel->getName()), 'wb'); + if (!$fp) { + return false; + } + + $info = $channel->toArray(); + if ($lastmodified) { + $info['_lastmodified'] = $lastmodified; + } else { + $info['_lastmodified'] = date('r'); + } + + fwrite($fp, serialize($info)); + fclose($fp); + return true; + } + + /** + * Deletion fails if there are any packages installed from the channel + * @param string|PEAR_ChannelFile channel name + * @return boolean|PEAR_Error True on deletion, false if it doesn't exist + */ + function _deleteChannel($channel) + { + if (!is_string($channel)) { + if (!is_a($channel, 'PEAR_ChannelFile')) { + return false; + } + + if (!$channel->validate()) { + return false; + } + $channel = $channel->getName(); + } + + if ($this->_getChannelFromAlias($channel) == '__uri') { + return false; + } + + if ($this->_getChannelFromAlias($channel) == 'pecl.php.net') { + return false; + } + + if ($this->_getChannelFromAlias($channel) == 'doc.php.net') { + return false; + } + + if (!$this->_channelExists($channel)) { + return false; + } + + if (!$channel || $this->_getChannelFromAlias($channel) == 'pear.php.net') { + return false; + } + + $channel = $this->_getChannelFromAlias($channel); + if ($channel == 'pear.php.net') { + return false; + } + + $test = $this->_listChannelPackages($channel); + if (count($test)) { + return false; + } + + $test = @rmdir($this->_channelDirectoryName($channel)); + if (!$test) { + return false; + } + + $file = $this->_getChannelAliasFileName($this->_getAlias($channel)); + if (file_exists($file)) { + $test = @unlink($file); + if (!$test) { + return false; + } + } + + $file = $this->_channelFileName($channel); + $ret = true; + if (file_exists($file)) { + $ret = @unlink($file); + } + + return $ret; + } + + /** + * Determine whether a channel exists in the registry + * @param string Channel Alias + * @return boolean + */ + function _isChannelAlias($alias) + { + return file_exists($this->_getChannelAliasFileName($alias)); + } + + /** + * @param string|null + * @param string|null + * @param string|null + * @return array|null + * @access private + */ + function _packageInfo($package = null, $key = null, $channel = 'pear.php.net') + { + if ($package === null) { + if ($channel === null) { + $channels = $this->_listChannels(); + $ret = array(); + foreach ($channels as $channel) { + $channel = strtolower($channel); + $ret[$channel] = array(); + $packages = $this->_listPackages($channel); + foreach ($packages as $package) { + $ret[$channel][] = $this->_packageInfo($package, null, $channel); + } + } + + return $ret; + } + + $ps = $this->_listPackages($channel); + if (!count($ps)) { + return array(); + } + return array_map(array(&$this, '_packageInfo'), + $ps, array_fill(0, count($ps), null), + array_fill(0, count($ps), $channel)); + } + + $fp = $this->_openPackageFile($package, 'r', $channel); + if ($fp === null) { + return null; + } + + $rt = get_magic_quotes_runtime(); + set_magic_quotes_runtime(0); + clearstatcache(); + $this->_closePackageFile($fp); + $data = file_get_contents($this->_packageFileName($package, $channel)); + set_magic_quotes_runtime($rt); + $data = unserialize($data); + if ($key === null) { + return $data; + } + + // compatibility for package.xml version 2.0 + if (isset($data['old'][$key])) { + return $data['old'][$key]; + } + + if (isset($data[$key])) { + return $data[$key]; + } + + return null; + } + + /** + * @param string Channel name + * @param bool whether to strictly retrieve info of channels, not just aliases + * @return array|null + */ + function _channelInfo($channel, $noaliases = false) + { + if (!$this->_channelExists($channel, $noaliases)) { + return null; + } + + $fp = $this->_openChannelFile($channel, 'r'); + if ($fp === null) { + return null; + } + + $rt = get_magic_quotes_runtime(); + set_magic_quotes_runtime(0); + clearstatcache(); + $this->_closeChannelFile($fp); + $data = file_get_contents($this->_channelFileName($channel)); + set_magic_quotes_runtime($rt); + $data = unserialize($data); + return $data; + } + + function _listChannels() + { + $channellist = array(); + if (!file_exists($this->channelsdir) || !is_dir($this->channelsdir)) { + return array('pear.php.net', 'pecl.php.net', 'doc.php.net', '__uri'); + } + + $dp = opendir($this->channelsdir); + while ($ent = readdir($dp)) { + if ($ent{0} == '.' || substr($ent, -4) != '.reg') { + continue; + } + + if ($ent == '__uri.reg') { + $channellist[] = '__uri'; + continue; + } + + $channellist[] = str_replace('_', '/', substr($ent, 0, -4)); + } + + closedir($dp); + if (!in_array('pear.php.net', $channellist)) { + $channellist[] = 'pear.php.net'; + } + + if (!in_array('pecl.php.net', $channellist)) { + $channellist[] = 'pecl.php.net'; + } + + if (!in_array('doc.php.net', $channellist)) { + $channellist[] = 'doc.php.net'; + } + + + if (!in_array('__uri', $channellist)) { + $channellist[] = '__uri'; + } + + natsort($channellist); + return $channellist; + } + + function _listPackages($channel = false) + { + if ($channel && $this->_getChannelFromAlias($channel) != 'pear.php.net') { + return $this->_listChannelPackages($channel); + } + + if (!file_exists($this->statedir) || !is_dir($this->statedir)) { + return array(); + } + + $pkglist = array(); + $dp = opendir($this->statedir); + if (!$dp) { + return $pkglist; + } + + while ($ent = readdir($dp)) { + if ($ent{0} == '.' || substr($ent, -4) != '.reg') { + continue; + } + + $pkglist[] = substr($ent, 0, -4); + } + closedir($dp); + return $pkglist; + } + + function _listChannelPackages($channel) + { + $pkglist = array(); + if (!file_exists($this->_channelDirectoryName($channel)) || + !is_dir($this->_channelDirectoryName($channel))) { + return array(); + } + + $dp = opendir($this->_channelDirectoryName($channel)); + if (!$dp) { + return $pkglist; + } + + while ($ent = readdir($dp)) { + if ($ent{0} == '.' || substr($ent, -4) != '.reg') { + continue; + } + $pkglist[] = substr($ent, 0, -4); + } + + closedir($dp); + return $pkglist; + } + + function _listAllPackages() + { + $ret = array(); + foreach ($this->_listChannels() as $channel) { + $ret[$channel] = $this->_listPackages($channel); + } + + return $ret; + } + + /** + * Add an installed package to the registry + * @param string package name + * @param array package info (parsed by PEAR_Common::infoFrom*() methods) + * @return bool success of saving + * @access private + */ + function _addPackage($package, $info) + { + if ($this->_packageExists($package)) { + return false; + } + + $fp = $this->_openPackageFile($package, 'wb'); + if ($fp === null) { + return false; + } + + $info['_lastmodified'] = time(); + fwrite($fp, serialize($info)); + $this->_closePackageFile($fp); + if (isset($info['filelist'])) { + $this->_rebuildFileMap(); + } + + return true; + } + + /** + * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 + * @return bool + * @access private + */ + function _addPackage2($info) + { + if (!is_a($info, 'PEAR_PackageFile_v1') && !is_a($info, 'PEAR_PackageFile_v2')) { + return false; + } + + if (!$info->validate()) { + if (class_exists('PEAR_Common')) { + $ui = PEAR_Frontend::singleton(); + if ($ui) { + foreach ($info->getValidationWarnings() as $err) { + $ui->log($err['message'], true); + } + } + } + return false; + } + + $channel = $info->getChannel(); + $package = $info->getPackage(); + $save = $info; + if ($this->_packageExists($package, $channel)) { + return false; + } + + if (!$this->_channelExists($channel, true)) { + return false; + } + + $info = $info->toArray(true); + if (!$info) { + return false; + } + + $fp = $this->_openPackageFile($package, 'wb', $channel); + if ($fp === null) { + return false; + } + + $info['_lastmodified'] = time(); + fwrite($fp, serialize($info)); + $this->_closePackageFile($fp); + $this->_rebuildFileMap(); + return true; + } + + /** + * @param string Package name + * @param array parsed package.xml 1.0 + * @param bool this parameter is only here for BC. Don't use it. + * @access private + */ + function _updatePackage($package, $info, $merge = true) + { + $oldinfo = $this->_packageInfo($package); + if (empty($oldinfo)) { + return false; + } + + $fp = $this->_openPackageFile($package, 'w'); + if ($fp === null) { + return false; + } + + if (is_object($info)) { + $info = $info->toArray(); + } + $info['_lastmodified'] = time(); + + $newinfo = $info; + if ($merge) { + $info = array_merge($oldinfo, $info); + } else { + $diff = $info; + } + + fwrite($fp, serialize($info)); + $this->_closePackageFile($fp); + if (isset($newinfo['filelist'])) { + $this->_rebuildFileMap(); + } + + return true; + } + + /** + * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 + * @return bool + * @access private + */ + function _updatePackage2($info) + { + if (!$this->_packageExists($info->getPackage(), $info->getChannel())) { + return false; + } + + $fp = $this->_openPackageFile($info->getPackage(), 'w', $info->getChannel()); + if ($fp === null) { + return false; + } + + $save = $info; + $info = $save->getArray(true); + $info['_lastmodified'] = time(); + fwrite($fp, serialize($info)); + $this->_closePackageFile($fp); + $this->_rebuildFileMap(); + return true; + } + + /** + * @param string Package name + * @param string Channel name + * @return PEAR_PackageFile_v1|PEAR_PackageFile_v2|null + * @access private + */ + function &_getPackage($package, $channel = 'pear.php.net') + { + $info = $this->_packageInfo($package, null, $channel); + if ($info === null) { + return $info; + } + + $a = $this->_config; + if (!$a) { + $this->_config = &new PEAR_Config; + $this->_config->set('php_dir', $this->statedir); + } + + if (!class_exists('PEAR_PackageFile')) { + require_once 'PEAR/PackageFile.php'; + } + + $pkg = &new PEAR_PackageFile($this->_config); + $pf = &$pkg->fromArray($info); + return $pf; + } + + /** + * @param string channel name + * @param bool whether to strictly retrieve channel names + * @return PEAR_ChannelFile|PEAR_Error + * @access private + */ + function &_getChannel($channel, $noaliases = false) + { + $ch = false; + if ($this->_channelExists($channel, $noaliases)) { + $chinfo = $this->_channelInfo($channel, $noaliases); + if ($chinfo) { + if (!class_exists('PEAR_ChannelFile')) { + require_once 'PEAR/ChannelFile.php'; + } + + $ch = &PEAR_ChannelFile::fromArrayWithErrors($chinfo); + } + } + + if ($ch) { + if ($ch->validate()) { + return $ch; + } + + foreach ($ch->getErrors(true) as $err) { + $message = $err['message'] . "\n"; + } + + $ch = PEAR::raiseError($message); + return $ch; + } + + if ($this->_getChannelFromAlias($channel) == 'pear.php.net') { + // the registry is not properly set up, so use defaults + if (!class_exists('PEAR_ChannelFile')) { + require_once 'PEAR/ChannelFile.php'; + } + + $pear_channel = new PEAR_ChannelFile; + $pear_channel->setServer('pear.php.net'); + $pear_channel->setAlias('pear'); + $pear_channel->setSummary('PHP Extension and Application Repository'); + $pear_channel->setDefaultPEARProtocols(); + $pear_channel->setBaseURL('REST1.0', 'http://pear.php.net/rest/'); + $pear_channel->setBaseURL('REST1.1', 'http://pear.php.net/rest/'); + $pear_channel->setBaseURL('REST1.3', 'http://pear.php.net/rest/'); + return $pear_channel; + } + + if ($this->_getChannelFromAlias($channel) == 'pecl.php.net') { + // the registry is not properly set up, so use defaults + if (!class_exists('PEAR_ChannelFile')) { + require_once 'PEAR/ChannelFile.php'; + } + $pear_channel = new PEAR_ChannelFile; + $pear_channel->setServer('pecl.php.net'); + $pear_channel->setAlias('pecl'); + $pear_channel->setSummary('PHP Extension Community Library'); + $pear_channel->setDefaultPEARProtocols(); + $pear_channel->setBaseURL('REST1.0', 'http://pecl.php.net/rest/'); + $pear_channel->setBaseURL('REST1.1', 'http://pecl.php.net/rest/'); + $pear_channel->setValidationPackage('PEAR_Validator_PECL', '1.0'); + return $pear_channel; + } + + if ($this->_getChannelFromAlias($channel) == 'doc.php.net') { + // the registry is not properly set up, so use defaults + if (!class_exists('PEAR_ChannelFile')) { + require_once 'PEAR/ChannelFile.php'; + } + + $doc_channel = new PEAR_ChannelFile; + $doc_channel->setServer('doc.php.net'); + $doc_channel->setAlias('phpdocs'); + $doc_channel->setSummary('PHP Documentation Team'); + $doc_channel->setDefaultPEARProtocols(); + $doc_channel->setBaseURL('REST1.0', 'http://doc.php.net/rest/'); + $doc_channel->setBaseURL('REST1.1', 'http://doc.php.net/rest/'); + $doc_channel->setBaseURL('REST1.3', 'http://doc.php.net/rest/'); + return $doc_channel; + } + + + if ($this->_getChannelFromAlias($channel) == '__uri') { + // the registry is not properly set up, so use defaults + if (!class_exists('PEAR_ChannelFile')) { + require_once 'PEAR/ChannelFile.php'; + } + + $private = new PEAR_ChannelFile; + $private->setName('__uri'); + $private->setDefaultPEARProtocols(); + $private->setBaseURL('REST1.0', '****'); + $private->setSummary('Pseudo-channel for static packages'); + return $private; + } + + return $ch; + } + + /** + * @param string Package name + * @param string Channel name + * @return bool + */ + function packageExists($package, $channel = 'pear.php.net') + { + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + $ret = $this->_packageExists($package, $channel); + $this->_unlock(); + return $ret; + } + + // }}} + + // {{{ channelExists() + + /** + * @param string channel name + * @param bool if true, then aliases will be ignored + * @return bool + */ + function channelExists($channel, $noaliases = false) + { + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + $ret = $this->_channelExists($channel, $noaliases); + $this->_unlock(); + return $ret; + } + + // }}} + + /** + * @param string channel name mirror is in + * @param string mirror name + * + * @return bool + */ + function mirrorExists($channel, $mirror) + { + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + + $ret = $this->_mirrorExists($channel, $mirror); + $this->_unlock(); + return $ret; + } + + // {{{ isAlias() + + /** + * Determines whether the parameter is an alias of a channel + * @param string + * @return bool + */ + function isAlias($alias) + { + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + $ret = $this->_isChannelAlias($alias); + $this->_unlock(); + return $ret; + } + + // }}} + // {{{ packageInfo() + + /** + * @param string|null + * @param string|null + * @param string + * @return array|null + */ + function packageInfo($package = null, $key = null, $channel = 'pear.php.net') + { + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + $ret = $this->_packageInfo($package, $key, $channel); + $this->_unlock(); + return $ret; + } + + // }}} + // {{{ channelInfo() + + /** + * Retrieve a raw array of channel data. + * + * Do not use this, instead use {@link getChannel()} for normal + * operations. Array structure is undefined in this method + * @param string channel name + * @param bool whether to strictly retrieve information only on non-aliases + * @return array|null|PEAR_Error + */ + function channelInfo($channel = null, $noaliases = false) + { + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + $ret = $this->_channelInfo($channel, $noaliases); + $this->_unlock(); + return $ret; + } + + // }}} + + /** + * @param string + */ + function channelName($channel) + { + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + $ret = $this->_getChannelFromAlias($channel); + $this->_unlock(); + return $ret; + } + + /** + * @param string + */ + function channelAlias($channel) + { + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + $ret = $this->_getAlias($channel); + $this->_unlock(); + return $ret; + } + // {{{ listPackages() + + function listPackages($channel = false) + { + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + $ret = $this->_listPackages($channel); + $this->_unlock(); + return $ret; + } + + // }}} + // {{{ listAllPackages() + + function listAllPackages() + { + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + $ret = $this->_listAllPackages(); + $this->_unlock(); + return $ret; + } + + // }}} + // {{{ listChannel() + + function listChannels() + { + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + $ret = $this->_listChannels(); + $this->_unlock(); + return $ret; + } + + // }}} + // {{{ addPackage() + + /** + * Add an installed package to the registry + * @param string|PEAR_PackageFile_v1|PEAR_PackageFile_v2 package name or object + * that will be passed to {@link addPackage2()} + * @param array package info (parsed by PEAR_Common::infoFrom*() methods) + * @return bool success of saving + */ + function addPackage($package, $info) + { + if (is_object($info)) { + return $this->addPackage2($info); + } + if (PEAR::isError($e = $this->_lock(LOCK_EX))) { + return $e; + } + $ret = $this->_addPackage($package, $info); + $this->_unlock(); + if ($ret) { + if (!class_exists('PEAR_PackageFile_v1')) { + require_once 'PEAR/PackageFile/v1.php'; + } + $pf = new PEAR_PackageFile_v1; + $pf->setConfig($this->_config); + $pf->fromArray($info); + $this->_dependencyDB->uninstallPackage($pf); + $this->_dependencyDB->installPackage($pf); + } + return $ret; + } + + // }}} + // {{{ addPackage2() + + function addPackage2($info) + { + if (!is_object($info)) { + return $this->addPackage($info['package'], $info); + } + if (PEAR::isError($e = $this->_lock(LOCK_EX))) { + return $e; + } + $ret = $this->_addPackage2($info); + $this->_unlock(); + if ($ret) { + $this->_dependencyDB->uninstallPackage($info); + $this->_dependencyDB->installPackage($info); + } + return $ret; + } + + // }}} + // {{{ updateChannel() + + /** + * For future expandibility purposes, separate this + * @param PEAR_ChannelFile + */ + function updateChannel($channel, $lastmodified = null) + { + if ($channel->getName() == '__uri') { + return false; + } + return $this->addChannel($channel, $lastmodified, true); + } + + // }}} + // {{{ deleteChannel() + + /** + * Deletion fails if there are any packages installed from the channel + * @param string|PEAR_ChannelFile channel name + * @return boolean|PEAR_Error True on deletion, false if it doesn't exist + */ + function deleteChannel($channel) + { + if (PEAR::isError($e = $this->_lock(LOCK_EX))) { + return $e; + } + + $ret = $this->_deleteChannel($channel); + $this->_unlock(); + if ($ret && is_a($this->_config, 'PEAR_Config')) { + $this->_config->setChannels($this->listChannels()); + } + + return $ret; + } + + // }}} + // {{{ addChannel() + + /** + * @param PEAR_ChannelFile Channel object + * @param string Last-Modified header from HTTP for caching + * @return boolean|PEAR_Error True on creation, false if it already exists + */ + function addChannel($channel, $lastmodified = false, $update = false) + { + if (!is_a($channel, 'PEAR_ChannelFile') || !$channel->validate()) { + return false; + } + + if (PEAR::isError($e = $this->_lock(LOCK_EX))) { + return $e; + } + + $ret = $this->_addChannel($channel, $update, $lastmodified); + $this->_unlock(); + if (!$update && $ret && is_a($this->_config, 'PEAR_Config')) { + $this->_config->setChannels($this->listChannels()); + } + + return $ret; + } + + // }}} + // {{{ deletePackage() + + function deletePackage($package, $channel = 'pear.php.net') + { + if (PEAR::isError($e = $this->_lock(LOCK_EX))) { + return $e; + } + + $file = $this->_packageFileName($package, $channel); + $ret = file_exists($file) ? @unlink($file) : false; + $this->_rebuildFileMap(); + $this->_unlock(); + $p = array('channel' => $channel, 'package' => $package); + $this->_dependencyDB->uninstallPackage($p); + return $ret; + } + + // }}} + // {{{ updatePackage() + + function updatePackage($package, $info, $merge = true) + { + if (is_object($info)) { + return $this->updatePackage2($info, $merge); + } + if (PEAR::isError($e = $this->_lock(LOCK_EX))) { + return $e; + } + $ret = $this->_updatePackage($package, $info, $merge); + $this->_unlock(); + if ($ret) { + if (!class_exists('PEAR_PackageFile_v1')) { + require_once 'PEAR/PackageFile/v1.php'; + } + $pf = new PEAR_PackageFile_v1; + $pf->setConfig($this->_config); + $pf->fromArray($this->packageInfo($package)); + $this->_dependencyDB->uninstallPackage($pf); + $this->_dependencyDB->installPackage($pf); + } + return $ret; + } + + // }}} + // {{{ updatePackage2() + + function updatePackage2($info) + { + + if (!is_object($info)) { + return $this->updatePackage($info['package'], $info, $merge); + } + + if (!$info->validate(PEAR_VALIDATE_DOWNLOADING)) { + return false; + } + + if (PEAR::isError($e = $this->_lock(LOCK_EX))) { + return $e; + } + + $ret = $this->_updatePackage2($info); + $this->_unlock(); + if ($ret) { + $this->_dependencyDB->uninstallPackage($info); + $this->_dependencyDB->installPackage($info); + } + + return $ret; + } + + // }}} + // {{{ getChannel() + /** + * @param string channel name + * @param bool whether to strictly return raw channels (no aliases) + * @return PEAR_ChannelFile|PEAR_Error + */ + function &getChannel($channel, $noaliases = false) + { + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + $ret = &$this->_getChannel($channel, $noaliases); + $this->_unlock(); + if (!$ret) { + return PEAR::raiseError('Unknown channel: ' . $channel); + } + return $ret; + } + + // }}} + // {{{ getPackage() + /** + * @param string package name + * @param string channel name + * @return PEAR_PackageFile_v1|PEAR_PackageFile_v2|null + */ + function &getPackage($package, $channel = 'pear.php.net') + { + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + $pf = &$this->_getPackage($package, $channel); + $this->_unlock(); + return $pf; + } + + // }}} + + /** + * Get PEAR_PackageFile_v[1/2] objects representing the contents of + * a dependency group that are installed. + * + * This is used at uninstall-time + * @param array + * @return array|false + */ + function getInstalledGroup($group) + { + $ret = array(); + if (isset($group['package'])) { + if (!isset($group['package'][0])) { + $group['package'] = array($group['package']); + } + foreach ($group['package'] as $package) { + $depchannel = isset($package['channel']) ? $package['channel'] : '__uri'; + $p = &$this->getPackage($package['name'], $depchannel); + if ($p) { + $save = &$p; + $ret[] = &$save; + } + } + } + if (isset($group['subpackage'])) { + if (!isset($group['subpackage'][0])) { + $group['subpackage'] = array($group['subpackage']); + } + foreach ($group['subpackage'] as $package) { + $depchannel = isset($package['channel']) ? $package['channel'] : '__uri'; + $p = &$this->getPackage($package['name'], $depchannel); + if ($p) { + $save = &$p; + $ret[] = &$save; + } + } + } + if (!count($ret)) { + return false; + } + return $ret; + } + + // {{{ getChannelValidator() + /** + * @param string channel name + * @return PEAR_Validate|false + */ + function &getChannelValidator($channel) + { + $chan = $this->getChannel($channel); + if (PEAR::isError($chan)) { + return $chan; + } + $val = $chan->getValidationObject(); + return $val; + } + // }}} + // {{{ getChannels() + /** + * @param string channel name + * @return array an array of PEAR_ChannelFile objects representing every installed channel + */ + function &getChannels() + { + $ret = array(); + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + foreach ($this->_listChannels() as $channel) { + $e = &$this->_getChannel($channel); + if (!$e || PEAR::isError($e)) { + continue; + } + $ret[] = $e; + } + $this->_unlock(); + return $ret; + } + + // }}} + // {{{ checkFileMap() + + /** + * Test whether a file or set of files belongs to a package. + * + * If an array is passed in + * @param string|array file path, absolute or relative to the pear + * install dir + * @param string|array name of PEAR package or array('package' => name, 'channel' => + * channel) of a package that will be ignored + * @param string API version - 1.1 will exclude any files belonging to a package + * @param array private recursion variable + * @return array|false which package and channel the file belongs to, or an empty + * string if the file does not belong to an installed package, + * or belongs to the second parameter's package + */ + function checkFileMap($path, $package = false, $api = '1.0', $attrs = false) + { + if (is_array($path)) { + static $notempty; + if (empty($notempty)) { + if (!class_exists('PEAR_Installer_Role')) { + require_once 'PEAR/Installer/Role.php'; + } + $notempty = create_function('$a','return !empty($a);'); + } + $package = is_array($package) ? array(strtolower($package[0]), strtolower($package[1])) + : strtolower($package); + $pkgs = array(); + foreach ($path as $name => $attrs) { + if (is_array($attrs)) { + if (isset($attrs['install-as'])) { + $name = $attrs['install-as']; + } + if (!in_array($attrs['role'], PEAR_Installer_Role::getInstallableRoles())) { + // these are not installed + continue; + } + if (!in_array($attrs['role'], PEAR_Installer_Role::getBaseinstallRoles())) { + $attrs['baseinstalldir'] = is_array($package) ? $package[1] : $package; + } + if (isset($attrs['baseinstalldir'])) { + $name = $attrs['baseinstalldir'] . DIRECTORY_SEPARATOR . $name; + } + } + $pkgs[$name] = $this->checkFileMap($name, $package, $api, $attrs); + if (PEAR::isError($pkgs[$name])) { + return $pkgs[$name]; + } + } + return array_filter($pkgs, $notempty); + } + if (empty($this->filemap_cache)) { + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + $err = $this->_readFileMap(); + $this->_unlock(); + if (PEAR::isError($err)) { + return $err; + } + } + if (!$attrs) { + $attrs = array('role' => 'php'); // any old call would be for PHP role only + } + if (isset($this->filemap_cache[$attrs['role']][$path])) { + if ($api >= '1.1' && $this->filemap_cache[$attrs['role']][$path] == $package) { + return false; + } + return $this->filemap_cache[$attrs['role']][$path]; + } + $l = strlen($this->install_dir); + if (substr($path, 0, $l) == $this->install_dir) { + $path = preg_replace('!^'.DIRECTORY_SEPARATOR.'+!', '', substr($path, $l)); + } + if (isset($this->filemap_cache[$attrs['role']][$path])) { + if ($api >= '1.1' && $this->filemap_cache[$attrs['role']][$path] == $package) { + return false; + } + return $this->filemap_cache[$attrs['role']][$path]; + } + return false; + } + + // }}} + // {{{ flush() + /** + * Force a reload of the filemap + * @since 1.5.0RC3 + */ + function flushFileMap() + { + $this->filemap_cache = null; + clearstatcache(); // ensure that the next read gets the full, current filemap + } + + // }}} + // {{{ apiVersion() + /** + * Get the expected API version. Channels API is version 1.1, as it is backwards + * compatible with 1.0 + * @return string + */ + function apiVersion() + { + return '1.1'; + } + // }}} + + + /** + * Parse a package name, or validate a parsed package name array + * @param string|array pass in an array of format + * array( + * 'package' => 'pname', + * ['channel' => 'channame',] + * ['version' => 'version',] + * ['state' => 'state',] + * ['group' => 'groupname']) + * or a string of format + * [channel://][channame/]pname[-version|-state][/group=groupname] + * @return array|PEAR_Error + */ + function parsePackageName($param, $defaultchannel = 'pear.php.net') + { + $saveparam = $param; + if (is_array($param)) { + // convert to string for error messages + $saveparam = $this->parsedPackageNameToString($param); + // process the array + if (!isset($param['package'])) { + return PEAR::raiseError('parsePackageName(): array $param ' . + 'must contain a valid package name in index "param"', + 'package', null, null, $param); + } + if (!isset($param['uri'])) { + if (!isset($param['channel'])) { + $param['channel'] = $defaultchannel; + } + } else { + $param['channel'] = '__uri'; + } + } else { + $components = @parse_url((string) $param); + if (isset($components['scheme'])) { + if ($components['scheme'] == 'http') { + // uri package + $param = array('uri' => $param, 'channel' => '__uri'); + } elseif($components['scheme'] != 'channel') { + return PEAR::raiseError('parsePackageName(): only channel:// uris may ' . + 'be downloaded, not "' . $param . '"', 'invalid', null, null, $param); + } + } + if (!isset($components['path'])) { + return PEAR::raiseError('parsePackageName(): array $param ' . + 'must contain a valid package name in "' . $param . '"', + 'package', null, null, $param); + } + if (isset($components['host'])) { + // remove the leading "/" + $components['path'] = substr($components['path'], 1); + } + if (!isset($components['scheme'])) { + if (strpos($components['path'], '/') !== false) { + if ($components['path']{0} == '/') { + return PEAR::raiseError('parsePackageName(): this is not ' . + 'a package name, it begins with "/" in "' . $param . '"', + 'invalid', null, null, $param); + } + $parts = explode('/', $components['path']); + $components['host'] = array_shift($parts); + if (count($parts) > 1) { + $components['path'] = array_pop($parts); + $components['host'] .= '/' . implode('/', $parts); + } else { + $components['path'] = implode('/', $parts); + } + } else { + $components['host'] = $defaultchannel; + } + } else { + if (strpos($components['path'], '/')) { + $parts = explode('/', $components['path']); + $components['path'] = array_pop($parts); + $components['host'] .= '/' . implode('/', $parts); + } + } + + if (is_array($param)) { + $param['package'] = $components['path']; + } else { + $param = array( + 'package' => $components['path'] + ); + if (isset($components['host'])) { + $param['channel'] = $components['host']; + } + } + if (isset($components['fragment'])) { + $param['group'] = $components['fragment']; + } + if (isset($components['user'])) { + $param['user'] = $components['user']; + } + if (isset($components['pass'])) { + $param['pass'] = $components['pass']; + } + if (isset($components['query'])) { + parse_str($components['query'], $param['opts']); + } + // check for extension + $pathinfo = pathinfo($param['package']); + if (isset($pathinfo['extension']) && + in_array(strtolower($pathinfo['extension']), array('tgz', 'tar'))) { + $param['extension'] = $pathinfo['extension']; + $param['package'] = substr($pathinfo['basename'], 0, + strlen($pathinfo['basename']) - 4); + } + // check for version + if (strpos($param['package'], '-')) { + $test = explode('-', $param['package']); + if (count($test) != 2) { + return PEAR::raiseError('parsePackageName(): only one version/state ' . + 'delimiter "-" is allowed in "' . $saveparam . '"', + 'version', null, null, $param); + } + list($param['package'], $param['version']) = $test; + } + } + // validation + $info = $this->channelExists($param['channel']); + if (PEAR::isError($info)) { + return $info; + } + if (!$info) { + return PEAR::raiseError('unknown channel "' . $param['channel'] . + '" in "' . $saveparam . '"', 'channel', null, null, $param); + } + $chan = $this->getChannel($param['channel']); + if (PEAR::isError($chan)) { + return $chan; + } + if (!$chan) { + return PEAR::raiseError("Exception: corrupt registry, could not " . + "retrieve channel " . $param['channel'] . " information", + 'registry', null, null, $param); + } + $param['channel'] = $chan->getName(); + $validate = $chan->getValidationObject(); + $vpackage = $chan->getValidationPackage(); + // validate package name + if (!$validate->validPackageName($param['package'], $vpackage['_content'])) { + return PEAR::raiseError('parsePackageName(): invalid package name "' . + $param['package'] . '" in "' . $saveparam . '"', + 'package', null, null, $param); + } + if (isset($param['group'])) { + if (!PEAR_Validate::validGroupName($param['group'])) { + return PEAR::raiseError('parsePackageName(): dependency group "' . $param['group'] . + '" is not a valid group name in "' . $saveparam . '"', 'group', null, null, + $param); + } + } + if (isset($param['state'])) { + if (!in_array(strtolower($param['state']), $validate->getValidStates())) { + return PEAR::raiseError('parsePackageName(): state "' . $param['state'] + . '" is not a valid state in "' . $saveparam . '"', + 'state', null, null, $param); + } + } + if (isset($param['version'])) { + if (isset($param['state'])) { + return PEAR::raiseError('parsePackageName(): cannot contain both ' . + 'a version and a stability (state) in "' . $saveparam . '"', + 'version/state', null, null, $param); + } + // check whether version is actually a state + if (in_array(strtolower($param['version']), $validate->getValidStates())) { + $param['state'] = strtolower($param['version']); + unset($param['version']); + } else { + if (!$validate->validVersion($param['version'])) { + return PEAR::raiseError('parsePackageName(): "' . $param['version'] . + '" is neither a valid version nor a valid state in "' . + $saveparam . '"', 'version/state', null, null, $param); + } + } + } + return $param; + } + + /** + * @param array + * @return string + */ + function parsedPackageNameToString($parsed, $brief = false) + { + if (is_string($parsed)) { + return $parsed; + } + if (is_object($parsed)) { + $p = $parsed; + $parsed = array( + 'package' => $p->getPackage(), + 'channel' => $p->getChannel(), + 'version' => $p->getVersion(), + ); + } + if (isset($parsed['uri'])) { + return $parsed['uri']; + } + if ($brief) { + if ($channel = $this->channelAlias($parsed['channel'])) { + return $channel . '/' . $parsed['package']; + } + } + $upass = ''; + if (isset($parsed['user'])) { + $upass = $parsed['user']; + if (isset($parsed['pass'])) { + $upass .= ':' . $parsed['pass']; + } + $upass = "$upass@"; + } + $ret = 'channel://' . $upass . $parsed['channel'] . '/' . $parsed['package']; + if (isset($parsed['version']) || isset($parsed['state'])) { + $ver = isset($parsed['version']) ? $parsed['version'] : ''; + $ver .= isset($parsed['state']) ? $parsed['state'] : ''; + $ret .= '-' . $ver; + } + if (isset($parsed['extension'])) { + $ret .= '.' . $parsed['extension']; + } + if (isset($parsed['opts'])) { + $ret .= '?'; + foreach ($parsed['opts'] as $name => $value) { + $parsed['opts'][$name] = "$name=$value"; + } + $ret .= implode('&', $parsed['opts']); + } + if (isset($parsed['group'])) { + $ret .= '#' . $parsed['group']; + } + return $ret; + } +} /** * PEAR_REST * @@ -48430,7 +49001,7 @@ class PEAR_Registry extends PEAR * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: REST.php,v 1.40 2009/03/26 23:12:46 dufuz Exp $ + * @version CVS: $Id: REST.php 286489 2009-07-29 05:59:08Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ @@ -48449,7 +49020,7 @@ require_once 'PEAR/XMLParser.php'; * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ @@ -48460,7 +49031,7 @@ class PEAR_REST function PEAR_REST(&$config, $options = array()) { - $this->config = &$config; + $this->config = &$config; $this->_options = $options; } @@ -48477,7 +49048,6 @@ class PEAR_REST */ function retrieveCacheFirst($url, $accept = false, $forcestring = false, $channel = false) { - $cachefile = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR . md5($url) . 'rest.cachefile'; @@ -48634,11 +49204,9 @@ class PEAR_REST */ function saveCache($url, $contents, $lastmodified, $nochange = false, $cacheid = null) { - $cacheidfile = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR . - md5($url) . 'rest.cacheid'; - - $cachefile = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR . - md5($url) . 'rest.cachefile'; + $cachedir = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR . md5($url); + $cacheidfile = $cachedir . 'rest.cacheid'; + $cachefile = $cachedir . 'rest.cachefile'; if ($cacheid === null && $nochange) { $cacheid = unserialize(implode('', file($cacheidfile))); @@ -48772,7 +49340,7 @@ class PEAR_REST } $request .= $ifmodifiedsince . - "User-Agent: PEAR/1.8.0/PHP/" . PHP_VERSION . "\r\n"; + "User-Agent: PEAR/1.9.0/PHP/" . PHP_VERSION . "\r\n"; $username = $this->config->get('username', null, $channel); $password = $this->config->get('password', null, $channel); @@ -48869,7 +49437,7 @@ class PEAR_REST return $data; } -} +} /** * PEAR_RunTest * @@ -48881,7 +49449,7 @@ class PEAR_REST * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: RunTest.php,v 1.74 2009/02/24 23:38:22 dufuz Exp $ + * @version CVS: $Id: RunTest.php 287447 2009-08-18 11:46:19Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.3.3 */ @@ -48909,7 +49477,7 @@ putenv("PHP_PEAR_RUNTESTS=1"); * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.3.3 */ @@ -49116,12 +49684,11 @@ class PEAR_RunTest { if (!file_exists($file) && file_exists(getcwd() . DIRECTORY_SEPARATOR . $file)) { $file = realpath(getcwd() . DIRECTORY_SEPARATOR . $file); - break; } elseif (file_exists($file)) { $file = realpath($file); } - $cmd = $this->_preparePhpBin($this->_php, $file. $ini_settings); + $cmd = $this->_preparePhpBin($this->_php, $file, $ini_settings); if (isset($this->_logger)) { $this->_logger->log(2, 'Running command "' . $cmd . '"'); } @@ -49422,7 +49989,13 @@ class PEAR_RunTest fclose($fp); $section_text['EXPECT'] = file_get_contents($f); } - $wanted = preg_replace('/\r\n/', "\n", trim($section_text['EXPECT'])); + + if (isset($section_text['EXPECT'])) { + $wanted = preg_replace('/\r\n/', "\n", trim($section_text['EXPECT'])); + } else { + $wanted = ''; + } + // compare and leave on success if (!$returnfail && 0 == strcmp($output, $wanted)) { if (file_exists($temp_file)) { @@ -49805,13 +50378,16 @@ $text if ($section_text['CLEAN']) { // perform test cleanup $this->save_text($temp_clean, $section_text['CLEAN']); - $this->system_with_timeout("$this->_php $temp_clean"); + $output = $this->system_with_timeout("$this->_php $temp_clean 2>&1"); + if (strlen($output[1])) { + echo "BORKED --CLEAN-- section! output:\n", $output[1]; + } if (file_exists($temp_clean)) { unlink($temp_clean); } } } -} +} /** * PEAR_Validate * @@ -49822,7 +50398,7 @@ $text * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Validate.php,v 1.54 2009/02/24 23:38:23 dufuz Exp $ + * @version CVS: $Id: Validate.php 276383 2009-02-24 23:39:37Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ @@ -49845,7 +50421,7 @@ require_once 'PEAR/Validator/PECL.php'; * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ @@ -50439,7 +51015,7 @@ class PEAR_Validate { return true; } -} +} /** * PEAR_XMLParser * @@ -50451,7 +51027,7 @@ class PEAR_Validate * @author Stephan Schmidt (original XML_Unserializer code) * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license New BSD License - * @version CVS: $Id: XMLParser.php,v 1.22 2009/03/08 00:45:39 dufuz Exp $ + * @version CVS: $Id: XMLParser.php 282970 2009-06-28 23:10:07Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ @@ -50464,7 +51040,7 @@ class PEAR_Validate * @author Stephan Schmidt (original XML_Unserializer code) * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ @@ -50486,13 +51062,13 @@ class PEAR_XMLParser * stack for all data that is found * @var array $_dataStack */ - var $_dataStack = array(); + var $_dataStack = array(); /** * stack for all values that are generated * @var array $_valStack */ - var $_valStack = array(); + var $_valStack = array(); /** * current tag depth @@ -50524,8 +51100,7 @@ class PEAR_XMLParser include_once 'PEAR.php'; return PEAR::raiseError("XML Extension not found", 1); } - $this->_valStack = array(); - $this->_dataStack = array(); + $this->_dataStack = $this->_valStack = array(); $this->_depth = 0; if ( @@ -50539,6 +51114,7 @@ class PEAR_XMLParser if (version_compare(phpversion(), '5.0.0', 'lt') && $this->encoding == 'UTF-8') { $data = utf8_decode($data); + $this->encoding = 'ISO-8859-1'; } $xp = xml_parser_create($this->encoding); @@ -50568,25 +51144,21 @@ class PEAR_XMLParser */ function startHandler($parser, $element, $attribs) { - $type = 'string'; - $this->_depth++; $this->_dataStack[$this->_depth] = null; $val = array( - 'name' => $element, - 'value' => null, - 'type' => $type, - 'childrenKeys' => array(), - 'aggregKeys' => array() - ); + 'name' => $element, + 'value' => null, + 'type' => 'string', + 'childrenKeys' => array(), + 'aggregKeys' => array() + ); if (count($attribs) > 0) { $val['children'] = array(); $val['type'] = 'array'; - $val['children']['attribs'] = $attribs; - } array_push($this->_valStack, $val); @@ -50617,18 +51189,14 @@ class PEAR_XMLParser $data = $this->postProcess($this->_dataStack[$this->_depth], $element); // adjust type of the value - switch(strtolower($value['type'])) { - + switch (strtolower($value['type'])) { // unserialize an array case 'array': if ($data !== '') { $value['children']['_content'] = $data; } - if (isset($value['children'])) { - $value['value'] = $value['children']; - } else { - $value['value'] = array(); - } + + $value['value'] = isset($value['children']) ? $value['children'] : array(); break; /* @@ -50699,7 +51267,7 @@ class PEAR_XMLParser { $this->_dataStack[$this->_depth] .= $cdata; } -} +} REM ----------------------------------------------------------------------
REM PHP version 5
@@ -50813,7 +51381,7 @@ GOTO END :RUN
"%PHP_PEAR_PHP_BIN%" -C -d output_buffering=1 -d safe_mode=0 -d open_basedir="" -d auto_prepend_file="" -d auto_append_file="" -d variables_order=EGPCS -d register_argc_argv="On" -d include_path="%PHP_PEAR_INSTALL_DIR%" -f "%PHP_PEAR_INSTALL_DIR%\pearcmd.php" -- %1 %2 %3 %4 %5 %6 %7 %8 %9
:END
-@ECHO ON +@ECHO ON REM ----------------------------------------------------------------------
REM PHP version 5
@@ -50831,7 +51399,7 @@ REM ---------------------------------------------------------------------- REM Authors: Alexander Merz (alexmerz@php.net)
REM ----------------------------------------------------------------------
REM
-REM $Id: peardev.bat,v 1.6 2007/09/03 03:00:17 cellog Exp $
+REM $Id: peardev.bat,v 1.6 2007-09-03 03:00:17 cellog Exp $
REM change this lines to match the paths of your system
REM -------------------
@@ -50927,7 +51495,7 @@ GOTO END :RUN
"%PHP_PEAR_PHP_BIN%" -C -d memory_limit="-1" -d safe_mode=0 -d register_argc_argv="On" -d auto_prepend_file="" -d auto_append_file="" -d variables_order=EGPCS -d open_basedir="" -d output_buffering=1 -d include_path="%PHP_PEAR_INSTALL_DIR%" -f "%PHP_PEAR_INSTALL_DIR%\pearcmd.php" -- %1 %2 %3 %4 %5 %6 %7 %8 %9
:END
-@ECHO ON +@ECHO ON REM ----------------------------------------------------------------------
REM PHP version 5
@@ -51041,7 +51609,7 @@ GOTO END :RUN
"%PHP_PEAR_PHP_BIN%" -C -n -d output_buffering=1 -d safe_mode=0 -d include_path="%PHP_PEAR_INSTALL_DIR%" -d register_argc_argv="On" -d variables_order=EGPCS -f "%PHP_PEAR_INSTALL_DIR%\peclcmd.php" -- %1 %2 %3 %4 %5 %6 %7 %8 %9
:END
-@ECHO ON +@ECHO ON # first find which PHP binary to use if test "x$PHP_PEAR_PHP_BIN" != "x"; then @@ -51069,7 +51637,7 @@ else fi exec $PHP -C -q $INCARG -d output_buffering=1 -d variables_order=EGPCS -d open_basedir="" -d safe_mode=0 -d register_argc_argv="On" -d auto_prepend_file="" -d auto_append_file="" $INCDIR/pearcmd.php "$@" - + # first find which PHP binary to use if test "x$PHP_PEAR_PHP_BIN" != "x"; then @@ -51097,7 +51665,7 @@ else fi exec $PHP -d memory_limit="-1" -C -q $INCARG -d output_buffering=1 -d open_basedir="" -d safe_mode=0 -d register_argc_argv="On" -d auto_prepend_file="" -d variables_order=EGPCS -d auto_append_file="" $INCDIR/pearcmd.php "$@" - + # first find which PHP binary to use if test "x$PHP_PEAR_PHP_BIN" != "x"; then @@ -51125,7 +51693,7 @@ else fi exec $PHP -C -n -q $INCARG -d output_buffering=1 -d variables_order=EGPCS -d safe_mode=0 -d register_argc_argv="On" $INCDIR/peclcmd.php "$@" - + /** * PEAR, the PHP Extension and Application Repository * @@ -51139,7 +51707,7 @@ exec $PHP -C -n -q $INCARG -d output_buffering=1 -d variables_order=EGPCS -d saf * @author Tomas V.V.Cox <cox@idecnet.com> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: pearcmd.php,v 1.41 2009/03/04 20:05:56 dufuz Exp $ + * @version CVS: $Id: pearcmd.php 286487 2009-07-29 05:57:28Z dufuz $ * @link http://pear.php.net/package/PEAR */ @@ -51187,6 +51755,7 @@ if (!isset($_SERVER['argv']) && !isset($argv) && !isset($HTTP_SERVER_VARS['argv' echo 'ERROR: either use the CLI php executable, or set register_argc_argv=On in php.ini'; exit(1); } + $argv = Console_Getopt::readPHPArgv(); // fix CGI sapi oddity - the -- in pear.bat/pear is not removed if (php_sapi_name() != 'cli' && isset($argv[1]) && $argv[1] == '--') { @@ -51194,12 +51763,8 @@ if (php_sapi_name() != 'cli' && isset($argv[1]) && $argv[1] == '--') { $argv = array_values($argv); } $progname = PEAR_RUNTYPE; -if (in_array('getopt2', get_class_methods('Console_Getopt'))) { - array_shift($argv); - $options = Console_Getopt::getopt2($argv, "c:C:d:D:Gh?sSqu:vV"); -} else { - $options = Console_Getopt::getopt($argv, "c:C:d:D:Gh?sSqu:vV"); -} +array_shift($argv); +$options = Console_Getopt::getopt2($argv, "c:C:d:D:Gh?sSqu:vV"); if (PEAR::isError($options)) { usage($options); } @@ -51372,7 +51937,6 @@ if ($store_user_config) { } $command = (isset($options[1][0])) ? $options[1][0] : null; - if (empty($command) && ($store_user_config || $store_system_config)) { exit; } @@ -51388,6 +51952,7 @@ if ($fetype == 'Gtk' || $fetype == 'Gtk2') { if ($command == 'help') { usage(null, @$options[1][1]); } + if (!$config->validConfiguration()) { PEAR::raiseError('CRITICAL ERROR: no existing valid configuration files found in files ' . "'$pear_user_config' or '$pear_system_config', please copy an existing configuration" . @@ -51403,15 +51968,13 @@ if ($fetype == 'Gtk' || $fetype == 'Gtk2') { $short_args = $long_args = null; PEAR_Command::getGetoptArgs($command, $short_args, $long_args); - if (in_array('getopt2', get_class_methods('Console_Getopt'))) { - array_shift($options[1]); - $tmp = Console_Getopt::getopt2($options[1], $short_args, $long_args); - } else { - $tmp = Console_Getopt::getopt($options[1], $short_args, $long_args); - } + array_shift($options[1]); + $tmp = Console_Getopt::getopt2($options[1], $short_args, $long_args); + if (PEAR::isError($tmp)) { break; } + list($tmpopt, $params) = $tmp; $opts = array(); foreach ($tmpopt as $foo => $tmp2) { @@ -51419,6 +51982,7 @@ if ($fetype == 'Gtk' || $fetype == 'Gtk2') { if ($value === null) { $value = true; // options without args } + if (strlen($opt) == 1) { $cmdoptions = $cmd->getOptions($command); foreach ($cmdoptions as $o => $d) { @@ -51432,10 +51996,12 @@ if ($fetype == 'Gtk' || $fetype == 'Gtk2') { } } } + $ok = $cmd->run($command, $opts, $params); if ($ok === false) { PEAR::raiseError("unknown command `$command'"); } + if (PEAR::isError($ok)) { PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array($ui, "displayFatalError")); PEAR::raiseError($ok); @@ -51453,6 +52019,7 @@ function usage($error = null, $helpsubject = null) } elseif ($error !== null) { fputs($stderr, "$error\n"); } + if ($helpsubject != null) { $put = cmdHelp($helpsubject); } else { @@ -51511,12 +52078,14 @@ function cmdHelp($command) if (is_string($help)) { return "$progname $command [options] $help\n"; } + if ($help[1] === null) { return "$progname $command $help[0]"; - } else { - return "$progname $command [options] $help[0]\n$help[1]"; } + + return "$progname $command [options] $help[0]\n$help[1]"; } + return "Command '$command' is not valid, try '$progname help'"; } @@ -51568,7 +52137,7 @@ function error_handler($errno, $errmsg, $file, $line, $vars) { * mode: php * End: */ -// vim600:syn=php +// vim600:syn=php /** * PEAR, the PHP Extension and Application Repository * @@ -51582,7 +52151,7 @@ function error_handler($errno, $errmsg, $file, $line, $vars) { * @author Tomas V.V.Cox <cox@idecnet.com> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: peclcmd.php,v 1.2 2009/02/25 00:06:23 dufuz Exp $ + * @version CVS: $Id: peclcmd.php 276392 2009-02-25 00:06:23Z dufuz $ * @link http://pear.php.net/package/PEAR */ @@ -51609,7 +52178,7 @@ require_once 'pearcmd.php'; // vim600:syn=php ?> - + Stig Bakken <ssb@php.net>, Gregory Beaver <cellog@php.net>, Helgi Þormar Þorbjörnsson <helgi@php.net>, @@ -51636,7 +52205,7 @@ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - + ========================= Installing the PEAR Installer. @@ -51688,8 +52257,8 @@ related issues. Happy PHPing, we hope PEAR will be a great tool for your development work! -$Id: INSTALL,v 1.1 2006/09/22 03:31:36 cellog Exp $ - $Id: package.dtd,v 1.38 2005/11/12 02:23:07 cellog Exp $ +$Id: INSTALL 220345 2006-09-22 03:31:36Z cellog $ + $Id: package.dtd,v 1.38 2005-11-12 02:23:07 cellog Exp $ This is the PEAR package description, version 1.0. It should be used with the informal public identifier: @@ -51791,7 +52360,39 @@ $Id: INSTALL,v 1.1 2006/09/22 03:31:36 cellog Exp $ to CDATA #REQUIRED> - + +/** + * This is only meant for PHP 5 to get rid of certain strict warning + * that doesn't get hidden since it's in the shutdown function + */ +class PEAR5 +{ + /** + * If you have a class that's mostly/entirely static, and you need static + * properties, you can use this method to simulate them. Eg. in your method(s) + * do this: $myVar = &PEAR5::getStaticProperty('myclass', 'myVar'); + * You MUST use a reference, or they will not persist! + * + * @access public + * @param string $class The calling classname, to prevent clashes + * @param string $var The variable to retrieve. + * @return mixed A reference to the variable. If not set it will be + * auto initialised to NULL. + */ + static function &getStaticProperty($class, $var) + { + static $properties; + if (!isset($properties[$class])) { + $properties[$class] = array(); + } + + if (!array_key_exists($var, $properties[$class])) { + $properties[$class][$var] = null; + } + + return $properties[$class][$var]; + } +} /** * PEAR, the PHP Extension and Application Repository * @@ -51807,7 +52408,7 @@ $Id: INSTALL,v 1.1 2006/09/22 03:31:36 cellog Exp $ * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: PEAR.php,v 1.111 2009/04/08 23:32:04 dufuz Exp $ + * @version CVS: $Id: PEAR.php 286670 2009-08-02 14:16:06Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 0.1 */ @@ -51871,7 +52472,7 @@ $GLOBALS['_PEAR_error_handler_stack'] = array(); * @author Greg Beaver <cellog@php.net> * @copyright 1997-2006 The PHP Group * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @see PEAR_Error * @since Class available since PHP 4.0.2 @@ -52556,38 +53157,7 @@ class PEAR } if (PEAR_ZE2) { - /** - * This is only meant for PHP 5 to get rid of certain strict warning - * that doesn't get hidden since it's in the shutdown function - */ - class PEAR5 - { - /** - * If you have a class that's mostly/entirely static, and you need static - * properties, you can use this method to simulate them. Eg. in your method(s) - * do this: $myVar = &PEAR5::getStaticProperty('myclass', 'myVar'); - * You MUST use a reference, or they will not persist! - * - * @access public - * @param string $class The calling classname, to prevent clashes - * @param string $var The variable to retrieve. - * @return mixed A reference to the variable. If not set it will be - * auto initialised to NULL. - */ - static function &getStaticProperty($class, $var) - { - static $properties; - if (!isset($properties[$class])) { - $properties[$class] = array(); - } - - if (!array_key_exists($var, $properties[$class])) { - $properties[$class][$var] = null; - } - - return $properties[$class][$var]; - } - } + include_once 'PEAR5.php'; } // {{{ _PEAR_call_destructors() @@ -52627,7 +53197,7 @@ function _PEAR_call_destructors() } // Now call the shutdown functions - if (is_array($GLOBALS['_PEAR_shutdown_funcs']) AND !empty($GLOBALS['_PEAR_shutdown_funcs'])) { + if (isset($GLOBALS['_PEAR_shutdown_funcs']) AND is_array($GLOBALS['_PEAR_shutdown_funcs']) AND !empty($GLOBALS['_PEAR_shutdown_funcs'])) { foreach ($GLOBALS['_PEAR_shutdown_funcs'] as $value) { call_user_func_array($value[0], $value[1]); } @@ -52647,7 +53217,7 @@ function _PEAR_call_destructors() * @author Gregory Beaver <cellog@php.net> * @copyright 1997-2006 The PHP Group * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/manual/en/core.pear.pear-error.php * @see PEAR::raiseError(), PEAR::throwError() * @since Class available since PHP 4.0.2 @@ -52710,6 +53280,7 @@ class PEAR_Error unset($this->backtrace[0]['object']); } } + if ($mode & PEAR_ERROR_CALLBACK) { $this->level = E_USER_NOTICE; $this->callback = $options; @@ -52717,20 +53288,25 @@ class PEAR_Error if ($options === null) { $options = E_USER_NOTICE; } + $this->level = $options; $this->callback = null; } + if ($this->mode & PEAR_ERROR_PRINT) { if (is_null($options) || is_int($options)) { $format = "%s"; } else { $format = $options; } + printf($format, $this->getMessage()); } + if ($this->mode & PEAR_ERROR_TRIGGER) { trigger_error($this->getMessage(), $this->level); } + if ($this->mode & PEAR_ERROR_DIE) { $msg = $this->getMessage(); if (is_null($options) || is_int($options)) { @@ -52743,11 +53319,13 @@ class PEAR_Error } die(sprintf($format, $msg)); } + if ($this->mode & PEAR_ERROR_CALLBACK) { if (is_callable($this->callback)) { call_user_func($this->callback, $this); } } + if ($this->mode & PEAR_ERROR_EXCEPTION) { trigger_error("PEAR_ERROR_EXCEPTION is obsolete, use class PEAR_Exception for exceptions", E_USER_WARNING); eval('$e = new Exception($this->message, $this->code);throw($e);'); @@ -52950,7 +53528,8 @@ class PEAR_Error * tab-width: 4 * c-basic-offset: 4 * End: - */ + */ + ========================= What is the PEAR Installer? What is PEAR? @@ -52981,7 +53560,7 @@ prior to use. Happy PHPing, we hope PEAR will be a great tool for your development work! -$Id: README,v 1.11 2006/09/22 03:31:36 cellog Exp $ +$Id: README 220345 2006-09-22 03:31:36Z cellog $ /** * File/Directory manipulation * @@ -52992,7 +53571,7 @@ $Id: README,v 1.11 2006/09/22 03:31:36 cellog Exp $ * @author Tomas V.V.Cox <cox@idecnet.com> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: System.php,v 1.66 2009/02/24 23:52:56 dufuz Exp $ + * @version CVS: $Id: System.php 276386 2009-02-24 23:52:56Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 0.1 */ @@ -53034,7 +53613,7 @@ $GLOBALS['_System_temp_files'] = array(); * @author Tomas V.V. Cox <cox@idecnet.com> * @copyright 1997-2006 The PHP Group * @license http://opensource.org/licenses/bsd-license.php New BSD License -* @version Release: 1.8.0 +* @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 0.1 * @static @@ -53601,7 +54180,7 @@ class System } return $files; } -} +} Name: @rpm_package@ Version: @version@ Release: 1 @@ -53673,9 +54252,9 @@ cp -p package@package2xml@.xml %{buildroot}@rpm_xml_dir@/@package@.xml %defattr(-,root,root) %doc @doc_files@ / - + <!DOCTYPE package SYSTEM "http://pear.php.net/dtd/package-1.0"> -<package version="1.0" packagerversion="1.8.0"> +<package version="1.0" packagerversion="1.9.0RC4"> <name>PEAR</name> <summary>PEAR Base System</summary> <description>The PEAR package contains: @@ -53761,14 +54340,11 @@ cp -p package@package2xml@.xml %{buildroot}@rpm_xml_dir@/@package@.xml </maintainer> </maintainers> <release> - <version>1.8.0</version> - <date>2009-04-10</date> + <version>1.9.0</version> + <date>2009-09-03</date> <license>New BSD License</license> <state>stable</state> - <notes>* Fix Bug #14792: Bad md5sum for files with replaced content [dufuz] -* Fix Bug #16057:-r is limited to 4 directories in depth [dufuz] -* Fix Bug #16077: PEAR5::getStaticProperty does not return a reference to the property [dufuz] -Remove custom XML_Util class in favor of using upstream XML_Util package as dependency + <notes>* Fix Bug #16547: The phar for PEAR installer uses ereg() which is deprecated [dufuz] </notes> <deps> <dep type="php" rel="ge" version="4.4.0"/> @@ -54062,6 +54638,7 @@ Remove custom XML_Util class in favor of using upstream XML_Util package as depe <file role="php" baseinstalldir="/" name="PEAR.php"> <replace from="@package_version@" to="version" type="package-info"/> </file> + <file role="php" baseinstalldir="/" name="PEAR5.php"/> <file role="doc" baseinstalldir="/" name="README"/> <file role="php" baseinstalldir="/" name="System.php"> <replace from="@package_version@" to="version" type="package-info"/> @@ -54232,9 +54809,73 @@ Alpha1 Release Notes: Move codebase from the PHP License to New BSD 2 clause license </notes> </release> + <release> + <version>1.8.1</version> + <date>2009-04-15</date> + <license>New BSD License</license> + <state>stable</state> + <notes>* Fix Bug #16099 PEAR crash on PHP4 (parse error) [dufuz] + </notes> + </release> + <release> + <version>1.9.0RC1</version> + <date>2009-08-18</date> + <license>New BSD License</license> + <state>beta</state> + <notes>* Implement Request #16213: add alias to list-channels output [dufuz] +* Implement Request #16378: pear svntag [dufuz] +* Implement Request #16386: PEAR_Config::remove() does not support specifying a channel [timj] +* Implement Request #16396: package-dependencies should allow package names [dufuz] +* Fix Bug #11181: pear requests channel.xml from main server instead from mirror [dufuz] +* Fix Bug #14493: pear install --offline doesn't print out errors [dufuz] +* Fix Bug #11348: pear package-dependencies isn't well explained [dufuz] +* Fix Bug #16108: PEAR_PackageFile_Generator_v2 PHP4 parse error when running upgrade-all [dufuz] +* Fix Bug #16113: Installing certain packages fails due incorrect encoding handling [dufuz] +* Fix Bug #16122: PEAR RunTest failed to run as expected [dufuz] +* Fix Bug #16366: compiling 5.2.10 leads to non-functioning pear [dufuz] +* Fix Bug #16387: channel-logout does not support logging out from a non-default channel [timj] +* Fix Bug #16444: Setting preferred mirror fails [dufuz] +* Fix the shutdown functions where a index might not exist and thus raise a notice [derick] + </notes> + </release> + <release> + <version>1.9.0RC2</version> + <date>2009-08-20</date> + <license>New BSD License</license> + <state>beta</state> + <notes>* REST 1.4 file was occasionally being included but REST 1.4 is not intended for this release cycle [dufuz] + </notes> + </release> + <release> + <version>1.9.0RC3</version> + <date>2009-08-21</date> + <license>New BSD License</license> + <state>beta</state> + <notes>* Improved svntag support to handle packages like PEAR it self [dufuz] + </notes> + </release> + <release> + <version>1.9.0RC4</version> + <date>2009-08-23</date> + <license>New BSD License</license> + <state>beta</state> + <notes>* Fixed a problem where the original channel could not be set as a preferred_mirror again [dufuz] +* Make sure channel aliases can't be made to start with - [dufuz] +* Output issues with pear search [dufuz] +* Fixed couple of stray notices [dufuz] + </notes> + </release> + <release> + <version>1.9.0</version> + <date>2009-09-03</date> + <license>New BSD License</license> + <state>stable</state> + <notes>* Fix Bug #16547: The phar for PEAR installer uses ereg() which is deprecated [dufuz] + </notes> + </release> </changelog> </package> - + /** * PEAR, the PHP Extension and Application Repository * @@ -54250,7 +54891,7 @@ Alpha1 Release Notes: * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: PEAR.php,v 1.111 2009/04/08 23:32:04 dufuz Exp $ + * @version CVS: $Id: PEAR.php 286670 2009-08-02 14:16:06Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 0.1 */ @@ -54314,7 +54955,7 @@ $GLOBALS['_PEAR_error_handler_stack'] = array(); * @author Greg Beaver <cellog@php.net> * @copyright 1997-2006 The PHP Group * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @see PEAR_Error * @since Class available since PHP 4.0.2 @@ -54999,38 +55640,7 @@ class PEAR } if (PEAR_ZE2) { - /** - * This is only meant for PHP 5 to get rid of certain strict warning - * that doesn't get hidden since it's in the shutdown function - */ - class PEAR5 - { - /** - * If you have a class that's mostly/entirely static, and you need static - * properties, you can use this method to simulate them. Eg. in your method(s) - * do this: $myVar = &PEAR5::getStaticProperty('myclass', 'myVar'); - * You MUST use a reference, or they will not persist! - * - * @access public - * @param string $class The calling classname, to prevent clashes - * @param string $var The variable to retrieve. - * @return mixed A reference to the variable. If not set it will be - * auto initialised to NULL. - */ - static function &getStaticProperty($class, $var) - { - static $properties; - if (!isset($properties[$class])) { - $properties[$class] = array(); - } - - if (!array_key_exists($var, $properties[$class])) { - $properties[$class][$var] = null; - } - - return $properties[$class][$var]; - } - } + include_once 'phar://install-pear-nozlib.phar/' . 'PEAR5.php'; } // {{{ _PEAR_call_destructors() @@ -55070,7 +55680,7 @@ function _PEAR_call_destructors() } // Now call the shutdown functions - if (is_array($GLOBALS['_PEAR_shutdown_funcs']) AND !empty($GLOBALS['_PEAR_shutdown_funcs'])) { + if (isset($GLOBALS['_PEAR_shutdown_funcs']) AND is_array($GLOBALS['_PEAR_shutdown_funcs']) AND !empty($GLOBALS['_PEAR_shutdown_funcs'])) { foreach ($GLOBALS['_PEAR_shutdown_funcs'] as $value) { call_user_func_array($value[0], $value[1]); } @@ -55090,7 +55700,7 @@ function _PEAR_call_destructors() * @author Gregory Beaver <cellog@php.net> * @copyright 1997-2006 The PHP Group * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/manual/en/core.pear.pear-error.php * @see PEAR::raiseError(), PEAR::throwError() * @since Class available since PHP 4.0.2 @@ -55153,6 +55763,7 @@ class PEAR_Error unset($this->backtrace[0]['object']); } } + if ($mode & PEAR_ERROR_CALLBACK) { $this->level = E_USER_NOTICE; $this->callback = $options; @@ -55160,20 +55771,25 @@ class PEAR_Error if ($options === null) { $options = E_USER_NOTICE; } + $this->level = $options; $this->callback = null; } + if ($this->mode & PEAR_ERROR_PRINT) { if (is_null($options) || is_int($options)) { $format = "%s"; } else { $format = $options; } + printf($format, $this->getMessage()); } + if ($this->mode & PEAR_ERROR_TRIGGER) { trigger_error($this->getMessage(), $this->level); } + if ($this->mode & PEAR_ERROR_DIE) { $msg = $this->getMessage(); if (is_null($options) || is_int($options)) { @@ -55186,11 +55802,13 @@ class PEAR_Error } die(sprintf($format, $msg)); } + if ($this->mode & PEAR_ERROR_CALLBACK) { if (is_callable($this->callback)) { call_user_func($this->callback, $this); } } + if ($this->mode & PEAR_ERROR_EXCEPTION) { trigger_error("PEAR_ERROR_EXCEPTION is obsolete, use class PEAR_Exception for exceptions", E_USER_WARNING); eval('$e = new Exception($this->message, $this->code);throw($e);'); @@ -55393,7 +56011,8 @@ class PEAR_Error * tab-width: 4 * c-basic-offset: 4 * End: - */<?php + */ +<?php /** * PEAR_ChannelFile, the channel handling class * @@ -55404,7 +56023,7 @@ class PEAR_Error * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: ChannelFile.php,v 1.84 2009/03/09 01:03:51 dufuz Exp $ + * @version CVS: $Id: ChannelFile.php 286951 2009-08-09 14:41:22Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ @@ -55541,7 +56160,7 @@ $GLOBALS['_PEAR_CHANNELS_MIRROR_TYPES'] = array('server'); * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ @@ -55893,12 +56512,15 @@ class PEAR_ChannelFile function _makeRestXml($info, $indent) { $ret = $indent . "<rest>\n"; - if (!isset($info['baseurl'][0])) { + if (isset($info['baseurl']) && !isset($info['baseurl'][0])) { $info['baseurl'] = array($info['baseurl']); } - foreach ($info['baseurl'] as $url) { - $ret .= "$indent <baseurl type=\"" . $url['attribs']['type'] . "\""; - $ret .= ">" . $url['_content'] . "</baseurl>\n"; + + if (isset($info['baseurl'])) { + foreach ($info['baseurl'] as $url) { + $ret .= "$indent <baseurl type=\"" . $url['attribs']['type'] . "\""; + $ret .= ">" . $url['_content'] . "</baseurl>\n"; + } } $ret .= $indent . "</rest>\n"; return $ret; @@ -56082,15 +56704,17 @@ class PEAR_ChannelFile if (!isset($functions[0])) { $functions = array($functions); } + foreach ($functions as $function) { if (!isset($function['_content']) || empty($function['_content'])) { $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_FUNCTIONNAME, array('parent' => $parent, 'protocol' => $protocol)); } + if ($protocol == 'rest') { if (!isset($function['attribs']['type']) || empty($function['attribs']['type'])) { - $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_BASEURLTYPE, + $this->_validateError(PEAR_CHANNELFILE_ERROR_NOBASEURLTYPE, array('parent' => $parent, 'protocol' => $protocol)); } } else { @@ -56414,6 +57038,14 @@ class PEAR_ChannelFile switch ($version) { case '1.0' : $this->resetREST($mirror); + + if (!isset($this->_channelInfo['servers'])) { + $this->_channelInfo['servers'] = array('primary' => + array('rest' => array())); + } elseif (!isset($this->_channelInfo['servers']['primary'])) { + $this->_channelInfo['servers']['primary'] = array('rest' => array()); + } + return true; break; default : @@ -56949,7 +57581,7 @@ class PEAR_ChannelFile * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Parser.php,v 1.7 2009/02/24 23:39:07 dufuz Exp $ + * @version CVS: $Id: Parser.php 276383 2009-02-24 23:39:37Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ @@ -56966,7 +57598,7 @@ require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/ChannelFile.php'; * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ @@ -57017,7 +57649,7 @@ class PEAR_ChannelFile_Parser extends PEAR_XMLParser * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Command.php,v 1.41 2009/02/24 23:38:22 dufuz Exp $ + * @version CVS: $Id: Command.php 286494 2009-07-29 06:57:11Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 0.1 */ @@ -57101,7 +57733,7 @@ $GLOBALS['_PEAR_Command_objects'] = array(); * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 0.1 */ @@ -57248,27 +57880,31 @@ class PEAR_Command if (!$merge) { $GLOBALS['_PEAR_Command_commandlist'] = array(); } - while ($entry = readdir($dp)) { - if ($entry{0} == '.' || substr($entry, -4) != '.xml') { + + while ($file = readdir($dp)) { + if ($file{0} == '.' || substr($file, -4) != '.xml') { continue; } - $class = "PEAR_Command_".substr($entry, 0, -4); - $file = "$dir/$entry"; - $parser->parse(file_get_contents($file)); - $implements = $parser->getData(); + + $f = substr($file, 0, -4); + $class = "PEAR_Command_" . $f; // List of commands if (empty($GLOBALS['_PEAR_Command_objects'][$class])) { - $GLOBALS['_PEAR_Command_objects'][$class] = "$dir/" . substr($entry, 0, -4) . - '.php'; + $GLOBALS['_PEAR_Command_objects'][$class] = "$dir/" . $f . '.php'; } + + $parser->parse(file_get_contents("$dir/$file")); + $implements = $parser->getData(); foreach ($implements as $command => $desc) { if ($command == 'attribs') { continue; } + if (isset($GLOBALS['_PEAR_Command_commandlist'][$command])) { return PEAR::raiseError('Command "' . $command . '" already registered in ' . 'class "' . $GLOBALS['_PEAR_Command_commandlist'][$command] . '"'); } + $GLOBALS['_PEAR_Command_commandlist'][$command] = $class; $GLOBALS['_PEAR_Command_commanddesc'][$command] = $desc['summary']; if (isset($desc['shortcut'])) { @@ -57280,6 +57916,7 @@ class PEAR_Command } $GLOBALS['_PEAR_Command_shortcuts'][$shortcut] = $command; } + if (isset($desc['options']) && $desc['options']) { foreach ($desc['options'] as $oname => $option) { if (isset($option['shortopt']) && strlen($option['shortopt']) > 1) { @@ -57292,6 +57929,7 @@ class PEAR_Command } } } + ksort($GLOBALS['_PEAR_Command_shortcuts']); ksort($GLOBALS['_PEAR_Command_commandlist']); @closedir($dp); @@ -57424,7 +58062,7 @@ class PEAR_Command * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Common.php,v 1.39 2009/02/24 23:39:29 dufuz Exp $ + * @version CVS: $Id: Common.php 276383 2009-02-24 23:39:37Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 0.1 */ @@ -57443,7 +58081,7 @@ require_once 'phar://install-pear-nozlib.phar/' . 'PEAR.php'; * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 0.1 */ @@ -57696,7 +58334,7 @@ class PEAR_Command_Common extends PEAR * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Install.php,v 1.153 2009/03/08 04:01:11 dufuz Exp $ + * @version CVS: $Id: Install.php 287477 2009-08-19 14:19:43Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 0.1 */ @@ -57716,7 +58354,7 @@ require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Command/Common.php'; * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 0.1 */ @@ -58249,8 +58887,7 @@ Run post-installation scripts in package <package>, if any exist. } } - $abstractpackages = array(); - $otherpackages = array(); + $abstractpackages = $otherpackages = array(); // parse params PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); @@ -58344,7 +58981,7 @@ Run post-installation scripts in package <package>, if any exist. } $this->downloader = &$this->getDownloader($this->ui, $options, $this->config); - $errors = $downloaded = $binaries = array(); + $errors = $downloaded = $binaries = array(); $downloaded = &$this->downloader->download($packages); if (PEAR::isError($downloaded)) { return $this->raiseError($downloaded); @@ -58389,8 +59026,7 @@ Run post-installation scripts in package <package>, if any exist. return true; } - $extrainfo = array(); - $binaries = array(); + $binaries = $extrainfo = array(); foreach ($downloaded as $param) { PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); $info = $this->installer->install($param, $options); @@ -58889,10 +59525,14 @@ Run post-installation scripts in package <package>, if any exist. return $this->raiseError($chan); } + $base2 = false; $preferred_mirror = $this->config->get('preferred_mirror', null, $channel); if ($chan->supportsREST($preferred_mirror) && - $base = $chan->getBaseURL('REST1.0', $preferred_mirror)) - { + ( + //($base2 = $chan->getBaseURL('REST1.4', $preferred_mirror)) || + ($base = $chan->getBaseURL('REST1.0', $preferred_mirror)) + ) + ) { $dorest = true; } @@ -58904,10 +59544,15 @@ Run post-installation scripts in package <package>, if any exist. } if ($dorest) { - $rest = &$this->config->getREST('1.0', array()); - $installed = array_flip($reg->listPackages($channel)); + if ($base2) { + $rest = &$this->config->getREST('1.4', array()); + $base = $base2; + } else { + $rest = &$this->config->getREST('1.0', array()); + } - $latest = $rest->listLatestUpgrades($base, $state, $installed, $channel, $reg); + $installed = array_flip($reg->listPackages($channel)); + $latest = $rest->listLatestUpgrades($base, $state, $installed, $channel, $reg); } PEAR::staticPopErrorHandling(); @@ -59174,7 +59819,7 @@ more stable. <arg>DIR</arg> </installroot> <ignore-errors> - <shortopt>f</shortopt> + <shortopt></shortopt> <doc>force install even if there were errors</doc> </ignore-errors> <offline> @@ -59199,7 +59844,7 @@ channel not in your default channel ({config default_channel}) <arg>DIR</arg> </destination> <force> - <shortopt></shortopt> + <shortopt>f</shortopt> <doc>Force the unpacking even if there were errors in the package</doc> </force> </options> @@ -59230,7 +59875,7 @@ Run post-installation scripts in package <package>, if any exist. * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Common.php,v 1.168 2009/03/27 19:35:47 dufuz Exp $ + * @version CVS: $Id: Common.php 282969 2009-06-28 23:09:27Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 0.1.0 * @deprecated File deprecated since Release 1.4.0a1 @@ -59337,7 +59982,7 @@ $GLOBALS['_PEAR_Common_script_phases'] = array('pre-install', 'post-install', 'p * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 * @deprecated This class will disappear, and its components will be spread @@ -59678,6 +60323,22 @@ class PEAR_Common extends PEAR return false; } + function _postProcessChecks($pf) + { + if (!PEAR::isError($pf)) { + return $this->_postProcessValidPackagexml($pf); + } + + $errs = $pf->getUserinfo(); + if (is_array($errs)) { + foreach ($errs as $error) { + $e = $this->raiseError($error['message'], $error['code'], null, null, $error); + } + } + + return $pf; + } + /** * Returns information about a package file. Expects the name of * a gzipped tar file as input. @@ -59694,18 +60355,7 @@ class PEAR_Common extends PEAR { $packagefile = &new PEAR_PackageFile($this->config); $pf = &$packagefile->fromTgzFile($file, PEAR_VALIDATE_NORMAL); - if (PEAR::isError($pf)) { - $errs = $pf->getUserinfo(); - if (is_array($errs)) { - foreach ($errs as $error) { - $e = $this->raiseError($error['message'], $error['code'], null, null, $error); - } - } - - return $pf; - } - - return $this->_postProcessValidPackagexml($pf); + return $this->_postProcessChecks($pf); } /** @@ -59724,18 +60374,7 @@ class PEAR_Common extends PEAR { $packagefile = &new PEAR_PackageFile($this->config); $pf = &$packagefile->fromPackageFile($descfile, PEAR_VALIDATE_NORMAL); - if (PEAR::isError($pf)) { - $errs = $pf->getUserinfo(); - if (is_array($errs)) { - foreach ($errs as $error) { - $e = $this->raiseError($error['message'], $error['code'], null, null, $error); - } - } - - return $pf; - } - - return $this->_postProcessValidPackagexml($pf); + return $this->_postProcessChecks($pf); } /** @@ -59754,18 +60393,7 @@ class PEAR_Common extends PEAR { $packagefile = &new PEAR_PackageFile($this->config); $pf = &$packagefile->fromXmlString($data, PEAR_VALIDATE_NORMAL, false); - if (PEAR::isError($pf)) { - $errs = $pf->getUserinfo(); - if (is_array($errs)) { - foreach ($errs as $error) { - $e = $this->raiseError($error['message'], $error['code'], null, null, $error); - } - } - - return $pf; - } - - return $this->_postProcessValidPackagexml($pf); + return $this->_postProcessChecks($pf); } /** @@ -59783,23 +60411,11 @@ class PEAR_Common extends PEAR // changelog is not converted to old format. $arr = $pf->toArray(true); $arr = array_merge($arr, $arr['old']); - unset($arr['old']); - unset($arr['xsdversion']); - unset($arr['contents']); - unset($arr['compatible']); - unset($arr['channel']); - unset($arr['uri']); - unset($arr['dependencies']); - unset($arr['phprelease']); - unset($arr['extsrcrelease']); - unset($arr['zendextsrcrelease']); - unset($arr['extbinrelease']); - unset($arr['zendextbinrelease']); - unset($arr['bundle']); - unset($arr['lead']); - unset($arr['developer']); - unset($arr['helper']); - unset($arr['contributor']); + unset($arr['old'], $arr['xsdversion'], $arr['contents'], $arr['compatible'], + $arr['channel'], $arr['uri'], $arr['dependencies'], $arr['phprelease'], + $arr['extsrcrelease'], $arr['zendextsrcrelease'], $arr['extbinrelease'], + $arr['zendextbinrelease'], $arr['bundle'], $arr['lead'], $arr['developer'], + $arr['helper'], $arr['contributor']); $arr['filelist'] = $pf->getFilelist(); $this->pkginfo = $arr; return $arr; @@ -60094,7 +60710,7 @@ require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/PackageFile.php';<?php * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Config.php,v 1.157 2009/02/25 00:23:26 dufuz Exp $ + * @version CVS: $Id: Config.php 286480 2009-07-29 02:50:02Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 0.1 */ @@ -60330,7 +60946,7 @@ if (getenv('PHP_PEAR_SIG_KEYDIR')) { * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 0.1 */ @@ -61915,13 +62531,17 @@ class PEAR_Config extends PEAR * * @param string config key * @param string (optional) config layer + * @param string (optional) channel (defaults to default channel) * @return bool TRUE on success, FALSE on failure * * @access public */ - function remove($key, $layer = 'user') + function remove($key, $layer = 'user', $channel = null) { - $channel = $this->getDefaultChannel(); + if ($channel === null) { + $channel = $this->getDefaultChannel(); + } + if ($channel !== 'pear.php.net') { if (isset($this->configuration[$layer]['__channels'][$channel][$key])) { unset($this->configuration[$layer]['__channels'][$channel][$key]); @@ -62186,7 +62806,7 @@ class PEAR_Config extends PEAR * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Dependency2.php,v 1.59 2009/02/24 23:38:22 dufuz Exp $ + * @version CVS: $Id: Dependency2.php 286494 2009-07-29 06:57:11Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ @@ -62208,7 +62828,7 @@ require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Validate.php'; * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ @@ -62523,7 +63143,8 @@ class PEAR_Dependency2 } if (!isset($dep['min']) && !isset($dep['max']) && - !isset($dep['recommended']) && !isset($dep['exclude'])) { + !isset($dep['recommended']) && !isset($dep['exclude']) + ) { if ($loaded) { if (isset($dep['conflicts'])) { if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { @@ -62536,24 +63157,24 @@ class PEAR_Dependency2 } return true; - } else { - if (isset($dep['conflicts'])) { - return true; - } + } - if ($required) { - if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { - return $this->raiseError('%s requires PHP extension "' . - $dep['name'] . '"' . $extra); - } + if (isset($dep['conflicts'])) { + return true; + } - return $this->warning('warning: %s requires PHP extension "' . + if ($required) { + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('%s requires PHP extension "' . $dep['name'] . '"' . $extra); } - return $this->warning('%s can optionally use PHP extension "' . + return $this->warning('warning: %s requires PHP extension "' . $dep['name'] . '"' . $extra); } + + return $this->warning('%s can optionally use PHP extension "' . + $dep['name'] . '"' . $extra); } if (!$loaded) { @@ -62717,7 +63338,7 @@ class PEAR_Dependency2 */ function getPEARVersion() { - return '1.8.0'; + return '1.9.0'; } function validatePearinstallerDependency($dep) @@ -63543,7 +64164,7 @@ class PEAR_Dependency2 * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: DependencyDB.php,v 1.44 2009/03/21 15:15:26 dufuz Exp $ + * @version CVS: $Id: DependencyDB.php 286686 2009-08-02 17:38:57Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ @@ -63563,7 +64184,7 @@ $GLOBALS['_PEAR_DEPENDENCYDB_INSTANCE'] = array(); * @author Tomas V.V.Cox <cox@idec.net.com> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ @@ -63697,18 +64318,19 @@ class PEAR_DependencyDB { if (!is_file($this->_depdb)) { $this->rebuildDB(); - } else { - $depdb = $this->_getDepDB(); - // Datatype format has been changed, rebuild the Deps DB - if ($depdb['_version'] < $this->_version) { - $this->rebuildDB(); - } + return; + } - if ($depdb['_version']{0} > $this->_version{0}) { - return PEAR::raiseError('Dependency database is version ' . - $depdb['_version'] . ', and we are version ' . - $this->_version . ', cannot continue'); - } + $depdb = $this->_getDepDB(); + // Datatype format has been changed, rebuild the Deps DB + if ($depdb['_version'] < $this->_version) { + $this->rebuildDB(); + } + + if ($depdb['_version']{0} > $this->_version{0}) { + return PEAR::raiseError('Dependency database is version ' . + $depdb['_version'] . ', and we are version ' . + $this->_version . ', cannot continue'); } } @@ -63761,9 +64383,10 @@ class PEAR_DependencyDB foreach ($depend as $info) { $temp = $this->getDependencies($info); foreach ($temp as $dep) { - if (isset($dep['dep'], $dep['dep']['channel'], $dep['dep']['name']) && - strtolower($dep['dep']['channel']) == $channel && - strtolower($dep['dep']['name']) == $package + if ( + isset($dep['dep'], $dep['dep']['channel'], $dep['dep']['name']) && + strtolower($dep['dep']['channel']) == $channel && + strtolower($dep['dep']['name']) == $package ) { if (!isset($dependencies[$info['channel']])) { $dependencies[$info['channel']] = array(); @@ -64274,13 +64897,6 @@ class PEAR_DependencyDB break; } } - - if (!$found) { - $data['packages'][$depchannel][$dep['name']][] = array( - 'channel' => $channel, - 'package' => $package - ); - } } else { if (!isset($data['packages'])) { $data['packages'] = array(); @@ -64294,6 +64910,10 @@ class PEAR_DependencyDB $data['packages'][$depchannel][$dep['name']] = array(); } + $found = false; + } + + if (!$found) { $data['packages'][$depchannel][$dep['name']][] = array( 'channel' => $channel, 'package' => $package @@ -64314,7 +64934,7 @@ class PEAR_DependencyDB * @author Martin Jansen <mj@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Downloader.php,v 1.159 2009/03/08 04:01:08 dufuz Exp $ + * @version CVS: $Id: Downloader.php 287109 2009-08-11 18:50:30Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.3.0 */ @@ -64341,7 +64961,7 @@ define('PEAR_INSTALLER_ERROR_NO_PREF_STATE', 2); * @author Martin Jansen <mj@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.3.0 */ @@ -64441,7 +65061,6 @@ class PEAR_Downloader extends PEAR_Common * @var string */ var $_downloadDir; - // {{{ PEAR_Downloader() /** * @param PEAR_Frontend_* @@ -64609,7 +65228,8 @@ class PEAR_Downloader extends PEAR_Common } if ($params[$i] && !isset($channelschecked[$params[$i]->getChannel()]) && - !isset($this->_options['offline'])) { + !isset($this->_options['offline']) + ) { $channelschecked[$params[$i]->getChannel()] = true; PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); if (!class_exists('System')) { @@ -64627,10 +65247,9 @@ class PEAR_Downloader extends PEAR_Common break; } - $mirror = $this->config->get('preferred_mirror', null, - $params[$i]->getChannel()); - $a = $this->downloadHttp('http://' . $mirror . - '/channel.xml', $this->ui, $dir, null, $curchannel->lastModified()); + $mirror = $this->config->get('preferred_mirror', null, $params[$i]->getChannel()); + $url = 'http://' . $mirror . '/channel.xml'; + $a = $this->downloadHttp($url, $this->ui, $dir, null, $curchannel->lastModified()); PEAR::staticPopErrorHandling(); if (PEAR::isError($a) || !$a) { @@ -65059,8 +65678,6 @@ class PEAR_Downloader extends PEAR_Common $this->_downloadDir = $dir; } - // }}} - // {{{ configSet() function configSet($key, $value, $layer = 'user', $channel = false) { $this->config->set($key, $value, $layer, $channel); @@ -65071,8 +65688,6 @@ class PEAR_Downloader extends PEAR_Common } } - // }}} - // {{{ setOptions() function setOptions($options) { $this->_options = $options; @@ -65085,8 +65700,6 @@ class PEAR_Downloader extends PEAR_Common return $this->_options; } - // }}} - /** * For simpler unit-testing * @param PEAR_Config @@ -65102,8 +65715,6 @@ class PEAR_Downloader extends PEAR_Common return $a; } - // {{{ _getPackageDownloadUrl() - /** * @param array output of {@link parsePackageName()} * @access private @@ -65150,7 +65761,7 @@ class PEAR_Downloader extends PEAR_Common !($base = $chan->getBaseURL('REST1.0', $preferred_mirror)) ) ) { - return $this->raiseError($parr['channel'] . ' is using a unsupported protocal - This should never happen.'); + return $this->raiseError($parr['channel'] . ' is using a unsupported protocol - This should never happen.'); } if ($base2) { @@ -65160,14 +65771,15 @@ class PEAR_Downloader extends PEAR_Common $rest = &$this->config->getREST('1.0', $this->_options); } + $downloadVersion = false; if (!isset($parr['version']) && !isset($parr['state']) && $version && !PEAR::isError($version) - && !isset($this->_options['downloadonly'])) { - $url = $rest->getDownloadURL($base, $parr, $state, $version, $chan->getName()); - } else { - $url = $rest->getDownloadURL($base, $parr, $state, false, $chan->getName()); + && !isset($this->_options['downloadonly']) + ) { + $downloadVersion = $version; } + $url = $rest->getDownloadURL($base, $parr, $state, $downloadVersion, $chan->getName()); if (PEAR::isError($url)) { $this->configSet('default_channel', $curchannel); return $url; @@ -65238,8 +65850,6 @@ class PEAR_Downloader extends PEAR_Common return $url; } - // }}} - // {{{ getDepPackageDownloadUrl() /** * @param array dependency array @@ -65369,10 +65979,8 @@ class PEAR_Downloader extends PEAR_Common return $url; } - return $this->raiseError($parr['channel'] . ' is using a unsupported protocal - This should never happen.'); + return $this->raiseError($parr['channel'] . ' is using a unsupported protocol - This should never happen.'); } - // }}} - // {{{ getPackageDownloadUrl() /** * @deprecated in favor of _getPackageDownloadUrl @@ -65397,9 +66005,6 @@ class PEAR_Downloader extends PEAR_Common return $package; } - // }}} - // {{{ getDownloadedPackages() - /** * Retrieve a list of downloaded packages after a call to {@link download()}. * @@ -65414,9 +66019,6 @@ class PEAR_Downloader extends PEAR_Common return $ret; } - // }}} - // {{{ _downloadCallback() - function _downloadCallback($msg, $params = null) { switch ($msg) { @@ -65449,9 +66051,6 @@ class PEAR_Downloader extends PEAR_Common $this->ui->_downloadCallback($msg, $params); } - // }}} - // {{{ _prependPath($path, $prepend) - function _prependPath($path, $prepend) { if (strlen($prepend) > 0) { @@ -65468,8 +66067,6 @@ class PEAR_Downloader extends PEAR_Common } return $path; } - // }}} - // {{{ pushError($errmsg, $code) /** * @param string @@ -65480,9 +66077,6 @@ class PEAR_Downloader extends PEAR_Common array_push($this->_errorStack, array($errmsg, $code)); } - // }}} - // {{{ getErrorMsgs() - function getErrorMsgs() { $msgs = array(); @@ -65494,10 +66088,10 @@ class PEAR_Downloader extends PEAR_Common return $msgs; } - // }}} - /** * for BC + * + * @deprecated */ function sortPkgDeps(&$packages, $uninstall = false) { @@ -65656,7 +66250,7 @@ class PEAR_Downloader extends PEAR_Common $installOrder = Structures_Graph_Manipulator_TopologicalSorter::sort($depgraph); $ret = array(); - for ($i = 0; $i < count($installOrder); $i++) { + for ($i = 0, $count = count($installOrder); $i < $count; $i++) { foreach ($installOrder[$i] as $index => $sortedpackage) { $data = &$installOrder[$i][$index]->getData(); $ret[] = &$nodes[$reg->parsedPackageNameToString( @@ -65691,6 +66285,7 @@ class PEAR_Downloader extends PEAR_Common if (count($deplinks[$dep]) == 0) { unset($deplinks[$dep]); } + continue 3; } } @@ -65705,25 +66300,30 @@ class PEAR_Downloader extends PEAR_Common $visited = array(); return; } + // this happens when a parent has a dep cycle on another dependency // but the child is not part of the cycle if (isset($visited[$dep])) { return false; } + $visited[$dep] = 1; if ($test == $dep) { return true; } + if (isset($deplinks[$dep])) { if (in_array($test, array_keys($deplinks[$dep]), true)) { return true; } + foreach ($deplinks[$dep] as $parent => $unused) { if ($this->_testCycle($test, $deplinks, $parent)) { return true; } } } + return false; } @@ -65960,7 +66560,7 @@ class PEAR_Downloader extends PEAR_Common } $request .= $ifmodifiedsince . - "User-Agent: PEAR/1.8.0/PHP/" . PHP_VERSION . "\r\n"; + "User-Agent: PEAR/1.9.0/PHP/" . PHP_VERSION . "\r\n"; if (isset($this)) { // only pass in authentication for non-static calls $username = $config->get('username', null, $channel); @@ -66057,6 +66657,7 @@ class PEAR_Downloader extends PEAR_Common return PEAR::raiseError("$dest_file: write failed ($php_errormsg)"); } } + fclose($fp); fclose($wp); if ($callback) { @@ -66067,6 +66668,7 @@ class PEAR_Downloader extends PEAR_Common if (isset($headers['etag'])) { $lastmodified = array('ETag' => $headers['etag']); } + if (isset($headers['last-modified'])) { if (is_array($lastmodified)) { $lastmodified['Last-Modified'] = $headers['last-modified']; @@ -66090,7 +66692,7 @@ class PEAR_Downloader extends PEAR_Common * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Package.php,v 1.126 2009/03/07 21:51:52 dufuz Exp $ + * @version CVS: $Id: Package.php 287560 2009-08-21 22:36:18Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ @@ -66131,7 +66733,7 @@ define('PEAR_DOWNLOADER_PACKAGE_PHPVERSION', -1004); * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ @@ -66246,6 +66848,12 @@ class PEAR_Downloader_Package $options = $this->_downloader->getOptions(); if (isset($options['offline'])) { if (PEAR::isError($origErr) && !isset($options['soft'])) { + foreach ($origErr->getUserInfo() as $userInfo) { + if (isset($userInfo['message'])) { + $this->_downloader->log(0, $userInfo['message']); + } + } + $this->_downloader->log(0, $origErr->getMessage()); } @@ -66343,8 +66951,15 @@ class PEAR_Downloader_Package if ($info != $newinfo) { do { - if ($info['package'] == 'pecl.php.net' && $newinfo['package'] == 'pear.php.net') { - $info['package'] = 'pear.php.net'; + if ($info['channel'] == 'pecl.php.net' && $newinfo['channel'] == 'pear.php.net') { + $info['channel'] = 'pear.php.net'; + if ($info == $newinfo) { + // skip the channel check if a pecl package says it's a PEAR package + break; + } + } + if ($info['channel'] == 'pear.php.net' && $newinfo['channel'] == 'pecl.php.net') { + $info['channel'] = 'pecl.php.net'; if ($info == $newinfo) { // skip the channel check if a pecl package says it's a PEAR package break; @@ -66733,8 +67348,7 @@ class PEAR_Downloader_Package // we can't determine whether upgrade is necessary until we know what // version would be downloaded if (!isset($options['force']) && $this->isInstalled($ret, $oper)) { - $version = $this->_installRegistry->packageInfo($dep['name'], 'version', - $dep['channel']); + $version = $this->_installRegistry->packageInfo($dep['name'], 'version', $dep['channel']); $dep['package'] = $dep['name']; if (!isset($options['soft'])) { $this->_downloader->log(3, $this->getShortName() . ': Skipping ' . $group . @@ -66811,8 +67425,7 @@ class PEAR_Downloader_Package $newdep = $newdep[0]; $newdep['channel'] = 'pecl.php.net'; $chan = 'pecl.php.net'; - $url = - $this->_downloader->_getDepPackageDownloadUrl($newdep, $pname); + $url = $this->_downloader->_getDepPackageDownloadUrl($newdep, $pname); $obj = &$this->_installRegistry->getPackage($dep['name']); if (PEAR::isError($url)) { PEAR::popErrorHandling(); @@ -66896,8 +67509,7 @@ class PEAR_Downloader_Package 'optional'; $dep['package'] = $dep['name']; if (isset($newdep)) { - $version = $this->_installRegistry->packageInfo($newdep['name'], 'version', - $newdep['channel']); + $version = $this->_installRegistry->packageInfo($newdep['name'], 'version', $newdep['channel']); } else { $version = $this->_installRegistry->packageInfo($dep['name'], 'version'); } @@ -67216,6 +67828,7 @@ class PEAR_Downloader_Package $channel = 'pear.php.net'; } } + return (strtolower($package) == strtolower($this->getPackage()) && $channel == $this->getChannel() && version_compare($newdep['min'], $this->getVersion(), '<=') && @@ -67360,13 +67973,9 @@ class PEAR_Downloader_Package if (!$param) { continue; } - if ($param->getPackage()) { - if ($ignoreGroups) { - $group = ''; - } else { - $group = $param->getGroup(); - } + if ($param->getPackage()) { + $group = $ignoreGroups ? '' : $param->getGroup(); $pnames[$i] = $param->getChannel() . '/' . $param->getPackage() . '-' . $param->getVersion() . '#' . $group; } @@ -67896,7 +68505,7 @@ class PEAR_Downloader_Package if ($info['version'] === $package_version) { if (!isset($options['soft'])) { $this->_downloader->log(1, 'WARNING: failed to download ' . $pname['channel'] . - '/' . $pname['package'] . '-' . $pname['version'] . ', additionally the suggested version' . + '/' . $pname['package'] . '-' . $package_version. ', additionally the suggested version' . ' (' . $package_version . ') is the same as the locally installed one.'); } @@ -67906,7 +68515,7 @@ class PEAR_Downloader_Package if (version_compare($info['version'], $package_version, '<=')) { if (!isset($options['soft'])) { $this->_downloader->log(1, 'WARNING: failed to download ' . $pname['channel'] . - '/' . $pname['package'] . '-' . $pname['version'] . ', additionally the suggested version' . + '/' . $pname['package'] . '-' . $package_version . ', additionally the suggested version' . ' (' . $info['version'] . ') is a lower version than the locally installed one (' . $package_version . ').'); } @@ -68075,1218 +68684,1218 @@ class PEAR_Downloader_Package return $info; } -}<?php
-/**
- * Error Stack Implementation
- *
- * This is an incredibly simple implementation of a very complex error handling
- * facility. It contains the ability
- * to track multiple errors from multiple packages simultaneously. In addition,
- * it can track errors of many levels, save data along with the error, context
- * information such as the exact file, line number, class and function that
- * generated the error, and if necessary, it can raise a traditional PEAR_Error.
- * It has built-in support for PEAR::Log, to log errors as they occur
- *
- * Since version 0.2alpha, it is also possible to selectively ignore errors,
- * through the use of an error callback, see {@link pushCallback()}
- *
- * Since version 0.3alpha, it is possible to specify the exception class
- * returned from {@link push()}
- *
- * Since version PEAR1.3.2, ErrorStack no longer instantiates an exception class. This can
- * still be done quite handily in an error callback or by manipulating the returned array
- * @category Debugging
- * @package PEAR_ErrorStack
- * @author Greg Beaver <cellog@php.net>
- * @copyright 2004-2008 Greg Beaver
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version CVS: $Id: ErrorStack.php,v 1.29 2009/02/24 23:38:22 dufuz Exp $
- * @link http://pear.php.net/package/PEAR_ErrorStack
- */
-
-/**
- * Singleton storage
- *
- * Format:
- * <pre>
- * array(
- * 'package1' => PEAR_ErrorStack object,
- * 'package2' => PEAR_ErrorStack object,
- * ...
- * )
- * </pre>
- * @access private
- * @global array $GLOBALS['_PEAR_ERRORSTACK_SINGLETON']
- */
-$GLOBALS['_PEAR_ERRORSTACK_SINGLETON'] = array();
-
-/**
- * Global error callback (default)
- *
- * This is only used if set to non-false. * is the default callback for
- * all packages, whereas specific packages may set a default callback
- * for all instances, regardless of whether they are a singleton or not.
- *
- * To exclude non-singletons, only set the local callback for the singleton
- * @see PEAR_ErrorStack::setDefaultCallback()
- * @access private
- * @global array $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK']
- */
-$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'] = array(
- '*' => false,
-);
-
-/**
- * Global Log object (default)
- *
- * This is only used if set to non-false. Use to set a default log object for
- * all stacks, regardless of instantiation order or location
- * @see PEAR_ErrorStack::setDefaultLogger()
- * @access private
- * @global array $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER']
- */
-$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] = false;
-
-/**
- * Global Overriding Callback
- *
- * This callback will override any error callbacks that specific loggers have set.
- * Use with EXTREME caution
- * @see PEAR_ErrorStack::staticPushCallback()
- * @access private
- * @global array $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER']
- */
-$GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'] = array();
-
-/**#@+
- * One of four possible return values from the error Callback
- * @see PEAR_ErrorStack::_errorCallback()
- */
-/**
- * If this is returned, then the error will be both pushed onto the stack
- * and logged.
- */
-define('PEAR_ERRORSTACK_PUSHANDLOG', 1);
-/**
- * If this is returned, then the error will only be pushed onto the stack,
- * and not logged.
- */
-define('PEAR_ERRORSTACK_PUSH', 2);
-/**
- * If this is returned, then the error will only be logged, but not pushed
- * onto the error stack.
- */
-define('PEAR_ERRORSTACK_LOG', 3);
-/**
- * If this is returned, then the error is completely ignored.
- */
-define('PEAR_ERRORSTACK_IGNORE', 4);
-/**
- * If this is returned, then the error is logged and die() is called.
- */
-define('PEAR_ERRORSTACK_DIE', 5);
-/**#@-*/
-
-/**
- * Error code for an attempt to instantiate a non-class as a PEAR_ErrorStack in
- * the singleton method.
- */
-define('PEAR_ERRORSTACK_ERR_NONCLASS', 1);
-
-/**
- * Error code for an attempt to pass an object into {@link PEAR_ErrorStack::getMessage()}
- * that has no __toString() method
- */
-define('PEAR_ERRORSTACK_ERR_OBJTOSTRING', 2);
-/**
- * Error Stack Implementation
- *
- * Usage:
- * <code>
- * // global error stack
- * $global_stack = &PEAR_ErrorStack::singleton('MyPackage');
- * // local error stack
- * $local_stack = new PEAR_ErrorStack('MyPackage');
- * </code>
- * @author Greg Beaver <cellog@php.net>
- * @version 1.8.0
- * @package PEAR_ErrorStack
- * @category Debugging
- * @copyright 2004-2008 Greg Beaver
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version CVS: $Id: ErrorStack.php,v 1.29 2009/02/24 23:38:22 dufuz Exp $
- * @link http://pear.php.net/package/PEAR_ErrorStack
- */
-class PEAR_ErrorStack {
- /**
- * Errors are stored in the order that they are pushed on the stack.
- * @since 0.4alpha Errors are no longer organized by error level.
- * This renders pop() nearly unusable, and levels could be more easily
- * handled in a callback anyway
- * @var array
- * @access private
- */
- var $_errors = array();
-
- /**
- * Storage of errors by level.
- *
- * Allows easy retrieval and deletion of only errors from a particular level
- * @since PEAR 1.4.0dev
- * @var array
- * @access private
- */
- var $_errorsByLevel = array();
-
- /**
- * Package name this error stack represents
- * @var string
- * @access protected
- */
- var $_package;
-
- /**
- * Determines whether a PEAR_Error is thrown upon every error addition
- * @var boolean
- * @access private
- */
- var $_compat = false;
-
- /**
- * If set to a valid callback, this will be used to generate the error
- * message from the error code, otherwise the message passed in will be
- * used
- * @var false|string|array
- * @access private
- */
- var $_msgCallback = false;
-
- /**
- * If set to a valid callback, this will be used to generate the error
- * context for an error. For PHP-related errors, this will be a file
- * and line number as retrieved from debug_backtrace(), but can be
- * customized for other purposes. The error might actually be in a separate
- * configuration file, or in a database query.
- * @var false|string|array
- * @access protected
- */
- var $_contextCallback = false;
-
- /**
- * If set to a valid callback, this will be called every time an error
- * is pushed onto the stack. The return value will be used to determine
- * whether to allow an error to be pushed or logged.
- *
- * The return value must be one an PEAR_ERRORSTACK_* constant
- * @see PEAR_ERRORSTACK_PUSHANDLOG, PEAR_ERRORSTACK_PUSH, PEAR_ERRORSTACK_LOG
- * @var false|string|array
- * @access protected
- */
- var $_errorCallback = array();
-
- /**
- * PEAR::Log object for logging errors
- * @var false|Log
- * @access protected
- */
- var $_logger = false;
-
- /**
- * Error messages - designed to be overridden
- * @var array
- * @abstract
- */
- var $_errorMsgs = array();
-
- /**
- * Set up a new error stack
- *
- * @param string $package name of the package this error stack represents
- * @param callback $msgCallback callback used for error message generation
- * @param callback $contextCallback callback used for context generation,
- * defaults to {@link getFileLine()}
- * @param boolean $throwPEAR_Error
- */
- function PEAR_ErrorStack($package, $msgCallback = false, $contextCallback = false,
- $throwPEAR_Error = false)
- {
- $this->_package = $package;
- $this->setMessageCallback($msgCallback);
- $this->setContextCallback($contextCallback);
- $this->_compat = $throwPEAR_Error;
- }
-
- /**
- * Return a single error stack for this package.
- *
- * Note that all parameters are ignored if the stack for package $package
- * has already been instantiated
- * @param string $package name of the package this error stack represents
- * @param callback $msgCallback callback used for error message generation
- * @param callback $contextCallback callback used for context generation,
- * defaults to {@link getFileLine()}
- * @param boolean $throwPEAR_Error
- * @param string $stackClass class to instantiate
- * @static
- * @return PEAR_ErrorStack
- */
- function &singleton($package, $msgCallback = false, $contextCallback = false,
- $throwPEAR_Error = false, $stackClass = 'PEAR_ErrorStack')
- {
- if (isset($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package])) {
- return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package];
- }
- if (!class_exists($stackClass)) {
- if (function_exists('debug_backtrace')) {
- $trace = debug_backtrace();
- }
- PEAR_ErrorStack::staticPush('PEAR_ErrorStack', PEAR_ERRORSTACK_ERR_NONCLASS,
- 'exception', array('stackclass' => $stackClass),
- 'stack class "%stackclass%" is not a valid class name (should be like PEAR_ErrorStack)',
- false, $trace);
- }
- $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package] =
- new $stackClass($package, $msgCallback, $contextCallback, $throwPEAR_Error);
-
- return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package];
- }
-
- /**
- * Internal error handler for PEAR_ErrorStack class
- *
- * Dies if the error is an exception (and would have died anyway)
- * @access private
- */
- function _handleError($err)
- {
- if ($err['level'] == 'exception') {
- $message = $err['message'];
- if (isset($_SERVER['REQUEST_URI'])) {
- echo '<br />';
- } else {
- echo "\n";
- }
- var_dump($err['context']);
- die($message);
- }
- }
-
- /**
- * Set up a PEAR::Log object for all error stacks that don't have one
- * @param Log $log
- * @static
- */
- function setDefaultLogger(&$log)
- {
- if (is_object($log) && method_exists($log, 'log') ) {
- $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] = &$log;
- } elseif (is_callable($log)) {
- $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] = &$log;
- }
- }
-
- /**
- * Set up a PEAR::Log object for this error stack
- * @param Log $log
- */
- function setLogger(&$log)
- {
- if (is_object($log) && method_exists($log, 'log') ) {
- $this->_logger = &$log;
- } elseif (is_callable($log)) {
- $this->_logger = &$log;
- }
- }
-
- /**
- * Set an error code => error message mapping callback
- *
- * This method sets the callback that can be used to generate error
- * messages for any instance
- * @param array|string Callback function/method
- */
- function setMessageCallback($msgCallback)
- {
- if (!$msgCallback) {
- $this->_msgCallback = array(&$this, 'getErrorMessage');
- } else {
- if (is_callable($msgCallback)) {
- $this->_msgCallback = $msgCallback;
- }
- }
- }
-
- /**
- * Get an error code => error message mapping callback
- *
- * This method returns the current callback that can be used to generate error
- * messages
- * @return array|string|false Callback function/method or false if none
- */
- function getMessageCallback()
- {
- return $this->_msgCallback;
- }
-
- /**
- * Sets a default callback to be used by all error stacks
- *
- * This method sets the callback that can be used to generate error
- * messages for a singleton
- * @param array|string Callback function/method
- * @param string Package name, or false for all packages
- * @static
- */
- function setDefaultCallback($callback = false, $package = false)
- {
- if (!is_callable($callback)) {
- $callback = false;
- }
- $package = $package ? $package : '*';
- $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'][$package] = $callback;
- }
-
- /**
- * Set a callback that generates context information (location of error) for an error stack
- *
- * This method sets the callback that can be used to generate context
- * information for an error. Passing in NULL will disable context generation
- * and remove the expensive call to debug_backtrace()
- * @param array|string|null Callback function/method
- */
- function setContextCallback($contextCallback)
- {
- if ($contextCallback === null) {
- return $this->_contextCallback = false;
- }
- if (!$contextCallback) {
- $this->_contextCallback = array(&$this, 'getFileLine');
- } else {
- if (is_callable($contextCallback)) {
- $this->_contextCallback = $contextCallback;
- }
- }
- }
-
- /**
- * Set an error Callback
- * If set to a valid callback, this will be called every time an error
- * is pushed onto the stack. The return value will be used to determine
- * whether to allow an error to be pushed or logged.
- *
- * The return value must be one of the ERRORSTACK_* constants.
- *
- * This functionality can be used to emulate PEAR's pushErrorHandling, and
- * the PEAR_ERROR_CALLBACK mode, without affecting the integrity of
- * the error stack or logging
- * @see PEAR_ERRORSTACK_PUSHANDLOG, PEAR_ERRORSTACK_PUSH, PEAR_ERRORSTACK_LOG
- * @see popCallback()
- * @param string|array $cb
- */
- function pushCallback($cb)
- {
- array_push($this->_errorCallback, $cb);
- }
-
- /**
- * Remove a callback from the error callback stack
- * @see pushCallback()
- * @return array|string|false
- */
- function popCallback()
- {
- if (!count($this->_errorCallback)) {
- return false;
- }
- return array_pop($this->_errorCallback);
- }
-
- /**
- * Set a temporary overriding error callback for every package error stack
- *
- * Use this to temporarily disable all existing callbacks (can be used
- * to emulate the @ operator, for instance)
- * @see PEAR_ERRORSTACK_PUSHANDLOG, PEAR_ERRORSTACK_PUSH, PEAR_ERRORSTACK_LOG
- * @see staticPopCallback(), pushCallback()
- * @param string|array $cb
- * @static
- */
- function staticPushCallback($cb)
- {
- array_push($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'], $cb);
- }
-
- /**
- * Remove a temporary overriding error callback
- * @see staticPushCallback()
- * @return array|string|false
- * @static
- */
- function staticPopCallback()
- {
- $ret = array_pop($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK']);
- if (!is_array($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'])) {
- $GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'] = array();
- }
- return $ret;
- }
-
- /**
- * Add an error to the stack
- *
- * If the message generator exists, it is called with 2 parameters.
- * - the current Error Stack object
- * - an array that is in the same format as an error. Available indices
- * are 'code', 'package', 'time', 'params', 'level', and 'context'
- *
- * Next, if the error should contain context information, this is
- * handled by the context grabbing method.
- * Finally, the error is pushed onto the proper error stack
- * @param int $code Package-specific error code
- * @param string $level Error level. This is NOT spell-checked
- * @param array $params associative array of error parameters
- * @param string $msg Error message, or a portion of it if the message
- * is to be generated
- * @param array $repackage If this error re-packages an error pushed by
- * another package, place the array returned from
- * {@link pop()} in this parameter
- * @param array $backtrace Protected parameter: use this to pass in the
- * {@link debug_backtrace()} that should be used
- * to find error context
- * @return PEAR_Error|array if compatibility mode is on, a PEAR_Error is also
- * thrown. If a PEAR_Error is returned, the userinfo
- * property is set to the following array:
- *
- * <code>
- * array(
- * 'code' => $code,
- * 'params' => $params,
- * 'package' => $this->_package,
- * 'level' => $level,
- * 'time' => time(),
- * 'context' => $context,
- * 'message' => $msg,
- * //['repackage' => $err] repackaged error array/Exception class
- * );
- * </code>
- *
- * Normally, the previous array is returned.
- */
- function push($code, $level = 'error', $params = array(), $msg = false,
- $repackage = false, $backtrace = false)
- {
- $context = false;
- // grab error context
- if ($this->_contextCallback) {
- if (!$backtrace) {
- $backtrace = debug_backtrace();
- }
- $context = call_user_func($this->_contextCallback, $code, $params, $backtrace);
- }
-
- // save error
- $time = explode(' ', microtime());
- $time = $time[1] + $time[0];
- $err = array(
- 'code' => $code,
- 'params' => $params,
- 'package' => $this->_package,
- 'level' => $level,
- 'time' => $time,
- 'context' => $context,
- 'message' => $msg,
- );
-
- if ($repackage) {
- $err['repackage'] = $repackage;
- }
-
- // set up the error message, if necessary
- if ($this->_msgCallback) {
- $msg = call_user_func_array($this->_msgCallback,
- array(&$this, $err));
- $err['message'] = $msg;
- }
- $push = $log = true;
- $die = false;
- // try the overriding callback first
- $callback = $this->staticPopCallback();
- if ($callback) {
- $this->staticPushCallback($callback);
- }
- if (!is_callable($callback)) {
- // try the local callback next
- $callback = $this->popCallback();
- if (is_callable($callback)) {
- $this->pushCallback($callback);
- } else {
- // try the default callback
- $callback = isset($GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'][$this->_package]) ?
- $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'][$this->_package] :
- $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK']['*'];
- }
- }
- if (is_callable($callback)) {
- switch(call_user_func($callback, $err)){
- case PEAR_ERRORSTACK_IGNORE:
- return $err;
- break;
- case PEAR_ERRORSTACK_PUSH:
- $log = false;
- break;
- case PEAR_ERRORSTACK_LOG:
- $push = false;
- break;
- case PEAR_ERRORSTACK_DIE:
- $die = true;
- break;
- // anything else returned has the same effect as pushandlog
- }
- }
- if ($push) {
- array_unshift($this->_errors, $err);
- if (!isset($this->_errorsByLevel[$err['level']])) {
- $this->_errorsByLevel[$err['level']] = array();
- }
- $this->_errorsByLevel[$err['level']][] = &$this->_errors[0];
- }
- if ($log) {
- if ($this->_logger || $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER']) {
- $this->_log($err);
- }
- }
- if ($die) {
- die();
- }
- if ($this->_compat && $push) {
- return $this->raiseError($msg, $code, null, null, $err);
- }
- return $err;
- }
-
- /**
- * Static version of {@link push()}
- *
- * @param string $package Package name this error belongs to
- * @param int $code Package-specific error code
- * @param string $level Error level. This is NOT spell-checked
- * @param array $params associative array of error parameters
- * @param string $msg Error message, or a portion of it if the message
- * is to be generated
- * @param array $repackage If this error re-packages an error pushed by
- * another package, place the array returned from
- * {@link pop()} in this parameter
- * @param array $backtrace Protected parameter: use this to pass in the
- * {@link debug_backtrace()} that should be used
- * to find error context
- * @return PEAR_Error|array if compatibility mode is on, a PEAR_Error is also
- * thrown. see docs for {@link push()}
- * @static
- */
- function staticPush($package, $code, $level = 'error', $params = array(),
- $msg = false, $repackage = false, $backtrace = false)
- {
- $s = &PEAR_ErrorStack::singleton($package);
- if ($s->_contextCallback) {
- if (!$backtrace) {
- if (function_exists('debug_backtrace')) {
- $backtrace = debug_backtrace();
- }
- }
- }
- return $s->push($code, $level, $params, $msg, $repackage, $backtrace);
- }
-
- /**
- * Log an error using PEAR::Log
- * @param array $err Error array
- * @param array $levels Error level => Log constant map
- * @access protected
- */
- function _log($err)
- {
- if ($this->_logger) {
- $logger = &$this->_logger;
- } else {
- $logger = &$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'];
- }
- if (is_a($logger, 'Log')) {
- $levels = array(
- 'exception' => PEAR_LOG_CRIT,
- 'alert' => PEAR_LOG_ALERT,
- 'critical' => PEAR_LOG_CRIT,
- 'error' => PEAR_LOG_ERR,
- 'warning' => PEAR_LOG_WARNING,
- 'notice' => PEAR_LOG_NOTICE,
- 'info' => PEAR_LOG_INFO,
- 'debug' => PEAR_LOG_DEBUG);
- if (isset($levels[$err['level']])) {
- $level = $levels[$err['level']];
- } else {
- $level = PEAR_LOG_INFO;
- }
- $logger->log($err['message'], $level, $err);
- } else { // support non-standard logs
- call_user_func($logger, $err);
- }
- }
-
-
- /**
- * Pop an error off of the error stack
- *
- * @return false|array
- * @since 0.4alpha it is no longer possible to specify a specific error
- * level to return - the last error pushed will be returned, instead
- */
- function pop()
- {
- $err = @array_shift($this->_errors);
- if (!is_null($err)) {
- @array_pop($this->_errorsByLevel[$err['level']]);
- if (!count($this->_errorsByLevel[$err['level']])) {
- unset($this->_errorsByLevel[$err['level']]);
- }
- }
- return $err;
- }
-
- /**
- * Pop an error off of the error stack, static method
- *
- * @param string package name
- * @return boolean
- * @since PEAR1.5.0a1
- */
- function staticPop($package)
- {
- if ($package) {
- if (!isset($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package])) {
- return false;
- }
- return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]->pop();
- }
- }
-
- /**
- * Determine whether there are any errors on the stack
- * @param string|array Level name. Use to determine if any errors
- * of level (string), or levels (array) have been pushed
- * @return boolean
- */
- function hasErrors($level = false)
- {
- if ($level) {
- return isset($this->_errorsByLevel[$level]);
- }
- return count($this->_errors);
- }
-
- /**
- * Retrieve all errors since last purge
- *
- * @param boolean set in order to empty the error stack
- * @param string level name, to return only errors of a particular severity
- * @return array
- */
- function getErrors($purge = false, $level = false)
- {
- if (!$purge) {
- if ($level) {
- if (!isset($this->_errorsByLevel[$level])) {
- return array();
- } else {
- return $this->_errorsByLevel[$level];
- }
- } else {
- return $this->_errors;
- }
- }
- if ($level) {
- $ret = $this->_errorsByLevel[$level];
- foreach ($this->_errorsByLevel[$level] as $i => $unused) {
- // entries are references to the $_errors array
- $this->_errorsByLevel[$level][$i] = false;
- }
- // array_filter removes all entries === false
- $this->_errors = array_filter($this->_errors);
- unset($this->_errorsByLevel[$level]);
- return $ret;
- }
- $ret = $this->_errors;
- $this->_errors = array();
- $this->_errorsByLevel = array();
- return $ret;
- }
-
- /**
- * Determine whether there are any errors on a single error stack, or on any error stack
- *
- * The optional parameter can be used to test the existence of any errors without the need of
- * singleton instantiation
- * @param string|false Package name to check for errors
- * @param string Level name to check for a particular severity
- * @return boolean
- * @static
- */
- function staticHasErrors($package = false, $level = false)
- {
- if ($package) {
- if (!isset($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package])) {
- return false;
- }
- return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]->hasErrors($level);
- }
- foreach ($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'] as $package => $obj) {
- if ($obj->hasErrors($level)) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Get a list of all errors since last purge, organized by package
- * @since PEAR 1.4.0dev BC break! $level is now in the place $merge used to be
- * @param boolean $purge Set to purge the error stack of existing errors
- * @param string $level Set to a level name in order to retrieve only errors of a particular level
- * @param boolean $merge Set to return a flat array, not organized by package
- * @param array $sortfunc Function used to sort a merged array - default
- * sorts by time, and should be good for most cases
- * @static
- * @return array
- */
- function staticGetErrors($purge = false, $level = false, $merge = false,
- $sortfunc = array('PEAR_ErrorStack', '_sortErrors'))
- {
- $ret = array();
- if (!is_callable($sortfunc)) {
- $sortfunc = array('PEAR_ErrorStack', '_sortErrors');
- }
- foreach ($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'] as $package => $obj) {
- $test = $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]->getErrors($purge, $level);
- if ($test) {
- if ($merge) {
- $ret = array_merge($ret, $test);
- } else {
- $ret[$package] = $test;
- }
- }
- }
- if ($merge) {
- usort($ret, $sortfunc);
- }
- return $ret;
- }
-
- /**
- * Error sorting function, sorts by time
- * @access private
- */
- function _sortErrors($a, $b)
- {
- if ($a['time'] == $b['time']) {
- return 0;
- }
- if ($a['time'] < $b['time']) {
- return 1;
- }
- return -1;
- }
-
- /**
- * Standard file/line number/function/class context callback
- *
- * This function uses a backtrace generated from {@link debug_backtrace()}
- * and so will not work at all in PHP < 4.3.0. The frame should
- * reference the frame that contains the source of the error.
- * @return array|false either array('file' => file, 'line' => line,
- * 'function' => function name, 'class' => class name) or
- * if this doesn't work, then false
- * @param unused
- * @param integer backtrace frame.
- * @param array Results of debug_backtrace()
- * @static
- */
- function getFileLine($code, $params, $backtrace = null)
- {
- if ($backtrace === null) {
- return false;
- }
- $frame = 0;
- $functionframe = 1;
- if (!isset($backtrace[1])) {
- $functionframe = 0;
- } else {
- while (isset($backtrace[$functionframe]['function']) &&
- $backtrace[$functionframe]['function'] == 'eval' &&
- isset($backtrace[$functionframe + 1])) {
- $functionframe++;
- }
- }
- if (isset($backtrace[$frame])) {
- if (!isset($backtrace[$frame]['file'])) {
- $frame++;
- }
- $funcbacktrace = $backtrace[$functionframe];
- $filebacktrace = $backtrace[$frame];
- $ret = array('file' => $filebacktrace['file'],
- 'line' => $filebacktrace['line']);
- // rearrange for eval'd code or create function errors
- if (strpos($filebacktrace['file'], '(') &&
- preg_match(';^(.*?)\((\d+)\) : (.*?)\\z;', $filebacktrace['file'],
- $matches)) {
- $ret['file'] = $matches[1];
- $ret['line'] = $matches[2] + 0;
- }
- if (isset($funcbacktrace['function']) && isset($backtrace[1])) {
- if ($funcbacktrace['function'] != 'eval') {
- if ($funcbacktrace['function'] == '__lambda_func') {
- $ret['function'] = 'create_function() code';
- } else {
- $ret['function'] = $funcbacktrace['function'];
- }
- }
- }
- if (isset($funcbacktrace['class']) && isset($backtrace[1])) {
- $ret['class'] = $funcbacktrace['class'];
- }
- return $ret;
- }
- return false;
- }
-
- /**
- * Standard error message generation callback
- *
- * This method may also be called by a custom error message generator
- * to fill in template values from the params array, simply
- * set the third parameter to the error message template string to use
- *
- * The special variable %__msg% is reserved: use it only to specify
- * where a message passed in by the user should be placed in the template,
- * like so:
- *
- * Error message: %msg% - internal error
- *
- * If the message passed like so:
- *
- * <code>
- * $stack->push(ERROR_CODE, 'error', array(), 'server error 500');
- * </code>
- *
- * The returned error message will be "Error message: server error 500 -
- * internal error"
- * @param PEAR_ErrorStack
- * @param array
- * @param string|false Pre-generated error message template
- * @static
- * @return string
- */
- function getErrorMessage(&$stack, $err, $template = false)
- {
- if ($template) {
- $mainmsg = $template;
- } else {
- $mainmsg = $stack->getErrorMessageTemplate($err['code']);
- }
- $mainmsg = str_replace('%__msg%', $err['message'], $mainmsg);
- if (is_array($err['params']) && count($err['params'])) {
- foreach ($err['params'] as $name => $val) {
- if (is_array($val)) {
- // @ is needed in case $val is a multi-dimensional array
- $val = @implode(', ', $val);
- }
- if (is_object($val)) {
- if (method_exists($val, '__toString')) {
- $val = $val->__toString();
- } else {
- PEAR_ErrorStack::staticPush('PEAR_ErrorStack', PEAR_ERRORSTACK_ERR_OBJTOSTRING,
- 'warning', array('obj' => get_class($val)),
- 'object %obj% passed into getErrorMessage, but has no __toString() method');
- $val = 'Object';
- }
- }
- $mainmsg = str_replace('%' . $name . '%', $val, $mainmsg);
- }
- }
- return $mainmsg;
- }
-
- /**
- * Standard Error Message Template generator from code
- * @return string
- */
- function getErrorMessageTemplate($code)
- {
- if (!isset($this->_errorMsgs[$code])) {
- return '%__msg%';
- }
- return $this->_errorMsgs[$code];
- }
-
- /**
- * Set the Error Message Template array
- *
- * The array format must be:
- * <pre>
- * array(error code => 'message template',...)
- * </pre>
- *
- * Error message parameters passed into {@link push()} will be used as input
- * for the error message. If the template is 'message %foo% was %bar%', and the
- * parameters are array('foo' => 'one', 'bar' => 'six'), the error message returned will
- * be 'message one was six'
- * @return string
- */
- function setErrorMessageTemplate($template)
- {
- $this->_errorMsgs = $template;
- }
-
-
- /**
- * emulate PEAR::raiseError()
- *
- * @return PEAR_Error
- */
- function raiseError()
- {
- require_once 'phar://install-pear-nozlib.phar/' . 'PEAR.php';
- $args = func_get_args();
- return call_user_func_array(array('PEAR', 'raiseError'), $args);
- }
-}
-$stack = &PEAR_ErrorStack::singleton('PEAR_ErrorStack');
-$stack->pushCallback(array('PEAR_ErrorStack', '_handleError'));
-?>
-<?php
-/**
- * PEAR_Frontend, the singleton-based frontend for user input/output
- *
- * PHP versions 4 and 5
- *
- * @category pear
- * @package PEAR
- * @author Greg Beaver <cellog@php.net>
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version CVS: $Id: Frontend.php,v 1.18 2009/02/24 23:38:22 dufuz Exp $
- * @link http://pear.php.net/package/PEAR
- * @since File available since Release 1.4.0a1
- */
-
-/**
- * Include error handling
- */
-//require_once 'PEAR.php';
-
-/**
- * Which user interface class is being used.
- * @var string class name
- */
-$GLOBALS['_PEAR_FRONTEND_CLASS'] = 'PEAR_Frontend_CLI';
-
-/**
- * Instance of $_PEAR_Command_uiclass.
- * @var object
- */
-$GLOBALS['_PEAR_FRONTEND_SINGLETON'] = null;
-
-/**
- * Singleton-based frontend for PEAR user input/output
- *
- * @category pear
- * @package PEAR
- * @author Greg Beaver <cellog@php.net>
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.8.0
- * @link http://pear.php.net/package/PEAR
- * @since Class available since Release 1.4.0a1
- */
-class PEAR_Frontend extends PEAR
-{
- /**
- * Retrieve the frontend object
- * @return PEAR_Frontend_CLI|PEAR_Frontend_Web|PEAR_Frontend_Gtk
- * @static
- */
- function &singleton($type = null)
- {
- if ($type === null) {
- if (!isset($GLOBALS['_PEAR_FRONTEND_SINGLETON'])) {
- $a = false;
- return $a;
- }
- return $GLOBALS['_PEAR_FRONTEND_SINGLETON'];
- }
-
- $a = PEAR_Frontend::setFrontendClass($type);
- return $a;
- }
-
- /**
- * Set the frontend class that will be used by calls to {@link singleton()}
- *
- * Frontends are expected to conform to the PEAR naming standard of
- * _ => DIRECTORY_SEPARATOR (PEAR_Frontend_CLI is in PEAR/Frontend/CLI.php)
- * @param string $uiclass full class name
- * @return PEAR_Frontend
- * @static
- */
- function &setFrontendClass($uiclass)
- {
- if (is_object($GLOBALS['_PEAR_FRONTEND_SINGLETON']) &&
- is_a($GLOBALS['_PEAR_FRONTEND_SINGLETON'], $uiclass)) {
- return $GLOBALS['_PEAR_FRONTEND_SINGLETON'];
- }
-
- if (!class_exists($uiclass)) {
- $file = 'phar://install-pear-nozlib.phar/' . str_replace('_', '/', $uiclass) . '.php';
- if (PEAR_Frontend::isIncludeable($file)) {
- include_once $file;
- }
- }
-
- if (class_exists($uiclass)) {
- $obj = &new $uiclass;
- // quick test to see if this class implements a few of the most
- // important frontend methods
- if (is_a($obj, 'PEAR_Frontend')) {
- $GLOBALS['_PEAR_FRONTEND_SINGLETON'] = &$obj;
- $GLOBALS['_PEAR_FRONTEND_CLASS'] = $uiclass;
- return $obj;
- }
-
- $err = PEAR::raiseError("not a frontend class: $uiclass");
- return $err;
- }
-
- $err = PEAR::raiseError("no such class: $uiclass");
- return $err;
- }
-
- /**
- * Set the frontend class that will be used by calls to {@link singleton()}
- *
- * Frontends are expected to be a descendant of PEAR_Frontend
- * @param PEAR_Frontend
- * @return PEAR_Frontend
- * @static
- */
- function &setFrontendObject($uiobject)
- {
- if (is_object($GLOBALS['_PEAR_FRONTEND_SINGLETON']) &&
- is_a($GLOBALS['_PEAR_FRONTEND_SINGLETON'], get_class($uiobject))) {
- return $GLOBALS['_PEAR_FRONTEND_SINGLETON'];
- }
-
- if (!is_a($uiobject, 'PEAR_Frontend')) {
- $err = PEAR::raiseError('not a valid frontend class: (' .
- get_class($uiobject) . ')');
- return $err;
- }
-
- $GLOBALS['_PEAR_FRONTEND_SINGLETON'] = &$uiobject;
- $GLOBALS['_PEAR_FRONTEND_CLASS'] = get_class($uiobject);
- return $uiobject;
- }
-
- /**
- * @param string $path relative or absolute include path
- * @return boolean
- * @static
- */
- function isIncludeable($path)
- {
- if (file_exists($path) && is_readable($path)) {
- return true;
- }
-
- $fp = @fopen($path, 'r', true);
- if ($fp) {
- fclose($fp);
- return true;
- }
-
- return false;
- }
-
- /**
- * @param PEAR_Config
- */
- function setConfig(&$config)
- {
- }
-
- /**
- * This can be overridden to allow session-based temporary file management
- *
- * By default, all files are deleted at the end of a session. The web installer
- * needs to be able to sustain a list over many sessions in order to support
- * user interaction with install scripts
- */
- function addTempFile($file)
- {
- $GLOBALS['_PEAR_Common_tempfiles'][] = $file;
- }
-
- /**
- * Log an action
- *
- * @param string $msg the message to log
- * @param boolean $append_crlf
- * @return boolean true
- * @abstract
- */
- function log($msg, $append_crlf = true)
- {
- }
-
- /**
- * Run a post-installation script
- *
- * @param array $scripts array of post-install scripts
- * @abstract
- */
- function runPostinstallScripts(&$scripts)
- {
- }
-
- /**
- * Display human-friendly output formatted depending on the
- * $command parameter.
- *
- * This should be able to handle basic output data with no command
- * @param mixed $data data structure containing the information to display
- * @param string $command command from which this method was called
- * @abstract
- */
- function outputData($data, $command = '_default')
- {
- }
-
- /**
- * Display a modal form dialog and return the given input
- *
- * A frontend that requires multiple requests to retrieve and process
- * data must take these needs into account, and implement the request
- * handling code.
- * @param string $command command from which this method was called
- * @param array $prompts associative array. keys are the input field names
- * and values are the description
- * @param array $types array of input field types (text, password,
- * etc.) keys have to be the same like in $prompts
- * @param array $defaults array of default values. again keys have
- * to be the same like in $prompts. Do not depend
- * on a default value being set.
- * @return array input sent by the user
- * @abstract
- */
- function userDialog($command, $prompts, $types = array(), $defaults = array())
- {
- }
+}<?php +/** + * Error Stack Implementation + * + * This is an incredibly simple implementation of a very complex error handling + * facility. It contains the ability + * to track multiple errors from multiple packages simultaneously. In addition, + * it can track errors of many levels, save data along with the error, context + * information such as the exact file, line number, class and function that + * generated the error, and if necessary, it can raise a traditional PEAR_Error. + * It has built-in support for PEAR::Log, to log errors as they occur + * + * Since version 0.2alpha, it is also possible to selectively ignore errors, + * through the use of an error callback, see {@link pushCallback()} + * + * Since version 0.3alpha, it is possible to specify the exception class + * returned from {@link push()} + * + * Since version PEAR1.3.2, ErrorStack no longer instantiates an exception class. This can + * still be done quite handily in an error callback or by manipulating the returned array + * @category Debugging + * @package PEAR_ErrorStack + * @author Greg Beaver <cellog@php.net> + * @copyright 2004-2008 Greg Beaver + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: ErrorStack.php 276383 2009-02-24 23:39:37Z dufuz $ + * @link http://pear.php.net/package/PEAR_ErrorStack + */ + +/** + * Singleton storage + * + * Format: + * <pre> + * array( + * 'package1' => PEAR_ErrorStack object, + * 'package2' => PEAR_ErrorStack object, + * ... + * ) + * </pre> + * @access private + * @global array $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'] + */ +$GLOBALS['_PEAR_ERRORSTACK_SINGLETON'] = array(); + +/** + * Global error callback (default) + * + * This is only used if set to non-false. * is the default callback for + * all packages, whereas specific packages may set a default callback + * for all instances, regardless of whether they are a singleton or not. + * + * To exclude non-singletons, only set the local callback for the singleton + * @see PEAR_ErrorStack::setDefaultCallback() + * @access private + * @global array $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'] + */ +$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'] = array( + '*' => false, +); + +/** + * Global Log object (default) + * + * This is only used if set to non-false. Use to set a default log object for + * all stacks, regardless of instantiation order or location + * @see PEAR_ErrorStack::setDefaultLogger() + * @access private + * @global array $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] + */ +$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] = false; + +/** + * Global Overriding Callback + * + * This callback will override any error callbacks that specific loggers have set. + * Use with EXTREME caution + * @see PEAR_ErrorStack::staticPushCallback() + * @access private + * @global array $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] + */ +$GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'] = array(); + +/**#@+ + * One of four possible return values from the error Callback + * @see PEAR_ErrorStack::_errorCallback() + */ +/** + * If this is returned, then the error will be both pushed onto the stack + * and logged. + */ +define('PEAR_ERRORSTACK_PUSHANDLOG', 1); +/** + * If this is returned, then the error will only be pushed onto the stack, + * and not logged. + */ +define('PEAR_ERRORSTACK_PUSH', 2); +/** + * If this is returned, then the error will only be logged, but not pushed + * onto the error stack. + */ +define('PEAR_ERRORSTACK_LOG', 3); +/** + * If this is returned, then the error is completely ignored. + */ +define('PEAR_ERRORSTACK_IGNORE', 4); +/** + * If this is returned, then the error is logged and die() is called. + */ +define('PEAR_ERRORSTACK_DIE', 5); +/**#@-*/ + +/** + * Error code for an attempt to instantiate a non-class as a PEAR_ErrorStack in + * the singleton method. + */ +define('PEAR_ERRORSTACK_ERR_NONCLASS', 1); + +/** + * Error code for an attempt to pass an object into {@link PEAR_ErrorStack::getMessage()} + * that has no __toString() method + */ +define('PEAR_ERRORSTACK_ERR_OBJTOSTRING', 2); +/** + * Error Stack Implementation + * + * Usage: + * <code> + * // global error stack + * $global_stack = &PEAR_ErrorStack::singleton('MyPackage'); + * // local error stack + * $local_stack = new PEAR_ErrorStack('MyPackage'); + * </code> + * @author Greg Beaver <cellog@php.net> + * @version 1.9.0 + * @package PEAR_ErrorStack + * @category Debugging + * @copyright 2004-2008 Greg Beaver + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: ErrorStack.php 276383 2009-02-24 23:39:37Z dufuz $ + * @link http://pear.php.net/package/PEAR_ErrorStack + */ +class PEAR_ErrorStack { + /** + * Errors are stored in the order that they are pushed on the stack. + * @since 0.4alpha Errors are no longer organized by error level. + * This renders pop() nearly unusable, and levels could be more easily + * handled in a callback anyway + * @var array + * @access private + */ + var $_errors = array(); + + /** + * Storage of errors by level. + * + * Allows easy retrieval and deletion of only errors from a particular level + * @since PEAR 1.4.0dev + * @var array + * @access private + */ + var $_errorsByLevel = array(); + + /** + * Package name this error stack represents + * @var string + * @access protected + */ + var $_package; + + /** + * Determines whether a PEAR_Error is thrown upon every error addition + * @var boolean + * @access private + */ + var $_compat = false; + + /** + * If set to a valid callback, this will be used to generate the error + * message from the error code, otherwise the message passed in will be + * used + * @var false|string|array + * @access private + */ + var $_msgCallback = false; + + /** + * If set to a valid callback, this will be used to generate the error + * context for an error. For PHP-related errors, this will be a file + * and line number as retrieved from debug_backtrace(), but can be + * customized for other purposes. The error might actually be in a separate + * configuration file, or in a database query. + * @var false|string|array + * @access protected + */ + var $_contextCallback = false; + + /** + * If set to a valid callback, this will be called every time an error + * is pushed onto the stack. The return value will be used to determine + * whether to allow an error to be pushed or logged. + * + * The return value must be one an PEAR_ERRORSTACK_* constant + * @see PEAR_ERRORSTACK_PUSHANDLOG, PEAR_ERRORSTACK_PUSH, PEAR_ERRORSTACK_LOG + * @var false|string|array + * @access protected + */ + var $_errorCallback = array(); + + /** + * PEAR::Log object for logging errors + * @var false|Log + * @access protected + */ + var $_logger = false; + + /** + * Error messages - designed to be overridden + * @var array + * @abstract + */ + var $_errorMsgs = array(); + + /** + * Set up a new error stack + * + * @param string $package name of the package this error stack represents + * @param callback $msgCallback callback used for error message generation + * @param callback $contextCallback callback used for context generation, + * defaults to {@link getFileLine()} + * @param boolean $throwPEAR_Error + */ + function PEAR_ErrorStack($package, $msgCallback = false, $contextCallback = false, + $throwPEAR_Error = false) + { + $this->_package = $package; + $this->setMessageCallback($msgCallback); + $this->setContextCallback($contextCallback); + $this->_compat = $throwPEAR_Error; + } + + /** + * Return a single error stack for this package. + * + * Note that all parameters are ignored if the stack for package $package + * has already been instantiated + * @param string $package name of the package this error stack represents + * @param callback $msgCallback callback used for error message generation + * @param callback $contextCallback callback used for context generation, + * defaults to {@link getFileLine()} + * @param boolean $throwPEAR_Error + * @param string $stackClass class to instantiate + * @static + * @return PEAR_ErrorStack + */ + function &singleton($package, $msgCallback = false, $contextCallback = false, + $throwPEAR_Error = false, $stackClass = 'PEAR_ErrorStack') + { + if (isset($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package])) { + return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]; + } + if (!class_exists($stackClass)) { + if (function_exists('debug_backtrace')) { + $trace = debug_backtrace(); + } + PEAR_ErrorStack::staticPush('PEAR_ErrorStack', PEAR_ERRORSTACK_ERR_NONCLASS, + 'exception', array('stackclass' => $stackClass), + 'stack class "%stackclass%" is not a valid class name (should be like PEAR_ErrorStack)', + false, $trace); + } + $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package] = + new $stackClass($package, $msgCallback, $contextCallback, $throwPEAR_Error); + + return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]; + } + + /** + * Internal error handler for PEAR_ErrorStack class + * + * Dies if the error is an exception (and would have died anyway) + * @access private + */ + function _handleError($err) + { + if ($err['level'] == 'exception') { + $message = $err['message']; + if (isset($_SERVER['REQUEST_URI'])) { + echo '<br />'; + } else { + echo "\n"; + } + var_dump($err['context']); + die($message); + } + } + + /** + * Set up a PEAR::Log object for all error stacks that don't have one + * @param Log $log + * @static + */ + function setDefaultLogger(&$log) + { + if (is_object($log) && method_exists($log, 'log') ) { + $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] = &$log; + } elseif (is_callable($log)) { + $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] = &$log; + } + } + + /** + * Set up a PEAR::Log object for this error stack + * @param Log $log + */ + function setLogger(&$log) + { + if (is_object($log) && method_exists($log, 'log') ) { + $this->_logger = &$log; + } elseif (is_callable($log)) { + $this->_logger = &$log; + } + } + + /** + * Set an error code => error message mapping callback + * + * This method sets the callback that can be used to generate error + * messages for any instance + * @param array|string Callback function/method + */ + function setMessageCallback($msgCallback) + { + if (!$msgCallback) { + $this->_msgCallback = array(&$this, 'getErrorMessage'); + } else { + if (is_callable($msgCallback)) { + $this->_msgCallback = $msgCallback; + } + } + } + + /** + * Get an error code => error message mapping callback + * + * This method returns the current callback that can be used to generate error + * messages + * @return array|string|false Callback function/method or false if none + */ + function getMessageCallback() + { + return $this->_msgCallback; + } + + /** + * Sets a default callback to be used by all error stacks + * + * This method sets the callback that can be used to generate error + * messages for a singleton + * @param array|string Callback function/method + * @param string Package name, or false for all packages + * @static + */ + function setDefaultCallback($callback = false, $package = false) + { + if (!is_callable($callback)) { + $callback = false; + } + $package = $package ? $package : '*'; + $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'][$package] = $callback; + } + + /** + * Set a callback that generates context information (location of error) for an error stack + * + * This method sets the callback that can be used to generate context + * information for an error. Passing in NULL will disable context generation + * and remove the expensive call to debug_backtrace() + * @param array|string|null Callback function/method + */ + function setContextCallback($contextCallback) + { + if ($contextCallback === null) { + return $this->_contextCallback = false; + } + if (!$contextCallback) { + $this->_contextCallback = array(&$this, 'getFileLine'); + } else { + if (is_callable($contextCallback)) { + $this->_contextCallback = $contextCallback; + } + } + } + + /** + * Set an error Callback + * If set to a valid callback, this will be called every time an error + * is pushed onto the stack. The return value will be used to determine + * whether to allow an error to be pushed or logged. + * + * The return value must be one of the ERRORSTACK_* constants. + * + * This functionality can be used to emulate PEAR's pushErrorHandling, and + * the PEAR_ERROR_CALLBACK mode, without affecting the integrity of + * the error stack or logging + * @see PEAR_ERRORSTACK_PUSHANDLOG, PEAR_ERRORSTACK_PUSH, PEAR_ERRORSTACK_LOG + * @see popCallback() + * @param string|array $cb + */ + function pushCallback($cb) + { + array_push($this->_errorCallback, $cb); + } + + /** + * Remove a callback from the error callback stack + * @see pushCallback() + * @return array|string|false + */ + function popCallback() + { + if (!count($this->_errorCallback)) { + return false; + } + return array_pop($this->_errorCallback); + } + + /** + * Set a temporary overriding error callback for every package error stack + * + * Use this to temporarily disable all existing callbacks (can be used + * to emulate the @ operator, for instance) + * @see PEAR_ERRORSTACK_PUSHANDLOG, PEAR_ERRORSTACK_PUSH, PEAR_ERRORSTACK_LOG + * @see staticPopCallback(), pushCallback() + * @param string|array $cb + * @static + */ + function staticPushCallback($cb) + { + array_push($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'], $cb); + } + + /** + * Remove a temporary overriding error callback + * @see staticPushCallback() + * @return array|string|false + * @static + */ + function staticPopCallback() + { + $ret = array_pop($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK']); + if (!is_array($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'])) { + $GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'] = array(); + } + return $ret; + } + + /** + * Add an error to the stack + * + * If the message generator exists, it is called with 2 parameters. + * - the current Error Stack object + * - an array that is in the same format as an error. Available indices + * are 'code', 'package', 'time', 'params', 'level', and 'context' + * + * Next, if the error should contain context information, this is + * handled by the context grabbing method. + * Finally, the error is pushed onto the proper error stack + * @param int $code Package-specific error code + * @param string $level Error level. This is NOT spell-checked + * @param array $params associative array of error parameters + * @param string $msg Error message, or a portion of it if the message + * is to be generated + * @param array $repackage If this error re-packages an error pushed by + * another package, place the array returned from + * {@link pop()} in this parameter + * @param array $backtrace Protected parameter: use this to pass in the + * {@link debug_backtrace()} that should be used + * to find error context + * @return PEAR_Error|array if compatibility mode is on, a PEAR_Error is also + * thrown. If a PEAR_Error is returned, the userinfo + * property is set to the following array: + * + * <code> + * array( + * 'code' => $code, + * 'params' => $params, + * 'package' => $this->_package, + * 'level' => $level, + * 'time' => time(), + * 'context' => $context, + * 'message' => $msg, + * //['repackage' => $err] repackaged error array/Exception class + * ); + * </code> + * + * Normally, the previous array is returned. + */ + function push($code, $level = 'error', $params = array(), $msg = false, + $repackage = false, $backtrace = false) + { + $context = false; + // grab error context + if ($this->_contextCallback) { + if (!$backtrace) { + $backtrace = debug_backtrace(); + } + $context = call_user_func($this->_contextCallback, $code, $params, $backtrace); + } + + // save error + $time = explode(' ', microtime()); + $time = $time[1] + $time[0]; + $err = array( + 'code' => $code, + 'params' => $params, + 'package' => $this->_package, + 'level' => $level, + 'time' => $time, + 'context' => $context, + 'message' => $msg, + ); + + if ($repackage) { + $err['repackage'] = $repackage; + } + + // set up the error message, if necessary + if ($this->_msgCallback) { + $msg = call_user_func_array($this->_msgCallback, + array(&$this, $err)); + $err['message'] = $msg; + } + $push = $log = true; + $die = false; + // try the overriding callback first + $callback = $this->staticPopCallback(); + if ($callback) { + $this->staticPushCallback($callback); + } + if (!is_callable($callback)) { + // try the local callback next + $callback = $this->popCallback(); + if (is_callable($callback)) { + $this->pushCallback($callback); + } else { + // try the default callback + $callback = isset($GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'][$this->_package]) ? + $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'][$this->_package] : + $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK']['*']; + } + } + if (is_callable($callback)) { + switch(call_user_func($callback, $err)){ + case PEAR_ERRORSTACK_IGNORE: + return $err; + break; + case PEAR_ERRORSTACK_PUSH: + $log = false; + break; + case PEAR_ERRORSTACK_LOG: + $push = false; + break; + case PEAR_ERRORSTACK_DIE: + $die = true; + break; + // anything else returned has the same effect as pushandlog + } + } + if ($push) { + array_unshift($this->_errors, $err); + if (!isset($this->_errorsByLevel[$err['level']])) { + $this->_errorsByLevel[$err['level']] = array(); + } + $this->_errorsByLevel[$err['level']][] = &$this->_errors[0]; + } + if ($log) { + if ($this->_logger || $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER']) { + $this->_log($err); + } + } + if ($die) { + die(); + } + if ($this->_compat && $push) { + return $this->raiseError($msg, $code, null, null, $err); + } + return $err; + } + + /** + * Static version of {@link push()} + * + * @param string $package Package name this error belongs to + * @param int $code Package-specific error code + * @param string $level Error level. This is NOT spell-checked + * @param array $params associative array of error parameters + * @param string $msg Error message, or a portion of it if the message + * is to be generated + * @param array $repackage If this error re-packages an error pushed by + * another package, place the array returned from + * {@link pop()} in this parameter + * @param array $backtrace Protected parameter: use this to pass in the + * {@link debug_backtrace()} that should be used + * to find error context + * @return PEAR_Error|array if compatibility mode is on, a PEAR_Error is also + * thrown. see docs for {@link push()} + * @static + */ + function staticPush($package, $code, $level = 'error', $params = array(), + $msg = false, $repackage = false, $backtrace = false) + { + $s = &PEAR_ErrorStack::singleton($package); + if ($s->_contextCallback) { + if (!$backtrace) { + if (function_exists('debug_backtrace')) { + $backtrace = debug_backtrace(); + } + } + } + return $s->push($code, $level, $params, $msg, $repackage, $backtrace); + } + + /** + * Log an error using PEAR::Log + * @param array $err Error array + * @param array $levels Error level => Log constant map + * @access protected + */ + function _log($err) + { + if ($this->_logger) { + $logger = &$this->_logger; + } else { + $logger = &$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER']; + } + if (is_a($logger, 'Log')) { + $levels = array( + 'exception' => PEAR_LOG_CRIT, + 'alert' => PEAR_LOG_ALERT, + 'critical' => PEAR_LOG_CRIT, + 'error' => PEAR_LOG_ERR, + 'warning' => PEAR_LOG_WARNING, + 'notice' => PEAR_LOG_NOTICE, + 'info' => PEAR_LOG_INFO, + 'debug' => PEAR_LOG_DEBUG); + if (isset($levels[$err['level']])) { + $level = $levels[$err['level']]; + } else { + $level = PEAR_LOG_INFO; + } + $logger->log($err['message'], $level, $err); + } else { // support non-standard logs + call_user_func($logger, $err); + } + } + + + /** + * Pop an error off of the error stack + * + * @return false|array + * @since 0.4alpha it is no longer possible to specify a specific error + * level to return - the last error pushed will be returned, instead + */ + function pop() + { + $err = @array_shift($this->_errors); + if (!is_null($err)) { + @array_pop($this->_errorsByLevel[$err['level']]); + if (!count($this->_errorsByLevel[$err['level']])) { + unset($this->_errorsByLevel[$err['level']]); + } + } + return $err; + } + + /** + * Pop an error off of the error stack, static method + * + * @param string package name + * @return boolean + * @since PEAR1.5.0a1 + */ + function staticPop($package) + { + if ($package) { + if (!isset($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package])) { + return false; + } + return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]->pop(); + } + } + + /** + * Determine whether there are any errors on the stack + * @param string|array Level name. Use to determine if any errors + * of level (string), or levels (array) have been pushed + * @return boolean + */ + function hasErrors($level = false) + { + if ($level) { + return isset($this->_errorsByLevel[$level]); + } + return count($this->_errors); + } + + /** + * Retrieve all errors since last purge + * + * @param boolean set in order to empty the error stack + * @param string level name, to return only errors of a particular severity + * @return array + */ + function getErrors($purge = false, $level = false) + { + if (!$purge) { + if ($level) { + if (!isset($this->_errorsByLevel[$level])) { + return array(); + } else { + return $this->_errorsByLevel[$level]; + } + } else { + return $this->_errors; + } + } + if ($level) { + $ret = $this->_errorsByLevel[$level]; + foreach ($this->_errorsByLevel[$level] as $i => $unused) { + // entries are references to the $_errors array + $this->_errorsByLevel[$level][$i] = false; + } + // array_filter removes all entries === false + $this->_errors = array_filter($this->_errors); + unset($this->_errorsByLevel[$level]); + return $ret; + } + $ret = $this->_errors; + $this->_errors = array(); + $this->_errorsByLevel = array(); + return $ret; + } + + /** + * Determine whether there are any errors on a single error stack, or on any error stack + * + * The optional parameter can be used to test the existence of any errors without the need of + * singleton instantiation + * @param string|false Package name to check for errors + * @param string Level name to check for a particular severity + * @return boolean + * @static + */ + function staticHasErrors($package = false, $level = false) + { + if ($package) { + if (!isset($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package])) { + return false; + } + return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]->hasErrors($level); + } + foreach ($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'] as $package => $obj) { + if ($obj->hasErrors($level)) { + return true; + } + } + return false; + } + + /** + * Get a list of all errors since last purge, organized by package + * @since PEAR 1.4.0dev BC break! $level is now in the place $merge used to be + * @param boolean $purge Set to purge the error stack of existing errors + * @param string $level Set to a level name in order to retrieve only errors of a particular level + * @param boolean $merge Set to return a flat array, not organized by package + * @param array $sortfunc Function used to sort a merged array - default + * sorts by time, and should be good for most cases + * @static + * @return array + */ + function staticGetErrors($purge = false, $level = false, $merge = false, + $sortfunc = array('PEAR_ErrorStack', '_sortErrors')) + { + $ret = array(); + if (!is_callable($sortfunc)) { + $sortfunc = array('PEAR_ErrorStack', '_sortErrors'); + } + foreach ($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'] as $package => $obj) { + $test = $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]->getErrors($purge, $level); + if ($test) { + if ($merge) { + $ret = array_merge($ret, $test); + } else { + $ret[$package] = $test; + } + } + } + if ($merge) { + usort($ret, $sortfunc); + } + return $ret; + } + + /** + * Error sorting function, sorts by time + * @access private + */ + function _sortErrors($a, $b) + { + if ($a['time'] == $b['time']) { + return 0; + } + if ($a['time'] < $b['time']) { + return 1; + } + return -1; + } + + /** + * Standard file/line number/function/class context callback + * + * This function uses a backtrace generated from {@link debug_backtrace()} + * and so will not work at all in PHP < 4.3.0. The frame should + * reference the frame that contains the source of the error. + * @return array|false either array('file' => file, 'line' => line, + * 'function' => function name, 'class' => class name) or + * if this doesn't work, then false + * @param unused + * @param integer backtrace frame. + * @param array Results of debug_backtrace() + * @static + */ + function getFileLine($code, $params, $backtrace = null) + { + if ($backtrace === null) { + return false; + } + $frame = 0; + $functionframe = 1; + if (!isset($backtrace[1])) { + $functionframe = 0; + } else { + while (isset($backtrace[$functionframe]['function']) && + $backtrace[$functionframe]['function'] == 'eval' && + isset($backtrace[$functionframe + 1])) { + $functionframe++; + } + } + if (isset($backtrace[$frame])) { + if (!isset($backtrace[$frame]['file'])) { + $frame++; + } + $funcbacktrace = $backtrace[$functionframe]; + $filebacktrace = $backtrace[$frame]; + $ret = array('file' => $filebacktrace['file'], + 'line' => $filebacktrace['line']); + // rearrange for eval'd code or create function errors + if (strpos($filebacktrace['file'], '(') && + preg_match(';^(.*?)\((\d+)\) : (.*?)\\z;', $filebacktrace['file'], + $matches)) { + $ret['file'] = $matches[1]; + $ret['line'] = $matches[2] + 0; + } + if (isset($funcbacktrace['function']) && isset($backtrace[1])) { + if ($funcbacktrace['function'] != 'eval') { + if ($funcbacktrace['function'] == '__lambda_func') { + $ret['function'] = 'create_function() code'; + } else { + $ret['function'] = $funcbacktrace['function']; + } + } + } + if (isset($funcbacktrace['class']) && isset($backtrace[1])) { + $ret['class'] = $funcbacktrace['class']; + } + return $ret; + } + return false; + } + + /** + * Standard error message generation callback + * + * This method may also be called by a custom error message generator + * to fill in template values from the params array, simply + * set the third parameter to the error message template string to use + * + * The special variable %__msg% is reserved: use it only to specify + * where a message passed in by the user should be placed in the template, + * like so: + * + * Error message: %msg% - internal error + * + * If the message passed like so: + * + * <code> + * $stack->push(ERROR_CODE, 'error', array(), 'server error 500'); + * </code> + * + * The returned error message will be "Error message: server error 500 - + * internal error" + * @param PEAR_ErrorStack + * @param array + * @param string|false Pre-generated error message template + * @static + * @return string + */ + function getErrorMessage(&$stack, $err, $template = false) + { + if ($template) { + $mainmsg = $template; + } else { + $mainmsg = $stack->getErrorMessageTemplate($err['code']); + } + $mainmsg = str_replace('%__msg%', $err['message'], $mainmsg); + if (is_array($err['params']) && count($err['params'])) { + foreach ($err['params'] as $name => $val) { + if (is_array($val)) { + // @ is needed in case $val is a multi-dimensional array + $val = @implode(', ', $val); + } + if (is_object($val)) { + if (method_exists($val, '__toString')) { + $val = $val->__toString(); + } else { + PEAR_ErrorStack::staticPush('PEAR_ErrorStack', PEAR_ERRORSTACK_ERR_OBJTOSTRING, + 'warning', array('obj' => get_class($val)), + 'object %obj% passed into getErrorMessage, but has no __toString() method'); + $val = 'Object'; + } + } + $mainmsg = str_replace('%' . $name . '%', $val, $mainmsg); + } + } + return $mainmsg; + } + + /** + * Standard Error Message Template generator from code + * @return string + */ + function getErrorMessageTemplate($code) + { + if (!isset($this->_errorMsgs[$code])) { + return '%__msg%'; + } + return $this->_errorMsgs[$code]; + } + + /** + * Set the Error Message Template array + * + * The array format must be: + * <pre> + * array(error code => 'message template',...) + * </pre> + * + * Error message parameters passed into {@link push()} will be used as input + * for the error message. If the template is 'message %foo% was %bar%', and the + * parameters are array('foo' => 'one', 'bar' => 'six'), the error message returned will + * be 'message one was six' + * @return string + */ + function setErrorMessageTemplate($template) + { + $this->_errorMsgs = $template; + } + + + /** + * emulate PEAR::raiseError() + * + * @return PEAR_Error + */ + function raiseError() + { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR.php'; + $args = func_get_args(); + return call_user_func_array(array('PEAR', 'raiseError'), $args); + } +} +$stack = &PEAR_ErrorStack::singleton('PEAR_ErrorStack'); +$stack->pushCallback(array('PEAR_ErrorStack', '_handleError')); +?> +<?php +/** + * PEAR_Frontend, the singleton-based frontend for user input/output + * + * PHP versions 4 and 5 + * + * @category pear + * @package PEAR + * @author Greg Beaver <cellog@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: Frontend.php 276383 2009-02-24 23:39:37Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ + +/** + * Include error handling + */ +//require_once 'PEAR.php'; + +/** + * Which user interface class is being used. + * @var string class name + */ +$GLOBALS['_PEAR_FRONTEND_CLASS'] = 'PEAR_Frontend_CLI'; + +/** + * Instance of $_PEAR_Command_uiclass. + * @var object + */ +$GLOBALS['_PEAR_FRONTEND_SINGLETON'] = null; + +/** + * Singleton-based frontend for PEAR user input/output + * + * @category pear + * @package PEAR + * @author Greg Beaver <cellog@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_Frontend extends PEAR +{ + /** + * Retrieve the frontend object + * @return PEAR_Frontend_CLI|PEAR_Frontend_Web|PEAR_Frontend_Gtk + * @static + */ + function &singleton($type = null) + { + if ($type === null) { + if (!isset($GLOBALS['_PEAR_FRONTEND_SINGLETON'])) { + $a = false; + return $a; + } + return $GLOBALS['_PEAR_FRONTEND_SINGLETON']; + } + + $a = PEAR_Frontend::setFrontendClass($type); + return $a; + } + + /** + * Set the frontend class that will be used by calls to {@link singleton()} + * + * Frontends are expected to conform to the PEAR naming standard of + * _ => DIRECTORY_SEPARATOR (PEAR_Frontend_CLI is in PEAR/Frontend/CLI.php) + * @param string $uiclass full class name + * @return PEAR_Frontend + * @static + */ + function &setFrontendClass($uiclass) + { + if (is_object($GLOBALS['_PEAR_FRONTEND_SINGLETON']) && + is_a($GLOBALS['_PEAR_FRONTEND_SINGLETON'], $uiclass)) { + return $GLOBALS['_PEAR_FRONTEND_SINGLETON']; + } + + if (!class_exists($uiclass)) { + $file = 'phar://install-pear-nozlib.phar/' . str_replace('_', '/', $uiclass) . '.php'; + if (PEAR_Frontend::isIncludeable($file)) { + include_once $file; + } + } + + if (class_exists($uiclass)) { + $obj = &new $uiclass; + // quick test to see if this class implements a few of the most + // important frontend methods + if (is_a($obj, 'PEAR_Frontend')) { + $GLOBALS['_PEAR_FRONTEND_SINGLETON'] = &$obj; + $GLOBALS['_PEAR_FRONTEND_CLASS'] = $uiclass; + return $obj; + } + + $err = PEAR::raiseError("not a frontend class: $uiclass"); + return $err; + } + + $err = PEAR::raiseError("no such class: $uiclass"); + return $err; + } + + /** + * Set the frontend class that will be used by calls to {@link singleton()} + * + * Frontends are expected to be a descendant of PEAR_Frontend + * @param PEAR_Frontend + * @return PEAR_Frontend + * @static + */ + function &setFrontendObject($uiobject) + { + if (is_object($GLOBALS['_PEAR_FRONTEND_SINGLETON']) && + is_a($GLOBALS['_PEAR_FRONTEND_SINGLETON'], get_class($uiobject))) { + return $GLOBALS['_PEAR_FRONTEND_SINGLETON']; + } + + if (!is_a($uiobject, 'PEAR_Frontend')) { + $err = PEAR::raiseError('not a valid frontend class: (' . + get_class($uiobject) . ')'); + return $err; + } + + $GLOBALS['_PEAR_FRONTEND_SINGLETON'] = &$uiobject; + $GLOBALS['_PEAR_FRONTEND_CLASS'] = get_class($uiobject); + return $uiobject; + } + + /** + * @param string $path relative or absolute include path + * @return boolean + * @static + */ + function isIncludeable($path) + { + if (file_exists($path) && is_readable($path)) { + return true; + } + + $fp = @fopen($path, 'r', true); + if ($fp) { + fclose($fp); + return true; + } + + return false; + } + + /** + * @param PEAR_Config + */ + function setConfig(&$config) + { + } + + /** + * This can be overridden to allow session-based temporary file management + * + * By default, all files are deleted at the end of a session. The web installer + * needs to be able to sustain a list over many sessions in order to support + * user interaction with install scripts + */ + function addTempFile($file) + { + $GLOBALS['_PEAR_Common_tempfiles'][] = $file; + } + + /** + * Log an action + * + * @param string $msg the message to log + * @param boolean $append_crlf + * @return boolean true + * @abstract + */ + function log($msg, $append_crlf = true) + { + } + + /** + * Run a post-installation script + * + * @param array $scripts array of post-install scripts + * @abstract + */ + function runPostinstallScripts(&$scripts) + { + } + + /** + * Display human-friendly output formatted depending on the + * $command parameter. + * + * This should be able to handle basic output data with no command + * @param mixed $data data structure containing the information to display + * @param string $command command from which this method was called + * @abstract + */ + function outputData($data, $command = '_default') + { + } + + /** + * Display a modal form dialog and return the given input + * + * A frontend that requires multiple requests to retrieve and process + * data must take these needs into account, and implement the request + * handling code. + * @param string $command command from which this method was called + * @param array $prompts associative array. keys are the input field names + * and values are the description + * @param array $types array of input field types (text, password, + * etc.) keys have to be the same like in $prompts + * @param array $defaults array of default values. again keys have + * to be the same like in $prompts. Do not depend + * on a default value being set. + * @return array input sent by the user + * @abstract + */ + function userDialog($command, $prompts, $types = array(), $defaults = array()) + { + } }<?php /** * PEAR_Frontend_CLI @@ -69299,7 +69908,7 @@ class PEAR_Frontend extends PEAR * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: CLI.php,v 1.76 2009/04/04 00:09:14 dufuz Exp $ + * @version CVS: $Id: CLI.php 278236 2009-04-04 00:09:14Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 0.1 */ @@ -69316,7 +69925,7 @@ require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Frontend.php'; * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 0.1 */ @@ -70032,7 +70641,7 @@ class PEAR_Frontend_CLI extends PEAR_Frontend * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Installer.php,v 1.259 2009/04/09 00:55:07 dufuz Exp $ + * @version CVS: $Id: Installer.php 287446 2009-08-18 11:45:05Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 0.1 */ @@ -70056,7 +70665,7 @@ define('PEAR_INSTALLER_NOBINARY', -240); * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 0.1 */ @@ -71146,7 +71755,6 @@ class PEAR_Installer extends PEAR_Downloader * * @return array|PEAR_Error package info if successful */ - function install($pkgfile, $options = array()) { $this->_options = $options; @@ -71160,7 +71768,7 @@ class PEAR_Installer extends PEAR_Downloader } else { $descfile = $pkgfile; $tmpdir = ''; - $pkg = &$this->_parsePackageXml($descfile, $tmpdir); + $pkg = $this->_parsePackageXml($descfile, $tmpdir); if (PEAR::isError($pkg)) { return $pkg; } @@ -71414,11 +72022,7 @@ class PEAR_Installer extends PEAR_Downloader } $p = &$installregistry->getPackage($pkgname, $channel); - if (empty($options['register-only']) && $p) { - $dirtree = $p->getDirTree(); - } else { - $dirtree = false; - } + $dirtree = (empty($options['register-only']) && $p) ? $p->getDirTree() : false; $pkg->resetFilelist(); $pkg->setLastInstalledVersion($installregistry->packageInfo($pkg->getPackage(), @@ -71591,11 +72195,8 @@ class PEAR_Installer extends PEAR_Downloader } $copyto = $this->_prependPath($dest, $packagingroot); - if ($copyto != $dest) { - $this->log(1, "Installing '$dest' as '$copyto'"); - } else { - $this->log(1, "Installing '$dest'"); - } + $extra = $copyto != $dest ? " as '$copyto'" : ''; + $this->log(1, "Installing '$dest'$extra"); $copydir = dirname($copyto); // pretty much nothing happens if we are only registering the install @@ -71624,24 +72225,20 @@ class PEAR_Installer extends PEAR_Downloader } } + + $data = array( + 'role' => $role, + 'name' => $bn, + 'installed_as' => $dest, + 'php_api' => $ext['php_api'], + 'zend_mod_api' => $ext['zend_mod_api'], + 'zend_ext_api' => $ext['zend_ext_api'], + ); + if ($filelist->getPackageXmlVersion() == '1.0') { - $filelist->installedFile($bn, array( - 'role' => $role, - 'name' => $bn, - 'installed_as' => $dest, - 'php_api' => $ext['php_api'], - 'zend_mod_api' => $ext['zend_mod_api'], - 'zend_ext_api' => $ext['zend_ext_api'], - )); + $filelist->installedFile($bn, $data); } else { - $filelist->installedFile($bn, array('attribs' => array( - 'role' => $role, - 'name' => $bn, - 'installed_as' => $dest, - 'php_api' => $ext['php_api'], - 'zend_mod_api' => $ext['zend_mod_api'], - 'zend_ext_api' => $ext['zend_ext_api'], - ))); + $filelist->installedFile($bn, array('attribs' => $data)); } } } @@ -71668,11 +72265,8 @@ class PEAR_Installer extends PEAR_Downloader */ function uninstall($package, $options = array()) { - if (isset($options['installroot'])) { - $this->config->setInstallRoot($options['installroot']); - } else { - $this->config->setInstallRoot(''); - } + $installRoot = isset($options['installroot']) ? $options['installroot'] : ''; + $this->config->setInstallRoot($installRoot); $this->installroot = ''; $this->_registry = &$this->config->getRegistry(); @@ -71765,17 +72359,18 @@ class PEAR_Installer extends PEAR_Downloader } } else { $this->startFileTransaction(); - if ($dirtree = $pkg->getDirTree()) { - // attempt to delete empty directories - uksort($dirtree, array($this, '_sortDirs')); - foreach($dirtree as $dir => $notused) { - $this->addFileOperation('rmdir', array($dir)); - } - } else { + $dirtree = $pkg->getDirTree(); + if ($dirtree === false) { $this->configSet('default_channel', $savechannel); return $this->_registry->deletePackage($package, $channel); } + // attempt to delete empty directories + uksort($dirtree, array($this, '_sortDirs')); + foreach($dirtree as $dir => $notused) { + $this->addFileOperation('rmdir', array($dir)); + } + if (!$this->commitFileTransaction()) { $this->rollbackFileTransaction(); if (!isset($options['ignore-errors'])) { @@ -71854,281 +72449,281 @@ class PEAR_Installer extends PEAR_Downloader } // }}} -}<?php
-/**
- * PEAR_Installer_Role
- *
- * PHP versions 4 and 5
- *
- * @category pear
- * @package PEAR
- * @author Greg Beaver <cellog@php.net>
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version CVS: $Id: Role.php,v 1.22 2009/04/10 19:42:49 dufuz Exp $
- * @link http://pear.php.net/package/PEAR
- * @since File available since Release 1.4.0a1
- */
-
-/**
- * base class for installer roles
- */
-require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Installer/Role/Common.php';
-require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/XMLParser.php';
-/**
- * @category pear
- * @package PEAR
- * @author Greg Beaver <cellog@php.net>
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.8.0
- * @link http://pear.php.net/package/PEAR
- * @since Class available since Release 1.4.0a1
- */
-class PEAR_Installer_Role
-{
- /**
- * Set up any additional configuration variables that file roles require
- *
- * Never call this directly, it is called by the PEAR_Config constructor
- * @param PEAR_Config
- * @access private
- * @static
- */
- function initializeConfig(&$config)
- {
- if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) {
- PEAR_Installer_Role::registerRoles();
- }
-
- foreach ($GLOBALS['_PEAR_INSTALLER_ROLES'] as $class => $info) {
- if (!$info['config_vars']) {
- continue;
- }
-
- $config->_addConfigVars($class, $info['config_vars']);
- }
- }
-
- /**
- * @param PEAR_PackageFile_v2
- * @param string role name
- * @param PEAR_Config
- * @return PEAR_Installer_Role_Common
- * @static
- */
- function &factory($pkg, $role, &$config)
- {
- if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) {
- PEAR_Installer_Role::registerRoles();
- }
-
- if (!in_array($role, PEAR_Installer_Role::getValidRoles($pkg->getPackageType()))) {
- $a = false;
- return $a;
- }
-
- $a = 'PEAR_Installer_Role_' . ucfirst($role);
- if (!class_exists($a)) {
- require_once 'phar://install-pear-nozlib.phar/' . str_replace('_', '/', $a) . '.php';
- }
-
- $b = new $a($config);
- return $b;
- }
-
- /**
- * Get a list of file roles that are valid for the particular release type.
- *
- * For instance, src files serve no purpose in regular php releases.
- * @param string
- * @param bool clear cache
- * @return array
- * @static
- */
- function getValidRoles($release, $clear = false)
- {
- if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) {
- PEAR_Installer_Role::registerRoles();
- }
-
- static $ret = array();
- if ($clear) {
- $ret = array();
- }
-
- if (isset($ret[$release])) {
- return $ret[$release];
- }
-
- $ret[$release] = array();
- foreach ($GLOBALS['_PEAR_INSTALLER_ROLES'] as $role => $okreleases) {
- if (in_array($release, $okreleases['releasetypes'])) {
- $ret[$release][] = strtolower(str_replace('PEAR_Installer_Role_', '', $role));
- }
- }
-
- return $ret[$release];
- }
-
- /**
- * Get a list of roles that require their files to be installed
- *
- * Most roles must be installed, but src and package roles, for instance
- * are pseudo-roles. src files are compiled into a new extension. Package
- * roles are actually fully bundled releases of a package
- * @param bool clear cache
- * @return array
- * @static
- */
- function getInstallableRoles($clear = false)
- {
- if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) {
- PEAR_Installer_Role::registerRoles();
- }
-
- static $ret;
- if ($clear) {
- unset($ret);
- }
-
- if (isset($ret)) {
- return $ret;
- }
-
- $ret = array();
- foreach ($GLOBALS['_PEAR_INSTALLER_ROLES'] as $role => $okreleases) {
- if ($okreleases['installable']) {
- $ret[] = strtolower(str_replace('PEAR_Installer_Role_', '', $role));
- }
- }
-
- return $ret;
- }
-
- /**
- * Return an array of roles that are affected by the baseinstalldir attribute
- *
- * Most roles ignore this attribute, and instead install directly into:
- * PackageName/filepath
- * so a tests file tests/file.phpt is installed into PackageName/tests/filepath.php
- * @param bool clear cache
- * @return array
- * @static
- */
- function getBaseinstallRoles($clear = false)
- {
- if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) {
- PEAR_Installer_Role::registerRoles();
- }
-
- static $ret;
- if ($clear) {
- unset($ret);
- }
-
- if (isset($ret)) {
- return $ret;
- }
-
- $ret = array();
- foreach ($GLOBALS['_PEAR_INSTALLER_ROLES'] as $role => $okreleases) {
- if ($okreleases['honorsbaseinstall']) {
- $ret[] = strtolower(str_replace('PEAR_Installer_Role_', '', $role));
- }
- }
-
- return $ret;
- }
-
- /**
- * Return an array of file roles that should be analyzed for PHP content at package time,
- * like the "php" role.
- * @param bool clear cache
- * @return array
- * @static
- */
- function getPhpRoles($clear = false)
- {
- if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) {
- PEAR_Installer_Role::registerRoles();
- }
-
- static $ret;
- if ($clear) {
- unset($ret);
- }
-
- if (isset($ret)) {
- return $ret;
- }
-
- $ret = array();
- foreach ($GLOBALS['_PEAR_INSTALLER_ROLES'] as $role => $okreleases) {
- if ($okreleases['phpfile']) {
- $ret[] = strtolower(str_replace('PEAR_Installer_Role_', '', $role));
- }
- }
-
- return $ret;
- }
-
- /**
- * Scan through the Command directory looking for classes
- * and see what commands they implement.
- * @param string which directory to look for classes, defaults to
- * the Installer/Roles subdirectory of
- * the directory from where this file (__FILE__) is
- * included.
- *
- * @return bool TRUE on success, a PEAR error on failure
- * @access public
- * @static
- */
- function registerRoles($dir = null)
- {
- $GLOBALS['_PEAR_INSTALLER_ROLES'] = array();
- $parser = new PEAR_XMLParser;
- if ($dir === null) {
- $dir = dirname(__FILE__) . '/Role';
- }
-
- if (!file_exists($dir) || !is_dir($dir)) {
- return PEAR::raiseError("registerRoles: opendir($dir) failed: does not exist/is not directory");
- }
-
- $dp = @opendir($dir);
- if (empty($dp)) {
- return PEAR::raiseError("registerRoles: opendir($dir) failed: $php_errmsg");
- }
-
- while ($entry = readdir($dp)) {
- if ($entry{0} == '.' || substr($entry, -4) != '.xml') {
- continue;
- }
-
- $class = "PEAR_Installer_Role_".substr($entry, 0, -4);
- // List of roles
- if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'][$class])) {
- $file = "$dir/$entry";
- $parser->parse(file_get_contents($file));
- $data = $parser->getData();
- if (!is_array($data['releasetypes'])) {
- $data['releasetypes'] = array($data['releasetypes']);
- }
-
- $GLOBALS['_PEAR_INSTALLER_ROLES'][$class] = $data;
- }
- }
-
- closedir($dp);
- ksort($GLOBALS['_PEAR_INSTALLER_ROLES']);
- PEAR_Installer_Role::getBaseinstallRoles(true);
- PEAR_Installer_Role::getInstallableRoles(true);
- PEAR_Installer_Role::getPhpRoles(true);
- PEAR_Installer_Role::getValidRoles('****', true);
- return true;
- }
+}<?php +/** + * PEAR_Installer_Role + * + * PHP versions 4 and 5 + * + * @category pear + * @package PEAR + * @author Greg Beaver <cellog@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: Role.php 278552 2009-04-10 19:42:49Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ + +/** + * base class for installer roles + */ +require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Installer/Role/Common.php'; +require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/XMLParser.php'; +/** + * @category pear + * @package PEAR + * @author Greg Beaver <cellog@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_Installer_Role +{ + /** + * Set up any additional configuration variables that file roles require + * + * Never call this directly, it is called by the PEAR_Config constructor + * @param PEAR_Config + * @access private + * @static + */ + function initializeConfig(&$config) + { + if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) { + PEAR_Installer_Role::registerRoles(); + } + + foreach ($GLOBALS['_PEAR_INSTALLER_ROLES'] as $class => $info) { + if (!$info['config_vars']) { + continue; + } + + $config->_addConfigVars($class, $info['config_vars']); + } + } + + /** + * @param PEAR_PackageFile_v2 + * @param string role name + * @param PEAR_Config + * @return PEAR_Installer_Role_Common + * @static + */ + function &factory($pkg, $role, &$config) + { + if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) { + PEAR_Installer_Role::registerRoles(); + } + + if (!in_array($role, PEAR_Installer_Role::getValidRoles($pkg->getPackageType()))) { + $a = false; + return $a; + } + + $a = 'PEAR_Installer_Role_' . ucfirst($role); + if (!class_exists($a)) { + require_once 'phar://install-pear-nozlib.phar/' . str_replace('_', '/', $a) . '.php'; + } + + $b = new $a($config); + return $b; + } + + /** + * Get a list of file roles that are valid for the particular release type. + * + * For instance, src files serve no purpose in regular php releases. + * @param string + * @param bool clear cache + * @return array + * @static + */ + function getValidRoles($release, $clear = false) + { + if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) { + PEAR_Installer_Role::registerRoles(); + } + + static $ret = array(); + if ($clear) { + $ret = array(); + } + + if (isset($ret[$release])) { + return $ret[$release]; + } + + $ret[$release] = array(); + foreach ($GLOBALS['_PEAR_INSTALLER_ROLES'] as $role => $okreleases) { + if (in_array($release, $okreleases['releasetypes'])) { + $ret[$release][] = strtolower(str_replace('PEAR_Installer_Role_', '', $role)); + } + } + + return $ret[$release]; + } + + /** + * Get a list of roles that require their files to be installed + * + * Most roles must be installed, but src and package roles, for instance + * are pseudo-roles. src files are compiled into a new extension. Package + * roles are actually fully bundled releases of a package + * @param bool clear cache + * @return array + * @static + */ + function getInstallableRoles($clear = false) + { + if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) { + PEAR_Installer_Role::registerRoles(); + } + + static $ret; + if ($clear) { + unset($ret); + } + + if (isset($ret)) { + return $ret; + } + + $ret = array(); + foreach ($GLOBALS['_PEAR_INSTALLER_ROLES'] as $role => $okreleases) { + if ($okreleases['installable']) { + $ret[] = strtolower(str_replace('PEAR_Installer_Role_', '', $role)); + } + } + + return $ret; + } + + /** + * Return an array of roles that are affected by the baseinstalldir attribute + * + * Most roles ignore this attribute, and instead install directly into: + * PackageName/filepath + * so a tests file tests/file.phpt is installed into PackageName/tests/filepath.php + * @param bool clear cache + * @return array + * @static + */ + function getBaseinstallRoles($clear = false) + { + if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) { + PEAR_Installer_Role::registerRoles(); + } + + static $ret; + if ($clear) { + unset($ret); + } + + if (isset($ret)) { + return $ret; + } + + $ret = array(); + foreach ($GLOBALS['_PEAR_INSTALLER_ROLES'] as $role => $okreleases) { + if ($okreleases['honorsbaseinstall']) { + $ret[] = strtolower(str_replace('PEAR_Installer_Role_', '', $role)); + } + } + + return $ret; + } + + /** + * Return an array of file roles that should be analyzed for PHP content at package time, + * like the "php" role. + * @param bool clear cache + * @return array + * @static + */ + function getPhpRoles($clear = false) + { + if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) { + PEAR_Installer_Role::registerRoles(); + } + + static $ret; + if ($clear) { + unset($ret); + } + + if (isset($ret)) { + return $ret; + } + + $ret = array(); + foreach ($GLOBALS['_PEAR_INSTALLER_ROLES'] as $role => $okreleases) { + if ($okreleases['phpfile']) { + $ret[] = strtolower(str_replace('PEAR_Installer_Role_', '', $role)); + } + } + + return $ret; + } + + /** + * Scan through the Command directory looking for classes + * and see what commands they implement. + * @param string which directory to look for classes, defaults to + * the Installer/Roles subdirectory of + * the directory from where this file (__FILE__) is + * included. + * + * @return bool TRUE on success, a PEAR error on failure + * @access public + * @static + */ + function registerRoles($dir = null) + { + $GLOBALS['_PEAR_INSTALLER_ROLES'] = array(); + $parser = new PEAR_XMLParser; + if ($dir === null) { + $dir = dirname(__FILE__) . '/Role'; + } + + if (!file_exists($dir) || !is_dir($dir)) { + return PEAR::raiseError("registerRoles: opendir($dir) failed: does not exist/is not directory"); + } + + $dp = @opendir($dir); + if (empty($dp)) { + return PEAR::raiseError("registerRoles: opendir($dir) failed: $php_errmsg"); + } + + while ($entry = readdir($dp)) { + if ($entry{0} == '.' || substr($entry, -4) != '.xml') { + continue; + } + + $class = "PEAR_Installer_Role_".substr($entry, 0, -4); + // List of roles + if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'][$class])) { + $file = "$dir/$entry"; + $parser->parse(file_get_contents($file)); + $data = $parser->getData(); + if (!is_array($data['releasetypes'])) { + $data['releasetypes'] = array($data['releasetypes']); + } + + $GLOBALS['_PEAR_INSTALLER_ROLES'][$class] = $data; + } + } + + closedir($dp); + ksort($GLOBALS['_PEAR_INSTALLER_ROLES']); + PEAR_Installer_Role::getBaseinstallRoles(true); + PEAR_Installer_Role::getInstallableRoles(true); + PEAR_Installer_Role::getPhpRoles(true); + PEAR_Installer_Role::getValidRoles('****', true); + return true; + } }<?php /** * Base class for all installation roles. @@ -72140,7 +72735,7 @@ class PEAR_Installer_Role * @author Greg Beaver <cellog@php.net> * @copyright 1997-2006 The PHP Group * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Common.php,v 1.13 2009/02/24 23:39:37 dufuz Exp $ + * @version CVS: $Id: Common.php 276383 2009-02-24 23:39:37Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ @@ -72155,7 +72750,7 @@ class PEAR_Installer_Role * @author Greg Beaver <cellog@php.net> * @copyright 1997-2006 The PHP Group * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ @@ -72302,33 +72897,33 @@ class PEAR_Installer_Role_Common return $roleInfo['phpextension']; } } -?><?php
-/**
- * PEAR_Installer_Role_Data
- *
- * PHP versions 4 and 5
- *
- * @category pear
- * @package PEAR
- * @author Greg Beaver <cellog@php.net>
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version CVS: $Id: Data.php,v 1.8 2009/02/24 23:39:37 dufuz Exp $
- * @link http://pear.php.net/package/PEAR
- * @since File available since Release 1.4.0a1
- */
-
-/**
- * @category pear
- * @package PEAR
- * @author Greg Beaver <cellog@php.net>
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.8.0
- * @link http://pear.php.net/package/PEAR
- * @since Class available since Release 1.4.0a1
- */
-class PEAR_Installer_Role_Data extends PEAR_Installer_Role_Common {}
+?><?php +/** + * PEAR_Installer_Role_Data + * + * PHP versions 4 and 5 + * + * @category pear + * @package PEAR + * @author Greg Beaver <cellog@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: Data.php 276383 2009-02-24 23:39:37Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ + +/** + * @category pear + * @package PEAR + * @author Greg Beaver <cellog@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_Installer_Role_Data extends PEAR_Installer_Role_Common {} ?><role version="1.0"> <releasetypes>php</releasetypes> <releasetypes>extsrc</releasetypes> @@ -72343,33 +72938,33 @@ class PEAR_Installer_Role_Data extends PEAR_Installer_Role_Common {} <executable /> <phpextension /> <config_vars /> -</role><?php
-/**
- * PEAR_Installer_Role_Doc
- *
- * PHP versions 4 and 5
- *
- * @category pear
- * @package PEAR
- * @author Greg Beaver <cellog@php.net>
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version CVS: $Id: Doc.php,v 1.8 2009/02/24 23:39:37 dufuz Exp $
- * @link http://pear.php.net/package/PEAR
- * @since File available since Release 1.4.0a1
- */
-
-/**
- * @category pear
- * @package PEAR
- * @author Greg Beaver <cellog@php.net>
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.8.0
- * @link http://pear.php.net/package/PEAR
- * @since Class available since Release 1.4.0a1
- */
-class PEAR_Installer_Role_Doc extends PEAR_Installer_Role_Common {}
+</role><?php +/** + * PEAR_Installer_Role_Doc + * + * PHP versions 4 and 5 + * + * @category pear + * @package PEAR + * @author Greg Beaver <cellog@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: Doc.php 276383 2009-02-24 23:39:37Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ + +/** + * @category pear + * @package PEAR + * @author Greg Beaver <cellog@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_Installer_Role_Doc extends PEAR_Installer_Role_Common {} ?><role version="1.0"> <releasetypes>php</releasetypes> <releasetypes>extsrc</releasetypes> @@ -72384,33 +72979,33 @@ class PEAR_Installer_Role_Doc extends PEAR_Installer_Role_Common {} <executable /> <phpextension /> <config_vars /> -</role><?php
-/**
- * PEAR_Installer_Role_Php
- *
- * PHP versions 4 and 5
- *
- * @category pear
- * @package PEAR
- * @author Greg Beaver <cellog@php.net>
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version CVS: $Id: Php.php,v 1.9 2009/02/24 23:39:37 dufuz Exp $
- * @link http://pear.php.net/package/PEAR
- * @since File available since Release 1.4.0a1
- */
-
-/**
- * @category pear
- * @package PEAR
- * @author Greg Beaver <cellog@php.net>
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.8.0
- * @link http://pear.php.net/package/PEAR
- * @since Class available since Release 1.4.0a1
- */
-class PEAR_Installer_Role_Php extends PEAR_Installer_Role_Common {}
+</role><?php +/** + * PEAR_Installer_Role_Php + * + * PHP versions 4 and 5 + * + * @category pear + * @package PEAR + * @author Greg Beaver <cellog@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: Php.php 276383 2009-02-24 23:39:37Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ + +/** + * @category pear + * @package PEAR + * @author Greg Beaver <cellog@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_Installer_Role_Php extends PEAR_Installer_Role_Common {} ?><role version="1.0"> <releasetypes>php</releasetypes> <releasetypes>extsrc</releasetypes> @@ -72425,33 +73020,33 @@ class PEAR_Installer_Role_Php extends PEAR_Installer_Role_Common {} <executable /> <phpextension /> <config_vars /> -</role><?php
-/**
- * PEAR_Installer_Role_Script
- *
- * PHP versions 4 and 5
- *
- * @category pear
- * @package PEAR
- * @author Greg Beaver <cellog@php.net>
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version CVS: $Id: Script.php,v 1.8 2009/02/24 23:39:37 dufuz Exp $
- * @link http://pear.php.net/package/PEAR
- * @since File available since Release 1.4.0a1
- */
-
-/**
- * @category pear
- * @package PEAR
- * @author Greg Beaver <cellog@php.net>
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.8.0
- * @link http://pear.php.net/package/PEAR
- * @since Class available since Release 1.4.0a1
- */
-class PEAR_Installer_Role_Script extends PEAR_Installer_Role_Common {}
+</role><?php +/** + * PEAR_Installer_Role_Script + * + * PHP versions 4 and 5 + * + * @category pear + * @package PEAR + * @author Greg Beaver <cellog@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: Script.php 276383 2009-02-24 23:39:37Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ + +/** + * @category pear + * @package PEAR + * @author Greg Beaver <cellog@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_Installer_Role_Script extends PEAR_Installer_Role_Common {} ?><role version="1.0"> <releasetypes>php</releasetypes> <releasetypes>extsrc</releasetypes> @@ -72466,33 +73061,33 @@ class PEAR_Installer_Role_Script extends PEAR_Installer_Role_Common {} <executable>1</executable> <phpextension /> <config_vars /> -</role><?php
-/**
- * PEAR_Installer_Role_Test
- *
- * PHP versions 4 and 5
- *
- * @category pear
- * @package PEAR
- * @author Greg Beaver <cellog@php.net>
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version CVS: $Id: Test.php,v 1.8 2009/02/24 23:39:37 dufuz Exp $
- * @link http://pear.php.net/package/PEAR
- * @since File available since Release 1.4.0a1
- */
-
-/**
- * @category pear
- * @package PEAR
- * @author Greg Beaver <cellog@php.net>
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.8.0
- * @link http://pear.php.net/package/PEAR
- * @since Class available since Release 1.4.0a1
- */
-class PEAR_Installer_Role_Test extends PEAR_Installer_Role_Common {}
+</role><?php +/** + * PEAR_Installer_Role_Test + * + * PHP versions 4 and 5 + * + * @category pear + * @package PEAR + * @author Greg Beaver <cellog@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: Test.php 276383 2009-02-24 23:39:37Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ + +/** + * @category pear + * @package PEAR + * @author Greg Beaver <cellog@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_Installer_Role_Test extends PEAR_Installer_Role_Common {} ?><role version="1.0"> <releasetypes>php</releasetypes> <releasetypes>extsrc</releasetypes> @@ -72518,7 +73113,7 @@ class PEAR_Installer_Role_Test extends PEAR_Installer_Role_Common {} * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: PackageFile.php,v 1.48 2009/04/09 22:16:26 dufuz Exp $ + * @version CVS: $Id: PackageFile.php 286670 2009-08-02 14:16:06Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ @@ -72544,7 +73139,7 @@ define('PEAR_PACKAGEFILE_ERROR_INVALID_PACKAGEVERSION', 2); * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ @@ -72714,9 +73309,10 @@ class PEAR_PackageFile return $pf; } - if (!$pf->validate($state)) { + if (!$pf->validate($state)) {; if ($this->_config->get('verbose') > 0 - && $this->_logger && $pf->getValidationWarnings(false)) { + && $this->_logger && $pf->getValidationWarnings(false) + ) { foreach ($pf->getValidationWarnings(false) as $warning) { $this->_logger->log(0, 'ERROR: ' . $warning['message']); } @@ -72832,11 +73428,11 @@ class PEAR_PackageFile $ret = PEAR::raiseError("Could not get contents of package \"$file\"". '. Invalid tgz file.'); return $ret; - } else { - if (!count($content) && !@is_file($file)) { - $ret = PEAR::raiseError("could not open file \"$file\""); - return $ret; - } + } + + if (!count($content) && !@is_file($file)) { + $ret = PEAR::raiseError("could not open file \"$file\""); + return $ret; } $xml = null; @@ -73017,7 +73613,7 @@ class PEAR_PackageFile * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: v1.php,v 1.76 2009/02/24 23:45:26 dufuz Exp $ + * @version CVS: $Id: v1.php 286494 2009-07-29 06:57:11Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ @@ -73037,7 +73633,7 @@ require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/PackageFile/v2.php'; * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ @@ -73054,7 +73650,7 @@ class PEAR_PackageFile_Generator_v1 function getPackagerVersion() { - return '1.8.0'; + return '1.9.0'; } /** @@ -73208,7 +73804,7 @@ class PEAR_PackageFile_Generator_v1 ); $ret = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"; $ret .= "<!DOCTYPE package SYSTEM \"http://pear.php.net/dtd/package-1.0\">\n"; - $ret .= "<package version=\"1.0\" packagerversion=\"1.8.0\">\n" . + $ret .= "<package version=\"1.0\" packagerversion=\"1.9.0\">\n" . " <name>$pkginfo[package]</name>"; if (isset($pkginfo['extends'])) { $ret .= "\n<extends>$pkginfo[extends]</extends>"; @@ -74223,16 +74819,15 @@ class PEAR_PackageFile_Generator_v1 */ function _processMultipleDepsName($deps) { - $tests = array(); + $ret = $tests = array(); foreach ($deps as $name => $dep) { foreach ($dep as $d) { $tests[$name][] = $this->_processDep($d); } } + foreach ($tests as $name => $test) { - $php = array(); - $min = array(); - $max = array(); + $max = $min = $php = array(); $php['name'] = $name; foreach ($test as $dep) { if (!$dep) { @@ -74302,7 +74897,7 @@ class PEAR_PackageFile_Generator_v1 * @author Stephan Schmidt (original XML_Serializer code) * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: v2.php,v 1.51 2009/03/27 17:11:18 dufuz Exp $ + * @version CVS: $Id: v2.php 278907 2009-04-17 21:10:04Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ @@ -74323,7 +74918,7 @@ require_once 'phar://install-pear-nozlib.phar/' . 'XML/Util.php'; * @author Stephan Schmidt (original XML_Serializer code) * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ @@ -74405,7 +75000,7 @@ http://pear.php.net/dtd/package-2.0.xsd', */ function getPackagerVersion() { - return '1.8.0'; + return '1.9.0'; } /** @@ -74669,7 +75264,8 @@ http://pear.php.net/dtd/package-2.0.xsd', $arr['changelog']['release'][0] = $release; } - foreach ($arr['changelog']['release'] as &$c) { + foreach (array_keys($arr['changelog']['release']) as $key) { + $c =& $arr['changelog']['release'][$key]; if (isset($c['notes'])) { // This trims out the indenting, needs fixing $c['notes'] = "\n" . trim($c['notes']) . "\n"; @@ -74689,7 +75285,7 @@ http://pear.php.net/dtd/package-2.0.xsd', $this->options['beautifyFilelist'] = true; } - $arr['attribs']['packagerversion'] = '1.8.0'; + $arr['attribs']['packagerversion'] = '1.9.0'; if ($this->serialize($arr, $options)) { return $this->_serializedData . "\n"; } @@ -75163,7 +75759,7 @@ http://pear.php.net/dtd/package-2.0.xsd', if ($this->options['encoding'] == 'UTF-8' && version_compare(phpversion(), '5.0.0', 'lt') ) { - $tag = utf8_encode($tag); + $tag['content'] = utf8_encode($tag['content']); } if ($replaceEntities === true) { @@ -75192,7 +75788,7 @@ http://pear.php.net/dtd/package-2.0.xsd', * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: v1.php,v 1.30 2009/02/24 23:45:22 dufuz Exp $ + * @version CVS: $Id: v1.php 276385 2009-02-24 23:46:03Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ @@ -75207,7 +75803,7 @@ require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/PackageFile/v1.php'; * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ @@ -75650,7 +76246,7 @@ class PEAR_PackageFile_Parser_v1 * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: v2.php,v 1.24 2009/02/24 23:45:22 dufuz Exp $ + * @version CVS: $Id: v2.php 276385 2009-02-24 23:46:03Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ @@ -75666,7 +76262,7 @@ require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/PackageFile/v2.php'; * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ @@ -75751,1618 +76347,1618 @@ class PEAR_PackageFile_Parser_v2 extends PEAR_XMLParser $ret->setPackagefile($file, $archive); return $ret; } -}<?php
-/**
- * PEAR_PackageFile_v1, package.xml version 1.0
- *
- * PHP versions 4 and 5
- *
- * @category pear
- * @package PEAR
- * @author Greg Beaver <cellog@php.net>
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version CVS: $Id: v1.php,v 1.75 2009/02/24 23:39:16 dufuz Exp $
- * @link http://pear.php.net/package/PEAR
- * @since File available since Release 1.4.0a1
- */
-/**
- * For error handling
- */
-require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/ErrorStack.php';
-
-/**
- * Error code if parsing is attempted with no xml extension
- */
-define('PEAR_PACKAGEFILE_ERROR_NO_XML_EXT', 3);
-
-/**
- * Error code if creating the xml parser resource fails
- */
-define('PEAR_PACKAGEFILE_ERROR_CANT_MAKE_PARSER', 4);
-
-/**
- * Error code used for all sax xml parsing errors
- */
-define('PEAR_PACKAGEFILE_ERROR_PARSER_ERROR', 5);
-
-/**
- * Error code used when there is no name
- */
-define('PEAR_PACKAGEFILE_ERROR_NO_NAME', 6);
-
-/**
- * Error code when a package name is not valid
- */
-define('PEAR_PACKAGEFILE_ERROR_INVALID_NAME', 7);
-
-/**
- * Error code used when no summary is parsed
- */
-define('PEAR_PACKAGEFILE_ERROR_NO_SUMMARY', 8);
-
-/**
- * Error code for summaries that are more than 1 line
- */
-define('PEAR_PACKAGEFILE_ERROR_MULTILINE_SUMMARY', 9);
-
-/**
- * Error code used when no description is present
- */
-define('PEAR_PACKAGEFILE_ERROR_NO_DESCRIPTION', 10);
-
-/**
- * Error code used when no license is present
- */
-define('PEAR_PACKAGEFILE_ERROR_NO_LICENSE', 11);
-
-/**
- * Error code used when a <version> version number is not present
- */
-define('PEAR_PACKAGEFILE_ERROR_NO_VERSION', 12);
-
-/**
- * Error code used when a <version> version number is invalid
- */
-define('PEAR_PACKAGEFILE_ERROR_INVALID_VERSION', 13);
-
-/**
- * Error code when release state is missing
- */
-define('PEAR_PACKAGEFILE_ERROR_NO_STATE', 14);
-
-/**
- * Error code when release state is invalid
- */
-define('PEAR_PACKAGEFILE_ERROR_INVALID_STATE', 15);
-
-/**
- * Error code when release state is missing
- */
-define('PEAR_PACKAGEFILE_ERROR_NO_DATE', 16);
-
-/**
- * Error code when release state is invalid
- */
-define('PEAR_PACKAGEFILE_ERROR_INVALID_DATE', 17);
-
-/**
- * Error code when no release notes are found
- */
-define('PEAR_PACKAGEFILE_ERROR_NO_NOTES', 18);
-
-/**
- * Error code when no maintainers are found
- */
-define('PEAR_PACKAGEFILE_ERROR_NO_MAINTAINERS', 19);
-
-/**
- * Error code when a maintainer has no handle
- */
-define('PEAR_PACKAGEFILE_ERROR_NO_MAINTHANDLE', 20);
-
-/**
- * Error code when a maintainer has no handle
- */
-define('PEAR_PACKAGEFILE_ERROR_NO_MAINTROLE', 21);
-
-/**
- * Error code when a maintainer has no name
- */
-define('PEAR_PACKAGEFILE_ERROR_NO_MAINTNAME', 22);
-
-/**
- * Error code when a maintainer has no email
- */
-define('PEAR_PACKAGEFILE_ERROR_NO_MAINTEMAIL', 23);
-
-/**
- * Error code when a maintainer has no handle
- */
-define('PEAR_PACKAGEFILE_ERROR_INVALID_MAINTROLE', 24);
-
-/**
- * Error code when a dependency is not a PHP dependency, but has no name
- */
-define('PEAR_PACKAGEFILE_ERROR_NO_DEPNAME', 25);
-
-/**
- * Error code when a dependency has no type (pkg, php, etc.)
- */
-define('PEAR_PACKAGEFILE_ERROR_NO_DEPTYPE', 26);
-
-/**
- * Error code when a dependency has no relation (lt, ge, has, etc.)
- */
-define('PEAR_PACKAGEFILE_ERROR_NO_DEPREL', 27);
-
-/**
- * Error code when a dependency is not a 'has' relation, but has no version
- */
-define('PEAR_PACKAGEFILE_ERROR_NO_DEPVERSION', 28);
-
-/**
- * Error code when a dependency has an invalid relation
- */
-define('PEAR_PACKAGEFILE_ERROR_INVALID_DEPREL', 29);
-
-/**
- * Error code when a dependency has an invalid type
- */
-define('PEAR_PACKAGEFILE_ERROR_INVALID_DEPTYPE', 30);
-
-/**
- * Error code when a dependency has an invalid optional option
- */
-define('PEAR_PACKAGEFILE_ERROR_INVALID_DEPOPTIONAL', 31);
-
-/**
- * Error code when a dependency is a pkg dependency, and has an invalid package name
- */
-define('PEAR_PACKAGEFILE_ERROR_INVALID_DEPNAME', 32);
-
-/**
- * Error code when a dependency has a channel="foo" attribute, and foo is not a registered channel
- */
-define('PEAR_PACKAGEFILE_ERROR_UNKNOWN_DEPCHANNEL', 33);
-
-/**
- * Error code when rel="has" and version attribute is present.
- */
-define('PEAR_PACKAGEFILE_ERROR_DEPVERSION_IGNORED', 34);
-
-/**
- * Error code when type="php" and dependency name is present
- */
-define('PEAR_PACKAGEFILE_ERROR_DEPNAME_IGNORED', 35);
-
-/**
- * Error code when a configure option has no name
- */
-define('PEAR_PACKAGEFILE_ERROR_NO_CONFNAME', 36);
-
-/**
- * Error code when a configure option has no name
- */
-define('PEAR_PACKAGEFILE_ERROR_NO_CONFPROMPT', 37);
-
-/**
- * Error code when a file in the filelist has an invalid role
- */
-define('PEAR_PACKAGEFILE_ERROR_INVALID_FILEROLE', 38);
-
-/**
- * Error code when a file in the filelist has no role
- */
-define('PEAR_PACKAGEFILE_ERROR_NO_FILEROLE', 39);
-
-/**
- * Error code when analyzing a php source file that has parse errors
- */
-define('PEAR_PACKAGEFILE_ERROR_INVALID_PHPFILE', 40);
-
-/**
- * Error code when analyzing a php source file reveals a source element
- * without a package name prefix
- */
-define('PEAR_PACKAGEFILE_ERROR_NO_PNAME_PREFIX', 41);
-
-/**
- * Error code when an unknown channel is specified
- */
-define('PEAR_PACKAGEFILE_ERROR_UNKNOWN_CHANNEL', 42);
-
-/**
- * Error code when no files are found in the filelist
- */
-define('PEAR_PACKAGEFILE_ERROR_NO_FILES', 43);
-
-/**
- * Error code when a file is not valid php according to _analyzeSourceCode()
- */
-define('PEAR_PACKAGEFILE_ERROR_INVALID_FILE', 44);
-
-/**
- * Error code when the channel validator returns an error or warning
- */
-define('PEAR_PACKAGEFILE_ERROR_CHANNELVAL', 45);
-
-/**
- * Error code when a php5 package is packaged in php4 (analysis doesn't work)
- */
-define('PEAR_PACKAGEFILE_ERROR_PHP5', 46);
-
-/**
- * Error code when a file is listed in package.xml but does not exist
- */
-define('PEAR_PACKAGEFILE_ERROR_FILE_NOTFOUND', 47);
-
-/**
- * Error code when a <dep type="php" rel="not"... is encountered (use rel="ne")
- */
-define('PEAR_PACKAGEFILE_PHP_NO_NOT', 48);
-
-/**
- * Error code when a package.xml contains non-ISO-8859-1 characters
- */
-define('PEAR_PACKAGEFILE_ERROR_NON_ISO_CHARS', 49);
-
-/**
- * Error code when a dependency is not a 'has' relation, but has no version
- */
-define('PEAR_PACKAGEFILE_ERROR_NO_DEPPHPVERSION', 50);
-
-/**
- * Error code when a package has no lead developer
- */
-define('PEAR_PACKAGEFILE_ERROR_NO_LEAD', 51);
-
-/**
- * Error code when a filename begins with "."
- */
-define('PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME', 52);
-/**
- * package.xml encapsulator
- * @category pear
- * @package PEAR
- * @author Greg Beaver <cellog@php.net>
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.8.0
- * @link http://pear.php.net/package/PEAR
- * @since Class available since Release 1.4.0a1
- */
-class PEAR_PackageFile_v1
-{
- /**
- * @access private
- * @var PEAR_ErrorStack
- * @access private
- */
- var $_stack;
-
- /**
- * A registry object, used to access the package name validation regex for non-standard channels
- * @var PEAR_Registry
- * @access private
- */
- var $_registry;
-
- /**
- * An object that contains a log method that matches PEAR_Common::log's signature
- * @var object
- * @access private
- */
- var $_logger;
-
- /**
- * Parsed package information
- * @var array
- * @access private
- */
- var $_packageInfo;
-
- /**
- * path to package.xml
- * @var string
- * @access private
- */
- var $_packageFile;
-
- /**
- * path to package .tgz or false if this is a local/extracted package.xml
- * @var string
- * @access private
- */
- var $_archiveFile;
-
- /**
- * @var int
- * @access private
- */
- var $_isValid = 0;
-
- /**
- * Determines whether this packagefile was initialized only with partial package info
- *
- * If this package file was constructed via parsing REST, it will only contain
- *
- * - package name
- * - channel name
- * - dependencies
- * @var boolean
- * @access private
- */
- var $_incomplete = true;
-
- /**
- * @param bool determines whether to return a PEAR_Error object, or use the PEAR_ErrorStack
- * @param string Name of Error Stack class to use.
- */
- function PEAR_PackageFile_v1()
- {
- $this->_stack = &new PEAR_ErrorStack('PEAR_PackageFile_v1');
- $this->_stack->setErrorMessageTemplate($this->_getErrorMessage());
- $this->_isValid = 0;
- }
-
- function installBinary($installer)
- {
- return false;
- }
-
- function isExtension($name)
- {
- return false;
- }
-
- function setConfig(&$config)
- {
- $this->_config = &$config;
- $this->_registry = &$config->getRegistry();
- }
-
- function setRequestedGroup()
- {
- // placeholder
- }
-
- /**
- * For saving in the registry.
- *
- * Set the last version that was installed
- * @param string
- */
- function setLastInstalledVersion($version)
- {
- $this->_packageInfo['_lastversion'] = $version;
- }
-
- /**
- * @return string|false
- */
- function getLastInstalledVersion()
- {
- if (isset($this->_packageInfo['_lastversion'])) {
- return $this->_packageInfo['_lastversion'];
- }
- return false;
- }
-
- function getInstalledBinary()
- {
- return false;
- }
-
- function listPostinstallScripts()
- {
- return false;
- }
-
- function initPostinstallScripts()
- {
- return false;
- }
-
- function setLogger(&$logger)
- {
- if ($logger && (!is_object($logger) || !method_exists($logger, 'log'))) {
- return PEAR::raiseError('Logger must be compatible with PEAR_Common::log');
- }
- $this->_logger = &$logger;
- }
-
- function setPackagefile($file, $archive = false)
- {
- $this->_packageFile = $file;
- $this->_archiveFile = $archive ? $archive : $file;
- }
-
- function getPackageFile()
- {
- return isset($this->_packageFile) ? $this->_packageFile : false;
- }
-
- function getPackageType()
- {
- return 'php';
- }
-
- function getArchiveFile()
- {
- return $this->_archiveFile;
- }
-
- function packageInfo($field)
- {
- if (!is_string($field) || empty($field) ||
- !isset($this->_packageInfo[$field])) {
- return false;
- }
- return $this->_packageInfo[$field];
- }
-
- function setDirtree($path)
- {
- if (!isset($this->_packageInfo['dirtree'])) {
- $this->_packageInfo['dirtree'] = array();
- }
- $this->_packageInfo['dirtree'][$path] = true;
- }
-
- function getDirtree()
- {
- if (isset($this->_packageInfo['dirtree']) && count($this->_packageInfo['dirtree'])) {
- return $this->_packageInfo['dirtree'];
- }
- return false;
- }
-
- function resetDirtree()
- {
- unset($this->_packageInfo['dirtree']);
- }
-
- function fromArray($pinfo)
- {
- $this->_incomplete = false;
- $this->_packageInfo = $pinfo;
- }
-
- function isIncomplete()
- {
- return $this->_incomplete;
- }
-
- function getChannel()
- {
- return 'pear.php.net';
- }
-
- function getUri()
- {
- return false;
- }
-
- function getTime()
- {
- return false;
- }
-
- function getExtends()
- {
- if (isset($this->_packageInfo['extends'])) {
- return $this->_packageInfo['extends'];
- }
- return false;
- }
-
- /**
- * @return array
- */
- function toArray()
- {
- if (!$this->validate(PEAR_VALIDATE_NORMAL)) {
- return false;
- }
- return $this->getArray();
- }
-
- function getArray()
- {
- return $this->_packageInfo;
- }
-
- function getName()
- {
- return $this->getPackage();
- }
-
- function getPackage()
- {
- if (isset($this->_packageInfo['package'])) {
- return $this->_packageInfo['package'];
- }
- return false;
- }
-
- /**
- * WARNING - don't use this unless you know what you are doing
- */
- function setRawPackage($package)
- {
- $this->_packageInfo['package'] = $package;
- }
-
- function setPackage($package)
- {
- $this->_packageInfo['package'] = $package;
- $this->_isValid = false;
- }
-
- function getVersion()
- {
- if (isset($this->_packageInfo['version'])) {
- return $this->_packageInfo['version'];
- }
- return false;
- }
-
- function setVersion($version)
- {
- $this->_packageInfo['version'] = $version;
- $this->_isValid = false;
- }
-
- function clearMaintainers()
- {
- unset($this->_packageInfo['maintainers']);
- }
-
- function getMaintainers()
- {
- if (isset($this->_packageInfo['maintainers'])) {
- return $this->_packageInfo['maintainers'];
- }
- return false;
- }
-
- /**
- * Adds a new maintainer - no checking of duplicates is performed, use
- * updatemaintainer for that purpose.
- */
- function addMaintainer($role, $handle, $name, $email)
- {
- $this->_packageInfo['maintainers'][] =
- array('handle' => $handle, 'role' => $role, 'email' => $email, 'name' => $name);
- $this->_isValid = false;
- }
-
- function updateMaintainer($role, $handle, $name, $email)
- {
- $found = false;
- if (!isset($this->_packageInfo['maintainers']) ||
- !is_array($this->_packageInfo['maintainers'])) {
- return $this->addMaintainer($role, $handle, $name, $email);
- }
- foreach ($this->_packageInfo['maintainers'] as $i => $maintainer) {
- if ($maintainer['handle'] == $handle) {
- $found = $i;
- break;
- }
- }
- if ($found !== false) {
- unset($this->_packageInfo['maintainers'][$found]);
- $this->_packageInfo['maintainers'] =
- array_values($this->_packageInfo['maintainers']);
- }
- $this->addMaintainer($role, $handle, $name, $email);
- }
-
- function deleteMaintainer($handle)
- {
- $found = false;
- foreach ($this->_packageInfo['maintainers'] as $i => $maintainer) {
- if ($maintainer['handle'] == $handle) {
- $found = $i;
- break;
- }
- }
- if ($found !== false) {
- unset($this->_packageInfo['maintainers'][$found]);
- $this->_packageInfo['maintainers'] =
- array_values($this->_packageInfo['maintainers']);
- return true;
- }
- return false;
- }
-
- function getState()
- {
- if (isset($this->_packageInfo['release_state'])) {
- return $this->_packageInfo['release_state'];
- }
- return false;
- }
-
- function setRawState($state)
- {
- $this->_packageInfo['release_state'] = $state;
- }
-
- function setState($state)
- {
- $this->_packageInfo['release_state'] = $state;
- $this->_isValid = false;
- }
-
- function getDate()
- {
- if (isset($this->_packageInfo['release_date'])) {
- return $this->_packageInfo['release_date'];
- }
- return false;
- }
-
- function setDate($date)
- {
- $this->_packageInfo['release_date'] = $date;
- $this->_isValid = false;
- }
-
- function getLicense()
- {
- if (isset($this->_packageInfo['release_license'])) {
- return $this->_packageInfo['release_license'];
- }
- return false;
- }
-
- function setLicense($date)
- {
- $this->_packageInfo['release_license'] = $date;
- $this->_isValid = false;
- }
-
- function getSummary()
- {
- if (isset($this->_packageInfo['summary'])) {
- return $this->_packageInfo['summary'];
- }
- return false;
- }
-
- function setSummary($summary)
- {
- $this->_packageInfo['summary'] = $summary;
- $this->_isValid = false;
- }
-
- function getDescription()
- {
- if (isset($this->_packageInfo['description'])) {
- return $this->_packageInfo['description'];
- }
- return false;
- }
-
- function setDescription($desc)
- {
- $this->_packageInfo['description'] = $desc;
- $this->_isValid = false;
- }
-
- function getNotes()
- {
- if (isset($this->_packageInfo['release_notes'])) {
- return $this->_packageInfo['release_notes'];
- }
- return false;
- }
-
- function setNotes($notes)
- {
- $this->_packageInfo['release_notes'] = $notes;
- $this->_isValid = false;
- }
-
- function getDeps()
- {
- if (isset($this->_packageInfo['release_deps'])) {
- return $this->_packageInfo['release_deps'];
- }
- return false;
- }
-
- /**
- * Reset dependencies prior to adding new ones
- */
- function clearDeps()
- {
- unset($this->_packageInfo['release_deps']);
- }
-
- function addPhpDep($version, $rel)
- {
- $this->_isValid = false;
- $this->_packageInfo['release_deps'][] =
- array('type' => 'php',
- 'rel' => $rel,
- 'version' => $version);
- }
-
- function addPackageDep($name, $version, $rel, $optional = 'no')
- {
- $this->_isValid = false;
- $dep =
- array('type' => 'pkg',
- 'name' => $name,
- 'rel' => $rel,
- 'optional' => $optional);
- if ($rel != 'has' && $rel != 'not') {
- $dep['version'] = $version;
- }
- $this->_packageInfo['release_deps'][] = $dep;
- }
-
- function addExtensionDep($name, $version, $rel, $optional = 'no')
- {
- $this->_isValid = false;
- $this->_packageInfo['release_deps'][] =
- array('type' => 'ext',
- 'name' => $name,
- 'rel' => $rel,
- 'version' => $version,
- 'optional' => $optional);
- }
-
- /**
- * WARNING - do not use this function directly unless you know what you're doing
- */
- function setDeps($deps)
- {
- $this->_packageInfo['release_deps'] = $deps;
- }
-
- function hasDeps()
- {
- return isset($this->_packageInfo['release_deps']) &&
- count($this->_packageInfo['release_deps']);
- }
-
- function getDependencyGroup($group)
- {
- return false;
- }
-
- function isCompatible($pf)
- {
- return false;
- }
-
- function isSubpackageOf($p)
- {
- return $p->isSubpackage($this);
- }
-
- function isSubpackage($p)
- {
- return false;
- }
-
- function dependsOn($package, $channel)
- {
- if (strtolower($channel) != 'pear.php.net') {
- return false;
- }
- if (!($deps = $this->getDeps())) {
- return false;
- }
- foreach ($deps as $dep) {
- if ($dep['type'] != 'pkg') {
- continue;
- }
- if (strtolower($dep['name']) == strtolower($package)) {
- return true;
- }
- }
- return false;
- }
-
- function getConfigureOptions()
- {
- if (isset($this->_packageInfo['configure_options'])) {
- return $this->_packageInfo['configure_options'];
- }
- return false;
- }
-
- function hasConfigureOptions()
- {
- return isset($this->_packageInfo['configure_options']) &&
- count($this->_packageInfo['configure_options']);
- }
-
- function addConfigureOption($name, $prompt, $default = false)
- {
- $o = array('name' => $name, 'prompt' => $prompt);
- if ($default !== false) {
- $o['default'] = $default;
- }
- if (!isset($this->_packageInfo['configure_options'])) {
- $this->_packageInfo['configure_options'] = array();
- }
- $this->_packageInfo['configure_options'][] = $o;
- }
-
- function clearConfigureOptions()
- {
- unset($this->_packageInfo['configure_options']);
- }
-
- function getProvides()
- {
- if (isset($this->_packageInfo['provides'])) {
- return $this->_packageInfo['provides'];
- }
- return false;
- }
-
- function getProvidesExtension()
- {
- return false;
- }
-
- function addFile($dir, $file, $attrs)
- {
- $dir = preg_replace(array('!\\\\+!', '!/+!'), array('/', '/'), $dir);
- if ($dir == '/' || $dir == '') {
- $dir = '';
- } else {
- $dir .= '/';
- }
- $file = $dir . $file;
- $file = preg_replace('![\\/]+!', '/', $file);
- $this->_packageInfo['filelist'][$file] = $attrs;
- }
-
- function getInstallationFilelist()
- {
- return $this->getFilelist();
- }
-
- function getFilelist()
- {
- if (isset($this->_packageInfo['filelist'])) {
- return $this->_packageInfo['filelist'];
- }
- return false;
- }
-
- function setFileAttribute($file, $attr, $value)
- {
- $this->_packageInfo['filelist'][$file][$attr] = $value;
- }
-
- function resetFilelist()
- {
- $this->_packageInfo['filelist'] = array();
- }
-
- function setInstalledAs($file, $path)
- {
- if ($path) {
- return $this->_packageInfo['filelist'][$file]['installed_as'] = $path;
- }
- unset($this->_packageInfo['filelist'][$file]['installed_as']);
- }
-
- function installedFile($file, $atts)
- {
- if (isset($this->_packageInfo['filelist'][$file])) {
- $this->_packageInfo['filelist'][$file] =
- array_merge($this->_packageInfo['filelist'][$file], $atts);
- } else {
- $this->_packageInfo['filelist'][$file] = $atts;
- }
- }
-
- function getChangelog()
- {
- if (isset($this->_packageInfo['changelog'])) {
- return $this->_packageInfo['changelog'];
- }
- return false;
- }
-
- function getPackagexmlVersion()
- {
- return '1.0';
- }
-
- /**
- * Wrapper to {@link PEAR_ErrorStack::getErrors()}
- * @param boolean determines whether to purge the error stack after retrieving
- * @return array
- */
- function getValidationWarnings($purge = true)
- {
- return $this->_stack->getErrors($purge);
- }
-
- // }}}
- /**
- * Validation error. Also marks the object contents as invalid
- * @param error code
- * @param array error information
- * @access private
- */
- function _validateError($code, $params = array())
- {
- $this->_stack->push($code, 'error', $params, false, false, debug_backtrace());
- $this->_isValid = false;
- }
-
- /**
- * Validation warning. Does not mark the object contents invalid.
- * @param error code
- * @param array error information
- * @access private
- */
- function _validateWarning($code, $params = array())
- {
- $this->_stack->push($code, 'warning', $params, false, false, debug_backtrace());
- }
-
- /**
- * @param integer error code
- * @access protected
- */
- function _getErrorMessage()
- {
- return array(
- PEAR_PACKAGEFILE_ERROR_NO_NAME =>
- 'Missing Package Name',
- PEAR_PACKAGEFILE_ERROR_NO_SUMMARY =>
- 'No summary found',
- PEAR_PACKAGEFILE_ERROR_MULTILINE_SUMMARY =>
- 'Summary should be on one line',
- PEAR_PACKAGEFILE_ERROR_NO_DESCRIPTION =>
- 'Missing description',
- PEAR_PACKAGEFILE_ERROR_NO_LICENSE =>
- 'Missing license',
- PEAR_PACKAGEFILE_ERROR_NO_VERSION =>
- 'No release version found',
- PEAR_PACKAGEFILE_ERROR_NO_STATE =>
- 'No release state found',
- PEAR_PACKAGEFILE_ERROR_NO_DATE =>
- 'No release date found',
- PEAR_PACKAGEFILE_ERROR_NO_NOTES =>
- 'No release notes found',
- PEAR_PACKAGEFILE_ERROR_NO_LEAD =>
- 'Package must have at least one lead maintainer',
- PEAR_PACKAGEFILE_ERROR_NO_MAINTAINERS =>
- 'No maintainers found, at least one must be defined',
- PEAR_PACKAGEFILE_ERROR_NO_MAINTHANDLE =>
- 'Maintainer %index% has no handle (user ID at channel server)',
- PEAR_PACKAGEFILE_ERROR_NO_MAINTROLE =>
- 'Maintainer %index% has no role',
- PEAR_PACKAGEFILE_ERROR_NO_MAINTNAME =>
- 'Maintainer %index% has no name',
- PEAR_PACKAGEFILE_ERROR_NO_MAINTEMAIL =>
- 'Maintainer %index% has no email',
- PEAR_PACKAGEFILE_ERROR_NO_DEPNAME =>
- 'Dependency %index% is not a php dependency, and has no name',
- PEAR_PACKAGEFILE_ERROR_NO_DEPREL =>
- 'Dependency %index% has no relation (rel)',
- PEAR_PACKAGEFILE_ERROR_NO_DEPTYPE =>
- 'Dependency %index% has no type',
- PEAR_PACKAGEFILE_ERROR_DEPNAME_IGNORED =>
- 'PHP Dependency %index% has a name attribute of "%name%" which will be' .
- ' ignored!',
- PEAR_PACKAGEFILE_ERROR_NO_DEPVERSION =>
- 'Dependency %index% is not a rel="has" or rel="not" dependency, ' .
- 'and has no version',
- PEAR_PACKAGEFILE_ERROR_NO_DEPPHPVERSION =>
- 'Dependency %index% is a type="php" dependency, ' .
- 'and has no version',
- PEAR_PACKAGEFILE_ERROR_DEPVERSION_IGNORED =>
- 'Dependency %index% is a rel="%rel%" dependency, versioning is ignored',
- PEAR_PACKAGEFILE_ERROR_INVALID_DEPOPTIONAL =>
- 'Dependency %index% has invalid optional value "%opt%", should be yes or no',
- PEAR_PACKAGEFILE_PHP_NO_NOT =>
- 'Dependency %index%: php dependencies cannot use "not" rel, use "ne"' .
- ' to exclude specific versions',
- PEAR_PACKAGEFILE_ERROR_NO_CONFNAME =>
- 'Configure Option %index% has no name',
- PEAR_PACKAGEFILE_ERROR_NO_CONFPROMPT =>
- 'Configure Option %index% has no prompt',
- PEAR_PACKAGEFILE_ERROR_NO_FILES =>
- 'No files in <filelist> section of package.xml',
- PEAR_PACKAGEFILE_ERROR_NO_FILEROLE =>
- 'File "%file%" has no role, expecting one of "%roles%"',
- PEAR_PACKAGEFILE_ERROR_INVALID_FILEROLE =>
- 'File "%file%" has invalid role "%role%", expecting one of "%roles%"',
- PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME =>
- 'File "%file%" cannot start with ".", cannot package or install',
- PEAR_PACKAGEFILE_ERROR_INVALID_PHPFILE =>
- 'Parser error: invalid PHP found in file "%file%"',
- PEAR_PACKAGEFILE_ERROR_NO_PNAME_PREFIX =>
- 'in %file%: %type% "%name%" not prefixed with package name "%package%"',
- PEAR_PACKAGEFILE_ERROR_INVALID_FILE =>
- 'Parser error: invalid PHP file "%file%"',
- PEAR_PACKAGEFILE_ERROR_CHANNELVAL =>
- 'Channel validator error: field "%field%" - %reason%',
- PEAR_PACKAGEFILE_ERROR_PHP5 =>
- 'Error, PHP5 token encountered in %file%, analysis should be in PHP5',
- PEAR_PACKAGEFILE_ERROR_FILE_NOTFOUND =>
- 'File "%file%" in package.xml does not exist',
- PEAR_PACKAGEFILE_ERROR_NON_ISO_CHARS =>
- 'Package.xml contains non-ISO-8859-1 characters, and may not validate',
- );
- }
-
- /**
- * Validate XML package definition file.
- *
- * @access public
- * @return boolean
- */
- function validate($state = PEAR_VALIDATE_NORMAL, $nofilechecking = false)
- {
- if (($this->_isValid & $state) == $state) {
- return true;
- }
- $this->_isValid = true;
- $info = $this->_packageInfo;
- if (empty($info['package'])) {
- $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_NAME);
- $this->_packageName = $pn = 'unknown';
- } else {
- $this->_packageName = $pn = $info['package'];
- }
-
- if (empty($info['summary'])) {
- $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_SUMMARY);
- } elseif (strpos(trim($info['summary']), "\n") !== false) {
- $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_MULTILINE_SUMMARY,
- array('summary' => $info['summary']));
- }
- if (empty($info['description'])) {
- $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DESCRIPTION);
- }
- if (empty($info['release_license'])) {
- $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_LICENSE);
- }
- if (empty($info['version'])) {
- $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_VERSION);
- }
- if (empty($info['release_state'])) {
- $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_STATE);
- }
- if (empty($info['release_date'])) {
- $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DATE);
- }
- if (empty($info['release_notes'])) {
- $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_NOTES);
- }
- if (empty($info['maintainers'])) {
- $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTAINERS);
- } else {
- $haslead = false;
- $i = 1;
- foreach ($info['maintainers'] as $m) {
- if (empty($m['handle'])) {
- $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTHANDLE,
- array('index' => $i));
- }
- if (empty($m['role'])) {
- $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTROLE,
- array('index' => $i, 'roles' => PEAR_Common::getUserRoles()));
- } elseif ($m['role'] == 'lead') {
- $haslead = true;
- }
- if (empty($m['name'])) {
- $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTNAME,
- array('index' => $i));
- }
- if (empty($m['email'])) {
- $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTEMAIL,
- array('index' => $i));
- }
- $i++;
- }
- if (!$haslead) {
- $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_LEAD);
- }
- }
- if (!empty($info['release_deps'])) {
- $i = 1;
- foreach ($info['release_deps'] as $d) {
- if (!isset($d['type']) || empty($d['type'])) {
- $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPTYPE,
- array('index' => $i, 'types' => PEAR_Common::getDependencyTypes()));
- continue;
- }
- if (!isset($d['rel']) || empty($d['rel'])) {
- $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPREL,
- array('index' => $i, 'rels' => PEAR_Common::getDependencyRelations()));
- continue;
- }
- if (!empty($d['optional'])) {
- if (!in_array($d['optional'], array('yes', 'no'))) {
- $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_DEPOPTIONAL,
- array('index' => $i, 'opt' => $d['optional']));
- }
- }
- if ($d['rel'] != 'has' && $d['rel'] != 'not' && empty($d['version'])) {
- $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPVERSION,
- array('index' => $i));
- } elseif (($d['rel'] == 'has' || $d['rel'] == 'not') && !empty($d['version'])) {
- $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_DEPVERSION_IGNORED,
- array('index' => $i, 'rel' => $d['rel']));
- }
- if ($d['type'] == 'php' && !empty($d['name'])) {
- $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_DEPNAME_IGNORED,
- array('index' => $i, 'name' => $d['name']));
- } elseif ($d['type'] != 'php' && empty($d['name'])) {
- $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPNAME,
- array('index' => $i));
- }
- if ($d['type'] == 'php' && empty($d['version'])) {
- $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPPHPVERSION,
- array('index' => $i));
- }
- if (($d['rel'] == 'not') && ($d['type'] == 'php')) {
- $this->_validateError(PEAR_PACKAGEFILE_PHP_NO_NOT,
- array('index' => $i));
- }
- $i++;
- }
- }
- if (!empty($info['configure_options'])) {
- $i = 1;
- foreach ($info['configure_options'] as $c) {
- if (empty($c['name'])) {
- $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_CONFNAME,
- array('index' => $i));
- }
- if (empty($c['prompt'])) {
- $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_CONFPROMPT,
- array('index' => $i));
- }
- $i++;
- }
- }
- if (empty($info['filelist'])) {
- $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_FILES);
- $errors[] = 'no files';
- } else {
- foreach ($info['filelist'] as $file => $fa) {
- if (empty($fa['role'])) {
- $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_FILEROLE,
- array('file' => $file, 'roles' => PEAR_Common::getFileRoles()));
- continue;
- } elseif (!in_array($fa['role'], PEAR_Common::getFileRoles())) {
- $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_FILEROLE,
- array('file' => $file, 'role' => $fa['role'], 'roles' => PEAR_Common::getFileRoles()));
- }
- if (preg_match('~/\.\.?(/|\\z)|^\.\.?/~', str_replace('\\', '/', $file))) {
- // file contains .. parent directory or . cur directory references
- $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME,
- array('file' => $file));
- }
- if (isset($fa['install-as']) &&
- preg_match('~/\.\.?(/|\\z)|^\.\.?/~',
- str_replace('\\', '/', $fa['install-as']))) {
- // install-as contains .. parent directory or . cur directory references
- $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME,
- array('file' => $file . ' [installed as ' . $fa['install-as'] . ']'));
- }
- if (isset($fa['baseinstalldir']) &&
- preg_match('~/\.\.?(/|\\z)|^\.\.?/~',
- str_replace('\\', '/', $fa['baseinstalldir']))) {
- // install-as contains .. parent directory or . cur directory references
- $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME,
- array('file' => $file . ' [baseinstalldir ' . $fa['baseinstalldir'] . ']'));
- }
- }
- }
- if (isset($this->_registry) && $this->_isValid) {
- $chan = $this->_registry->getChannel('pear.php.net');
- if (PEAR::isError($chan)) {
- $this->_validateError(PEAR_PACKAGEFILE_ERROR_CHANNELVAL, $chan->getMessage());
- return $this->_isValid = 0;
- }
- $validator = $chan->getValidationObject();
- $validator->setPackageFile($this);
- $validator->validate($state);
- $failures = $validator->getFailures();
- foreach ($failures['errors'] as $error) {
- $this->_validateError(PEAR_PACKAGEFILE_ERROR_CHANNELVAL, $error);
- }
- foreach ($failures['warnings'] as $warning) {
- $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_CHANNELVAL, $warning);
- }
- }
- if ($this->_isValid && $state == PEAR_VALIDATE_PACKAGING && !$nofilechecking) {
- if ($this->_analyzePhpFiles()) {
- $this->_isValid = true;
- }
- }
- if ($this->_isValid) {
- return $this->_isValid = $state;
- }
- return $this->_isValid = 0;
- }
-
- function _analyzePhpFiles()
- {
- if (!$this->_isValid) {
- return false;
- }
- if (!isset($this->_packageFile)) {
- return false;
- }
- $dir_prefix = dirname($this->_packageFile);
- $common = new PEAR_Common;
- $log = isset($this->_logger) ? array(&$this->_logger, 'log') :
- array($common, 'log');
- $info = $this->getFilelist();
- foreach ($info as $file => $fa) {
- if (!file_exists($dir_prefix . DIRECTORY_SEPARATOR . $file)) {
- $this->_validateError(PEAR_PACKAGEFILE_ERROR_FILE_NOTFOUND,
- array('file' => realpath($dir_prefix) . DIRECTORY_SEPARATOR . $file));
- continue;
- }
- if ($fa['role'] == 'php' && $dir_prefix) {
- call_user_func_array($log, array(1, "Analyzing $file"));
- $srcinfo = $this->_analyzeSourceCode($dir_prefix . DIRECTORY_SEPARATOR . $file);
- if ($srcinfo) {
- $this->_buildProvidesArray($srcinfo);
- }
- }
- }
- $this->_packageName = $pn = $this->getPackage();
- $pnl = strlen($pn);
- if (isset($this->_packageInfo['provides'])) {
- foreach ((array) $this->_packageInfo['provides'] as $key => $what) {
- if (isset($what['explicit'])) {
- // skip conformance checks if the provides entry is
- // specified in the package.xml file
- continue;
- }
- extract($what);
- if ($type == 'class') {
- if (!strncasecmp($name, $pn, $pnl)) {
- continue;
- }
- $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_NO_PNAME_PREFIX,
- array('file' => $file, 'type' => $type, 'name' => $name, 'package' => $pn));
- } elseif ($type == 'function') {
- if (strstr($name, '::') || !strncasecmp($name, $pn, $pnl)) {
- continue;
- }
- $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_NO_PNAME_PREFIX,
- array('file' => $file, 'type' => $type, 'name' => $name, 'package' => $pn));
- }
- }
- }
- return $this->_isValid;
- }
-
- /**
- * Get the default xml generator object
- *
- * @return PEAR_PackageFile_Generator_v1
- */
- function &getDefaultGenerator()
- {
- if (!class_exists('PEAR_PackageFile_Generator_v1')) {
- require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/PackageFile/Generator/v1.php';
- }
- $a = &new PEAR_PackageFile_Generator_v1($this);
- return $a;
- }
-
- /**
- * Get the contents of a file listed within the package.xml
- * @param string
- * @return string
- */
- function getFileContents($file)
- {
- if ($this->_archiveFile == $this->_packageFile) { // unpacked
- $dir = dirname($this->_packageFile);
- $file = $dir . DIRECTORY_SEPARATOR . $file;
- $file = str_replace(array('/', '\\'),
- array(DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR), $file);
- if (file_exists($file) && is_readable($file)) {
- return implode('', file($file));
- }
- } else { // tgz
- if (!class_exists('Archive_Tar')) {
- require_once 'phar://install-pear-nozlib.phar/' . 'Archive/Tar.php';
- }
- $tar = &new Archive_Tar($this->_archiveFile);
- $tar->pushErrorHandling(PEAR_ERROR_RETURN);
- if ($file != 'package.xml' && $file != 'package2.xml') {
- $file = $this->getPackage() . '-' . $this->getVersion() . '/' . $file;
- }
- $file = $tar->extractInString($file);
- $tar->popErrorHandling();
- if (PEAR::isError($file)) {
- return PEAR::raiseError("Cannot locate file '$file' in archive");
- }
- return $file;
- }
- }
-
- // {{{ analyzeSourceCode()
- /**
- * Analyze the source code of the given PHP file
- *
- * @param string Filename of the PHP file
- * @return mixed
- * @access private
- */
- function _analyzeSourceCode($file)
- {
- if (!function_exists("token_get_all")) {
- return false;
- }
- if (!defined('T_DOC_COMMENT')) {
- define('T_DOC_COMMENT', T_COMMENT);
- }
- if (!defined('T_INTERFACE')) {
- define('T_INTERFACE', -1);
- }
- if (!defined('T_IMPLEMENTS')) {
- define('T_IMPLEMENTS', -1);
- }
- if (!$fp = @fopen($file, "r")) {
- return false;
- }
- fclose($fp);
- $contents = file_get_contents($file);
- $tokens = token_get_all($contents);
-/*
- for ($i = 0; $i < sizeof($tokens); $i++) {
- @list($token, $data) = $tokens[$i];
- if (is_string($token)) {
- var_dump($token);
- } else {
- print token_name($token) . ' ';
- var_dump(rtrim($data));
- }
- }
-*/
- $look_for = 0;
- $paren_level = 0;
- $bracket_level = 0;
- $brace_level = 0;
- $lastphpdoc = '';
- $current_class = '';
- $current_interface = '';
- $current_class_level = -1;
- $current_function = '';
- $current_function_level = -1;
- $declared_classes = array();
- $declared_interfaces = array();
- $declared_functions = array();
- $declared_methods = array();
- $used_classes = array();
- $used_functions = array();
- $extends = array();
- $implements = array();
- $nodeps = array();
- $inquote = false;
- $interface = false;
- for ($i = 0; $i < sizeof($tokens); $i++) {
- if (is_array($tokens[$i])) {
- list($token, $data) = $tokens[$i];
- } else {
- $token = $tokens[$i];
- $data = '';
- }
- if ($inquote) {
- if ($token != '"' && $token != T_END_HEREDOC) {
- continue;
- } else {
- $inquote = false;
- continue;
- }
- }
- switch ($token) {
- case T_WHITESPACE :
- continue;
- case ';':
- if ($interface) {
- $current_function = '';
- $current_function_level = -1;
- }
- break;
- case '"':
- case T_START_HEREDOC:
- $inquote = true;
- break;
- case T_CURLY_OPEN:
- case T_DOLLAR_OPEN_CURLY_BRACES:
- case '{': $brace_level++; continue 2;
- case '}':
- $brace_level--;
- if ($current_class_level == $brace_level) {
- $current_class = '';
- $current_class_level = -1;
- }
- if ($current_function_level == $brace_level) {
- $current_function = '';
- $current_function_level = -1;
- }
- continue 2;
- case '[': $bracket_level++; continue 2;
- case ']': $bracket_level--; continue 2;
- case '(': $paren_level++; continue 2;
- case ')': $paren_level--; continue 2;
- case T_INTERFACE:
- $interface = true;
- case T_CLASS:
- if (($current_class_level != -1) || ($current_function_level != -1)) {
- $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_PHPFILE,
- array('file' => $file));
- return false;
- }
- case T_FUNCTION:
- case T_NEW:
- case T_EXTENDS:
- case T_IMPLEMENTS:
- $look_for = $token;
- continue 2;
- case T_STRING:
- if (version_compare(zend_version(), '2.0', '<')) {
- if (in_array(strtolower($data),
- array('public', 'private', 'protected', 'abstract',
- 'interface', 'implements', 'throw')
- )) {
- $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_PHP5,
- array($file));
- }
- }
- if ($look_for == T_CLASS) {
- $current_class = $data;
- $current_class_level = $brace_level;
- $declared_classes[] = $current_class;
- } elseif ($look_for == T_INTERFACE) {
- $current_interface = $data;
- $current_class_level = $brace_level;
- $declared_interfaces[] = $current_interface;
- } elseif ($look_for == T_IMPLEMENTS) {
- $implements[$current_class] = $data;
- } elseif ($look_for == T_EXTENDS) {
- $extends[$current_class] = $data;
- } elseif ($look_for == T_FUNCTION) {
- if ($current_class) {
- $current_function = "$current_class::$data";
- $declared_methods[$current_class][] = $data;
- } elseif ($current_interface) {
- $current_function = "$current_interface::$data";
- $declared_methods[$current_interface][] = $data;
- } else {
- $current_function = $data;
- $declared_functions[] = $current_function;
- }
- $current_function_level = $brace_level;
- $m = array();
- } elseif ($look_for == T_NEW) {
- $used_classes[$data] = true;
- }
- $look_for = 0;
- continue 2;
- case T_VARIABLE:
- $look_for = 0;
- continue 2;
- case T_DOC_COMMENT:
- case T_COMMENT:
- if (preg_match('!^/\*\*\s!', $data)) {
- $lastphpdoc = $data;
- if (preg_match_all('/@nodep\s+(\S+)/', $lastphpdoc, $m)) {
- $nodeps = array_merge($nodeps, $m[1]);
- }
- }
- continue 2;
- case T_DOUBLE_COLON:
- if (!($tokens[$i - 1][0] == T_WHITESPACE || $tokens[$i - 1][0] == T_STRING)) {
- $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_PHPFILE,
- array('file' => $file));
- return false;
- }
- $class = $tokens[$i - 1][1];
- if (strtolower($class) != 'parent') {
- $used_classes[$class] = true;
- }
- continue 2;
- }
- }
- return array(
- "source_file" => $file,
- "declared_classes" => $declared_classes,
- "declared_interfaces" => $declared_interfaces,
- "declared_methods" => $declared_methods,
- "declared_functions" => $declared_functions,
- "used_classes" => array_diff(array_keys($used_classes), $nodeps),
- "inheritance" => $extends,
- "implements" => $implements,
- );
- }
-
- /**
- * Build a "provides" array from data returned by
- * analyzeSourceCode(). The format of the built array is like
- * this:
- *
- * array(
- * 'class;MyClass' => 'array('type' => 'class', 'name' => 'MyClass'),
- * ...
- * )
- *
- *
- * @param array $srcinfo array with information about a source file
- * as returned by the analyzeSourceCode() method.
- *
- * @return void
- *
- * @access private
- *
- */
- function _buildProvidesArray($srcinfo)
- {
- if (!$this->_isValid) {
- return false;
- }
- $file = basename($srcinfo['source_file']);
- $pn = $this->getPackage();
- $pnl = strlen($pn);
- foreach ($srcinfo['declared_classes'] as $class) {
- $key = "class;$class";
- if (isset($this->_packageInfo['provides'][$key])) {
- continue;
- }
- $this->_packageInfo['provides'][$key] =
- array('file'=> $file, 'type' => 'class', 'name' => $class);
- if (isset($srcinfo['inheritance'][$class])) {
- $this->_packageInfo['provides'][$key]['extends'] =
- $srcinfo['inheritance'][$class];
- }
- }
- foreach ($srcinfo['declared_methods'] as $class => $methods) {
- foreach ($methods as $method) {
- $function = "$class::$method";
- $key = "function;$function";
- if ($method{0} == '_' || !strcasecmp($method, $class) ||
- isset($this->_packageInfo['provides'][$key])) {
- continue;
- }
- $this->_packageInfo['provides'][$key] =
- array('file'=> $file, 'type' => 'function', 'name' => $function);
- }
- }
-
- foreach ($srcinfo['declared_functions'] as $function) {
- $key = "function;$function";
- if ($function{0} == '_' || isset($this->_packageInfo['provides'][$key])) {
- continue;
- }
- if (!strstr($function, '::') && strncasecmp($function, $pn, $pnl)) {
- $warnings[] = "in1 " . $file . ": function \"$function\" not prefixed with package name \"$pn\"";
- }
- $this->_packageInfo['provides'][$key] =
- array('file'=> $file, 'type' => 'function', 'name' => $function);
- }
- }
-
- // }}}
-}
-?>
+}<?php +/** + * PEAR_PackageFile_v1, package.xml version 1.0 + * + * PHP versions 4 and 5 + * + * @category pear + * @package PEAR + * @author Greg Beaver <cellog@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: v1.php 276383 2009-02-24 23:39:37Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ +/** + * For error handling + */ +require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/ErrorStack.php'; + +/** + * Error code if parsing is attempted with no xml extension + */ +define('PEAR_PACKAGEFILE_ERROR_NO_XML_EXT', 3); + +/** + * Error code if creating the xml parser resource fails + */ +define('PEAR_PACKAGEFILE_ERROR_CANT_MAKE_PARSER', 4); + +/** + * Error code used for all sax xml parsing errors + */ +define('PEAR_PACKAGEFILE_ERROR_PARSER_ERROR', 5); + +/** + * Error code used when there is no name + */ +define('PEAR_PACKAGEFILE_ERROR_NO_NAME', 6); + +/** + * Error code when a package name is not valid + */ +define('PEAR_PACKAGEFILE_ERROR_INVALID_NAME', 7); + +/** + * Error code used when no summary is parsed + */ +define('PEAR_PACKAGEFILE_ERROR_NO_SUMMARY', 8); + +/** + * Error code for summaries that are more than 1 line + */ +define('PEAR_PACKAGEFILE_ERROR_MULTILINE_SUMMARY', 9); + +/** + * Error code used when no description is present + */ +define('PEAR_PACKAGEFILE_ERROR_NO_DESCRIPTION', 10); + +/** + * Error code used when no license is present + */ +define('PEAR_PACKAGEFILE_ERROR_NO_LICENSE', 11); + +/** + * Error code used when a <version> version number is not present + */ +define('PEAR_PACKAGEFILE_ERROR_NO_VERSION', 12); + +/** + * Error code used when a <version> version number is invalid + */ +define('PEAR_PACKAGEFILE_ERROR_INVALID_VERSION', 13); + +/** + * Error code when release state is missing + */ +define('PEAR_PACKAGEFILE_ERROR_NO_STATE', 14); + +/** + * Error code when release state is invalid + */ +define('PEAR_PACKAGEFILE_ERROR_INVALID_STATE', 15); + +/** + * Error code when release state is missing + */ +define('PEAR_PACKAGEFILE_ERROR_NO_DATE', 16); + +/** + * Error code when release state is invalid + */ +define('PEAR_PACKAGEFILE_ERROR_INVALID_DATE', 17); + +/** + * Error code when no release notes are found + */ +define('PEAR_PACKAGEFILE_ERROR_NO_NOTES', 18); + +/** + * Error code when no maintainers are found + */ +define('PEAR_PACKAGEFILE_ERROR_NO_MAINTAINERS', 19); + +/** + * Error code when a maintainer has no handle + */ +define('PEAR_PACKAGEFILE_ERROR_NO_MAINTHANDLE', 20); + +/** + * Error code when a maintainer has no handle + */ +define('PEAR_PACKAGEFILE_ERROR_NO_MAINTROLE', 21); + +/** + * Error code when a maintainer has no name + */ +define('PEAR_PACKAGEFILE_ERROR_NO_MAINTNAME', 22); + +/** + * Error code when a maintainer has no email + */ +define('PEAR_PACKAGEFILE_ERROR_NO_MAINTEMAIL', 23); + +/** + * Error code when a maintainer has no handle + */ +define('PEAR_PACKAGEFILE_ERROR_INVALID_MAINTROLE', 24); + +/** + * Error code when a dependency is not a PHP dependency, but has no name + */ +define('PEAR_PACKAGEFILE_ERROR_NO_DEPNAME', 25); + +/** + * Error code when a dependency has no type (pkg, php, etc.) + */ +define('PEAR_PACKAGEFILE_ERROR_NO_DEPTYPE', 26); + +/** + * Error code when a dependency has no relation (lt, ge, has, etc.) + */ +define('PEAR_PACKAGEFILE_ERROR_NO_DEPREL', 27); + +/** + * Error code when a dependency is not a 'has' relation, but has no version + */ +define('PEAR_PACKAGEFILE_ERROR_NO_DEPVERSION', 28); + +/** + * Error code when a dependency has an invalid relation + */ +define('PEAR_PACKAGEFILE_ERROR_INVALID_DEPREL', 29); + +/** + * Error code when a dependency has an invalid type + */ +define('PEAR_PACKAGEFILE_ERROR_INVALID_DEPTYPE', 30); + +/** + * Error code when a dependency has an invalid optional option + */ +define('PEAR_PACKAGEFILE_ERROR_INVALID_DEPOPTIONAL', 31); + +/** + * Error code when a dependency is a pkg dependency, and has an invalid package name + */ +define('PEAR_PACKAGEFILE_ERROR_INVALID_DEPNAME', 32); + +/** + * Error code when a dependency has a channel="foo" attribute, and foo is not a registered channel + */ +define('PEAR_PACKAGEFILE_ERROR_UNKNOWN_DEPCHANNEL', 33); + +/** + * Error code when rel="has" and version attribute is present. + */ +define('PEAR_PACKAGEFILE_ERROR_DEPVERSION_IGNORED', 34); + +/** + * Error code when type="php" and dependency name is present + */ +define('PEAR_PACKAGEFILE_ERROR_DEPNAME_IGNORED', 35); + +/** + * Error code when a configure option has no name + */ +define('PEAR_PACKAGEFILE_ERROR_NO_CONFNAME', 36); + +/** + * Error code when a configure option has no name + */ +define('PEAR_PACKAGEFILE_ERROR_NO_CONFPROMPT', 37); + +/** + * Error code when a file in the filelist has an invalid role + */ +define('PEAR_PACKAGEFILE_ERROR_INVALID_FILEROLE', 38); + +/** + * Error code when a file in the filelist has no role + */ +define('PEAR_PACKAGEFILE_ERROR_NO_FILEROLE', 39); + +/** + * Error code when analyzing a php source file that has parse errors + */ +define('PEAR_PACKAGEFILE_ERROR_INVALID_PHPFILE', 40); + +/** + * Error code when analyzing a php source file reveals a source element + * without a package name prefix + */ +define('PEAR_PACKAGEFILE_ERROR_NO_PNAME_PREFIX', 41); + +/** + * Error code when an unknown channel is specified + */ +define('PEAR_PACKAGEFILE_ERROR_UNKNOWN_CHANNEL', 42); + +/** + * Error code when no files are found in the filelist + */ +define('PEAR_PACKAGEFILE_ERROR_NO_FILES', 43); + +/** + * Error code when a file is not valid php according to _analyzeSourceCode() + */ +define('PEAR_PACKAGEFILE_ERROR_INVALID_FILE', 44); + +/** + * Error code when the channel validator returns an error or warning + */ +define('PEAR_PACKAGEFILE_ERROR_CHANNELVAL', 45); + +/** + * Error code when a php5 package is packaged in php4 (analysis doesn't work) + */ +define('PEAR_PACKAGEFILE_ERROR_PHP5', 46); + +/** + * Error code when a file is listed in package.xml but does not exist + */ +define('PEAR_PACKAGEFILE_ERROR_FILE_NOTFOUND', 47); + +/** + * Error code when a <dep type="php" rel="not"... is encountered (use rel="ne") + */ +define('PEAR_PACKAGEFILE_PHP_NO_NOT', 48); + +/** + * Error code when a package.xml contains non-ISO-8859-1 characters + */ +define('PEAR_PACKAGEFILE_ERROR_NON_ISO_CHARS', 49); + +/** + * Error code when a dependency is not a 'has' relation, but has no version + */ +define('PEAR_PACKAGEFILE_ERROR_NO_DEPPHPVERSION', 50); + +/** + * Error code when a package has no lead developer + */ +define('PEAR_PACKAGEFILE_ERROR_NO_LEAD', 51); + +/** + * Error code when a filename begins with "." + */ +define('PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME', 52); +/** + * package.xml encapsulator + * @category pear + * @package PEAR + * @author Greg Beaver <cellog@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_PackageFile_v1 +{ + /** + * @access private + * @var PEAR_ErrorStack + * @access private + */ + var $_stack; + + /** + * A registry object, used to access the package name validation regex for non-standard channels + * @var PEAR_Registry + * @access private + */ + var $_registry; + + /** + * An object that contains a log method that matches PEAR_Common::log's signature + * @var object + * @access private + */ + var $_logger; + + /** + * Parsed package information + * @var array + * @access private + */ + var $_packageInfo; + + /** + * path to package.xml + * @var string + * @access private + */ + var $_packageFile; + + /** + * path to package .tgz or false if this is a local/extracted package.xml + * @var string + * @access private + */ + var $_archiveFile; + + /** + * @var int + * @access private + */ + var $_isValid = 0; + + /** + * Determines whether this packagefile was initialized only with partial package info + * + * If this package file was constructed via parsing REST, it will only contain + * + * - package name + * - channel name + * - dependencies + * @var boolean + * @access private + */ + var $_incomplete = true; + + /** + * @param bool determines whether to return a PEAR_Error object, or use the PEAR_ErrorStack + * @param string Name of Error Stack class to use. + */ + function PEAR_PackageFile_v1() + { + $this->_stack = &new PEAR_ErrorStack('PEAR_PackageFile_v1'); + $this->_stack->setErrorMessageTemplate($this->_getErrorMessage()); + $this->_isValid = 0; + } + + function installBinary($installer) + { + return false; + } + + function isExtension($name) + { + return false; + } + + function setConfig(&$config) + { + $this->_config = &$config; + $this->_registry = &$config->getRegistry(); + } + + function setRequestedGroup() + { + // placeholder + } + + /** + * For saving in the registry. + * + * Set the last version that was installed + * @param string + */ + function setLastInstalledVersion($version) + { + $this->_packageInfo['_lastversion'] = $version; + } + + /** + * @return string|false + */ + function getLastInstalledVersion() + { + if (isset($this->_packageInfo['_lastversion'])) { + return $this->_packageInfo['_lastversion']; + } + return false; + } + + function getInstalledBinary() + { + return false; + } + + function listPostinstallScripts() + { + return false; + } + + function initPostinstallScripts() + { + return false; + } + + function setLogger(&$logger) + { + if ($logger && (!is_object($logger) || !method_exists($logger, 'log'))) { + return PEAR::raiseError('Logger must be compatible with PEAR_Common::log'); + } + $this->_logger = &$logger; + } + + function setPackagefile($file, $archive = false) + { + $this->_packageFile = $file; + $this->_archiveFile = $archive ? $archive : $file; + } + + function getPackageFile() + { + return isset($this->_packageFile) ? $this->_packageFile : false; + } + + function getPackageType() + { + return 'php'; + } + + function getArchiveFile() + { + return $this->_archiveFile; + } + + function packageInfo($field) + { + if (!is_string($field) || empty($field) || + !isset($this->_packageInfo[$field])) { + return false; + } + return $this->_packageInfo[$field]; + } + + function setDirtree($path) + { + if (!isset($this->_packageInfo['dirtree'])) { + $this->_packageInfo['dirtree'] = array(); + } + $this->_packageInfo['dirtree'][$path] = true; + } + + function getDirtree() + { + if (isset($this->_packageInfo['dirtree']) && count($this->_packageInfo['dirtree'])) { + return $this->_packageInfo['dirtree']; + } + return false; + } + + function resetDirtree() + { + unset($this->_packageInfo['dirtree']); + } + + function fromArray($pinfo) + { + $this->_incomplete = false; + $this->_packageInfo = $pinfo; + } + + function isIncomplete() + { + return $this->_incomplete; + } + + function getChannel() + { + return 'pear.php.net'; + } + + function getUri() + { + return false; + } + + function getTime() + { + return false; + } + + function getExtends() + { + if (isset($this->_packageInfo['extends'])) { + return $this->_packageInfo['extends']; + } + return false; + } + + /** + * @return array + */ + function toArray() + { + if (!$this->validate(PEAR_VALIDATE_NORMAL)) { + return false; + } + return $this->getArray(); + } + + function getArray() + { + return $this->_packageInfo; + } + + function getName() + { + return $this->getPackage(); + } + + function getPackage() + { + if (isset($this->_packageInfo['package'])) { + return $this->_packageInfo['package']; + } + return false; + } + + /** + * WARNING - don't use this unless you know what you are doing + */ + function setRawPackage($package) + { + $this->_packageInfo['package'] = $package; + } + + function setPackage($package) + { + $this->_packageInfo['package'] = $package; + $this->_isValid = false; + } + + function getVersion() + { + if (isset($this->_packageInfo['version'])) { + return $this->_packageInfo['version']; + } + return false; + } + + function setVersion($version) + { + $this->_packageInfo['version'] = $version; + $this->_isValid = false; + } + + function clearMaintainers() + { + unset($this->_packageInfo['maintainers']); + } + + function getMaintainers() + { + if (isset($this->_packageInfo['maintainers'])) { + return $this->_packageInfo['maintainers']; + } + return false; + } + + /** + * Adds a new maintainer - no checking of duplicates is performed, use + * updatemaintainer for that purpose. + */ + function addMaintainer($role, $handle, $name, $email) + { + $this->_packageInfo['maintainers'][] = + array('handle' => $handle, 'role' => $role, 'email' => $email, 'name' => $name); + $this->_isValid = false; + } + + function updateMaintainer($role, $handle, $name, $email) + { + $found = false; + if (!isset($this->_packageInfo['maintainers']) || + !is_array($this->_packageInfo['maintainers'])) { + return $this->addMaintainer($role, $handle, $name, $email); + } + foreach ($this->_packageInfo['maintainers'] as $i => $maintainer) { + if ($maintainer['handle'] == $handle) { + $found = $i; + break; + } + } + if ($found !== false) { + unset($this->_packageInfo['maintainers'][$found]); + $this->_packageInfo['maintainers'] = + array_values($this->_packageInfo['maintainers']); + } + $this->addMaintainer($role, $handle, $name, $email); + } + + function deleteMaintainer($handle) + { + $found = false; + foreach ($this->_packageInfo['maintainers'] as $i => $maintainer) { + if ($maintainer['handle'] == $handle) { + $found = $i; + break; + } + } + if ($found !== false) { + unset($this->_packageInfo['maintainers'][$found]); + $this->_packageInfo['maintainers'] = + array_values($this->_packageInfo['maintainers']); + return true; + } + return false; + } + + function getState() + { + if (isset($this->_packageInfo['release_state'])) { + return $this->_packageInfo['release_state']; + } + return false; + } + + function setRawState($state) + { + $this->_packageInfo['release_state'] = $state; + } + + function setState($state) + { + $this->_packageInfo['release_state'] = $state; + $this->_isValid = false; + } + + function getDate() + { + if (isset($this->_packageInfo['release_date'])) { + return $this->_packageInfo['release_date']; + } + return false; + } + + function setDate($date) + { + $this->_packageInfo['release_date'] = $date; + $this->_isValid = false; + } + + function getLicense() + { + if (isset($this->_packageInfo['release_license'])) { + return $this->_packageInfo['release_license']; + } + return false; + } + + function setLicense($date) + { + $this->_packageInfo['release_license'] = $date; + $this->_isValid = false; + } + + function getSummary() + { + if (isset($this->_packageInfo['summary'])) { + return $this->_packageInfo['summary']; + } + return false; + } + + function setSummary($summary) + { + $this->_packageInfo['summary'] = $summary; + $this->_isValid = false; + } + + function getDescription() + { + if (isset($this->_packageInfo['description'])) { + return $this->_packageInfo['description']; + } + return false; + } + + function setDescription($desc) + { + $this->_packageInfo['description'] = $desc; + $this->_isValid = false; + } + + function getNotes() + { + if (isset($this->_packageInfo['release_notes'])) { + return $this->_packageInfo['release_notes']; + } + return false; + } + + function setNotes($notes) + { + $this->_packageInfo['release_notes'] = $notes; + $this->_isValid = false; + } + + function getDeps() + { + if (isset($this->_packageInfo['release_deps'])) { + return $this->_packageInfo['release_deps']; + } + return false; + } + + /** + * Reset dependencies prior to adding new ones + */ + function clearDeps() + { + unset($this->_packageInfo['release_deps']); + } + + function addPhpDep($version, $rel) + { + $this->_isValid = false; + $this->_packageInfo['release_deps'][] = + array('type' => 'php', + 'rel' => $rel, + 'version' => $version); + } + + function addPackageDep($name, $version, $rel, $optional = 'no') + { + $this->_isValid = false; + $dep = + array('type' => 'pkg', + 'name' => $name, + 'rel' => $rel, + 'optional' => $optional); + if ($rel != 'has' && $rel != 'not') { + $dep['version'] = $version; + } + $this->_packageInfo['release_deps'][] = $dep; + } + + function addExtensionDep($name, $version, $rel, $optional = 'no') + { + $this->_isValid = false; + $this->_packageInfo['release_deps'][] = + array('type' => 'ext', + 'name' => $name, + 'rel' => $rel, + 'version' => $version, + 'optional' => $optional); + } + + /** + * WARNING - do not use this function directly unless you know what you're doing + */ + function setDeps($deps) + { + $this->_packageInfo['release_deps'] = $deps; + } + + function hasDeps() + { + return isset($this->_packageInfo['release_deps']) && + count($this->_packageInfo['release_deps']); + } + + function getDependencyGroup($group) + { + return false; + } + + function isCompatible($pf) + { + return false; + } + + function isSubpackageOf($p) + { + return $p->isSubpackage($this); + } + + function isSubpackage($p) + { + return false; + } + + function dependsOn($package, $channel) + { + if (strtolower($channel) != 'pear.php.net') { + return false; + } + if (!($deps = $this->getDeps())) { + return false; + } + foreach ($deps as $dep) { + if ($dep['type'] != 'pkg') { + continue; + } + if (strtolower($dep['name']) == strtolower($package)) { + return true; + } + } + return false; + } + + function getConfigureOptions() + { + if (isset($this->_packageInfo['configure_options'])) { + return $this->_packageInfo['configure_options']; + } + return false; + } + + function hasConfigureOptions() + { + return isset($this->_packageInfo['configure_options']) && + count($this->_packageInfo['configure_options']); + } + + function addConfigureOption($name, $prompt, $default = false) + { + $o = array('name' => $name, 'prompt' => $prompt); + if ($default !== false) { + $o['default'] = $default; + } + if (!isset($this->_packageInfo['configure_options'])) { + $this->_packageInfo['configure_options'] = array(); + } + $this->_packageInfo['configure_options'][] = $o; + } + + function clearConfigureOptions() + { + unset($this->_packageInfo['configure_options']); + } + + function getProvides() + { + if (isset($this->_packageInfo['provides'])) { + return $this->_packageInfo['provides']; + } + return false; + } + + function getProvidesExtension() + { + return false; + } + + function addFile($dir, $file, $attrs) + { + $dir = preg_replace(array('!\\\\+!', '!/+!'), array('/', '/'), $dir); + if ($dir == '/' || $dir == '') { + $dir = ''; + } else { + $dir .= '/'; + } + $file = $dir . $file; + $file = preg_replace('![\\/]+!', '/', $file); + $this->_packageInfo['filelist'][$file] = $attrs; + } + + function getInstallationFilelist() + { + return $this->getFilelist(); + } + + function getFilelist() + { + if (isset($this->_packageInfo['filelist'])) { + return $this->_packageInfo['filelist']; + } + return false; + } + + function setFileAttribute($file, $attr, $value) + { + $this->_packageInfo['filelist'][$file][$attr] = $value; + } + + function resetFilelist() + { + $this->_packageInfo['filelist'] = array(); + } + + function setInstalledAs($file, $path) + { + if ($path) { + return $this->_packageInfo['filelist'][$file]['installed_as'] = $path; + } + unset($this->_packageInfo['filelist'][$file]['installed_as']); + } + + function installedFile($file, $atts) + { + if (isset($this->_packageInfo['filelist'][$file])) { + $this->_packageInfo['filelist'][$file] = + array_merge($this->_packageInfo['filelist'][$file], $atts); + } else { + $this->_packageInfo['filelist'][$file] = $atts; + } + } + + function getChangelog() + { + if (isset($this->_packageInfo['changelog'])) { + return $this->_packageInfo['changelog']; + } + return false; + } + + function getPackagexmlVersion() + { + return '1.0'; + } + + /** + * Wrapper to {@link PEAR_ErrorStack::getErrors()} + * @param boolean determines whether to purge the error stack after retrieving + * @return array + */ + function getValidationWarnings($purge = true) + { + return $this->_stack->getErrors($purge); + } + + // }}} + /** + * Validation error. Also marks the object contents as invalid + * @param error code + * @param array error information + * @access private + */ + function _validateError($code, $params = array()) + { + $this->_stack->push($code, 'error', $params, false, false, debug_backtrace()); + $this->_isValid = false; + } + + /** + * Validation warning. Does not mark the object contents invalid. + * @param error code + * @param array error information + * @access private + */ + function _validateWarning($code, $params = array()) + { + $this->_stack->push($code, 'warning', $params, false, false, debug_backtrace()); + } + + /** + * @param integer error code + * @access protected + */ + function _getErrorMessage() + { + return array( + PEAR_PACKAGEFILE_ERROR_NO_NAME => + 'Missing Package Name', + PEAR_PACKAGEFILE_ERROR_NO_SUMMARY => + 'No summary found', + PEAR_PACKAGEFILE_ERROR_MULTILINE_SUMMARY => + 'Summary should be on one line', + PEAR_PACKAGEFILE_ERROR_NO_DESCRIPTION => + 'Missing description', + PEAR_PACKAGEFILE_ERROR_NO_LICENSE => + 'Missing license', + PEAR_PACKAGEFILE_ERROR_NO_VERSION => + 'No release version found', + PEAR_PACKAGEFILE_ERROR_NO_STATE => + 'No release state found', + PEAR_PACKAGEFILE_ERROR_NO_DATE => + 'No release date found', + PEAR_PACKAGEFILE_ERROR_NO_NOTES => + 'No release notes found', + PEAR_PACKAGEFILE_ERROR_NO_LEAD => + 'Package must have at least one lead maintainer', + PEAR_PACKAGEFILE_ERROR_NO_MAINTAINERS => + 'No maintainers found, at least one must be defined', + PEAR_PACKAGEFILE_ERROR_NO_MAINTHANDLE => + 'Maintainer %index% has no handle (user ID at channel server)', + PEAR_PACKAGEFILE_ERROR_NO_MAINTROLE => + 'Maintainer %index% has no role', + PEAR_PACKAGEFILE_ERROR_NO_MAINTNAME => + 'Maintainer %index% has no name', + PEAR_PACKAGEFILE_ERROR_NO_MAINTEMAIL => + 'Maintainer %index% has no email', + PEAR_PACKAGEFILE_ERROR_NO_DEPNAME => + 'Dependency %index% is not a php dependency, and has no name', + PEAR_PACKAGEFILE_ERROR_NO_DEPREL => + 'Dependency %index% has no relation (rel)', + PEAR_PACKAGEFILE_ERROR_NO_DEPTYPE => + 'Dependency %index% has no type', + PEAR_PACKAGEFILE_ERROR_DEPNAME_IGNORED => + 'PHP Dependency %index% has a name attribute of "%name%" which will be' . + ' ignored!', + PEAR_PACKAGEFILE_ERROR_NO_DEPVERSION => + 'Dependency %index% is not a rel="has" or rel="not" dependency, ' . + 'and has no version', + PEAR_PACKAGEFILE_ERROR_NO_DEPPHPVERSION => + 'Dependency %index% is a type="php" dependency, ' . + 'and has no version', + PEAR_PACKAGEFILE_ERROR_DEPVERSION_IGNORED => + 'Dependency %index% is a rel="%rel%" dependency, versioning is ignored', + PEAR_PACKAGEFILE_ERROR_INVALID_DEPOPTIONAL => + 'Dependency %index% has invalid optional value "%opt%", should be yes or no', + PEAR_PACKAGEFILE_PHP_NO_NOT => + 'Dependency %index%: php dependencies cannot use "not" rel, use "ne"' . + ' to exclude specific versions', + PEAR_PACKAGEFILE_ERROR_NO_CONFNAME => + 'Configure Option %index% has no name', + PEAR_PACKAGEFILE_ERROR_NO_CONFPROMPT => + 'Configure Option %index% has no prompt', + PEAR_PACKAGEFILE_ERROR_NO_FILES => + 'No files in <filelist> section of package.xml', + PEAR_PACKAGEFILE_ERROR_NO_FILEROLE => + 'File "%file%" has no role, expecting one of "%roles%"', + PEAR_PACKAGEFILE_ERROR_INVALID_FILEROLE => + 'File "%file%" has invalid role "%role%", expecting one of "%roles%"', + PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME => + 'File "%file%" cannot start with ".", cannot package or install', + PEAR_PACKAGEFILE_ERROR_INVALID_PHPFILE => + 'Parser error: invalid PHP found in file "%file%"', + PEAR_PACKAGEFILE_ERROR_NO_PNAME_PREFIX => + 'in %file%: %type% "%name%" not prefixed with package name "%package%"', + PEAR_PACKAGEFILE_ERROR_INVALID_FILE => + 'Parser error: invalid PHP file "%file%"', + PEAR_PACKAGEFILE_ERROR_CHANNELVAL => + 'Channel validator error: field "%field%" - %reason%', + PEAR_PACKAGEFILE_ERROR_PHP5 => + 'Error, PHP5 token encountered in %file%, analysis should be in PHP5', + PEAR_PACKAGEFILE_ERROR_FILE_NOTFOUND => + 'File "%file%" in package.xml does not exist', + PEAR_PACKAGEFILE_ERROR_NON_ISO_CHARS => + 'Package.xml contains non-ISO-8859-1 characters, and may not validate', + ); + } + + /** + * Validate XML package definition file. + * + * @access public + * @return boolean + */ + function validate($state = PEAR_VALIDATE_NORMAL, $nofilechecking = false) + { + if (($this->_isValid & $state) == $state) { + return true; + } + $this->_isValid = true; + $info = $this->_packageInfo; + if (empty($info['package'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_NAME); + $this->_packageName = $pn = 'unknown'; + } else { + $this->_packageName = $pn = $info['package']; + } + + if (empty($info['summary'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_SUMMARY); + } elseif (strpos(trim($info['summary']), "\n") !== false) { + $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_MULTILINE_SUMMARY, + array('summary' => $info['summary'])); + } + if (empty($info['description'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DESCRIPTION); + } + if (empty($info['release_license'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_LICENSE); + } + if (empty($info['version'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_VERSION); + } + if (empty($info['release_state'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_STATE); + } + if (empty($info['release_date'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DATE); + } + if (empty($info['release_notes'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_NOTES); + } + if (empty($info['maintainers'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTAINERS); + } else { + $haslead = false; + $i = 1; + foreach ($info['maintainers'] as $m) { + if (empty($m['handle'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTHANDLE, + array('index' => $i)); + } + if (empty($m['role'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTROLE, + array('index' => $i, 'roles' => PEAR_Common::getUserRoles())); + } elseif ($m['role'] == 'lead') { + $haslead = true; + } + if (empty($m['name'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTNAME, + array('index' => $i)); + } + if (empty($m['email'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTEMAIL, + array('index' => $i)); + } + $i++; + } + if (!$haslead) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_LEAD); + } + } + if (!empty($info['release_deps'])) { + $i = 1; + foreach ($info['release_deps'] as $d) { + if (!isset($d['type']) || empty($d['type'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPTYPE, + array('index' => $i, 'types' => PEAR_Common::getDependencyTypes())); + continue; + } + if (!isset($d['rel']) || empty($d['rel'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPREL, + array('index' => $i, 'rels' => PEAR_Common::getDependencyRelations())); + continue; + } + if (!empty($d['optional'])) { + if (!in_array($d['optional'], array('yes', 'no'))) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_DEPOPTIONAL, + array('index' => $i, 'opt' => $d['optional'])); + } + } + if ($d['rel'] != 'has' && $d['rel'] != 'not' && empty($d['version'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPVERSION, + array('index' => $i)); + } elseif (($d['rel'] == 'has' || $d['rel'] == 'not') && !empty($d['version'])) { + $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_DEPVERSION_IGNORED, + array('index' => $i, 'rel' => $d['rel'])); + } + if ($d['type'] == 'php' && !empty($d['name'])) { + $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_DEPNAME_IGNORED, + array('index' => $i, 'name' => $d['name'])); + } elseif ($d['type'] != 'php' && empty($d['name'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPNAME, + array('index' => $i)); + } + if ($d['type'] == 'php' && empty($d['version'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPPHPVERSION, + array('index' => $i)); + } + if (($d['rel'] == 'not') && ($d['type'] == 'php')) { + $this->_validateError(PEAR_PACKAGEFILE_PHP_NO_NOT, + array('index' => $i)); + } + $i++; + } + } + if (!empty($info['configure_options'])) { + $i = 1; + foreach ($info['configure_options'] as $c) { + if (empty($c['name'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_CONFNAME, + array('index' => $i)); + } + if (empty($c['prompt'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_CONFPROMPT, + array('index' => $i)); + } + $i++; + } + } + if (empty($info['filelist'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_FILES); + $errors[] = 'no files'; + } else { + foreach ($info['filelist'] as $file => $fa) { + if (empty($fa['role'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_FILEROLE, + array('file' => $file, 'roles' => PEAR_Common::getFileRoles())); + continue; + } elseif (!in_array($fa['role'], PEAR_Common::getFileRoles())) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_FILEROLE, + array('file' => $file, 'role' => $fa['role'], 'roles' => PEAR_Common::getFileRoles())); + } + if (preg_match('~/\.\.?(/|\\z)|^\.\.?/~', str_replace('\\', '/', $file))) { + // file contains .. parent directory or . cur directory references + $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME, + array('file' => $file)); + } + if (isset($fa['install-as']) && + preg_match('~/\.\.?(/|\\z)|^\.\.?/~', + str_replace('\\', '/', $fa['install-as']))) { + // install-as contains .. parent directory or . cur directory references + $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME, + array('file' => $file . ' [installed as ' . $fa['install-as'] . ']')); + } + if (isset($fa['baseinstalldir']) && + preg_match('~/\.\.?(/|\\z)|^\.\.?/~', + str_replace('\\', '/', $fa['baseinstalldir']))) { + // install-as contains .. parent directory or . cur directory references + $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME, + array('file' => $file . ' [baseinstalldir ' . $fa['baseinstalldir'] . ']')); + } + } + } + if (isset($this->_registry) && $this->_isValid) { + $chan = $this->_registry->getChannel('pear.php.net'); + if (PEAR::isError($chan)) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_CHANNELVAL, $chan->getMessage()); + return $this->_isValid = 0; + } + $validator = $chan->getValidationObject(); + $validator->setPackageFile($this); + $validator->validate($state); + $failures = $validator->getFailures(); + foreach ($failures['errors'] as $error) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_CHANNELVAL, $error); + } + foreach ($failures['warnings'] as $warning) { + $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_CHANNELVAL, $warning); + } + } + if ($this->_isValid && $state == PEAR_VALIDATE_PACKAGING && !$nofilechecking) { + if ($this->_analyzePhpFiles()) { + $this->_isValid = true; + } + } + if ($this->_isValid) { + return $this->_isValid = $state; + } + return $this->_isValid = 0; + } + + function _analyzePhpFiles() + { + if (!$this->_isValid) { + return false; + } + if (!isset($this->_packageFile)) { + return false; + } + $dir_prefix = dirname($this->_packageFile); + $common = new PEAR_Common; + $log = isset($this->_logger) ? array(&$this->_logger, 'log') : + array($common, 'log'); + $info = $this->getFilelist(); + foreach ($info as $file => $fa) { + if (!file_exists($dir_prefix . DIRECTORY_SEPARATOR . $file)) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_FILE_NOTFOUND, + array('file' => realpath($dir_prefix) . DIRECTORY_SEPARATOR . $file)); + continue; + } + if ($fa['role'] == 'php' && $dir_prefix) { + call_user_func_array($log, array(1, "Analyzing $file")); + $srcinfo = $this->_analyzeSourceCode($dir_prefix . DIRECTORY_SEPARATOR . $file); + if ($srcinfo) { + $this->_buildProvidesArray($srcinfo); + } + } + } + $this->_packageName = $pn = $this->getPackage(); + $pnl = strlen($pn); + if (isset($this->_packageInfo['provides'])) { + foreach ((array) $this->_packageInfo['provides'] as $key => $what) { + if (isset($what['explicit'])) { + // skip conformance checks if the provides entry is + // specified in the package.xml file + continue; + } + extract($what); + if ($type == 'class') { + if (!strncasecmp($name, $pn, $pnl)) { + continue; + } + $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_NO_PNAME_PREFIX, + array('file' => $file, 'type' => $type, 'name' => $name, 'package' => $pn)); + } elseif ($type == 'function') { + if (strstr($name, '::') || !strncasecmp($name, $pn, $pnl)) { + continue; + } + $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_NO_PNAME_PREFIX, + array('file' => $file, 'type' => $type, 'name' => $name, 'package' => $pn)); + } + } + } + return $this->_isValid; + } + + /** + * Get the default xml generator object + * + * @return PEAR_PackageFile_Generator_v1 + */ + function &getDefaultGenerator() + { + if (!class_exists('PEAR_PackageFile_Generator_v1')) { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/PackageFile/Generator/v1.php'; + } + $a = &new PEAR_PackageFile_Generator_v1($this); + return $a; + } + + /** + * Get the contents of a file listed within the package.xml + * @param string + * @return string + */ + function getFileContents($file) + { + if ($this->_archiveFile == $this->_packageFile) { // unpacked + $dir = dirname($this->_packageFile); + $file = $dir . DIRECTORY_SEPARATOR . $file; + $file = str_replace(array('/', '\\'), + array(DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR), $file); + if (file_exists($file) && is_readable($file)) { + return implode('', file($file)); + } + } else { // tgz + if (!class_exists('Archive_Tar')) { + require_once 'phar://install-pear-nozlib.phar/' . 'Archive/Tar.php'; + } + $tar = &new Archive_Tar($this->_archiveFile); + $tar->pushErrorHandling(PEAR_ERROR_RETURN); + if ($file != 'package.xml' && $file != 'package2.xml') { + $file = $this->getPackage() . '-' . $this->getVersion() . '/' . $file; + } + $file = $tar->extractInString($file); + $tar->popErrorHandling(); + if (PEAR::isError($file)) { + return PEAR::raiseError("Cannot locate file '$file' in archive"); + } + return $file; + } + } + + // {{{ analyzeSourceCode() + /** + * Analyze the source code of the given PHP file + * + * @param string Filename of the PHP file + * @return mixed + * @access private + */ + function _analyzeSourceCode($file) + { + if (!function_exists("token_get_all")) { + return false; + } + if (!defined('T_DOC_COMMENT')) { + define('T_DOC_COMMENT', T_COMMENT); + } + if (!defined('T_INTERFACE')) { + define('T_INTERFACE', -1); + } + if (!defined('T_IMPLEMENTS')) { + define('T_IMPLEMENTS', -1); + } + if (!$fp = @fopen($file, "r")) { + return false; + } + fclose($fp); + $contents = file_get_contents($file); + $tokens = token_get_all($contents); +/* + for ($i = 0; $i < sizeof($tokens); $i++) { + @list($token, $data) = $tokens[$i]; + if (is_string($token)) { + var_dump($token); + } else { + print token_name($token) . ' '; + var_dump(rtrim($data)); + } + } +*/ + $look_for = 0; + $paren_level = 0; + $bracket_level = 0; + $brace_level = 0; + $lastphpdoc = ''; + $current_class = ''; + $current_interface = ''; + $current_class_level = -1; + $current_function = ''; + $current_function_level = -1; + $declared_classes = array(); + $declared_interfaces = array(); + $declared_functions = array(); + $declared_methods = array(); + $used_classes = array(); + $used_functions = array(); + $extends = array(); + $implements = array(); + $nodeps = array(); + $inquote = false; + $interface = false; + for ($i = 0; $i < sizeof($tokens); $i++) { + if (is_array($tokens[$i])) { + list($token, $data) = $tokens[$i]; + } else { + $token = $tokens[$i]; + $data = ''; + } + if ($inquote) { + if ($token != '"' && $token != T_END_HEREDOC) { + continue; + } else { + $inquote = false; + continue; + } + } + switch ($token) { + case T_WHITESPACE : + continue; + case ';': + if ($interface) { + $current_function = ''; + $current_function_level = -1; + } + break; + case '"': + case T_START_HEREDOC: + $inquote = true; + break; + case T_CURLY_OPEN: + case T_DOLLAR_OPEN_CURLY_BRACES: + case '{': $brace_level++; continue 2; + case '}': + $brace_level--; + if ($current_class_level == $brace_level) { + $current_class = ''; + $current_class_level = -1; + } + if ($current_function_level == $brace_level) { + $current_function = ''; + $current_function_level = -1; + } + continue 2; + case '[': $bracket_level++; continue 2; + case ']': $bracket_level--; continue 2; + case '(': $paren_level++; continue 2; + case ')': $paren_level--; continue 2; + case T_INTERFACE: + $interface = true; + case T_CLASS: + if (($current_class_level != -1) || ($current_function_level != -1)) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_PHPFILE, + array('file' => $file)); + return false; + } + case T_FUNCTION: + case T_NEW: + case T_EXTENDS: + case T_IMPLEMENTS: + $look_for = $token; + continue 2; + case T_STRING: + if (version_compare(zend_version(), '2.0', '<')) { + if (in_array(strtolower($data), + array('public', 'private', 'protected', 'abstract', + 'interface', 'implements', 'throw') + )) { + $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_PHP5, + array($file)); + } + } + if ($look_for == T_CLASS) { + $current_class = $data; + $current_class_level = $brace_level; + $declared_classes[] = $current_class; + } elseif ($look_for == T_INTERFACE) { + $current_interface = $data; + $current_class_level = $brace_level; + $declared_interfaces[] = $current_interface; + } elseif ($look_for == T_IMPLEMENTS) { + $implements[$current_class] = $data; + } elseif ($look_for == T_EXTENDS) { + $extends[$current_class] = $data; + } elseif ($look_for == T_FUNCTION) { + if ($current_class) { + $current_function = "$current_class::$data"; + $declared_methods[$current_class][] = $data; + } elseif ($current_interface) { + $current_function = "$current_interface::$data"; + $declared_methods[$current_interface][] = $data; + } else { + $current_function = $data; + $declared_functions[] = $current_function; + } + $current_function_level = $brace_level; + $m = array(); + } elseif ($look_for == T_NEW) { + $used_classes[$data] = true; + } + $look_for = 0; + continue 2; + case T_VARIABLE: + $look_for = 0; + continue 2; + case T_DOC_COMMENT: + case T_COMMENT: + if (preg_match('!^/\*\*\s!', $data)) { + $lastphpdoc = $data; + if (preg_match_all('/@nodep\s+(\S+)/', $lastphpdoc, $m)) { + $nodeps = array_merge($nodeps, $m[1]); + } + } + continue 2; + case T_DOUBLE_COLON: + if (!($tokens[$i - 1][0] == T_WHITESPACE || $tokens[$i - 1][0] == T_STRING)) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_PHPFILE, + array('file' => $file)); + return false; + } + $class = $tokens[$i - 1][1]; + if (strtolower($class) != 'parent') { + $used_classes[$class] = true; + } + continue 2; + } + } + return array( + "source_file" => $file, + "declared_classes" => $declared_classes, + "declared_interfaces" => $declared_interfaces, + "declared_methods" => $declared_methods, + "declared_functions" => $declared_functions, + "used_classes" => array_diff(array_keys($used_classes), $nodeps), + "inheritance" => $extends, + "implements" => $implements, + ); + } + + /** + * Build a "provides" array from data returned by + * analyzeSourceCode(). The format of the built array is like + * this: + * + * array( + * 'class;MyClass' => 'array('type' => 'class', 'name' => 'MyClass'), + * ... + * ) + * + * + * @param array $srcinfo array with information about a source file + * as returned by the analyzeSourceCode() method. + * + * @return void + * + * @access private + * + */ + function _buildProvidesArray($srcinfo) + { + if (!$this->_isValid) { + return false; + } + $file = basename($srcinfo['source_file']); + $pn = $this->getPackage(); + $pnl = strlen($pn); + foreach ($srcinfo['declared_classes'] as $class) { + $key = "class;$class"; + if (isset($this->_packageInfo['provides'][$key])) { + continue; + } + $this->_packageInfo['provides'][$key] = + array('file'=> $file, 'type' => 'class', 'name' => $class); + if (isset($srcinfo['inheritance'][$class])) { + $this->_packageInfo['provides'][$key]['extends'] = + $srcinfo['inheritance'][$class]; + } + } + foreach ($srcinfo['declared_methods'] as $class => $methods) { + foreach ($methods as $method) { + $function = "$class::$method"; + $key = "function;$function"; + if ($method{0} == '_' || !strcasecmp($method, $class) || + isset($this->_packageInfo['provides'][$key])) { + continue; + } + $this->_packageInfo['provides'][$key] = + array('file'=> $file, 'type' => 'function', 'name' => $function); + } + } + + foreach ($srcinfo['declared_functions'] as $function) { + $key = "function;$function"; + if ($function{0} == '_' || isset($this->_packageInfo['provides'][$key])) { + continue; + } + if (!strstr($function, '::') && strncasecmp($function, $pn, $pnl)) { + $warnings[] = "in1 " . $file . ": function \"$function\" not prefixed with package name \"$pn\""; + } + $this->_packageInfo['provides'][$key] = + array('file'=> $file, 'type' => 'function', 'name' => $function); + } + } + + // }}} +} +?> <?php /** * PEAR_PackageFile_v2, package.xml version 2.0 @@ -77374,7 +77970,7 @@ class PEAR_PackageFile_v1 * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: v2.php,v 1.145 2009/02/24 23:39:16 dufuz Exp $ + * @version CVS: $Id: v2.php 276383 2009-02-24 23:39:37Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ @@ -77388,7 +77984,7 @@ require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/ErrorStack.php'; * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ @@ -79419,7 +80015,7 @@ class PEAR_PackageFile_v2 * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Validator.php,v 1.110 2009/03/27 19:29:31 dufuz Exp $ + * @version CVS: $Id: Validator.php 277885 2009-03-27 19:29:31Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a8 */ @@ -79431,7 +80027,7 @@ class PEAR_PackageFile_v2 * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a8 * @access private @@ -79522,7 +80118,7 @@ class PEAR_PackageFile_v2_Validator isset($test['dependencies']['required']) && isset($test['dependencies']['required']['pearinstaller']) && isset($test['dependencies']['required']['pearinstaller']['min']) && - version_compare('1.8.0', + version_compare('1.9.0', $test['dependencies']['required']['pearinstaller']['min'], '<') ) { $this->_pearVersionTooLow($test['dependencies']['required']['pearinstaller']['min']); @@ -80761,7 +81357,7 @@ class PEAR_PackageFile_v2_Validator $this->_stack->push(__FUNCTION__, 'error', array('version' => $version), 'This package.xml requires PEAR version %version% to parse properly, we are ' . - 'version 1.8.0'); + 'version 1.9.0'); } function _invalidTagOrder($oktags, $actual, $root) @@ -81561,2357 +82157,2400 @@ class PEAR_PackageFile_v2_Validator return $providesret; } -}<?php
-/**
- * PEAR_Registry
- *
- * PHP versions 4 and 5
- *
- * @category pear
- * @package PEAR
- * @author Stig Bakken <ssb@php.net>
- * @author Tomas V. V. Cox <cox@idecnet.com>
- * @author Greg Beaver <cellog@php.net>
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version CVS: $Id: Registry.php,v 1.179 2009/04/10 19:42:18 dufuz Exp $
- * @link http://pear.php.net/package/PEAR
- * @since File available since Release 0.1
- */
-
-/**
- * for PEAR_Error
- */
-require_once 'phar://install-pear-nozlib.phar/' . 'PEAR.php';
-require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/DependencyDB.php';
-
-define('PEAR_REGISTRY_ERROR_LOCK', -2);
-define('PEAR_REGISTRY_ERROR_FORMAT', -3);
-define('PEAR_REGISTRY_ERROR_FILE', -4);
-define('PEAR_REGISTRY_ERROR_CONFLICT', -5);
-define('PEAR_REGISTRY_ERROR_CHANNEL_FILE', -6);
-
-/**
- * Administration class used to maintain the installed package database.
- * @category pear
- * @package PEAR
- * @author Stig Bakken <ssb@php.net>
- * @author Tomas V. V. Cox <cox@idecnet.com>
- * @author Greg Beaver <cellog@php.net>
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.8.0
- * @link http://pear.php.net/package/PEAR
- * @since Class available since Release 1.4.0a1
- */
-class PEAR_Registry extends PEAR
-{
- /**
- * File containing all channel information.
- * @var string
- */
- var $channels = '';
-
- /** Directory where registry files are stored.
- * @var string
- */
- var $statedir = '';
-
- /** File where the file map is stored
- * @var string
- */
- var $filemap = '';
-
- /** Directory where registry files for channels are stored.
- * @var string
- */
- var $channelsdir = '';
-
- /** Name of file used for locking the registry
- * @var string
- */
- var $lockfile = '';
-
- /** File descriptor used during locking
- * @var resource
- */
- var $lock_fp = null;
-
- /** Mode used during locking
- * @var int
- */
- var $lock_mode = 0; // XXX UNUSED
-
- /** Cache of package information. Structure:
- * array(
- * 'package' => array('id' => ... ),
- * ... )
- * @var array
- */
- var $pkginfo_cache = array();
-
- /** Cache of file map. Structure:
- * array( '/path/to/file' => 'package', ... )
- * @var array
- */
- var $filemap_cache = array();
-
- /**
- * @var false|PEAR_ChannelFile
- */
- var $_pearChannel;
-
- /**
- * @var false|PEAR_ChannelFile
- */
- var $_peclChannel;
-
- /**
- * @var false|PEAR_ChannelFile
- */
- var $_docChannel;
-
- /**
- * @var PEAR_DependencyDB
- */
- var $_dependencyDB;
-
- /**
- * @var PEAR_Config
- */
- var $_config;
-
- /**
- * PEAR_Registry constructor.
- *
- * @param string (optional) PEAR install directory (for .php files)
- * @param PEAR_ChannelFile PEAR_ChannelFile object representing the PEAR channel, if
- * default values are not desired. Only used the very first time a PEAR
- * repository is initialized
- * @param PEAR_ChannelFile PEAR_ChannelFile object representing the PECL channel, if
- * default values are not desired. Only used the very first time a PEAR
- * repository is initialized
- *
- * @access public
- */
- function PEAR_Registry($pear_install_dir = PEAR_INSTALL_DIR, $pear_channel = false,
- $pecl_channel = false)
- {
- parent::PEAR();
- $this->setInstallDir($pear_install_dir);
- $this->_pearChannel = $pear_channel;
- $this->_peclChannel = $pecl_channel;
- $this->_config = false;
- }
-
- function setInstallDir($pear_install_dir = PEAR_INSTALL_DIR)
- {
- $ds = DIRECTORY_SEPARATOR;
- $this->install_dir = $pear_install_dir;
- $this->channelsdir = $pear_install_dir.$ds.'.channels';
- $this->statedir = $pear_install_dir.$ds.'.registry';
- $this->filemap = $pear_install_dir.$ds.'.filemap';
- $this->lockfile = $pear_install_dir.$ds.'.lock';
- }
-
- function hasWriteAccess()
- {
- if (!file_exists($this->install_dir)) {
- $dir = $this->install_dir;
- while ($dir && $dir != '.') {
- $olddir = $dir;
- $dir = dirname($dir);
- if ($dir != '.' && file_exists($dir)) {
- if (is_writeable($dir)) {
- return true;
- }
-
- return false;
- }
-
- if ($dir == $olddir) { // this can happen in safe mode
- return @is_writable($dir);
- }
- }
-
- return false;
- }
-
- return is_writeable($this->install_dir);
- }
-
- function setConfig(&$config, $resetInstallDir = true)
- {
- $this->_config = &$config;
- if ($resetInstallDir) {
- $this->setInstallDir($config->get('php_dir'));
- }
- }
-
- function _initializeChannelDirs()
- {
- static $running = false;
- if (!$running) {
- $running = true;
- $ds = DIRECTORY_SEPARATOR;
- if (!is_dir($this->channelsdir) ||
- !file_exists($this->channelsdir . $ds . 'pear.php.net.reg') ||
- !file_exists($this->channelsdir . $ds . 'pecl.php.net.reg') ||
- !file_exists($this->channelsdir . $ds . 'doc.php.net.reg') ||
- !file_exists($this->channelsdir . $ds . '__uri.reg')) {
- if (!file_exists($this->channelsdir . $ds . 'pear.php.net.reg')) {
- $pear_channel = $this->_pearChannel;
- if (!is_a($pear_channel, 'PEAR_ChannelFile') || !$pear_channel->validate()) {
- if (!class_exists('PEAR_ChannelFile')) {
- require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/ChannelFile.php';
- }
-
- $pear_channel = new PEAR_ChannelFile;
- $pear_channel->setName('pear.php.net');
- $pear_channel->setAlias('pear');
- $pear_channel->setServer('pear.php.net');
- $pear_channel->setSummary('PHP Extension and Application Repository');
- $pear_channel->setDefaultPEARProtocols();
- $pear_channel->setBaseURL('REST1.0', 'http://pear.php.net/rest/');
- $pear_channel->setBaseURL('REST1.1', 'http://pear.php.net/rest/');
- } else {
- $pear_channel->setName('pear.php.net');
- $pear_channel->setAlias('pear');
- }
-
- $pear_channel->validate();
- $this->_addChannel($pear_channel);
- }
-
- if (!file_exists($this->channelsdir . $ds . 'pecl.php.net.reg')) {
- $pecl_channel = $this->_peclChannel;
- if (!is_a($pecl_channel, 'PEAR_ChannelFile') || !$pecl_channel->validate()) {
- if (!class_exists('PEAR_ChannelFile')) {
- require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/ChannelFile.php';
- }
-
- $pecl_channel = new PEAR_ChannelFile;
- $pecl_channel->setName('pecl.php.net');
- $pecl_channel->setAlias('pecl');
- $pecl_channel->setServer('pecl.php.net');
- $pecl_channel->setSummary('PHP Extension Community Library');
- $pecl_channel->setDefaultPEARProtocols();
- $pecl_channel->setBaseURL('REST1.0', 'http://pecl.php.net/rest/');
- $pecl_channel->setBaseURL('REST1.1', 'http://pecl.php.net/rest/');
- $pecl_channel->setValidationPackage('PEAR_Validator_PECL', '1.0');
- } else {
- $pecl_channel->setName('pecl.php.net');
- $pecl_channel->setAlias('pecl');
- }
-
- $pecl_channel->validate();
- $this->_addChannel($pecl_channel);
- }
-
- if (!file_exists($this->channelsdir . $ds . 'doc.php.net.reg')) {
- $doc_channel = $this->_docChannel;
- if (!is_a($doc_channel, 'PEAR_ChannelFile') || !$doc_channel->validate()) {
- if (!class_exists('PEAR_ChannelFile')) {
- require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/ChannelFile.php';
- }
-
- $doc_channel = new PEAR_ChannelFile;
- $doc_channel->setName('doc.php.net');
- $doc_channel->setAlias('phpdocs');
- $doc_channel->setServer('doc.php.net');
- $doc_channel->setSummary('PHP Documentation Team');
- $doc_channel->setDefaultPEARProtocols();
- $doc_channel->setBaseURL('REST1.0', 'http://doc.php.net/Chiara_PEAR_Server_REST/');
- $doc_channel->setBaseURL('REST1.1', 'http://doc.php.net/Chiara_PEAR_Server_REST/');
- } else {
- $doc_channel->setName('doc.php.net');
- $doc_channel->setAlias('doc');
- }
-
- $doc_channel->validate();
- $this->_addChannel($doc_channel);
- }
-
- if (!file_exists($this->channelsdir . $ds . '__uri.reg')) {
- if (!class_exists('PEAR_ChannelFile')) {
- require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/ChannelFile.php';
- }
-
- $private = new PEAR_ChannelFile;
- $private->setName('__uri');
- $private->setDefaultPEARProtocols();
- $private->setBaseURL('REST1.0', '****');
- $private->setSummary('Pseudo-channel for static packages');
- $this->_addChannel($private);
- }
- $this->_rebuildFileMap();
- }
-
- $running = false;
- }
- }
-
- function _initializeDirs()
- {
- $ds = DIRECTORY_SEPARATOR;
- // XXX Compatibility code should be removed in the future
- // rename all registry files if any to lowercase
- if (!OS_WINDOWS && file_exists($this->statedir) && is_dir($this->statedir) &&
- $handle = opendir($this->statedir)) {
- $dest = $this->statedir . $ds;
- while (false !== ($file = readdir($handle))) {
- if (preg_match('/^.*[A-Z].*\.reg\\z/', $file)) {
- rename($dest . $file, $dest . strtolower($file));
- }
- }
- closedir($handle);
- }
-
- $this->_initializeChannelDirs();
- if (!file_exists($this->filemap)) {
- $this->_rebuildFileMap();
- }
- $this->_initializeDepDB();
- }
-
- function _initializeDepDB()
- {
- if (!isset($this->_dependencyDB)) {
- static $initializing = false;
- if (!$initializing) {
- $initializing = true;
- if (!$this->_config) { // never used?
- $file = OS_WINDOWS ? 'pear.ini' : '.pearrc';
- $this->_config = &new PEAR_Config($this->statedir . DIRECTORY_SEPARATOR .
- $file);
- $this->_config->setRegistry($this);
- $this->_config->set('php_dir', $this->install_dir);
- }
-
- $this->_dependencyDB = &PEAR_DependencyDB::singleton($this->_config);
- if (PEAR::isError($this->_dependencyDB)) {
- // attempt to recover by removing the dep db
- if (file_exists($this->_config->get('php_dir', null, 'pear.php.net') .
- DIRECTORY_SEPARATOR . '.depdb')) {
- @unlink($this->_config->get('php_dir', null, 'pear.php.net') .
- DIRECTORY_SEPARATOR . '.depdb');
- }
-
- $this->_dependencyDB = &PEAR_DependencyDB::singleton($this->_config);
- if (PEAR::isError($this->_dependencyDB)) {
- echo $this->_dependencyDB->getMessage();
- echo 'Unrecoverable error';
- exit(1);
- }
- }
-
- $initializing = false;
- }
- }
- }
-
- /**
- * PEAR_Registry destructor. Makes sure no locks are forgotten.
- *
- * @access private
- */
- function _PEAR_Registry()
- {
- parent::_PEAR();
- if (is_resource($this->lock_fp)) {
- $this->_unlock();
- }
- }
-
- /**
- * Make sure the directory where we keep registry files exists.
- *
- * @return bool TRUE if directory exists, FALSE if it could not be
- * created
- *
- * @access private
- */
- function _assertStateDir($channel = false)
- {
- if ($channel && $this->_getChannelFromAlias($channel) != 'pear.php.net') {
- return $this->_assertChannelStateDir($channel);
- }
-
- static $init = false;
- if (!file_exists($this->statedir)) {
- if (!$this->hasWriteAccess()) {
- return false;
- }
-
- require_once 'phar://install-pear-nozlib.phar/' . 'System.php';
- if (!System::mkdir(array('-p', $this->statedir))) {
- return $this->raiseError("could not create directory '{$this->statedir}'");
- }
- $init = true;
- } elseif (!is_dir($this->statedir)) {
- return $this->raiseError('Cannot create directory ' . $this->statedir . ', ' .
- 'it already exists and is not a directory');
- }
-
- $ds = DIRECTORY_SEPARATOR;
- if (!file_exists($this->channelsdir)) {
- if (!file_exists($this->channelsdir . $ds . 'pear.php.net.reg') ||
- !file_exists($this->channelsdir . $ds . 'pecl.php.net.reg') ||
- !file_exists($this->channelsdir . $ds . 'doc.php.net.reg') ||
- !file_exists($this->channelsdir . $ds . '__uri.reg')) {
- $init = true;
- }
- } elseif (!is_dir($this->channelsdir)) {
- return $this->raiseError('Cannot create directory ' . $this->channelsdir . ', ' .
- 'it already exists and is not a directory');
- }
-
- if ($init) {
- static $running = false;
- if (!$running) {
- $running = true;
- $this->_initializeDirs();
- $running = false;
- $init = false;
- }
- } else {
- $this->_initializeDepDB();
- }
-
- return true;
- }
-
- /**
- * Make sure the directory where we keep registry files exists for a non-standard channel.
- *
- * @param string channel name
- * @return bool TRUE if directory exists, FALSE if it could not be
- * created
- *
- * @access private
- */
- function _assertChannelStateDir($channel)
- {
- $ds = DIRECTORY_SEPARATOR;
- if (!$channel || $this->_getChannelFromAlias($channel) == 'pear.php.net') {
- if (!file_exists($this->channelsdir . $ds . 'pear.php.net.reg')) {
- $this->_initializeChannelDirs();
- }
- return $this->_assertStateDir($channel);
- }
-
- $channelDir = $this->_channelDirectoryName($channel);
- if (!is_dir($this->channelsdir) ||
- !file_exists($this->channelsdir . $ds . 'pear.php.net.reg')) {
- $this->_initializeChannelDirs();
- }
-
- if (!file_exists($channelDir)) {
- if (!$this->hasWriteAccess()) {
- return false;
- }
-
- require_once 'phar://install-pear-nozlib.phar/' . 'System.php';
- if (!System::mkdir(array('-p', $channelDir))) {
- return $this->raiseError("could not create directory '" . $channelDir .
- "'");
- }
- } elseif (!is_dir($channelDir)) {
- return $this->raiseError("could not create directory '" . $channelDir .
- "', already exists and is not a directory");
- }
-
- return true;
- }
-
- /**
- * Make sure the directory where we keep registry files for channels exists
- *
- * @return bool TRUE if directory exists, FALSE if it could not be
- * created
- *
- * @access private
- */
- function _assertChannelDir()
- {
- if (!file_exists($this->channelsdir)) {
- if (!$this->hasWriteAccess()) {
- return false;
- }
-
- require_once 'phar://install-pear-nozlib.phar/' . 'System.php';
- if (!System::mkdir(array('-p', $this->channelsdir))) {
- return $this->raiseError("could not create directory '{$this->channelsdir}'");
- }
- } elseif (!is_dir($this->channelsdir)) {
- return $this->raiseError("could not create directory '{$this->channelsdir}" .
- "', it already exists and is not a directory");
- }
-
- if (!file_exists($this->channelsdir . DIRECTORY_SEPARATOR . '.alias')) {
- if (!$this->hasWriteAccess()) {
- return false;
- }
-
- require_once 'phar://install-pear-nozlib.phar/' . 'System.php';
- if (!System::mkdir(array('-p', $this->channelsdir . DIRECTORY_SEPARATOR . '.alias'))) {
- return $this->raiseError("could not create directory '{$this->channelsdir}/.alias'");
- }
- } elseif (!is_dir($this->channelsdir . DIRECTORY_SEPARATOR . '.alias')) {
- return $this->raiseError("could not create directory '{$this->channelsdir}" .
- "/.alias', it already exists and is not a directory");
- }
-
- return true;
- }
-
- /**
- * Get the name of the file where data for a given package is stored.
- *
- * @param string channel name, or false if this is a PEAR package
- * @param string package name
- *
- * @return string registry file name
- *
- * @access public
- */
- function _packageFileName($package, $channel = false)
- {
- if ($channel && $this->_getChannelFromAlias($channel) != 'pear.php.net') {
- return $this->_channelDirectoryName($channel) . DIRECTORY_SEPARATOR .
- strtolower($package) . '.reg';
- }
-
- return $this->statedir . DIRECTORY_SEPARATOR . strtolower($package) . '.reg';
- }
-
- /**
- * Get the name of the file where data for a given channel is stored.
- * @param string channel name
- * @return string registry file name
- */
- function _channelFileName($channel, $noaliases = false)
- {
- if (!$noaliases) {
- if (file_exists($this->_getChannelAliasFileName($channel))) {
- $channel = implode('', file($this->_getChannelAliasFileName($channel)));
- }
- }
- return $this->channelsdir . DIRECTORY_SEPARATOR . str_replace('/', '_',
- strtolower($channel)) . '.reg';
- }
-
- /**
- * @param string
- * @return string
- */
- function _getChannelAliasFileName($alias)
- {
- return $this->channelsdir . DIRECTORY_SEPARATOR . '.alias' .
- DIRECTORY_SEPARATOR . str_replace('/', '_', strtolower($alias)) . '.txt';
- }
-
- /**
- * Get the name of a channel from its alias
- */
- function _getChannelFromAlias($channel)
- {
- if (!$this->_channelExists($channel)) {
- if ($channel == 'pear.php.net') {
- return 'pear.php.net';
- }
-
- if ($channel == 'pecl.php.net') {
- return 'pecl.php.net';
- }
-
- if ($channel == 'doc.php.net') {
- return 'doc.php.net';
- }
-
- if ($channel == '__uri') {
- return '__uri';
- }
-
- return false;
- }
-
- $channel = strtolower($channel);
- if (file_exists($this->_getChannelAliasFileName($channel))) {
- // translate an alias to an actual channel
- return implode('', file($this->_getChannelAliasFileName($channel)));
- }
-
- return $channel;
- }
-
- /**
- * Get the alias of a channel from its alias or its name
- */
- function _getAlias($channel)
- {
- if (!$this->_channelExists($channel)) {
- if ($channel == 'pear.php.net') {
- return 'pear';
- }
-
- if ($channel == 'pecl.php.net') {
- return 'pecl';
- }
-
- if ($channel == 'doc.php.net') {
- return 'phpdocs';
- }
-
- return false;
- }
-
- $channel = $this->_getChannel($channel);
- if (PEAR::isError($channel)) {
- return $channel;
- }
-
- return $channel->getAlias();
- }
-
- /**
- * Get the name of the file where data for a given package is stored.
- *
- * @param string channel name, or false if this is a PEAR package
- * @param string package name
- *
- * @return string registry file name
- *
- * @access public
- */
- function _channelDirectoryName($channel)
- {
- if (!$channel || $this->_getChannelFromAlias($channel) == 'pear.php.net') {
- return $this->statedir;
- }
-
- $ch = $this->_getChannelFromAlias($channel);
- if (!$ch) {
- $ch = $channel;
- }
-
- return $this->statedir . DIRECTORY_SEPARATOR . strtolower('.channel.' .
- str_replace('/', '_', $ch));
- }
-
- function _openPackageFile($package, $mode, $channel = false)
- {
- if (!$this->_assertStateDir($channel)) {
- return null;
- }
-
- if (!in_array($mode, array('r', 'rb')) && !$this->hasWriteAccess()) {
- return null;
- }
-
- $file = $this->_packageFileName($package, $channel);
- if (!file_exists($file) && $mode == 'r' || $mode == 'rb') {
- return null;
- }
-
- $fp = @fopen($file, $mode);
- if (!$fp) {
- return null;
- }
-
- return $fp;
- }
-
- function _closePackageFile($fp)
- {
- fclose($fp);
- }
-
- function _openChannelFile($channel, $mode)
- {
- if (!$this->_assertChannelDir()) {
- return null;
- }
-
- if (!in_array($mode, array('r', 'rb')) && !$this->hasWriteAccess()) {
- return null;
- }
-
- $file = $this->_channelFileName($channel);
- if (!file_exists($file) && $mode == 'r' || $mode == 'rb') {
- return null;
- }
-
- $fp = @fopen($file, $mode);
- if (!$fp) {
- return null;
- }
-
- return $fp;
- }
-
- function _closeChannelFile($fp)
- {
- fclose($fp);
- }
-
- function _rebuildFileMap()
- {
- if (!class_exists('PEAR_Installer_Role')) {
- require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Installer/Role.php';
- }
-
- $channels = $this->_listAllPackages();
- $files = array();
- foreach ($channels as $channel => $packages) {
- foreach ($packages as $package) {
- $version = $this->_packageInfo($package, 'version', $channel);
- $filelist = $this->_packageInfo($package, 'filelist', $channel);
- if (!is_array($filelist)) {
- continue;
- }
-
- foreach ($filelist as $name => $attrs) {
- if (isset($attrs['attribs'])) {
- $attrs = $attrs['attribs'];
- }
-
- // it is possible for conflicting packages in different channels to
- // conflict with data files/doc files
- if ($name == 'dirtree') {
- continue;
- }
-
- if (isset($attrs['role']) && !in_array($attrs['role'],
- PEAR_Installer_Role::getInstallableRoles())) {
- // these are not installed
- continue;
- }
-
- if (isset($attrs['role']) && !in_array($attrs['role'],
- PEAR_Installer_Role::getBaseinstallRoles())) {
- $attrs['baseinstalldir'] = $package;
- }
-
- if (isset($attrs['baseinstalldir'])) {
- $file = $attrs['baseinstalldir'].DIRECTORY_SEPARATOR.$name;
- } else {
- $file = $name;
- }
-
- $file = preg_replace(',^/+,', '', $file);
- if ($channel != 'pear.php.net') {
- if (!isset($files[$attrs['role']])) {
- $files[$attrs['role']] = array();
- }
- $files[$attrs['role']][$file] = array(strtolower($channel),
- strtolower($package));
- } else {
- if (!isset($files[$attrs['role']])) {
- $files[$attrs['role']] = array();
- }
- $files[$attrs['role']][$file] = strtolower($package);
- }
- }
- }
- }
-
-
- $this->_assertStateDir();
- if (!$this->hasWriteAccess()) {
- return false;
- }
-
- $fp = @fopen($this->filemap, 'wb');
- if (!$fp) {
- return false;
- }
-
- $this->filemap_cache = $files;
- fwrite($fp, serialize($files));
- fclose($fp);
- return true;
- }
-
- function _readFileMap()
- {
- if (!file_exists($this->filemap)) {
- return array();
- }
-
- $fp = @fopen($this->filemap, 'r');
- if (!$fp) {
- return $this->raiseError('PEAR_Registry: could not open filemap "' . $this->filemap . '"', PEAR_REGISTRY_ERROR_FILE, null, null, $php_errormsg);
- }
-
- clearstatcache();
- $rt = get_magic_quotes_runtime();
- set_magic_quotes_runtime(0);
- $fsize = filesize($this->filemap);
- fclose($fp);
- $data = file_get_contents($this->filemap);
- set_magic_quotes_runtime($rt);
- $tmp = unserialize($data);
- if (!$tmp && $fsize > 7) {
- return $this->raiseError('PEAR_Registry: invalid filemap data', PEAR_REGISTRY_ERROR_FORMAT, null, null, $data);
- }
-
- $this->filemap_cache = $tmp;
- return true;
- }
-
- /**
- * Lock the registry.
- *
- * @param integer lock mode, one of LOCK_EX, LOCK_SH or LOCK_UN.
- * See flock manual for more information.
- *
- * @return bool TRUE on success, FALSE if locking failed, or a
- * PEAR error if some other error occurs (such as the
- * lock file not being writable).
- *
- * @access private
- */
- function _lock($mode = LOCK_EX)
- {
- if (stristr(php_uname(), 'Windows 9')) {
- return true;
- }
-
- if ($mode != LOCK_UN && is_resource($this->lock_fp)) {
- // XXX does not check type of lock (LOCK_SH/LOCK_EX)
- return true;
- }
-
- if (!$this->_assertStateDir()) {
- if ($mode == LOCK_EX) {
- return $this->raiseError('Registry directory is not writeable by the current user');
- }
-
- return true;
- }
-
- $open_mode = 'w';
- // XXX People reported problems with LOCK_SH and 'w'
- if ($mode === LOCK_SH || $mode === LOCK_UN) {
- if (!file_exists($this->lockfile)) {
- touch($this->lockfile);
- }
- $open_mode = 'r';
- }
-
- if (!is_resource($this->lock_fp)) {
- $this->lock_fp = @fopen($this->lockfile, $open_mode);
- }
-
- if (!is_resource($this->lock_fp)) {
- $this->lock_fp = null;
- return $this->raiseError("could not create lock file" .
- (isset($php_errormsg) ? ": " . $php_errormsg : ""));
- }
-
- if (!(int)flock($this->lock_fp, $mode)) {
- switch ($mode) {
- case LOCK_SH: $str = 'shared'; break;
- case LOCK_EX: $str = 'exclusive'; break;
- case LOCK_UN: $str = 'unlock'; break;
- default: $str = 'unknown'; break;
- }
-
- //is resource at this point, close it on error.
- fclose($this->lock_fp);
- $this->lock_fp = null;
- return $this->raiseError("could not acquire $str lock ($this->lockfile)",
- PEAR_REGISTRY_ERROR_LOCK);
- }
-
- return true;
- }
-
- function _unlock()
- {
- $ret = $this->_lock(LOCK_UN);
- if (is_resource($this->lock_fp)) {
- fclose($this->lock_fp);
- }
-
- $this->lock_fp = null;
- return $ret;
- }
-
- function _packageExists($package, $channel = false)
- {
- return file_exists($this->_packageFileName($package, $channel));
- }
-
- /**
- * Determine whether a channel exists in the registry
- * @param string Channel name
- * @param bool if true, then aliases will be ignored
- * @return boolean
- */
- function _channelExists($channel, $noaliases = false)
- {
- $a = file_exists($this->_channelFileName($channel, $noaliases));
- if (!$a && $channel == 'pear.php.net') {
- return true;
- }
-
- if (!$a && $channel == 'pecl.php.net') {
- return true;
- }
-
- if (!$a && $channel == 'doc.php.net') {
- return true;
- }
-
- return $a;
- }
-
- /**
- * @param PEAR_ChannelFile Channel object
- * @param donotuse
- * @param string Last-Modified HTTP tag from remote request
- * @return boolean|PEAR_Error True on creation, false if it already exists
- */
- function _addChannel($channel, $update = false, $lastmodified = false)
- {
- if (!is_a($channel, 'PEAR_ChannelFile')) {
- return false;
- }
-
- if (!$channel->validate()) {
- return false;
- }
-
- if (file_exists($this->_channelFileName($channel->getName()))) {
- if (!$update) {
- return false;
- }
-
- $checker = $this->_getChannel($channel->getName());
- if (PEAR::isError($checker)) {
- return $checker;
- }
-
- if ($channel->getAlias() != $checker->getAlias()) {
- if (file_exists($this->_getChannelAliasFileName($checker->getAlias()))) {
- @unlink($this->_getChannelAliasFileName($checker->getAlias()));
- }
- }
- } else {
- if ($update && !in_array($channel->getName(), array('pear.php.net', 'pecl.php.net', 'doc.php.net'))) {
- return false;
- }
- }
-
- $ret = $this->_assertChannelDir();
- if (PEAR::isError($ret)) {
- return $ret;
- }
-
- $ret = $this->_assertChannelStateDir($channel->getName());
- if (PEAR::isError($ret)) {
- return $ret;
- }
-
- if ($channel->getAlias() != $channel->getName()) {
- if (file_exists($this->_getChannelAliasFileName($channel->getAlias())) &&
- $this->_getChannelFromAlias($channel->getAlias()) != $channel->getName()) {
- $channel->setAlias($channel->getName());
- }
-
- if (!$this->hasWriteAccess()) {
- return false;
- }
-
- $fp = @fopen($this->_getChannelAliasFileName($channel->getAlias()), 'w');
- if (!$fp) {
- return false;
- }
-
- fwrite($fp, $channel->getName());
- fclose($fp);
- }
-
- if (!$this->hasWriteAccess()) {
- return false;
- }
-
- $fp = @fopen($this->_channelFileName($channel->getName()), 'wb');
- if (!$fp) {
- return false;
- }
-
- $info = $channel->toArray();
- if ($lastmodified) {
- $info['_lastmodified'] = $lastmodified;
- } else {
- $info['_lastmodified'] = date('r');
- }
-
- fwrite($fp, serialize($info));
- fclose($fp);
- return true;
- }
-
- /**
- * Deletion fails if there are any packages installed from the channel
- * @param string|PEAR_ChannelFile channel name
- * @return boolean|PEAR_Error True on deletion, false if it doesn't exist
- */
- function _deleteChannel($channel)
- {
- if (!is_string($channel)) {
- if (!is_a($channel, 'PEAR_ChannelFile')) {
- return false;
- }
-
- if (!$channel->validate()) {
- return false;
- }
- $channel = $channel->getName();
- }
-
- if ($this->_getChannelFromAlias($channel) == '__uri') {
- return false;
- }
-
- if ($this->_getChannelFromAlias($channel) == 'pecl.php.net') {
- return false;
- }
-
- if ($this->_getChannelFromAlias($channel) == 'doc.php.net') {
- return false;
- }
-
- if (!$this->_channelExists($channel)) {
- return false;
- }
-
- if (!$channel || $this->_getChannelFromAlias($channel) == 'pear.php.net') {
- return false;
- }
-
- $channel = $this->_getChannelFromAlias($channel);
- if ($channel == 'pear.php.net') {
- return false;
- }
-
- $test = $this->_listChannelPackages($channel);
- if (count($test)) {
- return false;
- }
-
- $test = @rmdir($this->_channelDirectoryName($channel));
- if (!$test) {
- return false;
- }
-
- $file = $this->_getChannelAliasFileName($this->_getAlias($channel));
- if (file_exists($file)) {
- $test = @unlink($file);
- if (!$test) {
- return false;
- }
- }
-
- $file = $this->_channelFileName($channel);
- $ret = true;
- if (file_exists($file)) {
- $ret = @unlink($file);
- }
-
- return $ret;
- }
-
- /**
- * Determine whether a channel exists in the registry
- * @param string Channel Alias
- * @return boolean
- */
- function _isChannelAlias($alias)
- {
- return file_exists($this->_getChannelAliasFileName($alias));
- }
-
- /**
- * @param string|null
- * @param string|null
- * @param string|null
- * @return array|null
- * @access private
- */
- function _packageInfo($package = null, $key = null, $channel = 'pear.php.net')
- {
- if ($package === null) {
- if ($channel === null) {
- $channels = $this->_listChannels();
- $ret = array();
- foreach ($channels as $channel) {
- $channel = strtolower($channel);
- $ret[$channel] = array();
- $packages = $this->_listPackages($channel);
- foreach ($packages as $package) {
- $ret[$channel][] = $this->_packageInfo($package, null, $channel);
- }
- }
-
- return $ret;
- }
-
- $ps = $this->_listPackages($channel);
- if (!count($ps)) {
- return array();
- }
- return array_map(array(&$this, '_packageInfo'),
- $ps, array_fill(0, count($ps), null),
- array_fill(0, count($ps), $channel));
- }
-
- $fp = $this->_openPackageFile($package, 'r', $channel);
- if ($fp === null) {
- return null;
- }
-
- $rt = get_magic_quotes_runtime();
- set_magic_quotes_runtime(0);
- clearstatcache();
- $this->_closePackageFile($fp);
- $data = file_get_contents($this->_packageFileName($package, $channel));
- set_magic_quotes_runtime($rt);
- $data = unserialize($data);
- if ($key === null) {
- return $data;
- }
-
- // compatibility for package.xml version 2.0
- if (isset($data['old'][$key])) {
- return $data['old'][$key];
- }
-
- if (isset($data[$key])) {
- return $data[$key];
- }
-
- return null;
- }
-
- /**
- * @param string Channel name
- * @param bool whether to strictly retrieve info of channels, not just aliases
- * @return array|null
- */
- function _channelInfo($channel, $noaliases = false)
- {
- if (!$this->_channelExists($channel, $noaliases)) {
- return null;
- }
-
- $fp = $this->_openChannelFile($channel, 'r');
- if ($fp === null) {
- return null;
- }
-
- $rt = get_magic_quotes_runtime();
- set_magic_quotes_runtime(0);
- clearstatcache();
- $this->_closeChannelFile($fp);
- $data = file_get_contents($this->_channelFileName($channel));
- set_magic_quotes_runtime($rt);
- $data = unserialize($data);
- return $data;
- }
-
- function _listChannels()
- {
- $channellist = array();
- if (!file_exists($this->channelsdir) || !is_dir($this->channelsdir)) {
- return array('pear.php.net', 'pecl.php.net', 'doc.php.net', '__uri');
- }
-
- $dp = opendir($this->channelsdir);
- while ($ent = readdir($dp)) {
- if ($ent{0} == '.' || substr($ent, -4) != '.reg') {
- continue;
- }
-
- if ($ent == '__uri.reg') {
- $channellist[] = '__uri';
- continue;
- }
-
- $channellist[] = str_replace('_', '/', substr($ent, 0, -4));
- }
-
- closedir($dp);
- if (!in_array('pear.php.net', $channellist)) {
- $channellist[] = 'pear.php.net';
- }
-
- if (!in_array('pecl.php.net', $channellist)) {
- $channellist[] = 'pecl.php.net';
- }
-
- if (!in_array('doc.php.net', $channellist)) {
- $channellist[] = 'doc.php.net';
- }
-
-
- if (!in_array('__uri', $channellist)) {
- $channellist[] = '__uri';
- }
-
- natsort($channellist);
- return $channellist;
- }
-
- function _listPackages($channel = false)
- {
- if ($channel && $this->_getChannelFromAlias($channel) != 'pear.php.net') {
- return $this->_listChannelPackages($channel);
- }
-
- if (!file_exists($this->statedir) || !is_dir($this->statedir)) {
- return array();
- }
-
- $pkglist = array();
- $dp = opendir($this->statedir);
- if (!$dp) {
- return $pkglist;
- }
-
- while ($ent = readdir($dp)) {
- if ($ent{0} == '.' || substr($ent, -4) != '.reg') {
- continue;
- }
-
- $pkglist[] = substr($ent, 0, -4);
- }
- closedir($dp);
- return $pkglist;
- }
-
- function _listChannelPackages($channel)
- {
- $pkglist = array();
- if (!file_exists($this->_channelDirectoryName($channel)) ||
- !is_dir($this->_channelDirectoryName($channel))) {
- return array();
- }
-
- $dp = opendir($this->_channelDirectoryName($channel));
- if (!$dp) {
- return $pkglist;
- }
-
- while ($ent = readdir($dp)) {
- if ($ent{0} == '.' || substr($ent, -4) != '.reg') {
- continue;
- }
- $pkglist[] = substr($ent, 0, -4);
- }
-
- closedir($dp);
- return $pkglist;
- }
-
- function _listAllPackages()
- {
- $ret = array();
- foreach ($this->_listChannels() as $channel) {
- $ret[$channel] = $this->_listPackages($channel);
- }
-
- return $ret;
- }
-
- /**
- * Add an installed package to the registry
- * @param string package name
- * @param array package info (parsed by PEAR_Common::infoFrom*() methods)
- * @return bool success of saving
- * @access private
- */
- function _addPackage($package, $info)
- {
- if ($this->_packageExists($package)) {
- return false;
- }
-
- $fp = $this->_openPackageFile($package, 'wb');
- if ($fp === null) {
- return false;
- }
-
- $info['_lastmodified'] = time();
- fwrite($fp, serialize($info));
- $this->_closePackageFile($fp);
- if (isset($info['filelist'])) {
- $this->_rebuildFileMap();
- }
-
- return true;
- }
-
- /**
- * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2
- * @return bool
- * @access private
- */
- function _addPackage2($info)
- {
- if (!is_a($info, 'PEAR_PackageFile_v1') && !is_a($info, 'PEAR_PackageFile_v2')) {
- return false;
- }
-
- if (!$info->validate()) {
- if (class_exists('PEAR_Common')) {
- $ui = PEAR_Frontend::singleton();
- if ($ui) {
- foreach ($info->getValidationWarnings() as $err) {
- $ui->log($err['message'], true);
- }
- }
- }
- return false;
- }
-
- $channel = $info->getChannel();
- $package = $info->getPackage();
- $save = $info;
- if ($this->_packageExists($package, $channel)) {
- return false;
- }
-
- if (!$this->_channelExists($channel, true)) {
- return false;
- }
-
- $info = $info->toArray(true);
- if (!$info) {
- return false;
- }
-
- $fp = $this->_openPackageFile($package, 'wb', $channel);
- if ($fp === null) {
- return false;
- }
-
- $info['_lastmodified'] = time();
- fwrite($fp, serialize($info));
- $this->_closePackageFile($fp);
- $this->_rebuildFileMap();
- return true;
- }
-
- /**
- * @param string Package name
- * @param array parsed package.xml 1.0
- * @param bool this parameter is only here for BC. Don't use it.
- * @access private
- */
- function _updatePackage($package, $info, $merge = true)
- {
- $oldinfo = $this->_packageInfo($package);
- if (empty($oldinfo)) {
- return false;
- }
-
- $fp = $this->_openPackageFile($package, 'w');
- if ($fp === null) {
- return false;
- }
-
- if (is_object($info)) {
- $info = $info->toArray();
- }
- $info['_lastmodified'] = time();
-
- $newinfo = $info;
- if ($merge) {
- $info = array_merge($oldinfo, $info);
- } else {
- $diff = $info;
- }
-
- fwrite($fp, serialize($info));
- $this->_closePackageFile($fp);
- if (isset($newinfo['filelist'])) {
- $this->_rebuildFileMap();
- }
-
- return true;
- }
-
- /**
- * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2
- * @return bool
- * @access private
- */
- function _updatePackage2($info)
- {
- if (!$this->_packageExists($info->getPackage(), $info->getChannel())) {
- return false;
- }
-
- $fp = $this->_openPackageFile($info->getPackage(), 'w', $info->getChannel());
- if ($fp === null) {
- return false;
- }
-
- $save = $info;
- $info = $save->getArray(true);
- $info['_lastmodified'] = time();
- fwrite($fp, serialize($info));
- $this->_closePackageFile($fp);
- $this->_rebuildFileMap();
- return true;
- }
-
- /**
- * @param string Package name
- * @param string Channel name
- * @return PEAR_PackageFile_v1|PEAR_PackageFile_v2|null
- * @access private
- */
- function &_getPackage($package, $channel = 'pear.php.net')
- {
- $info = $this->_packageInfo($package, null, $channel);
- if ($info === null) {
- return $info;
- }
-
- $a = $this->_config;
- if (!$a) {
- $this->_config = &new PEAR_Config;
- $this->_config->set('php_dir', $this->statedir);
- }
-
- if (!class_exists('PEAR_PackageFile')) {
- require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/PackageFile.php';
- }
-
- $pkg = &new PEAR_PackageFile($this->_config);
- $pf = &$pkg->fromArray($info);
- return $pf;
- }
-
- /**
- * @param string channel name
- * @param bool whether to strictly retrieve channel names
- * @return PEAR_ChannelFile|PEAR_Error
- * @access private
- */
- function &_getChannel($channel, $noaliases = false)
- {
- $ch = false;
- if ($this->_channelExists($channel, $noaliases)) {
- $chinfo = $this->_channelInfo($channel, $noaliases);
- if ($chinfo) {
- if (!class_exists('PEAR_ChannelFile')) {
- require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/ChannelFile.php';
- }
-
- $ch = &PEAR_ChannelFile::fromArrayWithErrors($chinfo);
- }
- }
-
- if ($ch) {
- if ($ch->validate()) {
- return $ch;
- }
-
- foreach ($ch->getErrors(true) as $err) {
- $message = $err['message'] . "\n";
- }
-
- $ch = PEAR::raiseError($message);
- return $ch;
- }
-
- if ($this->_getChannelFromAlias($channel) == 'pear.php.net') {
- // the registry is not properly set up, so use defaults
- if (!class_exists('PEAR_ChannelFile')) {
- require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/ChannelFile.php';
- }
-
- $pear_channel = new PEAR_ChannelFile;
- $pear_channel->setName('pear.php.net');
- $pear_channel->setAlias('pear');
- $pear_channel->setSummary('PHP Extension and Application Repository');
- $pear_channel->setDefaultPEARProtocols();
- $pear_channel->setBaseURL('REST1.0', 'http://pear.php.net/rest/');
- $pear_channel->setBaseURL('REST1.1', 'http://pear.php.net/rest/');
- return $pear_channel;
- }
-
- if ($this->_getChannelFromAlias($channel) == 'pecl.php.net') {
- // the registry is not properly set up, so use defaults
- if (!class_exists('PEAR_ChannelFile')) {
- require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/ChannelFile.php';
- }
- $pear_channel = new PEAR_ChannelFile;
- $pear_channel->setName('pecl.php.net');
- $pear_channel->setAlias('pecl');
- $pear_channel->setSummary('PHP Extension Community Library');
- $pear_channel->setDefaultPEARProtocols();
- $pear_channel->setBaseURL('REST1.0', 'http://pecl.php.net/rest/');
- $pear_channel->setBaseURL('REST1.1', 'http://pecl.php.net/rest/');
- $pear_channel->setValidationPackage('PEAR_Validator_PECL', '1.0');
- return $pear_channel;
- }
-
- if ($this->_getChannelFromAlias($channel) == 'doc.php.net') {
- // the registry is not properly set up, so use defaults
- if (!class_exists('PEAR_ChannelFile')) {
- require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/ChannelFile.php';
- }
-
- $doc_channel = new PEAR_ChannelFile;
- $doc_channel->setName('doc.php.net');
- $doc_channel->setAlias('phpdocs');
- $doc_channel->setSummary('PHP Documentation Team');
- $doc_channel->setDefaultPEARProtocols();
- $doc_channel->setBaseURL('REST1.0', 'http://doc.php.net/Chiara_PEAR_Server_REST/');
- $doc_channel->setBaseURL('REST1.1', 'http://doc.php.net/Chiara_PEAR_Server_REST/');
- return $doc_channel;
- }
-
-
- if ($this->_getChannelFromAlias($channel) == '__uri') {
- // the registry is not properly set up, so use defaults
- if (!class_exists('PEAR_ChannelFile')) {
- require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/ChannelFile.php';
- }
-
- $private = new PEAR_ChannelFile;
- $private->setName('__uri');
- $private->setDefaultPEARProtocols();
- $private->setBaseURL('REST1.0', '****');
- $private->setSummary('Pseudo-channel for static packages');
- return $private;
- }
-
- return $ch;
- }
-
- /**
- * @param string Package name
- * @param string Channel name
- * @return bool
- */
- function packageExists($package, $channel = 'pear.php.net')
- {
- if (PEAR::isError($e = $this->_lock(LOCK_SH))) {
- return $e;
- }
- $ret = $this->_packageExists($package, $channel);
- $this->_unlock();
- return $ret;
- }
-
- // }}}
-
- // {{{ channelExists()
-
- /**
- * @param string channel name
- * @param bool if true, then aliases will be ignored
- * @return bool
- */
- function channelExists($channel, $noaliases = false)
- {
- if (PEAR::isError($e = $this->_lock(LOCK_SH))) {
- return $e;
- }
- $ret = $this->_channelExists($channel, $noaliases);
- $this->_unlock();
- return $ret;
- }
-
- // }}}
-
- // {{{ isAlias()
-
- /**
- * Determines whether the parameter is an alias of a channel
- * @param string
- * @return bool
- */
- function isAlias($alias)
- {
- if (PEAR::isError($e = $this->_lock(LOCK_SH))) {
- return $e;
- }
- $ret = $this->_isChannelAlias($alias);
- $this->_unlock();
- return $ret;
- }
-
- // }}}
- // {{{ packageInfo()
-
- /**
- * @param string|null
- * @param string|null
- * @param string
- * @return array|null
- */
- function packageInfo($package = null, $key = null, $channel = 'pear.php.net')
- {
- if (PEAR::isError($e = $this->_lock(LOCK_SH))) {
- return $e;
- }
- $ret = $this->_packageInfo($package, $key, $channel);
- $this->_unlock();
- return $ret;
- }
-
- // }}}
- // {{{ channelInfo()
-
- /**
- * Retrieve a raw array of channel data.
- *
- * Do not use this, instead use {@link getChannel()} for normal
- * operations. Array structure is undefined in this method
- * @param string channel name
- * @param bool whether to strictly retrieve information only on non-aliases
- * @return array|null|PEAR_Error
- */
- function channelInfo($channel = null, $noaliases = false)
- {
- if (PEAR::isError($e = $this->_lock(LOCK_SH))) {
- return $e;
- }
- $ret = $this->_channelInfo($channel, $noaliases);
- $this->_unlock();
- return $ret;
- }
-
- // }}}
-
- /**
- * @param string
- */
- function channelName($channel)
- {
- if (PEAR::isError($e = $this->_lock(LOCK_SH))) {
- return $e;
- }
- $ret = $this->_getChannelFromAlias($channel);
- $this->_unlock();
- return $ret;
- }
-
- /**
- * @param string
- */
- function channelAlias($channel)
- {
- if (PEAR::isError($e = $this->_lock(LOCK_SH))) {
- return $e;
- }
- $ret = $this->_getAlias($channel);
- $this->_unlock();
- return $ret;
- }
- // {{{ listPackages()
-
- function listPackages($channel = false)
- {
- if (PEAR::isError($e = $this->_lock(LOCK_SH))) {
- return $e;
- }
- $ret = $this->_listPackages($channel);
- $this->_unlock();
- return $ret;
- }
-
- // }}}
- // {{{ listAllPackages()
-
- function listAllPackages()
- {
- if (PEAR::isError($e = $this->_lock(LOCK_SH))) {
- return $e;
- }
- $ret = $this->_listAllPackages();
- $this->_unlock();
- return $ret;
- }
-
- // }}}
- // {{{ listChannel()
-
- function listChannels()
- {
- if (PEAR::isError($e = $this->_lock(LOCK_SH))) {
- return $e;
- }
- $ret = $this->_listChannels();
- $this->_unlock();
- return $ret;
- }
-
- // }}}
- // {{{ addPackage()
-
- /**
- * Add an installed package to the registry
- * @param string|PEAR_PackageFile_v1|PEAR_PackageFile_v2 package name or object
- * that will be passed to {@link addPackage2()}
- * @param array package info (parsed by PEAR_Common::infoFrom*() methods)
- * @return bool success of saving
- */
- function addPackage($package, $info)
- {
- if (is_object($info)) {
- return $this->addPackage2($info);
- }
- if (PEAR::isError($e = $this->_lock(LOCK_EX))) {
- return $e;
- }
- $ret = $this->_addPackage($package, $info);
- $this->_unlock();
- if ($ret) {
- if (!class_exists('PEAR_PackageFile_v1')) {
- require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/PackageFile/v1.php';
- }
- $pf = new PEAR_PackageFile_v1;
- $pf->setConfig($this->_config);
- $pf->fromArray($info);
- $this->_dependencyDB->uninstallPackage($pf);
- $this->_dependencyDB->installPackage($pf);
- }
- return $ret;
- }
-
- // }}}
- // {{{ addPackage2()
-
- function addPackage2($info)
- {
- if (!is_object($info)) {
- return $this->addPackage($info['package'], $info);
- }
- if (PEAR::isError($e = $this->_lock(LOCK_EX))) {
- return $e;
- }
- $ret = $this->_addPackage2($info);
- $this->_unlock();
- if ($ret) {
- $this->_dependencyDB->uninstallPackage($info);
- $this->_dependencyDB->installPackage($info);
- }
- return $ret;
- }
-
- // }}}
- // {{{ updateChannel()
-
- /**
- * For future expandibility purposes, separate this
- * @param PEAR_ChannelFile
- */
- function updateChannel($channel, $lastmodified = null)
- {
- if ($channel->getName() == '__uri') {
- return false;
- }
- return $this->addChannel($channel, $lastmodified, true);
- }
-
- // }}}
- // {{{ deleteChannel()
-
- /**
- * Deletion fails if there are any packages installed from the channel
- * @param string|PEAR_ChannelFile channel name
- * @return boolean|PEAR_Error True on deletion, false if it doesn't exist
- */
- function deleteChannel($channel)
- {
- if (PEAR::isError($e = $this->_lock(LOCK_EX))) {
- return $e;
- }
- $ret = $this->_deleteChannel($channel);
- $this->_unlock();
- if ($ret && is_a($this->_config, 'PEAR_Config')) {
- $this->_config->setChannels($this->listChannels());
- }
- return $ret;
- }
-
- // }}}
- // {{{ addChannel()
-
- /**
- * @param PEAR_ChannelFile Channel object
- * @param string Last-Modified header from HTTP for caching
- * @return boolean|PEAR_Error True on creation, false if it already exists
- */
- function addChannel($channel, $lastmodified = false, $update = false)
- {
- if (!is_a($channel, 'PEAR_ChannelFile')) {
- return false;
- }
- if (!$channel->validate()) {
- return false;
- }
- if (PEAR::isError($e = $this->_lock(LOCK_EX))) {
- return $e;
- }
- $ret = $this->_addChannel($channel, $update, $lastmodified);
- $this->_unlock();
- if (!$update && $ret && is_a($this->_config, 'PEAR_Config')) {
- $this->_config->setChannels($this->listChannels());
- }
- return $ret;
- }
-
- // }}}
- // {{{ deletePackage()
-
- function deletePackage($package, $channel = 'pear.php.net')
- {
- if (PEAR::isError($e = $this->_lock(LOCK_EX))) {
- return $e;
- }
- $file = $this->_packageFileName($package, $channel);
- if (file_exists($file)) {
- $ret = @unlink($file);
- } else {
- $ret = false;
- }
- $this->_rebuildFileMap();
- $this->_unlock();
- $p = array('channel' => $channel, 'package' => $package);
- $this->_dependencyDB->uninstallPackage($p);
- return $ret;
- }
-
- // }}}
- // {{{ updatePackage()
-
- function updatePackage($package, $info, $merge = true)
- {
- if (is_object($info)) {
- return $this->updatePackage2($info, $merge);
- }
- if (PEAR::isError($e = $this->_lock(LOCK_EX))) {
- return $e;
- }
- $ret = $this->_updatePackage($package, $info, $merge);
- $this->_unlock();
- if ($ret) {
- if (!class_exists('PEAR_PackageFile_v1')) {
- require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/PackageFile/v1.php';
- }
- $pf = new PEAR_PackageFile_v1;
- $pf->setConfig($this->_config);
- $pf->fromArray($this->packageInfo($package));
- $this->_dependencyDB->uninstallPackage($pf);
- $this->_dependencyDB->installPackage($pf);
- }
- return $ret;
- }
-
- // }}}
- // {{{ updatePackage2()
-
- function updatePackage2($info)
- {
-
- if (!is_object($info)) {
- return $this->updatePackage($info['package'], $info, $merge);
- }
-
- if (!$info->validate(PEAR_VALIDATE_DOWNLOADING)) {
- return false;
- }
-
- if (PEAR::isError($e = $this->_lock(LOCK_EX))) {
- return $e;
- }
-
- $ret = $this->_updatePackage2($info);
- $this->_unlock();
- if ($ret) {
- $this->_dependencyDB->uninstallPackage($info);
- $this->_dependencyDB->installPackage($info);
- }
-
- return $ret;
- }
-
- // }}}
- // {{{ getChannel()
- /**
- * @param string channel name
- * @param bool whether to strictly return raw channels (no aliases)
- * @return PEAR_ChannelFile|PEAR_Error
- */
- function &getChannel($channel, $noaliases = false)
- {
- if (PEAR::isError($e = $this->_lock(LOCK_SH))) {
- return $e;
- }
- $ret = &$this->_getChannel($channel, $noaliases);
- $this->_unlock();
- if (!$ret) {
- return PEAR::raiseError('Unknown channel: ' . $channel);
- }
- return $ret;
- }
-
- // }}}
- // {{{ getPackage()
- /**
- * @param string package name
- * @param string channel name
- * @return PEAR_PackageFile_v1|PEAR_PackageFile_v2|null
- */
- function &getPackage($package, $channel = 'pear.php.net')
- {
- if (PEAR::isError($e = $this->_lock(LOCK_SH))) {
- return $e;
- }
- $pf = &$this->_getPackage($package, $channel);
- $this->_unlock();
- return $pf;
- }
-
- // }}}
-
- /**
- * Get PEAR_PackageFile_v[1/2] objects representing the contents of
- * a dependency group that are installed.
- *
- * This is used at uninstall-time
- * @param array
- * @return array|false
- */
- function getInstalledGroup($group)
- {
- $ret = array();
- if (isset($group['package'])) {
- if (!isset($group['package'][0])) {
- $group['package'] = array($group['package']);
- }
- foreach ($group['package'] as $package) {
- $depchannel = isset($package['channel']) ? $package['channel'] : '__uri';
- $p = &$this->getPackage($package['name'], $depchannel);
- if ($p) {
- $save = &$p;
- $ret[] = &$save;
- }
- }
- }
- if (isset($group['subpackage'])) {
- if (!isset($group['subpackage'][0])) {
- $group['subpackage'] = array($group['subpackage']);
- }
- foreach ($group['subpackage'] as $package) {
- $depchannel = isset($package['channel']) ? $package['channel'] : '__uri';
- $p = &$this->getPackage($package['name'], $depchannel);
- if ($p) {
- $save = &$p;
- $ret[] = &$save;
- }
- }
- }
- if (!count($ret)) {
- return false;
- }
- return $ret;
- }
-
- // {{{ getChannelValidator()
- /**
- * @param string channel name
- * @return PEAR_Validate|false
- */
- function &getChannelValidator($channel)
- {
- $chan = $this->getChannel($channel);
- if (PEAR::isError($chan)) {
- return $chan;
- }
- $val = $chan->getValidationObject();
- return $val;
- }
- // }}}
- // {{{ getChannels()
- /**
- * @param string channel name
- * @return array an array of PEAR_ChannelFile objects representing every installed channel
- */
- function &getChannels()
- {
- $ret = array();
- if (PEAR::isError($e = $this->_lock(LOCK_SH))) {
- return $e;
- }
- foreach ($this->_listChannels() as $channel) {
- $e = &$this->_getChannel($channel);
- if (!$e || PEAR::isError($e)) {
- continue;
- }
- $ret[] = $e;
- }
- $this->_unlock();
- return $ret;
- }
-
- // }}}
- // {{{ checkFileMap()
-
- /**
- * Test whether a file or set of files belongs to a package.
- *
- * If an array is passed in
- * @param string|array file path, absolute or relative to the pear
- * install dir
- * @param string|array name of PEAR package or array('package' => name, 'channel' =>
- * channel) of a package that will be ignored
- * @param string API version - 1.1 will exclude any files belonging to a package
- * @param array private recursion variable
- * @return array|false which package and channel the file belongs to, or an empty
- * string if the file does not belong to an installed package,
- * or belongs to the second parameter's package
- */
- function checkFileMap($path, $package = false, $api = '1.0', $attrs = false)
- {
- if (is_array($path)) {
- static $notempty;
- if (empty($notempty)) {
- if (!class_exists('PEAR_Installer_Role')) {
- require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Installer/Role.php';
- }
- $notempty = create_function('$a','return !empty($a);');
- }
- $package = is_array($package) ? array(strtolower($package[0]), strtolower($package[1]))
- : strtolower($package);
- $pkgs = array();
- foreach ($path as $name => $attrs) {
- if (is_array($attrs)) {
- if (isset($attrs['install-as'])) {
- $name = $attrs['install-as'];
- }
- if (!in_array($attrs['role'], PEAR_Installer_Role::getInstallableRoles())) {
- // these are not installed
- continue;
- }
- if (!in_array($attrs['role'], PEAR_Installer_Role::getBaseinstallRoles())) {
- $attrs['baseinstalldir'] = is_array($package) ? $package[1] : $package;
- }
- if (isset($attrs['baseinstalldir'])) {
- $name = $attrs['baseinstalldir'] . DIRECTORY_SEPARATOR . $name;
- }
- }
- $pkgs[$name] = $this->checkFileMap($name, $package, $api, $attrs);
- if (PEAR::isError($pkgs[$name])) {
- return $pkgs[$name];
- }
- }
- return array_filter($pkgs, $notempty);
- }
- if (empty($this->filemap_cache)) {
- if (PEAR::isError($e = $this->_lock(LOCK_SH))) {
- return $e;
- }
- $err = $this->_readFileMap();
- $this->_unlock();
- if (PEAR::isError($err)) {
- return $err;
- }
- }
- if (!$attrs) {
- $attrs = array('role' => 'php'); // any old call would be for PHP role only
- }
- if (isset($this->filemap_cache[$attrs['role']][$path])) {
- if ($api >= '1.1' && $this->filemap_cache[$attrs['role']][$path] == $package) {
- return false;
- }
- return $this->filemap_cache[$attrs['role']][$path];
- }
- $l = strlen($this->install_dir);
- if (substr($path, 0, $l) == $this->install_dir) {
- $path = preg_replace('!^'.DIRECTORY_SEPARATOR.'+!', '', substr($path, $l));
- }
- if (isset($this->filemap_cache[$attrs['role']][$path])) {
- if ($api >= '1.1' && $this->filemap_cache[$attrs['role']][$path] == $package) {
- return false;
- }
- return $this->filemap_cache[$attrs['role']][$path];
- }
- return false;
- }
-
- // }}}
- // {{{ flush()
- /**
- * Force a reload of the filemap
- * @since 1.5.0RC3
- */
- function flushFileMap()
- {
- $this->filemap_cache = null;
- clearstatcache(); // ensure that the next read gets the full, current filemap
- }
-
- // }}}
- // {{{ apiVersion()
- /**
- * Get the expected API version. Channels API is version 1.1, as it is backwards
- * compatible with 1.0
- * @return string
- */
- function apiVersion()
- {
- return '1.1';
- }
- // }}}
-
-
- /**
- * Parse a package name, or validate a parsed package name array
- * @param string|array pass in an array of format
- * array(
- * 'package' => 'pname',
- * ['channel' => 'channame',]
- * ['version' => 'version',]
- * ['state' => 'state',]
- * ['group' => 'groupname'])
- * or a string of format
- * [channel://][channame/]pname[-version|-state][/group=groupname]
- * @return array|PEAR_Error
- */
- function parsePackageName($param, $defaultchannel = 'pear.php.net')
- {
- $saveparam = $param;
- if (is_array($param)) {
- // convert to string for error messages
- $saveparam = $this->parsedPackageNameToString($param);
- // process the array
- if (!isset($param['package'])) {
- return PEAR::raiseError('parsePackageName(): array $param ' .
- 'must contain a valid package name in index "param"',
- 'package', null, null, $param);
- }
- if (!isset($param['uri'])) {
- if (!isset($param['channel'])) {
- $param['channel'] = $defaultchannel;
- }
- } else {
- $param['channel'] = '__uri';
- }
- } else {
- $components = @parse_url((string) $param);
- if (isset($components['scheme'])) {
- if ($components['scheme'] == 'http') {
- // uri package
- $param = array('uri' => $param, 'channel' => '__uri');
- } elseif($components['scheme'] != 'channel') {
- return PEAR::raiseError('parsePackageName(): only channel:// uris may ' .
- 'be downloaded, not "' . $param . '"', 'invalid', null, null, $param);
- }
- }
- if (!isset($components['path'])) {
- return PEAR::raiseError('parsePackageName(): array $param ' .
- 'must contain a valid package name in "' . $param . '"',
- 'package', null, null, $param);
- }
- if (isset($components['host'])) {
- // remove the leading "/"
- $components['path'] = substr($components['path'], 1);
- }
- if (!isset($components['scheme'])) {
- if (strpos($components['path'], '/') !== false) {
- if ($components['path']{0} == '/') {
- return PEAR::raiseError('parsePackageName(): this is not ' .
- 'a package name, it begins with "/" in "' . $param . '"',
- 'invalid', null, null, $param);
- }
- $parts = explode('/', $components['path']);
- $components['host'] = array_shift($parts);
- if (count($parts) > 1) {
- $components['path'] = array_pop($parts);
- $components['host'] .= '/' . implode('/', $parts);
- } else {
- $components['path'] = implode('/', $parts);
- }
- } else {
- $components['host'] = $defaultchannel;
- }
- } else {
- if (strpos($components['path'], '/')) {
- $parts = explode('/', $components['path']);
- $components['path'] = array_pop($parts);
- $components['host'] .= '/' . implode('/', $parts);
- }
- }
-
- if (is_array($param)) {
- $param['package'] = $components['path'];
- } else {
- $param = array(
- 'package' => $components['path']
- );
- if (isset($components['host'])) {
- $param['channel'] = $components['host'];
- }
- }
- if (isset($components['fragment'])) {
- $param['group'] = $components['fragment'];
- }
- if (isset($components['user'])) {
- $param['user'] = $components['user'];
- }
- if (isset($components['pass'])) {
- $param['pass'] = $components['pass'];
- }
- if (isset($components['query'])) {
- parse_str($components['query'], $param['opts']);
- }
- // check for extension
- $pathinfo = pathinfo($param['package']);
- if (isset($pathinfo['extension']) &&
- in_array(strtolower($pathinfo['extension']), array('tgz', 'tar'))) {
- $param['extension'] = $pathinfo['extension'];
- $param['package'] = substr($pathinfo['basename'], 0,
- strlen($pathinfo['basename']) - 4);
- }
- // check for version
- if (strpos($param['package'], '-')) {
- $test = explode('-', $param['package']);
- if (count($test) != 2) {
- return PEAR::raiseError('parsePackageName(): only one version/state ' .
- 'delimiter "-" is allowed in "' . $saveparam . '"',
- 'version', null, null, $param);
- }
- list($param['package'], $param['version']) = $test;
- }
- }
- // validation
- $info = $this->channelExists($param['channel']);
- if (PEAR::isError($info)) {
- return $info;
- }
- if (!$info) {
- return PEAR::raiseError('unknown channel "' . $param['channel'] .
- '" in "' . $saveparam . '"', 'channel', null, null, $param);
- }
- $chan = $this->getChannel($param['channel']);
- if (PEAR::isError($chan)) {
- return $chan;
- }
- if (!$chan) {
- return PEAR::raiseError("Exception: corrupt registry, could not " .
- "retrieve channel " . $param['channel'] . " information",
- 'registry', null, null, $param);
- }
- $param['channel'] = $chan->getName();
- $validate = $chan->getValidationObject();
- $vpackage = $chan->getValidationPackage();
- // validate package name
- if (!$validate->validPackageName($param['package'], $vpackage['_content'])) {
- return PEAR::raiseError('parsePackageName(): invalid package name "' .
- $param['package'] . '" in "' . $saveparam . '"',
- 'package', null, null, $param);
- }
- if (isset($param['group'])) {
- if (!PEAR_Validate::validGroupName($param['group'])) {
- return PEAR::raiseError('parsePackageName(): dependency group "' . $param['group'] .
- '" is not a valid group name in "' . $saveparam . '"', 'group', null, null,
- $param);
- }
- }
- if (isset($param['state'])) {
- if (!in_array(strtolower($param['state']), $validate->getValidStates())) {
- return PEAR::raiseError('parsePackageName(): state "' . $param['state']
- . '" is not a valid state in "' . $saveparam . '"',
- 'state', null, null, $param);
- }
- }
- if (isset($param['version'])) {
- if (isset($param['state'])) {
- return PEAR::raiseError('parsePackageName(): cannot contain both ' .
- 'a version and a stability (state) in "' . $saveparam . '"',
- 'version/state', null, null, $param);
- }
- // check whether version is actually a state
- if (in_array(strtolower($param['version']), $validate->getValidStates())) {
- $param['state'] = strtolower($param['version']);
- unset($param['version']);
- } else {
- if (!$validate->validVersion($param['version'])) {
- return PEAR::raiseError('parsePackageName(): "' . $param['version'] .
- '" is neither a valid version nor a valid state in "' .
- $saveparam . '"', 'version/state', null, null, $param);
- }
- }
- }
- return $param;
- }
-
- /**
- * @param array
- * @return string
- */
- function parsedPackageNameToString($parsed, $brief = false)
- {
- if (is_string($parsed)) {
- return $parsed;
- }
- if (is_object($parsed)) {
- $p = $parsed;
- $parsed = array(
- 'package' => $p->getPackage(),
- 'channel' => $p->getChannel(),
- 'version' => $p->getVersion(),
- );
- }
- if (isset($parsed['uri'])) {
- return $parsed['uri'];
- }
- if ($brief) {
- if ($channel = $this->channelAlias($parsed['channel'])) {
- return $channel . '/' . $parsed['package'];
- }
- }
- $upass = '';
- if (isset($parsed['user'])) {
- $upass = $parsed['user'];
- if (isset($parsed['pass'])) {
- $upass .= ':' . $parsed['pass'];
- }
- $upass = "$upass@";
- }
- $ret = 'channel://' . $upass . $parsed['channel'] . '/' . $parsed['package'];
- if (isset($parsed['version']) || isset($parsed['state'])) {
- $ver = isset($parsed['version']) ? $parsed['version'] : '';
- $ver .= isset($parsed['state']) ? $parsed['state'] : '';
- $ret .= '-' . $ver;
- }
- if (isset($parsed['extension'])) {
- $ret .= '.' . $parsed['extension'];
- }
- if (isset($parsed['opts'])) {
- $ret .= '?';
- foreach ($parsed['opts'] as $name => $value) {
- $parsed['opts'][$name] = "$name=$value";
- }
- $ret .= implode('&', $parsed['opts']);
- }
- if (isset($parsed['group'])) {
- $ret .= '#' . $parsed['group'];
- }
- return $ret;
- }
+}<?php +/** + * PEAR_Registry + * + * PHP versions 4 and 5 + * + * @category pear + * @package PEAR + * @author Stig Bakken <ssb@php.net> + * @author Tomas V. V. Cox <cox@idecnet.com> + * @author Greg Beaver <cellog@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: Registry.php 287555 2009-08-21 21:27:27Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 0.1 + */ + +/** + * for PEAR_Error + */ +require_once 'phar://install-pear-nozlib.phar/' . 'PEAR.php'; +require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/DependencyDB.php'; + +define('PEAR_REGISTRY_ERROR_LOCK', -2); +define('PEAR_REGISTRY_ERROR_FORMAT', -3); +define('PEAR_REGISTRY_ERROR_FILE', -4); +define('PEAR_REGISTRY_ERROR_CONFLICT', -5); +define('PEAR_REGISTRY_ERROR_CHANNEL_FILE', -6); + +/** + * Administration class used to maintain the installed package database. + * @category pear + * @package PEAR + * @author Stig Bakken <ssb@php.net> + * @author Tomas V. V. Cox <cox@idecnet.com> + * @author Greg Beaver <cellog@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_Registry extends PEAR +{ + /** + * File containing all channel information. + * @var string + */ + var $channels = ''; + + /** Directory where registry files are stored. + * @var string + */ + var $statedir = ''; + + /** File where the file map is stored + * @var string + */ + var $filemap = ''; + + /** Directory where registry files for channels are stored. + * @var string + */ + var $channelsdir = ''; + + /** Name of file used for locking the registry + * @var string + */ + var $lockfile = ''; + + /** File descriptor used during locking + * @var resource + */ + var $lock_fp = null; + + /** Mode used during locking + * @var int + */ + var $lock_mode = 0; // XXX UNUSED + + /** Cache of package information. Structure: + * array( + * 'package' => array('id' => ... ), + * ... ) + * @var array + */ + var $pkginfo_cache = array(); + + /** Cache of file map. Structure: + * array( '/path/to/file' => 'package', ... ) + * @var array + */ + var $filemap_cache = array(); + + /** + * @var false|PEAR_ChannelFile + */ + var $_pearChannel; + + /** + * @var false|PEAR_ChannelFile + */ + var $_peclChannel; + + /** + * @var false|PEAR_ChannelFile + */ + var $_docChannel; + + /** + * @var PEAR_DependencyDB + */ + var $_dependencyDB; + + /** + * @var PEAR_Config + */ + var $_config; + + /** + * PEAR_Registry constructor. + * + * @param string (optional) PEAR install directory (for .php files) + * @param PEAR_ChannelFile PEAR_ChannelFile object representing the PEAR channel, if + * default values are not desired. Only used the very first time a PEAR + * repository is initialized + * @param PEAR_ChannelFile PEAR_ChannelFile object representing the PECL channel, if + * default values are not desired. Only used the very first time a PEAR + * repository is initialized + * + * @access public + */ + function PEAR_Registry($pear_install_dir = PEAR_INSTALL_DIR, $pear_channel = false, + $pecl_channel = false) + { + parent::PEAR(); + $this->setInstallDir($pear_install_dir); + $this->_pearChannel = $pear_channel; + $this->_peclChannel = $pecl_channel; + $this->_config = false; + } + + function setInstallDir($pear_install_dir = PEAR_INSTALL_DIR) + { + $ds = DIRECTORY_SEPARATOR; + $this->install_dir = $pear_install_dir; + $this->channelsdir = $pear_install_dir.$ds.'.channels'; + $this->statedir = $pear_install_dir.$ds.'.registry'; + $this->filemap = $pear_install_dir.$ds.'.filemap'; + $this->lockfile = $pear_install_dir.$ds.'.lock'; + } + + function hasWriteAccess() + { + if (!file_exists($this->install_dir)) { + $dir = $this->install_dir; + while ($dir && $dir != '.') { + $olddir = $dir; + $dir = dirname($dir); + if ($dir != '.' && file_exists($dir)) { + if (is_writeable($dir)) { + return true; + } + + return false; + } + + if ($dir == $olddir) { // this can happen in safe mode + return @is_writable($dir); + } + } + + return false; + } + + return is_writeable($this->install_dir); + } + + function setConfig(&$config, $resetInstallDir = true) + { + $this->_config = &$config; + if ($resetInstallDir) { + $this->setInstallDir($config->get('php_dir')); + } + } + + function _initializeChannelDirs() + { + static $running = false; + if (!$running) { + $running = true; + $ds = DIRECTORY_SEPARATOR; + if (!is_dir($this->channelsdir) || + !file_exists($this->channelsdir . $ds . 'pear.php.net.reg') || + !file_exists($this->channelsdir . $ds . 'pecl.php.net.reg') || + !file_exists($this->channelsdir . $ds . 'doc.php.net.reg') || + !file_exists($this->channelsdir . $ds . '__uri.reg')) { + if (!file_exists($this->channelsdir . $ds . 'pear.php.net.reg')) { + $pear_channel = $this->_pearChannel; + if (!is_a($pear_channel, 'PEAR_ChannelFile') || !$pear_channel->validate()) { + if (!class_exists('PEAR_ChannelFile')) { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/ChannelFile.php'; + } + + $pear_channel = new PEAR_ChannelFile; + $pear_channel->setAlias('pear'); + $pear_channel->setServer('pear.php.net'); + $pear_channel->setSummary('PHP Extension and Application Repository'); + $pear_channel->setDefaultPEARProtocols(); + $pear_channel->setBaseURL('REST1.0', 'http://pear.php.net/rest/'); + $pear_channel->setBaseURL('REST1.1', 'http://pear.php.net/rest/'); + $pear_channel->setBaseURL('REST1.3', 'http://pear.php.net/rest/'); + //$pear_channel->setBaseURL('REST1.4', 'http://pear.php.net/rest/'); + } else { + $pear_channel->setServer('pear.php.net'); + $pear_channel->setAlias('pear'); + } + + $pear_channel->validate(); + $this->_addChannel($pear_channel); + } + + if (!file_exists($this->channelsdir . $ds . 'pecl.php.net.reg')) { + $pecl_channel = $this->_peclChannel; + if (!is_a($pecl_channel, 'PEAR_ChannelFile') || !$pecl_channel->validate()) { + if (!class_exists('PEAR_ChannelFile')) { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/ChannelFile.php'; + } + + $pecl_channel = new PEAR_ChannelFile; + $pecl_channel->setAlias('pecl'); + $pecl_channel->setServer('pecl.php.net'); + $pecl_channel->setSummary('PHP Extension Community Library'); + $pecl_channel->setDefaultPEARProtocols(); + $pecl_channel->setBaseURL('REST1.0', 'http://pecl.php.net/rest/'); + $pecl_channel->setBaseURL('REST1.1', 'http://pecl.php.net/rest/'); + $pecl_channel->setValidationPackage('PEAR_Validator_PECL', '1.0'); + } else { + $pecl_channel->setServer('pecl.php.net'); + $pecl_channel->setAlias('pecl'); + } + + $pecl_channel->validate(); + $this->_addChannel($pecl_channel); + } + + if (!file_exists($this->channelsdir . $ds . 'doc.php.net.reg')) { + $doc_channel = $this->_docChannel; + if (!is_a($doc_channel, 'PEAR_ChannelFile') || !$doc_channel->validate()) { + if (!class_exists('PEAR_ChannelFile')) { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/ChannelFile.php'; + } + + $doc_channel = new PEAR_ChannelFile; + $doc_channel->setAlias('phpdocs'); + $doc_channel->setServer('doc.php.net'); + $doc_channel->setSummary('PHP Documentation Team'); + $doc_channel->setDefaultPEARProtocols(); + $doc_channel->setBaseURL('REST1.0', 'http://doc.php.net/rest/'); + $doc_channel->setBaseURL('REST1.1', 'http://doc.php.net/rest/'); + $doc_channel->setBaseURL('REST1.3', 'http://doc.php.net/rest/'); + } else { + $doc_channel->setServer('doc.php.net'); + $doc_channel->setAlias('doc'); + } + + $doc_channel->validate(); + $this->_addChannel($doc_channel); + } + + if (!file_exists($this->channelsdir . $ds . '__uri.reg')) { + if (!class_exists('PEAR_ChannelFile')) { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/ChannelFile.php'; + } + + $private = new PEAR_ChannelFile; + $private->setName('__uri'); + $private->setDefaultPEARProtocols(); + $private->setBaseURL('REST1.0', '****'); + $private->setSummary('Pseudo-channel for static packages'); + $this->_addChannel($private); + } + $this->_rebuildFileMap(); + } + + $running = false; + } + } + + function _initializeDirs() + { + $ds = DIRECTORY_SEPARATOR; + // XXX Compatibility code should be removed in the future + // rename all registry files if any to lowercase + if (!OS_WINDOWS && file_exists($this->statedir) && is_dir($this->statedir) && + $handle = opendir($this->statedir)) { + $dest = $this->statedir . $ds; + while (false !== ($file = readdir($handle))) { + if (preg_match('/^.*[A-Z].*\.reg\\z/', $file)) { + rename($dest . $file, $dest . strtolower($file)); + } + } + closedir($handle); + } + + $this->_initializeChannelDirs(); + if (!file_exists($this->filemap)) { + $this->_rebuildFileMap(); + } + $this->_initializeDepDB(); + } + + function _initializeDepDB() + { + if (!isset($this->_dependencyDB)) { + static $initializing = false; + if (!$initializing) { + $initializing = true; + if (!$this->_config) { // never used? + $file = OS_WINDOWS ? 'pear.ini' : '.pearrc'; + $this->_config = &new PEAR_Config($this->statedir . DIRECTORY_SEPARATOR . + $file); + $this->_config->setRegistry($this); + $this->_config->set('php_dir', $this->install_dir); + } + + $this->_dependencyDB = &PEAR_DependencyDB::singleton($this->_config); + if (PEAR::isError($this->_dependencyDB)) { + // attempt to recover by removing the dep db + if (file_exists($this->_config->get('php_dir', null, 'pear.php.net') . + DIRECTORY_SEPARATOR . '.depdb')) { + @unlink($this->_config->get('php_dir', null, 'pear.php.net') . + DIRECTORY_SEPARATOR . '.depdb'); + } + + $this->_dependencyDB = &PEAR_DependencyDB::singleton($this->_config); + if (PEAR::isError($this->_dependencyDB)) { + echo $this->_dependencyDB->getMessage(); + echo 'Unrecoverable error'; + exit(1); + } + } + + $initializing = false; + } + } + } + + /** + * PEAR_Registry destructor. Makes sure no locks are forgotten. + * + * @access private + */ + function _PEAR_Registry() + { + parent::_PEAR(); + if (is_resource($this->lock_fp)) { + $this->_unlock(); + } + } + + /** + * Make sure the directory where we keep registry files exists. + * + * @return bool TRUE if directory exists, FALSE if it could not be + * created + * + * @access private + */ + function _assertStateDir($channel = false) + { + if ($channel && $this->_getChannelFromAlias($channel) != 'pear.php.net') { + return $this->_assertChannelStateDir($channel); + } + + static $init = false; + if (!file_exists($this->statedir)) { + if (!$this->hasWriteAccess()) { + return false; + } + + require_once 'phar://install-pear-nozlib.phar/' . 'System.php'; + if (!System::mkdir(array('-p', $this->statedir))) { + return $this->raiseError("could not create directory '{$this->statedir}'"); + } + $init = true; + } elseif (!is_dir($this->statedir)) { + return $this->raiseError('Cannot create directory ' . $this->statedir . ', ' . + 'it already exists and is not a directory'); + } + + $ds = DIRECTORY_SEPARATOR; + if (!file_exists($this->channelsdir)) { + if (!file_exists($this->channelsdir . $ds . 'pear.php.net.reg') || + !file_exists($this->channelsdir . $ds . 'pecl.php.net.reg') || + !file_exists($this->channelsdir . $ds . 'doc.php.net.reg') || + !file_exists($this->channelsdir . $ds . '__uri.reg')) { + $init = true; + } + } elseif (!is_dir($this->channelsdir)) { + return $this->raiseError('Cannot create directory ' . $this->channelsdir . ', ' . + 'it already exists and is not a directory'); + } + + if ($init) { + static $running = false; + if (!$running) { + $running = true; + $this->_initializeDirs(); + $running = false; + $init = false; + } + } else { + $this->_initializeDepDB(); + } + + return true; + } + + /** + * Make sure the directory where we keep registry files exists for a non-standard channel. + * + * @param string channel name + * @return bool TRUE if directory exists, FALSE if it could not be + * created + * + * @access private + */ + function _assertChannelStateDir($channel) + { + $ds = DIRECTORY_SEPARATOR; + if (!$channel || $this->_getChannelFromAlias($channel) == 'pear.php.net') { + if (!file_exists($this->channelsdir . $ds . 'pear.php.net.reg')) { + $this->_initializeChannelDirs(); + } + return $this->_assertStateDir($channel); + } + + $channelDir = $this->_channelDirectoryName($channel); + if (!is_dir($this->channelsdir) || + !file_exists($this->channelsdir . $ds . 'pear.php.net.reg')) { + $this->_initializeChannelDirs(); + } + + if (!file_exists($channelDir)) { + if (!$this->hasWriteAccess()) { + return false; + } + + require_once 'phar://install-pear-nozlib.phar/' . 'System.php'; + if (!System::mkdir(array('-p', $channelDir))) { + return $this->raiseError("could not create directory '" . $channelDir . + "'"); + } + } elseif (!is_dir($channelDir)) { + return $this->raiseError("could not create directory '" . $channelDir . + "', already exists and is not a directory"); + } + + return true; + } + + /** + * Make sure the directory where we keep registry files for channels exists + * + * @return bool TRUE if directory exists, FALSE if it could not be + * created + * + * @access private + */ + function _assertChannelDir() + { + if (!file_exists($this->channelsdir)) { + if (!$this->hasWriteAccess()) { + return false; + } + + require_once 'phar://install-pear-nozlib.phar/' . 'System.php'; + if (!System::mkdir(array('-p', $this->channelsdir))) { + return $this->raiseError("could not create directory '{$this->channelsdir}'"); + } + } elseif (!is_dir($this->channelsdir)) { + return $this->raiseError("could not create directory '{$this->channelsdir}" . + "', it already exists and is not a directory"); + } + + if (!file_exists($this->channelsdir . DIRECTORY_SEPARATOR . '.alias')) { + if (!$this->hasWriteAccess()) { + return false; + } + + require_once 'phar://install-pear-nozlib.phar/' . 'System.php'; + if (!System::mkdir(array('-p', $this->channelsdir . DIRECTORY_SEPARATOR . '.alias'))) { + return $this->raiseError("could not create directory '{$this->channelsdir}/.alias'"); + } + } elseif (!is_dir($this->channelsdir . DIRECTORY_SEPARATOR . '.alias')) { + return $this->raiseError("could not create directory '{$this->channelsdir}" . + "/.alias', it already exists and is not a directory"); + } + + return true; + } + + /** + * Get the name of the file where data for a given package is stored. + * + * @param string channel name, or false if this is a PEAR package + * @param string package name + * + * @return string registry file name + * + * @access public + */ + function _packageFileName($package, $channel = false) + { + if ($channel && $this->_getChannelFromAlias($channel) != 'pear.php.net') { + return $this->_channelDirectoryName($channel) . DIRECTORY_SEPARATOR . + strtolower($package) . '.reg'; + } + + return $this->statedir . DIRECTORY_SEPARATOR . strtolower($package) . '.reg'; + } + + /** + * Get the name of the file where data for a given channel is stored. + * @param string channel name + * @return string registry file name + */ + function _channelFileName($channel, $noaliases = false) + { + if (!$noaliases) { + if (file_exists($this->_getChannelAliasFileName($channel))) { + $channel = implode('', file($this->_getChannelAliasFileName($channel))); + } + } + return $this->channelsdir . DIRECTORY_SEPARATOR . str_replace('/', '_', + strtolower($channel)) . '.reg'; + } + + /** + * @param string + * @return string + */ + function _getChannelAliasFileName($alias) + { + return $this->channelsdir . DIRECTORY_SEPARATOR . '.alias' . + DIRECTORY_SEPARATOR . str_replace('/', '_', strtolower($alias)) . '.txt'; + } + + /** + * Get the name of a channel from its alias + */ + function _getChannelFromAlias($channel) + { + if (!$this->_channelExists($channel)) { + if ($channel == 'pear.php.net') { + return 'pear.php.net'; + } + + if ($channel == 'pecl.php.net') { + return 'pecl.php.net'; + } + + if ($channel == 'doc.php.net') { + return 'doc.php.net'; + } + + if ($channel == '__uri') { + return '__uri'; + } + + return false; + } + + $channel = strtolower($channel); + if (file_exists($this->_getChannelAliasFileName($channel))) { + // translate an alias to an actual channel + return implode('', file($this->_getChannelAliasFileName($channel))); + } + + return $channel; + } + + /** + * Get the alias of a channel from its alias or its name + */ + function _getAlias($channel) + { + if (!$this->_channelExists($channel)) { + if ($channel == 'pear.php.net') { + return 'pear'; + } + + if ($channel == 'pecl.php.net') { + return 'pecl'; + } + + if ($channel == 'doc.php.net') { + return 'phpdocs'; + } + + return false; + } + + $channel = $this->_getChannel($channel); + if (PEAR::isError($channel)) { + return $channel; + } + + return $channel->getAlias(); + } + + /** + * Get the name of the file where data for a given package is stored. + * + * @param string channel name, or false if this is a PEAR package + * @param string package name + * + * @return string registry file name + * + * @access public + */ + function _channelDirectoryName($channel) + { + if (!$channel || $this->_getChannelFromAlias($channel) == 'pear.php.net') { + return $this->statedir; + } + + $ch = $this->_getChannelFromAlias($channel); + if (!$ch) { + $ch = $channel; + } + + return $this->statedir . DIRECTORY_SEPARATOR . strtolower('.channel.' . + str_replace('/', '_', $ch)); + } + + function _openPackageFile($package, $mode, $channel = false) + { + if (!$this->_assertStateDir($channel)) { + return null; + } + + if (!in_array($mode, array('r', 'rb')) && !$this->hasWriteAccess()) { + return null; + } + + $file = $this->_packageFileName($package, $channel); + if (!file_exists($file) && $mode == 'r' || $mode == 'rb') { + return null; + } + + $fp = @fopen($file, $mode); + if (!$fp) { + return null; + } + + return $fp; + } + + function _closePackageFile($fp) + { + fclose($fp); + } + + function _openChannelFile($channel, $mode) + { + if (!$this->_assertChannelDir()) { + return null; + } + + if (!in_array($mode, array('r', 'rb')) && !$this->hasWriteAccess()) { + return null; + } + + $file = $this->_channelFileName($channel); + if (!file_exists($file) && $mode == 'r' || $mode == 'rb') { + return null; + } + + $fp = @fopen($file, $mode); + if (!$fp) { + return null; + } + + return $fp; + } + + function _closeChannelFile($fp) + { + fclose($fp); + } + + function _rebuildFileMap() + { + if (!class_exists('PEAR_Installer_Role')) { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Installer/Role.php'; + } + + $channels = $this->_listAllPackages(); + $files = array(); + foreach ($channels as $channel => $packages) { + foreach ($packages as $package) { + $version = $this->_packageInfo($package, 'version', $channel); + $filelist = $this->_packageInfo($package, 'filelist', $channel); + if (!is_array($filelist)) { + continue; + } + + foreach ($filelist as $name => $attrs) { + if (isset($attrs['attribs'])) { + $attrs = $attrs['attribs']; + } + + // it is possible for conflicting packages in different channels to + // conflict with data files/doc files + if ($name == 'dirtree') { + continue; + } + + if (isset($attrs['role']) && !in_array($attrs['role'], + PEAR_Installer_Role::getInstallableRoles())) { + // these are not installed + continue; + } + + if (isset($attrs['role']) && !in_array($attrs['role'], + PEAR_Installer_Role::getBaseinstallRoles())) { + $attrs['baseinstalldir'] = $package; + } + + if (isset($attrs['baseinstalldir'])) { + $file = $attrs['baseinstalldir'].DIRECTORY_SEPARATOR.$name; + } else { + $file = $name; + } + + $file = preg_replace(',^/+,', '', $file); + if ($channel != 'pear.php.net') { + if (!isset($files[$attrs['role']])) { + $files[$attrs['role']] = array(); + } + $files[$attrs['role']][$file] = array(strtolower($channel), + strtolower($package)); + } else { + if (!isset($files[$attrs['role']])) { + $files[$attrs['role']] = array(); + } + $files[$attrs['role']][$file] = strtolower($package); + } + } + } + } + + + $this->_assertStateDir(); + if (!$this->hasWriteAccess()) { + return false; + } + + $fp = @fopen($this->filemap, 'wb'); + if (!$fp) { + return false; + } + + $this->filemap_cache = $files; + fwrite($fp, serialize($files)); + fclose($fp); + return true; + } + + function _readFileMap() + { + if (!file_exists($this->filemap)) { + return array(); + } + + $fp = @fopen($this->filemap, 'r'); + if (!$fp) { + return $this->raiseError('PEAR_Registry: could not open filemap "' . $this->filemap . '"', PEAR_REGISTRY_ERROR_FILE, null, null, $php_errormsg); + } + + clearstatcache(); + $rt = get_magic_quotes_runtime(); + set_magic_quotes_runtime(0); + $fsize = filesize($this->filemap); + fclose($fp); + $data = file_get_contents($this->filemap); + set_magic_quotes_runtime($rt); + $tmp = unserialize($data); + if (!$tmp && $fsize > 7) { + return $this->raiseError('PEAR_Registry: invalid filemap data', PEAR_REGISTRY_ERROR_FORMAT, null, null, $data); + } + + $this->filemap_cache = $tmp; + return true; + } + + /** + * Lock the registry. + * + * @param integer lock mode, one of LOCK_EX, LOCK_SH or LOCK_UN. + * See flock manual for more information. + * + * @return bool TRUE on success, FALSE if locking failed, or a + * PEAR error if some other error occurs (such as the + * lock file not being writable). + * + * @access private + */ + function _lock($mode = LOCK_EX) + { + if (stristr(php_uname(), 'Windows 9')) { + return true; + } + + if ($mode != LOCK_UN && is_resource($this->lock_fp)) { + // XXX does not check type of lock (LOCK_SH/LOCK_EX) + return true; + } + + if (!$this->_assertStateDir()) { + if ($mode == LOCK_EX) { + return $this->raiseError('Registry directory is not writeable by the current user'); + } + + return true; + } + + $open_mode = 'w'; + // XXX People reported problems with LOCK_SH and 'w' + if ($mode === LOCK_SH || $mode === LOCK_UN) { + if (!file_exists($this->lockfile)) { + touch($this->lockfile); + } + $open_mode = 'r'; + } + + if (!is_resource($this->lock_fp)) { + $this->lock_fp = @fopen($this->lockfile, $open_mode); + } + + if (!is_resource($this->lock_fp)) { + $this->lock_fp = null; + return $this->raiseError("could not create lock file" . + (isset($php_errormsg) ? ": " . $php_errormsg : "")); + } + + if (!(int)flock($this->lock_fp, $mode)) { + switch ($mode) { + case LOCK_SH: $str = 'shared'; break; + case LOCK_EX: $str = 'exclusive'; break; + case LOCK_UN: $str = 'unlock'; break; + default: $str = 'unknown'; break; + } + + //is resource at this point, close it on error. + fclose($this->lock_fp); + $this->lock_fp = null; + return $this->raiseError("could not acquire $str lock ($this->lockfile)", + PEAR_REGISTRY_ERROR_LOCK); + } + + return true; + } + + function _unlock() + { + $ret = $this->_lock(LOCK_UN); + if (is_resource($this->lock_fp)) { + fclose($this->lock_fp); + } + + $this->lock_fp = null; + return $ret; + } + + function _packageExists($package, $channel = false) + { + return file_exists($this->_packageFileName($package, $channel)); + } + + /** + * Determine whether a channel exists in the registry + * + * @param string Channel name + * @param bool if true, then aliases will be ignored + * @return boolean + */ + function _channelExists($channel, $noaliases = false) + { + $a = file_exists($this->_channelFileName($channel, $noaliases)); + if (!$a && $channel == 'pear.php.net') { + return true; + } + + if (!$a && $channel == 'pecl.php.net') { + return true; + } + + if (!$a && $channel == 'doc.php.net') { + return true; + } + + return $a; + } + + /** + * Determine whether a mirror exists within the deafult channel in the registry + * + * @param string Channel name + * @param string Mirror name + * + * @return boolean + */ + function _mirrorExists($channel, $mirror) + { + $data = $this->_channelInfo($channel); + if (!isset($data['servers']['mirror'])) { + return false; + } + + foreach ($data['servers']['mirror'] as $m) { + if ($m['attribs']['host'] == $mirror) { + return true; + } + } + + return false; + } + + /** + * @param PEAR_ChannelFile Channel object + * @param donotuse + * @param string Last-Modified HTTP tag from remote request + * @return boolean|PEAR_Error True on creation, false if it already exists + */ + function _addChannel($channel, $update = false, $lastmodified = false) + { + if (!is_a($channel, 'PEAR_ChannelFile')) { + return false; + } + + if (!$channel->validate()) { + return false; + } + + if (file_exists($this->_channelFileName($channel->getName()))) { + if (!$update) { + return false; + } + + $checker = $this->_getChannel($channel->getName()); + if (PEAR::isError($checker)) { + return $checker; + } + + if ($channel->getAlias() != $checker->getAlias()) { + if (file_exists($this->_getChannelAliasFileName($checker->getAlias()))) { + @unlink($this->_getChannelAliasFileName($checker->getAlias())); + } + } + } else { + if ($update && !in_array($channel->getName(), array('pear.php.net', 'pecl.php.net', 'doc.php.net'))) { + return false; + } + } + + $ret = $this->_assertChannelDir(); + if (PEAR::isError($ret)) { + return $ret; + } + + $ret = $this->_assertChannelStateDir($channel->getName()); + if (PEAR::isError($ret)) { + return $ret; + } + + if ($channel->getAlias() != $channel->getName()) { + if (file_exists($this->_getChannelAliasFileName($channel->getAlias())) && + $this->_getChannelFromAlias($channel->getAlias()) != $channel->getName()) { + $channel->setAlias($channel->getName()); + } + + if (!$this->hasWriteAccess()) { + return false; + } + + $fp = @fopen($this->_getChannelAliasFileName($channel->getAlias()), 'w'); + if (!$fp) { + return false; + } + + fwrite($fp, $channel->getName()); + fclose($fp); + } + + if (!$this->hasWriteAccess()) { + return false; + } + + $fp = @fopen($this->_channelFileName($channel->getName()), 'wb'); + if (!$fp) { + return false; + } + + $info = $channel->toArray(); + if ($lastmodified) { + $info['_lastmodified'] = $lastmodified; + } else { + $info['_lastmodified'] = date('r'); + } + + fwrite($fp, serialize($info)); + fclose($fp); + return true; + } + + /** + * Deletion fails if there are any packages installed from the channel + * @param string|PEAR_ChannelFile channel name + * @return boolean|PEAR_Error True on deletion, false if it doesn't exist + */ + function _deleteChannel($channel) + { + if (!is_string($channel)) { + if (!is_a($channel, 'PEAR_ChannelFile')) { + return false; + } + + if (!$channel->validate()) { + return false; + } + $channel = $channel->getName(); + } + + if ($this->_getChannelFromAlias($channel) == '__uri') { + return false; + } + + if ($this->_getChannelFromAlias($channel) == 'pecl.php.net') { + return false; + } + + if ($this->_getChannelFromAlias($channel) == 'doc.php.net') { + return false; + } + + if (!$this->_channelExists($channel)) { + return false; + } + + if (!$channel || $this->_getChannelFromAlias($channel) == 'pear.php.net') { + return false; + } + + $channel = $this->_getChannelFromAlias($channel); + if ($channel == 'pear.php.net') { + return false; + } + + $test = $this->_listChannelPackages($channel); + if (count($test)) { + return false; + } + + $test = @rmdir($this->_channelDirectoryName($channel)); + if (!$test) { + return false; + } + + $file = $this->_getChannelAliasFileName($this->_getAlias($channel)); + if (file_exists($file)) { + $test = @unlink($file); + if (!$test) { + return false; + } + } + + $file = $this->_channelFileName($channel); + $ret = true; + if (file_exists($file)) { + $ret = @unlink($file); + } + + return $ret; + } + + /** + * Determine whether a channel exists in the registry + * @param string Channel Alias + * @return boolean + */ + function _isChannelAlias($alias) + { + return file_exists($this->_getChannelAliasFileName($alias)); + } + + /** + * @param string|null + * @param string|null + * @param string|null + * @return array|null + * @access private + */ + function _packageInfo($package = null, $key = null, $channel = 'pear.php.net') + { + if ($package === null) { + if ($channel === null) { + $channels = $this->_listChannels(); + $ret = array(); + foreach ($channels as $channel) { + $channel = strtolower($channel); + $ret[$channel] = array(); + $packages = $this->_listPackages($channel); + foreach ($packages as $package) { + $ret[$channel][] = $this->_packageInfo($package, null, $channel); + } + } + + return $ret; + } + + $ps = $this->_listPackages($channel); + if (!count($ps)) { + return array(); + } + return array_map(array(&$this, '_packageInfo'), + $ps, array_fill(0, count($ps), null), + array_fill(0, count($ps), $channel)); + } + + $fp = $this->_openPackageFile($package, 'r', $channel); + if ($fp === null) { + return null; + } + + $rt = get_magic_quotes_runtime(); + set_magic_quotes_runtime(0); + clearstatcache(); + $this->_closePackageFile($fp); + $data = file_get_contents($this->_packageFileName($package, $channel)); + set_magic_quotes_runtime($rt); + $data = unserialize($data); + if ($key === null) { + return $data; + } + + // compatibility for package.xml version 2.0 + if (isset($data['old'][$key])) { + return $data['old'][$key]; + } + + if (isset($data[$key])) { + return $data[$key]; + } + + return null; + } + + /** + * @param string Channel name + * @param bool whether to strictly retrieve info of channels, not just aliases + * @return array|null + */ + function _channelInfo($channel, $noaliases = false) + { + if (!$this->_channelExists($channel, $noaliases)) { + return null; + } + + $fp = $this->_openChannelFile($channel, 'r'); + if ($fp === null) { + return null; + } + + $rt = get_magic_quotes_runtime(); + set_magic_quotes_runtime(0); + clearstatcache(); + $this->_closeChannelFile($fp); + $data = file_get_contents($this->_channelFileName($channel)); + set_magic_quotes_runtime($rt); + $data = unserialize($data); + return $data; + } + + function _listChannels() + { + $channellist = array(); + if (!file_exists($this->channelsdir) || !is_dir($this->channelsdir)) { + return array('pear.php.net', 'pecl.php.net', 'doc.php.net', '__uri'); + } + + $dp = opendir($this->channelsdir); + while ($ent = readdir($dp)) { + if ($ent{0} == '.' || substr($ent, -4) != '.reg') { + continue; + } + + if ($ent == '__uri.reg') { + $channellist[] = '__uri'; + continue; + } + + $channellist[] = str_replace('_', '/', substr($ent, 0, -4)); + } + + closedir($dp); + if (!in_array('pear.php.net', $channellist)) { + $channellist[] = 'pear.php.net'; + } + + if (!in_array('pecl.php.net', $channellist)) { + $channellist[] = 'pecl.php.net'; + } + + if (!in_array('doc.php.net', $channellist)) { + $channellist[] = 'doc.php.net'; + } + + + if (!in_array('__uri', $channellist)) { + $channellist[] = '__uri'; + } + + natsort($channellist); + return $channellist; + } + + function _listPackages($channel = false) + { + if ($channel && $this->_getChannelFromAlias($channel) != 'pear.php.net') { + return $this->_listChannelPackages($channel); + } + + if (!file_exists($this->statedir) || !is_dir($this->statedir)) { + return array(); + } + + $pkglist = array(); + $dp = opendir($this->statedir); + if (!$dp) { + return $pkglist; + } + + while ($ent = readdir($dp)) { + if ($ent{0} == '.' || substr($ent, -4) != '.reg') { + continue; + } + + $pkglist[] = substr($ent, 0, -4); + } + closedir($dp); + return $pkglist; + } + + function _listChannelPackages($channel) + { + $pkglist = array(); + if (!file_exists($this->_channelDirectoryName($channel)) || + !is_dir($this->_channelDirectoryName($channel))) { + return array(); + } + + $dp = opendir($this->_channelDirectoryName($channel)); + if (!$dp) { + return $pkglist; + } + + while ($ent = readdir($dp)) { + if ($ent{0} == '.' || substr($ent, -4) != '.reg') { + continue; + } + $pkglist[] = substr($ent, 0, -4); + } + + closedir($dp); + return $pkglist; + } + + function _listAllPackages() + { + $ret = array(); + foreach ($this->_listChannels() as $channel) { + $ret[$channel] = $this->_listPackages($channel); + } + + return $ret; + } + + /** + * Add an installed package to the registry + * @param string package name + * @param array package info (parsed by PEAR_Common::infoFrom*() methods) + * @return bool success of saving + * @access private + */ + function _addPackage($package, $info) + { + if ($this->_packageExists($package)) { + return false; + } + + $fp = $this->_openPackageFile($package, 'wb'); + if ($fp === null) { + return false; + } + + $info['_lastmodified'] = time(); + fwrite($fp, serialize($info)); + $this->_closePackageFile($fp); + if (isset($info['filelist'])) { + $this->_rebuildFileMap(); + } + + return true; + } + + /** + * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 + * @return bool + * @access private + */ + function _addPackage2($info) + { + if (!is_a($info, 'PEAR_PackageFile_v1') && !is_a($info, 'PEAR_PackageFile_v2')) { + return false; + } + + if (!$info->validate()) { + if (class_exists('PEAR_Common')) { + $ui = PEAR_Frontend::singleton(); + if ($ui) { + foreach ($info->getValidationWarnings() as $err) { + $ui->log($err['message'], true); + } + } + } + return false; + } + + $channel = $info->getChannel(); + $package = $info->getPackage(); + $save = $info; + if ($this->_packageExists($package, $channel)) { + return false; + } + + if (!$this->_channelExists($channel, true)) { + return false; + } + + $info = $info->toArray(true); + if (!$info) { + return false; + } + + $fp = $this->_openPackageFile($package, 'wb', $channel); + if ($fp === null) { + return false; + } + + $info['_lastmodified'] = time(); + fwrite($fp, serialize($info)); + $this->_closePackageFile($fp); + $this->_rebuildFileMap(); + return true; + } + + /** + * @param string Package name + * @param array parsed package.xml 1.0 + * @param bool this parameter is only here for BC. Don't use it. + * @access private + */ + function _updatePackage($package, $info, $merge = true) + { + $oldinfo = $this->_packageInfo($package); + if (empty($oldinfo)) { + return false; + } + + $fp = $this->_openPackageFile($package, 'w'); + if ($fp === null) { + return false; + } + + if (is_object($info)) { + $info = $info->toArray(); + } + $info['_lastmodified'] = time(); + + $newinfo = $info; + if ($merge) { + $info = array_merge($oldinfo, $info); + } else { + $diff = $info; + } + + fwrite($fp, serialize($info)); + $this->_closePackageFile($fp); + if (isset($newinfo['filelist'])) { + $this->_rebuildFileMap(); + } + + return true; + } + + /** + * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 + * @return bool + * @access private + */ + function _updatePackage2($info) + { + if (!$this->_packageExists($info->getPackage(), $info->getChannel())) { + return false; + } + + $fp = $this->_openPackageFile($info->getPackage(), 'w', $info->getChannel()); + if ($fp === null) { + return false; + } + + $save = $info; + $info = $save->getArray(true); + $info['_lastmodified'] = time(); + fwrite($fp, serialize($info)); + $this->_closePackageFile($fp); + $this->_rebuildFileMap(); + return true; + } + + /** + * @param string Package name + * @param string Channel name + * @return PEAR_PackageFile_v1|PEAR_PackageFile_v2|null + * @access private + */ + function &_getPackage($package, $channel = 'pear.php.net') + { + $info = $this->_packageInfo($package, null, $channel); + if ($info === null) { + return $info; + } + + $a = $this->_config; + if (!$a) { + $this->_config = &new PEAR_Config; + $this->_config->set('php_dir', $this->statedir); + } + + if (!class_exists('PEAR_PackageFile')) { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/PackageFile.php'; + } + + $pkg = &new PEAR_PackageFile($this->_config); + $pf = &$pkg->fromArray($info); + return $pf; + } + + /** + * @param string channel name + * @param bool whether to strictly retrieve channel names + * @return PEAR_ChannelFile|PEAR_Error + * @access private + */ + function &_getChannel($channel, $noaliases = false) + { + $ch = false; + if ($this->_channelExists($channel, $noaliases)) { + $chinfo = $this->_channelInfo($channel, $noaliases); + if ($chinfo) { + if (!class_exists('PEAR_ChannelFile')) { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/ChannelFile.php'; + } + + $ch = &PEAR_ChannelFile::fromArrayWithErrors($chinfo); + } + } + + if ($ch) { + if ($ch->validate()) { + return $ch; + } + + foreach ($ch->getErrors(true) as $err) { + $message = $err['message'] . "\n"; + } + + $ch = PEAR::raiseError($message); + return $ch; + } + + if ($this->_getChannelFromAlias($channel) == 'pear.php.net') { + // the registry is not properly set up, so use defaults + if (!class_exists('PEAR_ChannelFile')) { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/ChannelFile.php'; + } + + $pear_channel = new PEAR_ChannelFile; + $pear_channel->setServer('pear.php.net'); + $pear_channel->setAlias('pear'); + $pear_channel->setSummary('PHP Extension and Application Repository'); + $pear_channel->setDefaultPEARProtocols(); + $pear_channel->setBaseURL('REST1.0', 'http://pear.php.net/rest/'); + $pear_channel->setBaseURL('REST1.1', 'http://pear.php.net/rest/'); + $pear_channel->setBaseURL('REST1.3', 'http://pear.php.net/rest/'); + return $pear_channel; + } + + if ($this->_getChannelFromAlias($channel) == 'pecl.php.net') { + // the registry is not properly set up, so use defaults + if (!class_exists('PEAR_ChannelFile')) { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/ChannelFile.php'; + } + $pear_channel = new PEAR_ChannelFile; + $pear_channel->setServer('pecl.php.net'); + $pear_channel->setAlias('pecl'); + $pear_channel->setSummary('PHP Extension Community Library'); + $pear_channel->setDefaultPEARProtocols(); + $pear_channel->setBaseURL('REST1.0', 'http://pecl.php.net/rest/'); + $pear_channel->setBaseURL('REST1.1', 'http://pecl.php.net/rest/'); + $pear_channel->setValidationPackage('PEAR_Validator_PECL', '1.0'); + return $pear_channel; + } + + if ($this->_getChannelFromAlias($channel) == 'doc.php.net') { + // the registry is not properly set up, so use defaults + if (!class_exists('PEAR_ChannelFile')) { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/ChannelFile.php'; + } + + $doc_channel = new PEAR_ChannelFile; + $doc_channel->setServer('doc.php.net'); + $doc_channel->setAlias('phpdocs'); + $doc_channel->setSummary('PHP Documentation Team'); + $doc_channel->setDefaultPEARProtocols(); + $doc_channel->setBaseURL('REST1.0', 'http://doc.php.net/rest/'); + $doc_channel->setBaseURL('REST1.1', 'http://doc.php.net/rest/'); + $doc_channel->setBaseURL('REST1.3', 'http://doc.php.net/rest/'); + return $doc_channel; + } + + + if ($this->_getChannelFromAlias($channel) == '__uri') { + // the registry is not properly set up, so use defaults + if (!class_exists('PEAR_ChannelFile')) { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/ChannelFile.php'; + } + + $private = new PEAR_ChannelFile; + $private->setName('__uri'); + $private->setDefaultPEARProtocols(); + $private->setBaseURL('REST1.0', '****'); + $private->setSummary('Pseudo-channel for static packages'); + return $private; + } + + return $ch; + } + + /** + * @param string Package name + * @param string Channel name + * @return bool + */ + function packageExists($package, $channel = 'pear.php.net') + { + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + $ret = $this->_packageExists($package, $channel); + $this->_unlock(); + return $ret; + } + + // }}} + + // {{{ channelExists() + + /** + * @param string channel name + * @param bool if true, then aliases will be ignored + * @return bool + */ + function channelExists($channel, $noaliases = false) + { + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + $ret = $this->_channelExists($channel, $noaliases); + $this->_unlock(); + return $ret; + } + + // }}} + + /** + * @param string channel name mirror is in + * @param string mirror name + * + * @return bool + */ + function mirrorExists($channel, $mirror) + { + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + + $ret = $this->_mirrorExists($channel, $mirror); + $this->_unlock(); + return $ret; + } + + // {{{ isAlias() + + /** + * Determines whether the parameter is an alias of a channel + * @param string + * @return bool + */ + function isAlias($alias) + { + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + $ret = $this->_isChannelAlias($alias); + $this->_unlock(); + return $ret; + } + + // }}} + // {{{ packageInfo() + + /** + * @param string|null + * @param string|null + * @param string + * @return array|null + */ + function packageInfo($package = null, $key = null, $channel = 'pear.php.net') + { + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + $ret = $this->_packageInfo($package, $key, $channel); + $this->_unlock(); + return $ret; + } + + // }}} + // {{{ channelInfo() + + /** + * Retrieve a raw array of channel data. + * + * Do not use this, instead use {@link getChannel()} for normal + * operations. Array structure is undefined in this method + * @param string channel name + * @param bool whether to strictly retrieve information only on non-aliases + * @return array|null|PEAR_Error + */ + function channelInfo($channel = null, $noaliases = false) + { + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + $ret = $this->_channelInfo($channel, $noaliases); + $this->_unlock(); + return $ret; + } + + // }}} + + /** + * @param string + */ + function channelName($channel) + { + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + $ret = $this->_getChannelFromAlias($channel); + $this->_unlock(); + return $ret; + } + + /** + * @param string + */ + function channelAlias($channel) + { + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + $ret = $this->_getAlias($channel); + $this->_unlock(); + return $ret; + } + // {{{ listPackages() + + function listPackages($channel = false) + { + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + $ret = $this->_listPackages($channel); + $this->_unlock(); + return $ret; + } + + // }}} + // {{{ listAllPackages() + + function listAllPackages() + { + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + $ret = $this->_listAllPackages(); + $this->_unlock(); + return $ret; + } + + // }}} + // {{{ listChannel() + + function listChannels() + { + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + $ret = $this->_listChannels(); + $this->_unlock(); + return $ret; + } + + // }}} + // {{{ addPackage() + + /** + * Add an installed package to the registry + * @param string|PEAR_PackageFile_v1|PEAR_PackageFile_v2 package name or object + * that will be passed to {@link addPackage2()} + * @param array package info (parsed by PEAR_Common::infoFrom*() methods) + * @return bool success of saving + */ + function addPackage($package, $info) + { + if (is_object($info)) { + return $this->addPackage2($info); + } + if (PEAR::isError($e = $this->_lock(LOCK_EX))) { + return $e; + } + $ret = $this->_addPackage($package, $info); + $this->_unlock(); + if ($ret) { + if (!class_exists('PEAR_PackageFile_v1')) { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/PackageFile/v1.php'; + } + $pf = new PEAR_PackageFile_v1; + $pf->setConfig($this->_config); + $pf->fromArray($info); + $this->_dependencyDB->uninstallPackage($pf); + $this->_dependencyDB->installPackage($pf); + } + return $ret; + } + + // }}} + // {{{ addPackage2() + + function addPackage2($info) + { + if (!is_object($info)) { + return $this->addPackage($info['package'], $info); + } + if (PEAR::isError($e = $this->_lock(LOCK_EX))) { + return $e; + } + $ret = $this->_addPackage2($info); + $this->_unlock(); + if ($ret) { + $this->_dependencyDB->uninstallPackage($info); + $this->_dependencyDB->installPackage($info); + } + return $ret; + } + + // }}} + // {{{ updateChannel() + + /** + * For future expandibility purposes, separate this + * @param PEAR_ChannelFile + */ + function updateChannel($channel, $lastmodified = null) + { + if ($channel->getName() == '__uri') { + return false; + } + return $this->addChannel($channel, $lastmodified, true); + } + + // }}} + // {{{ deleteChannel() + + /** + * Deletion fails if there are any packages installed from the channel + * @param string|PEAR_ChannelFile channel name + * @return boolean|PEAR_Error True on deletion, false if it doesn't exist + */ + function deleteChannel($channel) + { + if (PEAR::isError($e = $this->_lock(LOCK_EX))) { + return $e; + } + + $ret = $this->_deleteChannel($channel); + $this->_unlock(); + if ($ret && is_a($this->_config, 'PEAR_Config')) { + $this->_config->setChannels($this->listChannels()); + } + + return $ret; + } + + // }}} + // {{{ addChannel() + + /** + * @param PEAR_ChannelFile Channel object + * @param string Last-Modified header from HTTP for caching + * @return boolean|PEAR_Error True on creation, false if it already exists + */ + function addChannel($channel, $lastmodified = false, $update = false) + { + if (!is_a($channel, 'PEAR_ChannelFile') || !$channel->validate()) { + return false; + } + + if (PEAR::isError($e = $this->_lock(LOCK_EX))) { + return $e; + } + + $ret = $this->_addChannel($channel, $update, $lastmodified); + $this->_unlock(); + if (!$update && $ret && is_a($this->_config, 'PEAR_Config')) { + $this->_config->setChannels($this->listChannels()); + } + + return $ret; + } + + // }}} + // {{{ deletePackage() + + function deletePackage($package, $channel = 'pear.php.net') + { + if (PEAR::isError($e = $this->_lock(LOCK_EX))) { + return $e; + } + + $file = $this->_packageFileName($package, $channel); + $ret = file_exists($file) ? @unlink($file) : false; + $this->_rebuildFileMap(); + $this->_unlock(); + $p = array('channel' => $channel, 'package' => $package); + $this->_dependencyDB->uninstallPackage($p); + return $ret; + } + + // }}} + // {{{ updatePackage() + + function updatePackage($package, $info, $merge = true) + { + if (is_object($info)) { + return $this->updatePackage2($info, $merge); + } + if (PEAR::isError($e = $this->_lock(LOCK_EX))) { + return $e; + } + $ret = $this->_updatePackage($package, $info, $merge); + $this->_unlock(); + if ($ret) { + if (!class_exists('PEAR_PackageFile_v1')) { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/PackageFile/v1.php'; + } + $pf = new PEAR_PackageFile_v1; + $pf->setConfig($this->_config); + $pf->fromArray($this->packageInfo($package)); + $this->_dependencyDB->uninstallPackage($pf); + $this->_dependencyDB->installPackage($pf); + } + return $ret; + } + + // }}} + // {{{ updatePackage2() + + function updatePackage2($info) + { + + if (!is_object($info)) { + return $this->updatePackage($info['package'], $info, $merge); + } + + if (!$info->validate(PEAR_VALIDATE_DOWNLOADING)) { + return false; + } + + if (PEAR::isError($e = $this->_lock(LOCK_EX))) { + return $e; + } + + $ret = $this->_updatePackage2($info); + $this->_unlock(); + if ($ret) { + $this->_dependencyDB->uninstallPackage($info); + $this->_dependencyDB->installPackage($info); + } + + return $ret; + } + + // }}} + // {{{ getChannel() + /** + * @param string channel name + * @param bool whether to strictly return raw channels (no aliases) + * @return PEAR_ChannelFile|PEAR_Error + */ + function &getChannel($channel, $noaliases = false) + { + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + $ret = &$this->_getChannel($channel, $noaliases); + $this->_unlock(); + if (!$ret) { + return PEAR::raiseError('Unknown channel: ' . $channel); + } + return $ret; + } + + // }}} + // {{{ getPackage() + /** + * @param string package name + * @param string channel name + * @return PEAR_PackageFile_v1|PEAR_PackageFile_v2|null + */ + function &getPackage($package, $channel = 'pear.php.net') + { + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + $pf = &$this->_getPackage($package, $channel); + $this->_unlock(); + return $pf; + } + + // }}} + + /** + * Get PEAR_PackageFile_v[1/2] objects representing the contents of + * a dependency group that are installed. + * + * This is used at uninstall-time + * @param array + * @return array|false + */ + function getInstalledGroup($group) + { + $ret = array(); + if (isset($group['package'])) { + if (!isset($group['package'][0])) { + $group['package'] = array($group['package']); + } + foreach ($group['package'] as $package) { + $depchannel = isset($package['channel']) ? $package['channel'] : '__uri'; + $p = &$this->getPackage($package['name'], $depchannel); + if ($p) { + $save = &$p; + $ret[] = &$save; + } + } + } + if (isset($group['subpackage'])) { + if (!isset($group['subpackage'][0])) { + $group['subpackage'] = array($group['subpackage']); + } + foreach ($group['subpackage'] as $package) { + $depchannel = isset($package['channel']) ? $package['channel'] : '__uri'; + $p = &$this->getPackage($package['name'], $depchannel); + if ($p) { + $save = &$p; + $ret[] = &$save; + } + } + } + if (!count($ret)) { + return false; + } + return $ret; + } + + // {{{ getChannelValidator() + /** + * @param string channel name + * @return PEAR_Validate|false + */ + function &getChannelValidator($channel) + { + $chan = $this->getChannel($channel); + if (PEAR::isError($chan)) { + return $chan; + } + $val = $chan->getValidationObject(); + return $val; + } + // }}} + // {{{ getChannels() + /** + * @param string channel name + * @return array an array of PEAR_ChannelFile objects representing every installed channel + */ + function &getChannels() + { + $ret = array(); + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + foreach ($this->_listChannels() as $channel) { + $e = &$this->_getChannel($channel); + if (!$e || PEAR::isError($e)) { + continue; + } + $ret[] = $e; + } + $this->_unlock(); + return $ret; + } + + // }}} + // {{{ checkFileMap() + + /** + * Test whether a file or set of files belongs to a package. + * + * If an array is passed in + * @param string|array file path, absolute or relative to the pear + * install dir + * @param string|array name of PEAR package or array('package' => name, 'channel' => + * channel) of a package that will be ignored + * @param string API version - 1.1 will exclude any files belonging to a package + * @param array private recursion variable + * @return array|false which package and channel the file belongs to, or an empty + * string if the file does not belong to an installed package, + * or belongs to the second parameter's package + */ + function checkFileMap($path, $package = false, $api = '1.0', $attrs = false) + { + if (is_array($path)) { + static $notempty; + if (empty($notempty)) { + if (!class_exists('PEAR_Installer_Role')) { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Installer/Role.php'; + } + $notempty = create_function('$a','return !empty($a);'); + } + $package = is_array($package) ? array(strtolower($package[0]), strtolower($package[1])) + : strtolower($package); + $pkgs = array(); + foreach ($path as $name => $attrs) { + if (is_array($attrs)) { + if (isset($attrs['install-as'])) { + $name = $attrs['install-as']; + } + if (!in_array($attrs['role'], PEAR_Installer_Role::getInstallableRoles())) { + // these are not installed + continue; + } + if (!in_array($attrs['role'], PEAR_Installer_Role::getBaseinstallRoles())) { + $attrs['baseinstalldir'] = is_array($package) ? $package[1] : $package; + } + if (isset($attrs['baseinstalldir'])) { + $name = $attrs['baseinstalldir'] . DIRECTORY_SEPARATOR . $name; + } + } + $pkgs[$name] = $this->checkFileMap($name, $package, $api, $attrs); + if (PEAR::isError($pkgs[$name])) { + return $pkgs[$name]; + } + } + return array_filter($pkgs, $notempty); + } + if (empty($this->filemap_cache)) { + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + $err = $this->_readFileMap(); + $this->_unlock(); + if (PEAR::isError($err)) { + return $err; + } + } + if (!$attrs) { + $attrs = array('role' => 'php'); // any old call would be for PHP role only + } + if (isset($this->filemap_cache[$attrs['role']][$path])) { + if ($api >= '1.1' && $this->filemap_cache[$attrs['role']][$path] == $package) { + return false; + } + return $this->filemap_cache[$attrs['role']][$path]; + } + $l = strlen($this->install_dir); + if (substr($path, 0, $l) == $this->install_dir) { + $path = preg_replace('!^'.DIRECTORY_SEPARATOR.'+!', '', substr($path, $l)); + } + if (isset($this->filemap_cache[$attrs['role']][$path])) { + if ($api >= '1.1' && $this->filemap_cache[$attrs['role']][$path] == $package) { + return false; + } + return $this->filemap_cache[$attrs['role']][$path]; + } + return false; + } + + // }}} + // {{{ flush() + /** + * Force a reload of the filemap + * @since 1.5.0RC3 + */ + function flushFileMap() + { + $this->filemap_cache = null; + clearstatcache(); // ensure that the next read gets the full, current filemap + } + + // }}} + // {{{ apiVersion() + /** + * Get the expected API version. Channels API is version 1.1, as it is backwards + * compatible with 1.0 + * @return string + */ + function apiVersion() + { + return '1.1'; + } + // }}} + + + /** + * Parse a package name, or validate a parsed package name array + * @param string|array pass in an array of format + * array( + * 'package' => 'pname', + * ['channel' => 'channame',] + * ['version' => 'version',] + * ['state' => 'state',] + * ['group' => 'groupname']) + * or a string of format + * [channel://][channame/]pname[-version|-state][/group=groupname] + * @return array|PEAR_Error + */ + function parsePackageName($param, $defaultchannel = 'pear.php.net') + { + $saveparam = $param; + if (is_array($param)) { + // convert to string for error messages + $saveparam = $this->parsedPackageNameToString($param); + // process the array + if (!isset($param['package'])) { + return PEAR::raiseError('parsePackageName(): array $param ' . + 'must contain a valid package name in index "param"', + 'package', null, null, $param); + } + if (!isset($param['uri'])) { + if (!isset($param['channel'])) { + $param['channel'] = $defaultchannel; + } + } else { + $param['channel'] = '__uri'; + } + } else { + $components = @parse_url((string) $param); + if (isset($components['scheme'])) { + if ($components['scheme'] == 'http') { + // uri package + $param = array('uri' => $param, 'channel' => '__uri'); + } elseif($components['scheme'] != 'channel') { + return PEAR::raiseError('parsePackageName(): only channel:// uris may ' . + 'be downloaded, not "' . $param . '"', 'invalid', null, null, $param); + } + } + if (!isset($components['path'])) { + return PEAR::raiseError('parsePackageName(): array $param ' . + 'must contain a valid package name in "' . $param . '"', + 'package', null, null, $param); + } + if (isset($components['host'])) { + // remove the leading "/" + $components['path'] = substr($components['path'], 1); + } + if (!isset($components['scheme'])) { + if (strpos($components['path'], '/') !== false) { + if ($components['path']{0} == '/') { + return PEAR::raiseError('parsePackageName(): this is not ' . + 'a package name, it begins with "/" in "' . $param . '"', + 'invalid', null, null, $param); + } + $parts = explode('/', $components['path']); + $components['host'] = array_shift($parts); + if (count($parts) > 1) { + $components['path'] = array_pop($parts); + $components['host'] .= '/' . implode('/', $parts); + } else { + $components['path'] = implode('/', $parts); + } + } else { + $components['host'] = $defaultchannel; + } + } else { + if (strpos($components['path'], '/')) { + $parts = explode('/', $components['path']); + $components['path'] = array_pop($parts); + $components['host'] .= '/' . implode('/', $parts); + } + } + + if (is_array($param)) { + $param['package'] = $components['path']; + } else { + $param = array( + 'package' => $components['path'] + ); + if (isset($components['host'])) { + $param['channel'] = $components['host']; + } + } + if (isset($components['fragment'])) { + $param['group'] = $components['fragment']; + } + if (isset($components['user'])) { + $param['user'] = $components['user']; + } + if (isset($components['pass'])) { + $param['pass'] = $components['pass']; + } + if (isset($components['query'])) { + parse_str($components['query'], $param['opts']); + } + // check for extension + $pathinfo = pathinfo($param['package']); + if (isset($pathinfo['extension']) && + in_array(strtolower($pathinfo['extension']), array('tgz', 'tar'))) { + $param['extension'] = $pathinfo['extension']; + $param['package'] = substr($pathinfo['basename'], 0, + strlen($pathinfo['basename']) - 4); + } + // check for version + if (strpos($param['package'], '-')) { + $test = explode('-', $param['package']); + if (count($test) != 2) { + return PEAR::raiseError('parsePackageName(): only one version/state ' . + 'delimiter "-" is allowed in "' . $saveparam . '"', + 'version', null, null, $param); + } + list($param['package'], $param['version']) = $test; + } + } + // validation + $info = $this->channelExists($param['channel']); + if (PEAR::isError($info)) { + return $info; + } + if (!$info) { + return PEAR::raiseError('unknown channel "' . $param['channel'] . + '" in "' . $saveparam . '"', 'channel', null, null, $param); + } + $chan = $this->getChannel($param['channel']); + if (PEAR::isError($chan)) { + return $chan; + } + if (!$chan) { + return PEAR::raiseError("Exception: corrupt registry, could not " . + "retrieve channel " . $param['channel'] . " information", + 'registry', null, null, $param); + } + $param['channel'] = $chan->getName(); + $validate = $chan->getValidationObject(); + $vpackage = $chan->getValidationPackage(); + // validate package name + if (!$validate->validPackageName($param['package'], $vpackage['_content'])) { + return PEAR::raiseError('parsePackageName(): invalid package name "' . + $param['package'] . '" in "' . $saveparam . '"', + 'package', null, null, $param); + } + if (isset($param['group'])) { + if (!PEAR_Validate::validGroupName($param['group'])) { + return PEAR::raiseError('parsePackageName(): dependency group "' . $param['group'] . + '" is not a valid group name in "' . $saveparam . '"', 'group', null, null, + $param); + } + } + if (isset($param['state'])) { + if (!in_array(strtolower($param['state']), $validate->getValidStates())) { + return PEAR::raiseError('parsePackageName(): state "' . $param['state'] + . '" is not a valid state in "' . $saveparam . '"', + 'state', null, null, $param); + } + } + if (isset($param['version'])) { + if (isset($param['state'])) { + return PEAR::raiseError('parsePackageName(): cannot contain both ' . + 'a version and a stability (state) in "' . $saveparam . '"', + 'version/state', null, null, $param); + } + // check whether version is actually a state + if (in_array(strtolower($param['version']), $validate->getValidStates())) { + $param['state'] = strtolower($param['version']); + unset($param['version']); + } else { + if (!$validate->validVersion($param['version'])) { + return PEAR::raiseError('parsePackageName(): "' . $param['version'] . + '" is neither a valid version nor a valid state in "' . + $saveparam . '"', 'version/state', null, null, $param); + } + } + } + return $param; + } + + /** + * @param array + * @return string + */ + function parsedPackageNameToString($parsed, $brief = false) + { + if (is_string($parsed)) { + return $parsed; + } + if (is_object($parsed)) { + $p = $parsed; + $parsed = array( + 'package' => $p->getPackage(), + 'channel' => $p->getChannel(), + 'version' => $p->getVersion(), + ); + } + if (isset($parsed['uri'])) { + return $parsed['uri']; + } + if ($brief) { + if ($channel = $this->channelAlias($parsed['channel'])) { + return $channel . '/' . $parsed['package']; + } + } + $upass = ''; + if (isset($parsed['user'])) { + $upass = $parsed['user']; + if (isset($parsed['pass'])) { + $upass .= ':' . $parsed['pass']; + } + $upass = "$upass@"; + } + $ret = 'channel://' . $upass . $parsed['channel'] . '/' . $parsed['package']; + if (isset($parsed['version']) || isset($parsed['state'])) { + $ver = isset($parsed['version']) ? $parsed['version'] : ''; + $ver .= isset($parsed['state']) ? $parsed['state'] : ''; + $ret .= '-' . $ver; + } + if (isset($parsed['extension'])) { + $ret .= '.' . $parsed['extension']; + } + if (isset($parsed['opts'])) { + $ret .= '?'; + foreach ($parsed['opts'] as $name => $value) { + $parsed['opts'][$name] = "$name=$value"; + } + $ret .= implode('&', $parsed['opts']); + } + if (isset($parsed['group'])) { + $ret .= '#' . $parsed['group']; + } + return $ret; + } }<?php /** * PEAR_REST @@ -83923,7 +84562,7 @@ class PEAR_Registry extends PEAR * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: REST.php,v 1.40 2009/03/26 23:12:46 dufuz Exp $ + * @version CVS: $Id: REST.php 286489 2009-07-29 05:59:08Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ @@ -83942,7 +84581,7 @@ require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/XMLParser.php'; * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ @@ -83953,7 +84592,7 @@ class PEAR_REST function PEAR_REST(&$config, $options = array()) { - $this->config = &$config; + $this->config = &$config; $this->_options = $options; } @@ -83970,7 +84609,6 @@ class PEAR_REST */ function retrieveCacheFirst($url, $accept = false, $forcestring = false, $channel = false) { - $cachefile = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR . md5($url) . 'rest.cachefile'; @@ -84127,11 +84765,9 @@ class PEAR_REST */ function saveCache($url, $contents, $lastmodified, $nochange = false, $cacheid = null) { - $cacheidfile = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR . - md5($url) . 'rest.cacheid'; - - $cachefile = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR . - md5($url) . 'rest.cachefile'; + $cachedir = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR . md5($url); + $cacheidfile = $cachedir . 'rest.cacheid'; + $cachefile = $cachedir . 'rest.cachefile'; if ($cacheid === null && $nochange) { $cacheid = unserialize(implode('', file($cacheidfile))); @@ -84265,7 +84901,7 @@ class PEAR_REST } $request .= $ifmodifiedsince . - "User-Agent: PEAR/1.8.0/PHP/" . PHP_VERSION . "\r\n"; + "User-Agent: PEAR/1.9.0/PHP/" . PHP_VERSION . "\r\n"; $username = $this->config->get('username', null, $channel); $password = $this->config->get('password', null, $channel); @@ -84373,7 +85009,7 @@ class PEAR_REST * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: 10.php,v 1.60 2009/03/07 23:09:56 dufuz Exp $ + * @version CVS: $Id: 10.php 287558 2009-08-21 22:21:28Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a12 */ @@ -84391,7 +85027,7 @@ require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/REST.php'; * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a12 */ @@ -84425,16 +85061,18 @@ class PEAR_REST_10 */ function getDownloadURL($base, $packageinfo, $prefstate, $installed, $channel = false) { - $channel = $packageinfo['channel']; - $package = $packageinfo['package']; $states = $this->betterStates($prefstate, true); if (!$states) { return PEAR::raiseError('"' . $prefstate . '" is not a valid state'); } - $state = isset($packageinfo['state']) ? $packageinfo['state'] : null; - $version = isset($packageinfo['version']) ? $packageinfo['version'] : null; - $info = $this->_rest->retrieveData($base . 'r/' . strtolower($package) . '/allreleases.xml', false, false, $channel); + $channel = $packageinfo['channel']; + $package = $packageinfo['package']; + $state = isset($packageinfo['state']) ? $packageinfo['state'] : null; + $version = isset($packageinfo['version']) ? $packageinfo['version'] : null; + $restFile = $base . 'r/' . strtolower($package) . '/allreleases.xml'; + + $info = $this->_rest->retrieveData($restFile, false, false, $channel); if (PEAR::isError($info)) { return PEAR::raiseError('No releases available for package "' . $channel . '/' . $package . '"'); @@ -84486,22 +85124,27 @@ class PEAR_REST_10 function getDepDownloadURL($base, $xsdversion, $dependency, $deppackage, $prefstate = 'stable', $installed = false, $channel = false) { - $channel = $dependency['channel']; - $package = $dependency['name']; $states = $this->betterStates($prefstate, true); if (!$states) { return PEAR::raiseError('"' . $prefstate . '" is not a valid state'); } - $state = isset($dependency['state']) ? $dependency['state'] : null; - $version = isset($dependency['version']) ? $dependency['version'] : null; - $info = $this->_rest->retrieveData($base . 'r/' . strtolower($package) . '/allreleases.xml', false, false, $channel); + + $channel = $dependency['channel']; + $package = $dependency['name']; + $state = isset($dependency['state']) ? $dependency['state'] : null; + $version = isset($dependency['version']) ? $dependency['version'] : null; + $restFile = $base . 'r/' . strtolower($package) . '/allreleases.xml'; + + $info = $this->_rest->retrieveData($restFile, false, false, $channel); if (PEAR::isError($info)) { return PEAR::raiseError('Package "' . $deppackage['channel'] . '/' . $deppackage['package'] . '" dependency "' . $channel . '/' . $package . '" has no releases'); } + if (!is_array($info) || !isset($info['r'])) { return false; } + $exclude = array(); $min = $max = $recommended = false; if ($xsdversion == '1.0') { @@ -84619,19 +85262,23 @@ class PEAR_REST_10 if (!$found) { $release = $info['r'][0]; } - $pinfo = $this->_rest->retrieveCacheFirst($base . 'p/' . strtolower($package) . '/' . + + $packageLower = strtolower($package); + $pinfo = $this->_rest->retrieveCacheFirst($base . 'p/' . $packageLower . '/' . 'info.xml', false, false, $channel); if (PEAR::isError($pinfo)) { return PEAR::raiseError('Package "' . $package . '" does not have REST info xml available'); } - $releaseinfo = $this->_rest->retrieveCacheFirst($base . 'r/' . strtolower($package) . '/' . + + $releaseinfo = $this->_rest->retrieveCacheFirst($base . 'r/' . $packageLower . '/' . $release['v'] . '.xml', false, false, $channel); if (PEAR::isError($releaseinfo)) { return PEAR::raiseError('Package "' . $package . '" Version "' . $release['v'] . '" does not have REST xml available'); } - $packagexml = $this->_rest->retrieveCacheFirst($base . 'r/' . strtolower($package) . '/' . + + $packagexml = $this->_rest->retrieveCacheFirst($base . 'r/' . $packageLower . '/' . 'deps.' . $release['v'] . '.txt', false, true, $channel); if (PEAR::isError($packagexml)) { return PEAR::raiseError('Package "' . $package . '" Version "' . $release['v'] . @@ -84642,39 +85289,49 @@ class PEAR_REST_10 if (!$packagexml) { $packagexml = array(); } - $allinfo = $this->_rest->retrieveData($base . 'r/' . strtolower($package) . + + $allinfo = $this->_rest->retrieveData($base . 'r/' . $packageLower . '/allreleases.xml', false, false, $channel); if (!is_array($allinfo['r']) || !isset($allinfo['r'][0])) { $allinfo['r'] = array($allinfo['r']); } + $compatible = false; foreach ($allinfo['r'] as $release) { if ($release['v'] != $releaseinfo['v']) { continue; } + if (!isset($release['co'])) { break; } + $compatible = array(); if (!is_array($release['co']) || !isset($release['co'][0])) { $release['co'] = array($release['co']); } + foreach ($release['co'] as $entry) { $comp = array(); - $comp['name'] = $entry['p']; + $comp['name'] = $entry['p']; $comp['channel'] = $entry['c']; - $comp['min'] = $entry['min']; - $comp['max'] = $entry['max']; + $comp['min'] = $entry['min']; + $comp['max'] = $entry['max']; if (isset($entry['x']) && !is_array($entry['x'])) { $comp['exclude'] = $entry['x']; } + $compatible[] = $comp; } + if (count($compatible) == 1) { $compatible = $compatible[0]; } + break; } + + $deprecated = false; if (isset($pinfo['dc']) && isset($pinfo['dp'])) { if (is_array($pinfo['dp'])) { $deprecated = array('channel' => (string) $pinfo['dc'], @@ -84683,30 +85340,24 @@ class PEAR_REST_10 $deprecated = array('channel' => (string) $pinfo['dc'], 'package' => trim($pinfo['dp'])); } - } else { - $deprecated = false; } + + $return = array( + 'version' => $releaseinfo['v'], + 'info' => $packagexml, + 'package' => $releaseinfo['p']['_content'], + 'stability' => $releaseinfo['st'], + 'compatible' => $compatible, + 'deprecated' => $deprecated, + ); + if ($found) { - return - array('version' => $releaseinfo['v'], - 'info' => $packagexml, - 'package' => $releaseinfo['p']['_content'], - 'stability' => $releaseinfo['st'], - 'url' => $releaseinfo['g'], - 'compatible' => $compatible, - 'deprecated' => $deprecated, - ); - } else { - return - array('version' => $releaseinfo['v'], - 'package' => $releaseinfo['p']['_content'], - 'stability' => $releaseinfo['st'], - 'info' => $packagexml, - 'compatible' => $compatible, - 'deprecated' => $deprecated, - 'php' => $phpversion - ); + $return['url'] = $releaseinfo['g']; + return $return; } + + $return['php'] = $phpversion; + return $return; } function listPackages($base, $channel = false) @@ -84715,12 +85366,15 @@ class PEAR_REST_10 if (PEAR::isError($packagelist)) { return $packagelist; } + if (!is_array($packagelist) || !isset($packagelist['p'])) { return array(); } + if (!is_array($packagelist['p'])) { $packagelist['p'] = array($packagelist['p']); } + return $packagelist['p']; } @@ -84741,10 +85395,12 @@ class PEAR_REST_10 if (PEAR::isError($packagelist)) { return $packagelist; } + if (!is_array($packagelist) || !isset($packagelist['p'])) { $ret = array(); return $ret; } + if (!is_array($packagelist['p'])) { $packagelist['p'] = array($packagelist['p']); } @@ -84761,6 +85417,7 @@ class PEAR_REST_10 $categories[$cat] = $inf['ca']; } } + return array_values($categories); } @@ -84779,9 +85436,11 @@ class PEAR_REST_10 if (PEAR::isError($packagelist)) { return $packagelist; } + if (!is_array($packagelist) || !isset($packagelist['p'])) { return array(); } + if (!is_array($packagelist['p']) || !isset($packagelist['p'][0])) { // only 1 pkg $packagelist = array($packagelist['p']); @@ -84825,7 +85484,7 @@ class PEAR_REST_10 } if ($this->_rest->config->get('verbose') > 0) { $ui = &PEAR_Frontend::singleton(); - $ui->log('Retrieving data...0%', false); + $ui->log('Retrieving data...0%', true); } $ret = array(); if (!is_array($packagelist) || !isset($packagelist['p'])) { @@ -86232,7 +86891,7 @@ Double-click this file to add it to the current user registry. * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Common.php,v 1.20 2009/02/25 00:15:49 dufuz Exp $ + * @version CVS: $Id: Common.php 276394 2009-02-25 00:15:49Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ @@ -86270,7 +86929,7 @@ define('PEAR_TASK_PACKAGEANDINSTALL', 3); * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 * @abstract @@ -86433,7 +87092,7 @@ class PEAR_Task_Common * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Postinstallscript.php,v 1.22 2009/02/24 23:45:56 dufuz Exp $ + * @version CVS: $Id: Postinstallscript.php 276385 2009-02-24 23:46:03Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ @@ -86451,7 +87110,7 @@ require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Task/Common.php'; * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ @@ -86755,7 +87414,7 @@ class PEAR_Task_Postinstallscript extends PEAR_Task_Common * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: rw.php,v 1.14 2009/02/24 23:45:32 dufuz Exp $ + * @version CVS: $Id: rw.php 276385 2009-02-24 23:46:03Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a10 */ @@ -86770,7 +87429,7 @@ require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Task/Postinstallscript.p * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a10 */ @@ -86923,7 +87582,7 @@ class PEAR_Task_Postinstallscript_rw extends PEAR_Task_Postinstallscript * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Replace.php,v 1.19 2009/02/25 00:15:49 dufuz Exp $ + * @version CVS: $Id: Replace.php 276394 2009-02-25 00:15:49Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ @@ -86938,7 +87597,7 @@ require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Task/Common.php'; * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ @@ -87087,66 +87746,66 @@ class PEAR_Task_Replace extends PEAR_Task_Common return $contents; } } -?><?php
-/**
- * <tasks:replace> - read/write version
- *
- * PHP versions 4 and 5
- *
- * @category pear
- * @package PEAR
- * @author Greg Beaver <cellog@php.net>
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version CVS: $Id: rw.php,v 1.5 2009/02/24 23:45:44 dufuz Exp $
- * @link http://pear.php.net/package/PEAR
- * @since File available since Release 1.4.0a10
- */
-/**
- * Base class
- */
-require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Task/Replace.php';
-/**
- * Abstracts the replace task xml.
- * @category pear
- * @package PEAR
- * @author Greg Beaver <cellog@php.net>
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.8.0
- * @link http://pear.php.net/package/PEAR
- * @since Class available since Release 1.4.0a10
- */
-class PEAR_Task_Replace_rw extends PEAR_Task_Replace
-{
- function PEAR_Task_Replace_rw(&$pkg, &$config, &$logger, $fileXml)
- {
- parent::PEAR_Task_Common($config, $logger, PEAR_TASK_PACKAGE);
- $this->_contents = $fileXml;
- $this->_pkg = &$pkg;
- $this->_params = array();
- }
-
- function validate()
- {
- return $this->validateXml($this->_pkg, $this->_params, $this->config, $this->_contents);
- }
-
- function setInfo($from, $to, $type)
- {
- $this->_params = array('attribs' => array('from' => $from, 'to' => $to, 'type' => $type));
- }
-
- function getName()
- {
- return 'replace';
- }
-
- function getXml()
- {
- return $this->_params;
- }
-}
+?><?php +/** + * <tasks:replace> - read/write version + * + * PHP versions 4 and 5 + * + * @category pear + * @package PEAR + * @author Greg Beaver <cellog@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: rw.php 276385 2009-02-24 23:46:03Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a10 + */ +/** + * Base class + */ +require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Task/Replace.php'; +/** + * Abstracts the replace task xml. + * @category pear + * @package PEAR + * @author Greg Beaver <cellog@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a10 + */ +class PEAR_Task_Replace_rw extends PEAR_Task_Replace +{ + function PEAR_Task_Replace_rw(&$pkg, &$config, &$logger, $fileXml) + { + parent::PEAR_Task_Common($config, $logger, PEAR_TASK_PACKAGE); + $this->_contents = $fileXml; + $this->_pkg = &$pkg; + $this->_params = array(); + } + + function validate() + { + return $this->validateXml($this->_pkg, $this->_params, $this->config, $this->_contents); + } + + function setInfo($from, $to, $type) + { + $this->_params = array('attribs' => array('from' => $from, 'to' => $to, 'type' => $type)); + } + + function getName() + { + return 'replace'; + } + + function getXml() + { + return $this->_params; + } +} ?><?php /** * <tasks:unixeol> @@ -87158,7 +87817,7 @@ class PEAR_Task_Replace_rw extends PEAR_Task_Replace * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Unixeol.php,v 1.12 2009/02/25 00:15:49 dufuz Exp $ + * @version CVS: $Id: Unixeol.php 276394 2009-02-25 00:15:49Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ @@ -87173,7 +87832,7 @@ require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Task/Common.php'; * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ @@ -87223,61 +87882,61 @@ class PEAR_Task_Unixeol extends PEAR_Task_Common return preg_replace("/\r\n|\n\r|\r|\n/", "\n", $contents); } } -?><?php
-/**
- * <tasks:unixeol> - read/write version
- *
- * PHP versions 4 and 5
- *
- * @category pear
- * @package PEAR
- * @author Greg Beaver <cellog@php.net>
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version CVS: $Id: rw.php,v 1.6 2009/02/24 23:45:30 dufuz Exp $
- * @link http://pear.php.net/package/PEAR
- * @since File available since Release 1.4.0a10
- */
-/**
- * Base class
- */
-require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Task/Unixeol.php';
-/**
- * Abstracts the unixeol task xml.
- * @category pear
- * @package PEAR
- * @author Greg Beaver <cellog@php.net>
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.8.0
- * @link http://pear.php.net/package/PEAR
- * @since Class available since Release 1.4.0a10
- */
-class PEAR_Task_Unixeol_rw extends PEAR_Task_Unixeol
-{
- function PEAR_Task_Unixeol_rw(&$pkg, &$config, &$logger, $fileXml)
- {
- parent::PEAR_Task_Common($config, $logger, PEAR_TASK_PACKAGE);
- $this->_contents = $fileXml;
- $this->_pkg = &$pkg;
- $this->_params = array();
- }
-
- function validate()
- {
- return true;
- }
-
- function getName()
- {
- return 'unixeol';
- }
-
- function getXml()
- {
- return '';
- }
-}
+?><?php +/** + * <tasks:unixeol> - read/write version + * + * PHP versions 4 and 5 + * + * @category pear + * @package PEAR + * @author Greg Beaver <cellog@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: rw.php 276385 2009-02-24 23:46:03Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a10 + */ +/** + * Base class + */ +require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Task/Unixeol.php'; +/** + * Abstracts the unixeol task xml. + * @category pear + * @package PEAR + * @author Greg Beaver <cellog@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a10 + */ +class PEAR_Task_Unixeol_rw extends PEAR_Task_Unixeol +{ + function PEAR_Task_Unixeol_rw(&$pkg, &$config, &$logger, $fileXml) + { + parent::PEAR_Task_Common($config, $logger, PEAR_TASK_PACKAGE); + $this->_contents = $fileXml; + $this->_pkg = &$pkg; + $this->_params = array(); + } + + function validate() + { + return true; + } + + function getName() + { + return 'unixeol'; + } + + function getXml() + { + return ''; + } +} ?><?php /** * <tasks:windowseol> @@ -87289,7 +87948,7 @@ class PEAR_Task_Unixeol_rw extends PEAR_Task_Unixeol * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Windowseol.php,v 1.11 2009/02/25 00:15:49 dufuz Exp $ + * @version CVS: $Id: Windowseol.php 276394 2009-02-25 00:15:49Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ @@ -87304,7 +87963,7 @@ require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Task/Common.php'; * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ @@ -87354,61 +88013,61 @@ class PEAR_Task_Windowseol extends PEAR_Task_Common return preg_replace("/\r\n|\n\r|\r|\n/", "\r\n", $contents); } } -?><?php
-/**
- * <tasks:windowseol> - read/write version
- *
- * PHP versions 4 and 5
- *
- * @category pear
- * @package PEAR
- * @author Greg Beaver <cellog@php.net>
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version CVS: $Id: rw.php,v 1.6 2009/02/24 23:45:20 dufuz Exp $
- * @link http://pear.php.net/package/PEAR
- * @since File available since Release 1.4.0a10
- */
-/**
- * Base class
- */
-require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Task/Windowseol.php';
-/**
- * Abstracts the windowseol task xml.
- * @category pear
- * @package PEAR
- * @author Greg Beaver <cellog@php.net>
- * @copyright 1997-2009 The Authors
- * @license http://opensource.org/licenses/bsd-license.php New BSD License
- * @version Release: 1.8.0
- * @link http://pear.php.net/package/PEAR
- * @since Class available since Release 1.4.0a10
- */
-class PEAR_Task_Windowseol_rw extends PEAR_Task_Windowseol
-{
- function PEAR_Task_Windowseol_rw(&$pkg, &$config, &$logger, $fileXml)
- {
- parent::PEAR_Task_Common($config, $logger, PEAR_TASK_PACKAGE);
- $this->_contents = $fileXml;
- $this->_pkg = &$pkg;
- $this->_params = array();
- }
-
- function validate()
- {
- return true;
- }
-
- function getName()
- {
- return 'windowseol';
- }
-
- function getXml()
- {
- return '';
- }
-}
+?><?php +/** + * <tasks:windowseol> - read/write version + * + * PHP versions 4 and 5 + * + * @category pear + * @package PEAR + * @author Greg Beaver <cellog@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: rw.php 276385 2009-02-24 23:46:03Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a10 + */ +/** + * Base class + */ +require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Task/Windowseol.php'; +/** + * Abstracts the windowseol task xml. + * @category pear + * @package PEAR + * @author Greg Beaver <cellog@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a10 + */ +class PEAR_Task_Windowseol_rw extends PEAR_Task_Windowseol +{ + function PEAR_Task_Windowseol_rw(&$pkg, &$config, &$logger, $fileXml) + { + parent::PEAR_Task_Common($config, $logger, PEAR_TASK_PACKAGE); + $this->_contents = $fileXml; + $this->_pkg = &$pkg; + $this->_params = array(); + } + + function validate() + { + return true; + } + + function getName() + { + return 'windowseol'; + } + + function getXml() + { + return ''; + } +} ?><?php /** * PEAR_Validate @@ -87420,7 +88079,7 @@ class PEAR_Task_Windowseol_rw extends PEAR_Task_Windowseol * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Validate.php,v 1.54 2009/02/24 23:38:23 dufuz Exp $ + * @version CVS: $Id: Validate.php 276383 2009-02-24 23:39:37Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ @@ -87443,7 +88102,7 @@ require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Validator/PECL.php'; * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ @@ -88048,7 +88707,7 @@ class PEAR_Validate * @author Greg Beaver <cellog@php.net> * @copyright 1997-2006 The PHP Group * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: PECL.php,v 1.10 2009/02/24 23:39:19 dufuz Exp $ + * @version CVS: $Id: PECL.php 276383 2009-02-24 23:39:37Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a5 */ @@ -88063,7 +88722,7 @@ require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Validate.php'; * @author Greg Beaver <cellog@php.net> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a5 */ @@ -88111,7 +88770,7 @@ class PEAR_Validator_PECL extends PEAR_Validate * @author Stephan Schmidt (original XML_Unserializer code) * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license New BSD License - * @version CVS: $Id: XMLParser.php,v 1.22 2009/03/08 00:45:39 dufuz Exp $ + * @version CVS: $Id: XMLParser.php 282970 2009-06-28 23:10:07Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ @@ -88124,7 +88783,7 @@ class PEAR_Validator_PECL extends PEAR_Validate * @author Stephan Schmidt (original XML_Unserializer code) * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ @@ -88146,13 +88805,13 @@ class PEAR_XMLParser * stack for all data that is found * @var array $_dataStack */ - var $_dataStack = array(); + var $_dataStack = array(); /** * stack for all values that are generated * @var array $_valStack */ - var $_valStack = array(); + var $_valStack = array(); /** * current tag depth @@ -88184,8 +88843,7 @@ class PEAR_XMLParser include_once 'phar://install-pear-nozlib.phar/' . 'PEAR.php'; return PEAR::raiseError("XML Extension not found", 1); } - $this->_valStack = array(); - $this->_dataStack = array(); + $this->_dataStack = $this->_valStack = array(); $this->_depth = 0; if ( @@ -88199,6 +88857,7 @@ class PEAR_XMLParser if (version_compare(phpversion(), '5.0.0', 'lt') && $this->encoding == 'UTF-8') { $data = utf8_decode($data); + $this->encoding = 'ISO-8859-1'; } $xp = xml_parser_create($this->encoding); @@ -88228,25 +88887,21 @@ class PEAR_XMLParser */ function startHandler($parser, $element, $attribs) { - $type = 'string'; - $this->_depth++; $this->_dataStack[$this->_depth] = null; $val = array( - 'name' => $element, - 'value' => null, - 'type' => $type, - 'childrenKeys' => array(), - 'aggregKeys' => array() - ); + 'name' => $element, + 'value' => null, + 'type' => 'string', + 'childrenKeys' => array(), + 'aggregKeys' => array() + ); if (count($attribs) > 0) { $val['children'] = array(); $val['type'] = 'array'; - $val['children']['attribs'] = $attribs; - } array_push($this->_valStack, $val); @@ -88277,18 +88932,14 @@ class PEAR_XMLParser $data = $this->postProcess($this->_dataStack[$this->_depth], $element); // adjust type of the value - switch(strtolower($value['type'])) { - + switch (strtolower($value['type'])) { // unserialize an array case 'array': if ($data !== '') { $value['children']['_content'] = $data; } - if (isset($value['children'])) { - $value['value'] = $value['children']; - } else { - $value['value'] = array(); - } + + $value['value'] = isset($value['children']) ? $value['children'] : array(); break; /* @@ -88360,6 +89011,38 @@ class PEAR_XMLParser $this->_dataStack[$this->_depth] .= $cdata; } }<?php +/** + * This is only meant for PHP 5 to get rid of certain strict warning + * that doesn't get hidden since it's in the shutdown function + */ +class PEAR5 +{ + /** + * If you have a class that's mostly/entirely static, and you need static + * properties, you can use this method to simulate them. Eg. in your method(s) + * do this: $myVar = &PEAR5::getStaticProperty('myclass', 'myVar'); + * You MUST use a reference, or they will not persist! + * + * @access public + * @param string $class The calling classname, to prevent clashes + * @param string $var The variable to retrieve. + * @return mixed A reference to the variable. If not set it will be + * auto initialised to NULL. + */ + static function &getStaticProperty($class, $var) + { + static $properties; + if (!isset($properties[$class])) { + $properties[$class] = array(); + } + + if (!array_key_exists($var, $properties[$class])) { + $properties[$class][$var] = null; + } + + return $properties[$class][$var]; + } +}<?php /* vim: set expandtab tabstop=4 shiftwidth=4 foldmethod=marker: */ // +-----------------------------------------------------------------------------+ // | Copyright (c) 2003 Sérgio Gonçalves Carvalho | @@ -93560,7 +94243,7 @@ as well as for characteristic extraction from the graph topology. * @author Tomas V.V.Cox <cox@idecnet.com> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: System.php,v 1.66 2009/02/24 23:52:56 dufuz Exp $ + * @version CVS: $Id: System.php 276386 2009-02-24 23:52:56Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 0.1 */ @@ -93602,7 +94285,7 @@ $GLOBALS['_System_temp_files'] = array(); * @author Tomas V.V. Cox <cox@idecnet.com> * @copyright 1997-2006 The PHP Group * @license http://opensource.org/licenses/bsd-license.php New BSD License -* @version Release: 1.8.0 +* @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 0.1 * @static @@ -94214,7 +94897,7 @@ class System * @author Stephan Schmidt <schst@php.net> * @copyright 2003-2008 Stephan Schmidt <schst@php.net> * @license http://opensource.org/licenses/bsd-license New BSD License - * @version CVS: $Id: Util.php,v 1.39 2009/02/09 14:23:42 ashnazg Exp $ + * @version CVS: $Id: Util.php 275418 2009-02-09 14:23:42Z ashnazg $ * @link http://pear.php.net/package/XML_Util */ @@ -98095,4 +98778,4 @@ iEYEABECAAYFAkk8e2QACgkQcqMhusJF8XULZgCg0iwVLWueraJzK5s1AesDkVzv GucAn22sSv3QiTSUWG9BmakiW9hFsb4V =g2mr -----END PGP SIGNATURE----- - + |
