From: Diogo Cordeiro Date: Sun, 28 Apr 2019 22:39:36 +0000 (+0100) Subject: Update PEAR to v1.10.9 and patch it so it works quietly X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=b17e0b4169102cf40d56d0c0ebac704d7bbf2713;p=quix0rs-gnu-social.git Update PEAR to v1.10.9 and patch it so it works quietly --- diff --git a/extlib/DB.php b/extlib/DB.php index 1aa9477065..e43f6091ab 100644 --- a/extlib/DB.php +++ b/extlib/DB.php @@ -164,7 +164,7 @@ define('DB_ERROR_CONNECT_FAILED', -24); /** * The PHP extension needed for this DBMS could not be found */ -define('DB_ERROR_EXTENSION_NOT_FOUND',-25); +define('DB_ERROR_EXTENSION_NOT_FOUND', -25); /** * The present user has inadequate permissions to perform the task requestd @@ -179,7 +179,7 @@ define('DB_ERROR_NOSUCHDB', -27); /** * Tried to insert a null value into a column that doesn't allow nulls */ -define('DB_ERROR_CONSTRAINT_NOT_NULL',-29); +define('DB_ERROR_CONSTRAINT_NOT_NULL', -29); /**#@-*/ @@ -212,7 +212,7 @@ define('DB_PARAM_OPAQUE', 2); * * The value should not be quoted or escaped. */ -define('DB_PARAM_MISC', 3); +define('DB_PARAM_MISC', 3); /**#@-*/ @@ -287,7 +287,7 @@ define('DB_FETCHMODE_FLIPPED', 4); * Old fetch modes. Left here for compatibility. */ define('DB_GETMODE_ORDERED', DB_FETCHMODE_ORDERED); -define('DB_GETMODE_ASSOC', DB_FETCHMODE_ASSOC); +define('DB_GETMODE_ASSOC', DB_FETCHMODE_ASSOC); define('DB_GETMODE_FLIPPED', DB_FETCHMODE_FLIPPED); /**#@-*/ @@ -437,14 +437,14 @@ class DB * Create a new DB object for the specified database type but don't * connect to the database * - * @param string $type the database type (eg "mysql") - * @param array $options an associative array of option names and values + * @param string $type the database type (eg "mysql") + * @param array $options an associative array of option names and values * * @return object a new DB object. A DB_Error object on failure. * * @see DB_common::setOption() */ - public static function factory($type, $options = false) + public static function factory($type, $options = []) { if (!is_array($options)) { $options = array('persistent' => $options); @@ -461,9 +461,9 @@ class DB if (!class_exists($classname)) { $tmp = PEAR::raiseError(null, DB_ERROR_NOT_FOUND, null, null, - "Unable to include the DB/{$type}.php" - . " file for '$dsn'", - 'DB_Error', true); + "Unable to include the DB/{$type}.php" + . " file for '$dsn'", + 'DB_Error', true); return $tmp; } @@ -482,6 +482,21 @@ class DB // }}} // {{{ connect() + /** + * Determines if a variable is a DB_Error object + * + * @param mixed $value the variable to check + * + * @return bool whether $value is DB_Error object + */ + public static function isError($value) + { + return is_object($value) && is_a($value, 'DB_Error'); + } + + // }}} + // {{{ apiVersion() + /** * Create a new DB object including a connection to the specified database * @@ -501,9 +516,9 @@ class DB * } * * - * @param mixed $dsn the string "data source name" or array in the + * @param mixed $dsn the string "data source name" or array in the * format returned by DB::parseDSN() - * @param array $options an associative array of option names and values + * @param array $options an associative array of option names and values * * @return object a new DB object. A DB_Error object on failure. * @@ -538,10 +553,10 @@ class DB $classname = "DB_${type}"; if (!class_exists($classname)) { $tmp = PEAR::raiseError(null, DB_ERROR_NOT_FOUND, null, null, - "Unable to include the DB/{$type}.php" - . " file for '" - . DB::getDSNString($dsn, true) . "'", - 'DB_Error', true); + "Unable to include the DB/{$type}.php" + . " file for '" + . DB::getDSNString($dsn, true) . "'", + 'DB_Error', true); return $tmp; } @@ -567,136 +582,9 @@ class DB return $obj; } - // }}} - // {{{ apiVersion() - - /** - * Return the DB API version - * - * @return string the DB API version number - */ - function apiVersion() - { - return '1.9.2'; - } - // }}} // {{{ isError() - /** - * Determines if a variable is a DB_Error object - * - * @param mixed $value the variable to check - * - * @return bool whether $value is DB_Error object - */ - public static function isError($value) - { - return is_object($value) && is_a($value, 'DB_Error'); - } - - // }}} - // {{{ isConnection() - - /** - * Determines if a value is a DB_ object - * - * @param mixed $value the value to test - * - * @return bool whether $value is a DB_ object - */ - public static function isConnection($value) - { - return (is_object($value) && - is_subclass_of($value, 'db_common') && - method_exists($value, 'simpleQuery')); - } - - // }}} - // {{{ isManip() - - /** - * Tell whether a query is a data manipulation or data definition query - * - * Examples of data manipulation queries are INSERT, UPDATE and DELETE. - * Examples of data definition queries are CREATE, DROP, ALTER, GRANT, - * REVOKE. - * - * @param string $query the query - * - * @return boolean whether $query is a data manipulation query - */ - public static function isManip($query) - { - $manips = 'INSERT|UPDATE|DELETE|REPLACE|' - . 'CREATE|DROP|' - . 'LOAD DATA|SELECT .* INTO .* FROM|COPY|' - . 'ALTER|GRANT|REVOKE|' - . 'LOCK|UNLOCK'; - if (preg_match('/^\s*"?(' . $manips . ')\s+/i', $query)) { - return true; - } - return false; - } - - // }}} - // {{{ errorMessage() - - /** - * Return a textual error message for a DB error code - * - * @param integer $value the DB error code - * - * @return string the error message or false if the error code was - * not recognized - */ - public static function errorMessage($value) - { - static $errorMessages; - if (!isset($errorMessages)) { - $errorMessages = array( - DB_ERROR => 'unknown error', - DB_ERROR_ACCESS_VIOLATION => 'insufficient permissions', - DB_ERROR_ALREADY_EXISTS => 'already exists', - DB_ERROR_CANNOT_CREATE => 'can not create', - DB_ERROR_CANNOT_DROP => 'can not drop', - DB_ERROR_CONNECT_FAILED => 'connect failed', - DB_ERROR_CONSTRAINT => 'constraint violation', - DB_ERROR_CONSTRAINT_NOT_NULL=> 'null value violates not-null constraint', - DB_ERROR_DIVZERO => 'division by zero', - DB_ERROR_EXTENSION_NOT_FOUND=> 'extension not found', - DB_ERROR_INVALID => 'invalid', - DB_ERROR_INVALID_DATE => 'invalid date or time', - DB_ERROR_INVALID_DSN => 'invalid DSN', - DB_ERROR_INVALID_NUMBER => 'invalid number', - DB_ERROR_MISMATCH => 'mismatch', - DB_ERROR_NEED_MORE_DATA => 'insufficient data supplied', - DB_ERROR_NODBSELECTED => 'no database selected', - DB_ERROR_NOSUCHDB => 'no such database', - DB_ERROR_NOSUCHFIELD => 'no such field', - DB_ERROR_NOSUCHTABLE => 'no such table', - DB_ERROR_NOT_CAPABLE => 'DB backend not capable', - DB_ERROR_NOT_FOUND => 'not found', - DB_ERROR_NOT_LOCKED => 'not locked', - DB_ERROR_SYNTAX => 'syntax error', - DB_ERROR_UNSUPPORTED => 'not supported', - DB_ERROR_TRUNCATED => 'truncated', - DB_ERROR_VALUE_COUNT_ON_ROW => 'value count on row', - DB_OK => 'no error', - ); - } - - if (DB::isError($value)) { - $value = $value->getCode(); - } - - return isset($errorMessages[$value]) ? $errorMessages[$value] - : $errorMessages[DB_ERROR]; - } - - // }}} - // {{{ parseDSN() - /** * Parse a data source name * @@ -734,14 +622,14 @@ class DB public static function parseDSN($dsn) { $parsed = array( - 'phptype' => false, + 'phptype' => false, 'dbsyntax' => false, 'username' => false, 'password' => false, 'protocol' => false, 'hostspec' => false, - 'port' => false, - 'socket' => false, + 'port' => false, + 'socket' => false, 'database' => false, ); @@ -765,10 +653,10 @@ class DB // Get phptype and dbsyntax // $str => phptype(dbsyntax) if (preg_match('|^(.+?)\((.*?)\)$|', $str, $arr)) { - $parsed['phptype'] = $arr[1]; + $parsed['phptype'] = $arr[1]; $parsed['dbsyntax'] = !$arr[2] ? $arr[1] : $arr[2]; } else { - $parsed['phptype'] = $str; + $parsed['phptype'] = $str; $parsed['dbsyntax'] = $str; } @@ -778,7 +666,7 @@ class DB // Get (if found): username and password // $dsn => username:password@protocol+hostspec/database - if (($at = strrpos($dsn,'@')) !== false) { + if (($at = strrpos($dsn, '@')) !== false) { $str = substr($dsn, 0, $at); $dsn = substr($dsn, $at + 1); if (($pos = strpos($str, ':')) !== false) { @@ -793,9 +681,9 @@ class DB if (preg_match('|^([^(]+)\((.*?)\)/?(.*?)$|', $dsn, $match)) { // $dsn => proto(proto_opts)/database - $proto = $match[1]; - $proto_opts = $match[2] ? $match[2] : false; - $dsn = $match[3]; + $proto = $match[1]; + $proto_opts = $match[2] ? $match[2] : false; + $dsn = $match[3]; } else { // $dsn => protocol+hostspec/database (old format) @@ -851,7 +739,7 @@ class DB } // }}} - // {{{ getDSNString() + // {{{ isConnection() /** * Returns the given DSN in a string format suitable for output. @@ -860,12 +748,13 @@ class DB * @param boolean true to hide the password, false to include it * @return string */ - public static function getDSNString($dsn, $hidePassword) { + public static function getDSNString($dsn, $hidePassword) + { /* Calling parseDSN will ensure that we have all the array elements * defined, and means that we deal with strings and array in the same * manner. */ $dsnArray = DB::parseDSN($dsn); - + if ($hidePassword) { $dsnArray['password'] = 'PASSWORD'; } @@ -875,42 +764,42 @@ class DB if (is_string($dsn) && strpos($dsn, 'tcp') === false && $dsnArray['protocol'] == 'tcp') { $dsnArray['protocol'] = false; } - + // Now we just have to construct the actual string. This is ugly. $dsnString = $dsnArray['phptype']; if ($dsnArray['dbsyntax']) { - $dsnString .= '('.$dsnArray['dbsyntax'].')'; + $dsnString .= '(' . $dsnArray['dbsyntax'] . ')'; } $dsnString .= '://' - .$dsnArray['username'] - .':' - .$dsnArray['password'] - .'@' - .$dsnArray['protocol']; + . $dsnArray['username'] + . ':' + . $dsnArray['password'] + . '@' + . $dsnArray['protocol']; if ($dsnArray['socket']) { - $dsnString .= '('.$dsnArray['socket'].')'; + $dsnString .= '(' . $dsnArray['socket'] . ')'; } if ($dsnArray['protocol'] && $dsnArray['hostspec']) { $dsnString .= '+'; } $dsnString .= $dsnArray['hostspec']; if ($dsnArray['port']) { - $dsnString .= ':'.$dsnArray['port']; + $dsnString .= ':' . $dsnArray['port']; } - $dsnString .= '/'.$dsnArray['database']; - + $dsnString .= '/' . $dsnArray['database']; + /* Option handling. Unfortunately, parseDSN simply places options into * the top-level array, so we'll first get rid of the fields defined by * DB and see what's left. */ unset($dsnArray['phptype'], - $dsnArray['dbsyntax'], - $dsnArray['username'], - $dsnArray['password'], - $dsnArray['protocol'], - $dsnArray['socket'], - $dsnArray['hostspec'], - $dsnArray['port'], - $dsnArray['database'] + $dsnArray['dbsyntax'], + $dsnArray['username'], + $dsnArray['password'], + $dsnArray['protocol'], + $dsnArray['socket'], + $dsnArray['hostspec'], + $dsnArray['port'], + $dsnArray['database'] ); if (count($dsnArray) > 0) { $dsnString .= '?'; @@ -919,13 +808,125 @@ class DB if (++$i > 1) { $dsnString .= '&'; } - $dsnString .= $key.'='.$value; + $dsnString .= $key . '=' . $value; } } return $dsnString; } - + + // }}} + // {{{ isManip() + + /** + * Determines if a value is a DB_ object + * + * @param mixed $value the value to test + * + * @return bool whether $value is a DB_ object + */ + public static function isConnection($value) + { + return (is_object($value) && + is_subclass_of($value, 'db_common') && + method_exists($value, 'simpleQuery')); + } + + // }}} + // {{{ errorMessage() + + /** + * Tell whether a query is a data manipulation or data definition query + * + * Examples of data manipulation queries are INSERT, UPDATE and DELETE. + * Examples of data definition queries are CREATE, DROP, ALTER, GRANT, + * REVOKE. + * + * @param string $query the query + * + * @return boolean whether $query is a data manipulation query + */ + public static function isManip($query) + { + $manips = 'INSERT|UPDATE|DELETE|REPLACE|' + . 'CREATE|DROP|' + . 'LOAD DATA|SELECT .* INTO .* FROM|COPY|' + . 'ALTER|GRANT|REVOKE|' + . 'LOCK|UNLOCK'; + if (preg_match('/^\s*"?(' . $manips . ')\s+/i', $query)) { + return true; + } + return false; + } + + // }}} + // {{{ parseDSN() + + /** + * Return a textual error message for a DB error code + * + * @param integer $value the DB error code + * + * @return string the error message or false if the error code was + * not recognized + */ + public static function errorMessage($value) + { + static $errorMessages; + if (!isset($errorMessages)) { + $errorMessages = array( + DB_ERROR => 'unknown error', + DB_ERROR_ACCESS_VIOLATION => 'insufficient permissions', + DB_ERROR_ALREADY_EXISTS => 'already exists', + DB_ERROR_CANNOT_CREATE => 'can not create', + DB_ERROR_CANNOT_DROP => 'can not drop', + DB_ERROR_CONNECT_FAILED => 'connect failed', + DB_ERROR_CONSTRAINT => 'constraint violation', + DB_ERROR_CONSTRAINT_NOT_NULL => 'null value violates not-null constraint', + DB_ERROR_DIVZERO => 'division by zero', + DB_ERROR_EXTENSION_NOT_FOUND => 'extension not found', + DB_ERROR_INVALID => 'invalid', + DB_ERROR_INVALID_DATE => 'invalid date or time', + DB_ERROR_INVALID_DSN => 'invalid DSN', + DB_ERROR_INVALID_NUMBER => 'invalid number', + DB_ERROR_MISMATCH => 'mismatch', + DB_ERROR_NEED_MORE_DATA => 'insufficient data supplied', + DB_ERROR_NODBSELECTED => 'no database selected', + DB_ERROR_NOSUCHDB => 'no such database', + DB_ERROR_NOSUCHFIELD => 'no such field', + DB_ERROR_NOSUCHTABLE => 'no such table', + DB_ERROR_NOT_CAPABLE => 'DB backend not capable', + DB_ERROR_NOT_FOUND => 'not found', + DB_ERROR_NOT_LOCKED => 'not locked', + DB_ERROR_SYNTAX => 'syntax error', + DB_ERROR_UNSUPPORTED => 'not supported', + DB_ERROR_TRUNCATED => 'truncated', + DB_ERROR_VALUE_COUNT_ON_ROW => 'value count on row', + DB_OK => 'no error', + ); + } + + if (DB::isError($value)) { + $value = $value->getCode(); + } + + return isset($errorMessages[$value]) ? $errorMessages[$value] + : $errorMessages[DB_ERROR]; + } + + // }}} + // {{{ getDSNString() + + /** + * Return the DB API version + * + * @return string the DB API version number + */ + function apiVersion() + { + return '1.9.2'; + } + // }}} } @@ -951,23 +952,23 @@ class DB_Error extends PEAR_Error /** * DB_Error constructor * - * @param mixed $code DB error code, or string with error message - * @param int $mode what "error mode" to operate in - * @param int $level what error level to use for $mode & + * @param mixed $code DB error code, or string with error message + * @param int $mode what "error mode" to operate in + * @param int $level what error level to use for $mode & * PEAR_ERROR_TRIGGER - * @param mixed $debuginfo additional debug info, such as the last query + * @param mixed $debuginfo additional debug info, such as the last query * * @see PEAR_Error */ function __construct($code = DB_ERROR, $mode = PEAR_ERROR_RETURN, - $level = E_USER_NOTICE, $debuginfo = null) + $level = E_USER_NOTICE, $debuginfo = null) { if (is_int($code)) { parent::__construct('DB Error: ' . DB::errorMessage($code), $code, - $mode, $level, $debuginfo); + $mode, $level, $debuginfo); } else { parent::__construct("DB Error: $code", DB_ERROR, - $mode, $level, $debuginfo); + $mode, $level, $debuginfo); } } @@ -975,6 +976,9 @@ class DB_Error extends PEAR_Error * Workaround to both avoid the "Redefining already defined constructor" * PHP error and provide backward compatibility in case someone is calling * DB_Error() dynamically + * @param $method + * @param $arguments + * @return bool|mixed */ public function __call($method, $arguments) { @@ -984,6 +988,7 @@ class DB_Error extends PEAR_Error trigger_error( 'Call to undefined method DB_Error::' . $method . '()', E_USER_ERROR ); + return false; } // }}} } @@ -1103,22 +1108,22 @@ class DB_result /** * This constructor sets the object's properties * - * @param object &$dbh the DB object reference - * @param resource $result the result resource id - * @param array $options an associative array with result options + * @param object &$dbh the DB object reference + * @param resource $result the result resource id + * @param array $options an associative array with result options * * @return void */ function __construct(&$dbh, $result, $options = array()) { - $this->autofree = $dbh->options['autofree']; - $this->dbh = &$dbh; - $this->fetchmode = $dbh->fetchmode; + $this->autofree = $dbh->options['autofree']; + $this->dbh = &$dbh; + $this->fetchmode = $dbh->fetchmode; $this->fetchmode_object_class = $dbh->fetchmode_object_class; - $this->parameters = $dbh->last_parameters; - $this->query = $dbh->last_query; - $this->result = $result; - $this->statement = empty($dbh->last_stmt) ? null : $dbh->last_stmt; + $this->parameters = $dbh->last_parameters; + $this->query = $dbh->last_query; + $this->result = $result; + $this->statement = empty($dbh->last_stmt) ? null : $dbh->last_stmt; foreach ($options as $key => $value) { $this->setOption($key, $value); } @@ -1127,8 +1132,8 @@ class DB_result /** * Set options for the DB_result object * - * @param string $key the option to set - * @param mixed $value the value to set the option to + * @param string $key the option to set + * @param mixed $value the value to set the option to * * @return void */ @@ -1164,8 +1169,8 @@ class DB_result * + DB_PORTABILITY_RTRIM * right trim the data * - * @param int $fetchmode the constant indicating how to format the data - * @param int $rownum the row number to fetch (index starts at 0) + * @param int $fetchmode the constant indicating how to format the data + * @param int $rownum the row number to fetch (index starts at 0) * * @return mixed an array or object containing the row's data, * NULL when the end of the result set is reached @@ -1193,8 +1198,7 @@ class DB_result } } } - if ($this->row_counter >= ($this->limit_from + $this->limit_count)) - { + if ($this->row_counter >= ($this->limit_from + $this->limit_count)) { if ($this->autofree) { $this->free(); } @@ -1212,7 +1216,7 @@ class DB_result // The default mode is specified in the // DB_common::fetchmode_object_class property if ($object_class == 'stdClass') { - $arr = (object) $arr; + $arr = (object)$arr; } else { $arr = new $object_class($arr); } @@ -1228,6 +1232,25 @@ class DB_result // }}} // {{{ fetchInto() + /** + * Frees the resources allocated for this result set + * + * @return bool true on success. A DB_Error object on failure. + */ + function free() + { + $err = $this->dbh->freeResult($this->result); + if (DB::isError($err)) { + return $err; + } + $this->result = false; + $this->statement = false; + return true; + } + + // }}} + // {{{ numCols() + /** * Fetch a row of data into an array which is passed by reference * @@ -1246,9 +1269,9 @@ class DB_result * + DB_PORTABILITY_RTRIM * right trim the data * - * @param array &$arr the variable where the data should be placed - * @param int $fetchmode the constant indicating how to format the data - * @param int $rownum the row number to fetch (index starts at 0) + * @param array &$arr the variable where the data should be placed + * @param int $fetchmode the constant indicating how to format the data + * @param int $rownum the row number to fetch (index starts at 0) * * @return mixed DB_OK if a row is processed, NULL when the end of the * result set is reached or a DB_Error object on failure @@ -1276,8 +1299,7 @@ class DB_result } } if ($this->row_counter >= ( - $this->limit_from + $this->limit_count)) - { + $this->limit_from + $this->limit_count)) { if ($this->autofree) { $this->free(); } @@ -1295,7 +1317,7 @@ class DB_result // default mode specified in the // DB_common::fetchmode_object_class property if ($object_class == 'stdClass') { - $arr = (object) $arr; + $arr = (object)$arr; } else { $arr = new $object_class($arr); } @@ -1309,7 +1331,7 @@ class DB_result } // }}} - // {{{ numCols() + // {{{ numRows() /** * Get the the number of columns in a result set @@ -1322,7 +1344,7 @@ class DB_result } // }}} - // {{{ numRows() + // {{{ nextResult() /** * Get the number of rows in a result set @@ -1332,8 +1354,7 @@ class DB_result function numRows() { if ($this->dbh->features['numrows'] === 'emulate' - && $this->dbh->options['portability'] & DB_PORTABILITY_NUMROWS) - { + && $this->dbh->options['portability'] & DB_PORTABILITY_NUMROWS) { if ($this->dbh->features['prepare']) { $res = $this->dbh->query($this->query, $this->parameters); } else { @@ -1360,7 +1381,7 @@ class DB_result * because that only gets the result resource, rather than the full * DB_Result object. */ if (($this->dbh->features['limit'] === 'emulate' - && $this->limit_from !== null) + && $this->limit_from !== null) || $this->dbh->phptype == 'fbsql') { $limit_count = is_null($this->limit_count) ? $count : $this->limit_count; if ($count < $this->limit_from) { @@ -1376,7 +1397,7 @@ class DB_result } // }}} - // {{{ nextResult() + // {{{ free() /** * Get the next result if a batch of queries was executed @@ -1388,29 +1409,12 @@ class DB_result return $this->dbh->nextResult($this->result); } - // }}} - // {{{ free() - - /** - * Frees the resources allocated for this result set - * - * @return bool true on success. A DB_Error object on failure. - */ - function free() - { - $err = $this->dbh->freeResult($this->result); - if (DB::isError($err)) { - return $err; - } - $this->result = false; - $this->statement = false; - return true; - } - // }}} // {{{ tableInfo() /** + * @param null $mode + * @return * @see DB_common::tableInfo() * @deprecated Method deprecated some time before Release 1.2 */ @@ -1499,6 +1503,4 @@ class DB_row * tab-width: 4 * c-basic-offset: 4 * End: - */ - -?> + */ \ No newline at end of file diff --git a/extlib/PEAR.php b/extlib/PEAR.php index 2aa85259d6..c1fc361e50 100644 --- a/extlib/PEAR.php +++ b/extlib/PEAR.php @@ -14,7 +14,6 @@ * @author Greg Beaver * @copyright 1997-2010 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: PEAR.php 313023 2011-07-06 19:17:11Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 0.1 */ @@ -22,35 +21,33 @@ /**#@+ * ERROR constants */ -define('PEAR_ERROR_RETURN', 1); -define('PEAR_ERROR_PRINT', 2); -define('PEAR_ERROR_TRIGGER', 4); -define('PEAR_ERROR_DIE', 8); -define('PEAR_ERROR_CALLBACK', 16); +define('PEAR_ERROR_RETURN', 1); +define('PEAR_ERROR_PRINT', 2); +define('PEAR_ERROR_TRIGGER', 4); +define('PEAR_ERROR_DIE', 8); +define('PEAR_ERROR_CALLBACK', 16); /** * WARNING: obsolete * @deprecated */ define('PEAR_ERROR_EXCEPTION', 32); /**#@-*/ -define('PEAR_ZE2', (function_exists('version_compare') && - version_compare(zend_version(), "2-dev", "ge"))); if (substr(PHP_OS, 0, 3) == 'WIN') { define('OS_WINDOWS', true); - define('OS_UNIX', false); - define('PEAR_OS', 'Windows'); + define('OS_UNIX', false); + define('PEAR_OS', 'Windows'); } else { define('OS_WINDOWS', false); - define('OS_UNIX', true); - define('PEAR_OS', 'Unix'); // blatant assumption + define('OS_UNIX', true); + define('PEAR_OS', 'Unix'); // blatant assumption } -$GLOBALS['_PEAR_default_error_mode'] = PEAR_ERROR_RETURN; -$GLOBALS['_PEAR_default_error_options'] = E_USER_NOTICE; +$GLOBALS['_PEAR_default_error_mode'] = PEAR_ERROR_RETURN; +$GLOBALS['_PEAR_default_error_options'] = E_USER_NOTICE; $GLOBALS['_PEAR_destructor_object_list'] = array(); -$GLOBALS['_PEAR_shutdown_funcs'] = array(); -$GLOBALS['_PEAR_error_handler_stack'] = array(); +$GLOBALS['_PEAR_shutdown_funcs'] = array(); +$GLOBALS['_PEAR_error_handler_stack'] = array(); @ini_set('track_errors', true); @@ -78,7 +75,7 @@ $GLOBALS['_PEAR_error_handler_stack'] = array(); * @author Greg Beaver * @copyright 1997-2006 The PHP Group * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.9.4 + * @version Release: @package_version@ * @link http://pear.php.net/package/PEAR * @see PEAR_Error * @since Class available since PHP 4.0.2 @@ -86,6 +83,17 @@ $GLOBALS['_PEAR_error_handler_stack'] = array(); */ class PEAR { + /** + * List of methods that can be called both statically and non-statically. + * @var array + */ + protected static $bivalentMethods = array( + 'setErrorHandling' => true, + 'raiseError' => true, + 'throwError' => true, + 'pushErrorHandling' => true, + 'popErrorHandling' => true, + ); /** * Whether to enable internal debug messages. * @@ -93,7 +101,6 @@ class PEAR * @access private */ var $_debug = false; - /** * Default error mode for this object. * @@ -101,7 +108,6 @@ class PEAR * @access private */ var $_default_error_mode = null; - /** * Default error options used for this object when error mode * is PEAR_ERROR_TRIGGER. @@ -110,7 +116,6 @@ class PEAR * @access private */ var $_default_error_options = null; - /** * Default error handler (callback) for this object, if error mode is * PEAR_ERROR_CALLBACK. @@ -119,7 +124,6 @@ class PEAR * @access private */ var $_default_error_handler = ''; - /** * Which class to use for error objects. * @@ -127,7 +131,6 @@ class PEAR * @access private */ var $_error_class = 'PEAR_Error'; - /** * An array of expected errors. * @@ -136,73 +139,31 @@ class PEAR */ var $_expected_errors = array(); - /** - * Constructor. Registers this object in - * $_PEAR_destructor_object_list for destructor emulation if a - * destructor object exists. - * - * @param string $error_class (optional) which class to use for - * error objects, defaults to PEAR_Error. - * @access public - * @return void - */ - function PEAR($error_class = null) + public static function __callStatic($method, $arguments) { - $classname = strtolower(get_class($this)); - if ($this->_debug) { - print "PEAR constructor called, class=$classname\n"; - } - - if ($error_class !== null) { - $this->_error_class = $error_class; - } - - while ($classname && strcasecmp($classname, "pear")) { - $destructor = "_$classname"; - if (method_exists($this, $destructor)) { - global $_PEAR_destructor_object_list; - $_PEAR_destructor_object_list[] = &$this; - if (!isset($GLOBALS['_PEAR_SHUTDOWN_REGISTERED'])) { - register_shutdown_function("_PEAR_call_destructors"); - $GLOBALS['_PEAR_SHUTDOWN_REGISTERED'] = true; - } - break; - } else { - $classname = get_parent_class($classname); - } + if (!isset(self::$bivalentMethods[$method])) { + trigger_error( + 'Call to undefined method PEAR::' . $method . '()', E_USER_ERROR + ); } + return call_user_func_array( + array(get_class(), '_' . $method), + array_merge(array(null), $arguments) + ); } /** - * Destructor (the emulated type of...). Does nothing right now, - * but is included for forward compatibility, so subclass - * destructors should always call it. + * 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 = &PEAR::getStaticProperty('myclass', 'myVar'); + * You MUST use a reference, or they will not persist! * - * See the note in the class desciption about output from - * destructors. - * - * @access public - * @return void + * @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. */ - function _PEAR() { - if ($this->_debug) { - printf("PEAR destructor called, class=%s\n", strtolower(get_class($this))); - } - } - - /** - * 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 = &PEAR::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. - */ - function &getStaticProperty($class, $var) + public static function &getStaticProperty($class, $var) { static $properties; if (!isset($properties[$class])) { @@ -217,15 +178,15 @@ class PEAR } /** - * Use this function to register a shutdown method for static - * classes. - * - * @access public - * @param mixed $func The function name (or array of class/method) to call - * @param mixed $args The arguments to pass to the function - * @return void - */ - function registerShutdownFunc($func, $args = array()) + * Use this function to register a shutdown method for static + * classes. + * + * @param mixed $func The function name (or array of class/method) to call + * @param mixed $args The arguments to pass to the function + * + * @return void + */ + public static function registerShutdownFunc($func, $args = array()) { // if we are called statically, there is a potential // that no shutdown func is registered. Bug #6445 @@ -239,15 +200,15 @@ class PEAR /** * Tell whether a value is a PEAR error. * - * @param mixed $data the value to test - * @param int $code if $data is an error object, return true + * @param mixed $data the value to test + * @param int $code if $data is an error object, return true * only if $code is a string and * $obj->getMessage() == $code or * $code is an integer and $obj->getCode() == $code - * @access public + * * @return bool true if parameter is an error */ - function isError($data, $code = null) + public static function isError($data, $code = null) { if (!is_a($data, 'PEAR_Error')) { return false; @@ -262,6 +223,113 @@ class PEAR return $data->getCode() == $code; } + public static function staticPushErrorHandling($mode, $options = null) + { + $stack = &$GLOBALS['_PEAR_error_handler_stack']; + $def_mode = &$GLOBALS['_PEAR_default_error_mode']; + $def_options = &$GLOBALS['_PEAR_default_error_options']; + $stack[] = array($def_mode, $def_options); + switch ($mode) { + case PEAR_ERROR_EXCEPTION: + case PEAR_ERROR_RETURN: + case PEAR_ERROR_PRINT: + case PEAR_ERROR_TRIGGER: + case PEAR_ERROR_DIE: + case null: + $def_mode = $mode; + $def_options = $options; + break; + + case PEAR_ERROR_CALLBACK: + $def_mode = $mode; + // class/object method callback + if (is_callable($options)) { + $def_options = $options; + } else { + trigger_error("invalid error callback", E_USER_WARNING); + } + break; + + default: + trigger_error("invalid error mode", E_USER_WARNING); + break; + } + $stack[] = array($mode, $options); + return true; + } + + public static function staticPopErrorHandling() + { + $stack = &$GLOBALS['_PEAR_error_handler_stack']; + $setmode = &$GLOBALS['_PEAR_default_error_mode']; + $setoptions = &$GLOBALS['_PEAR_default_error_options']; + array_pop($stack); + list($mode, $options) = $stack[sizeof($stack) - 1]; + array_pop($stack); + switch ($mode) { + case PEAR_ERROR_EXCEPTION: + case PEAR_ERROR_RETURN: + case PEAR_ERROR_PRINT: + case PEAR_ERROR_TRIGGER: + case PEAR_ERROR_DIE: + case null: + $setmode = $mode; + $setoptions = $options; + break; + + case PEAR_ERROR_CALLBACK: + $setmode = $mode; + // class/object method callback + if (is_callable($options)) { + $setoptions = $options; + } else { + trigger_error("invalid error callback", E_USER_WARNING); + } + break; + + default: + trigger_error("invalid error mode", E_USER_WARNING); + break; + } + return true; + } + + /** + * OS independent PHP extension load. Remember to take care + * on the correct extension name for case sensitive OSes. + * + * @param string $ext The extension name + * @return bool Success or not on the dl() call + */ + public static function loadExtension($ext) + { + if (extension_loaded($ext)) { + return true; + } + + // if either returns true dl() will produce a FATAL error, stop that + if ( + function_exists('dl') === false || + ini_get('enable_dl') != 1 + ) { + return false; + } + + if (OS_WINDOWS) { + $suffix = '.dll'; + } elseif (PHP_OS == 'HP-UX') { + $suffix = '.sl'; + } elseif (PHP_OS == 'AIX') { + $suffix = '.a'; + } elseif (PHP_OS == 'OSX') { + $suffix = '.bundle'; + } else { + $suffix = '.so'; + } + + return @dl('php_' . $ext . $suffix) || @dl($ext . $suffix); + } + /** * Sets how errors generated by this object should be handled. * Can be invoked both in objects and statically. If called @@ -269,6 +337,9 @@ class PEAR * PEAR objects. If called in an object, setErrorHandling sets * the default behaviour for that object. * + * @param object $object + * Object the method was called on (non-static mode) + * * @param int $mode * One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT, * PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE, @@ -300,14 +371,16 @@ class PEAR * * @since PHP 4.0.5 */ - function setErrorHandling($mode = null, $options = null) + protected static function _setErrorHandling( + $object, $mode = null, $options = null + ) { - if (isset($this) && is_a($this, 'PEAR')) { - $setmode = &$this->_default_error_mode; - $setoptions = &$this->_default_error_options; + if ($object !== null) { + $setmode = &$object->_default_error_mode; + $setoptions = &$object->_default_error_options; } else { - $setmode = &$GLOBALS['_PEAR_default_error_mode']; - $setoptions = &$GLOBALS['_PEAR_default_error_options']; + $setmode = &$GLOBALS['_PEAR_default_error_mode']; + $setoptions = &$GLOBALS['_PEAR_default_error_options']; } switch ($mode) { @@ -337,113 +410,19 @@ class PEAR } } - /** - * This method is used to tell which errors you expect to get. - * Expected errors are always returned with error mode - * PEAR_ERROR_RETURN. Expected error codes are stored in a stack, - * and this method pushes a new element onto it. The list of - * expected errors are in effect until they are popped off the - * stack with the popExpect() method. - * - * Note that this method can not be called statically - * - * @param mixed $code a single error code or an array of error codes to expect - * - * @return int the new depth of the "expected errors" stack - * @access public - */ - function expectError($code = '*') - { - if (is_array($code)) { - array_push($this->_expected_errors, $code); - } else { - array_push($this->_expected_errors, array($code)); - } - return count($this->_expected_errors); - } - - /** - * This method pops one element off the expected error codes - * stack. - * - * @return array the list of error codes that were popped - */ - function popExpect() - { - return array_pop($this->_expected_errors); - } - - /** - * This method checks unsets an error code if available - * - * @param mixed error code - * @return bool true if the error code was unset, false otherwise - * @access private - * @since PHP 4.3.0 - */ - function _checkDelExpect($error_code) - { - $deleted = false; - foreach ($this->_expected_errors as $key => $error_array) { - if (in_array($error_code, $error_array)) { - unset($this->_expected_errors[$key][array_search($error_code, $error_array)]); - $deleted = true; - } - - // clean up empty arrays - if (0 == count($this->_expected_errors[$key])) { - unset($this->_expected_errors[$key]); - } - } - - return $deleted; - } - - /** - * This method deletes all occurences of the specified element from - * the expected error codes stack. - * - * @param mixed $error_code error code that should be deleted - * @return mixed list of error codes that were deleted or error - * @access public - * @since PHP 4.3.0 - */ - function delExpect($error_code) - { - $deleted = false; - if ((is_array($error_code) && (0 != count($error_code)))) { - // $error_code is a non-empty array here; we walk through it trying - // to unset all values - foreach ($error_code as $key => $error) { - $deleted = $this->_checkDelExpect($error) ? true : false; - } - - return $deleted ? true : PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME - } elseif (!empty($error_code)) { - // $error_code comes alone, trying to unset it - if ($this->_checkDelExpect($error_code)) { - return true; - } - - return PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME - } - - // $error_code is empty - return PEAR::raiseError("The expected error you submitted is empty"); // IMPROVE ME - } - /** * This method is a wrapper that returns an instance of the * configured error class with this object's default error * handling applied. If the $mode and $options parameters are not * specified, the object's defaults are used. * + * @param $object * @param mixed $message a text error message or a PEAR error object * - * @param int $code a numeric error code (it is up to your class + * @param int $code a numeric error code (it is up to your class * to define these if you want to use codes) * - * @param int $mode One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT, + * @param int $mode One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT, * PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE, * PEAR_ERROR_CALLBACK, PEAR_ERROR_EXCEPTION. * @@ -464,35 +443,35 @@ class PEAR * @param bool $skipmsg If true, raiseError will only pass error codes, * the error message parameter will be dropped. * - * @access public * @return object a PEAR error object * @see PEAR::setErrorHandling * @since PHP 4.0.5 */ - function &raiseError($message = null, - $code = null, - $mode = null, - $options = null, - $userinfo = null, - $error_class = null, - $skipmsg = false) + protected static function _raiseError($object, + $message = null, + $code = null, + $mode = null, + $options = null, + $userinfo = null, + $error_class = null, + $skipmsg = false) { // The error is yet a PEAR error object if (is_object($message)) { - $code = $message->getCode(); - $userinfo = $message->getUserInfo(); + $code = $message->getCode(); + $userinfo = $message->getUserInfo(); $error_class = $message->getType(); $message->error_message_prefix = ''; - $message = $message->getMessage(); + $message = $message->getMessage(); } if ( - isset($this) && - isset($this->_expected_errors) && - count($this->_expected_errors) > 0 && - count($exp = end($this->_expected_errors)) + $object !== null && + isset($object->_expected_errors) && + count($object->_expected_errors) > 0 && + count($exp = end($object->_expected_errors)) ) { - if ($exp[0] == "*" || + if ($exp[0] === "*" || (is_int(reset($exp)) && in_array($code, $exp)) || (is_string(reset($exp)) && in_array($message, $exp)) ) { @@ -503,30 +482,24 @@ class PEAR // No mode given, try global ones if ($mode === null) { // Class error handler - if (isset($this) && isset($this->_default_error_mode)) { - $mode = $this->_default_error_mode; - $options = $this->_default_error_options; - // Global error handler + if ($object !== null && isset($object->_default_error_mode)) { + $mode = $object->_default_error_mode; + $options = $object->_default_error_options; + // Global error handler } elseif (isset($GLOBALS['_PEAR_default_error_mode'])) { - $mode = $GLOBALS['_PEAR_default_error_mode']; + $mode = $GLOBALS['_PEAR_default_error_mode']; $options = $GLOBALS['_PEAR_default_error_options']; } } if ($error_class !== null) { $ec = $error_class; - } elseif (isset($this) && isset($this->_error_class)) { - $ec = $this->_error_class; + } elseif ($object !== null && isset($object->_error_class)) { + $ec = $object->_error_class; } else { $ec = 'PEAR_Error'; } - if (intval(PHP_VERSION) < 5) { - // little non-eval hack to fix bug #12147 - include 'PEAR/FixPHP5PEARWarnings.php'; - return $a; - } - if ($skipmsg) { $a = new $ec($code, $mode, $options, $userinfo); } else { @@ -540,105 +513,35 @@ class PEAR * Simpler form of raiseError with fewer options. In most cases * message, code and userinfo are enough. * + * @param $object * @param mixed $message a text error message or a PEAR error object * - * @param int $code a numeric error code (it is up to your class + * @param int $code a numeric error code (it is up to your class * to define these if you want to use codes) * * @param string $userinfo If you need to pass along for example debug * information, this parameter is meant for that. * - * @access public * @return object a PEAR error object * @see PEAR::raiseError */ - function &throwError($message = null, $code = null, $userinfo = null) + protected static function _throwError($object, $message = null, $code = null, $userinfo = null) { - if (isset($this) && is_a($this, 'PEAR')) { - $a = &$this->raiseError($message, $code, null, null, $userinfo); + if ($object !== null) { + $a = $object->raiseError($message, $code, null, null, $userinfo); return $a; } - $a = &PEAR::raiseError($message, $code, null, null, $userinfo); + $a = PEAR::raiseError($message, $code, null, null, $userinfo); return $a; } - function staticPushErrorHandling($mode, $options = null) - { - $stack = &$GLOBALS['_PEAR_error_handler_stack']; - $def_mode = &$GLOBALS['_PEAR_default_error_mode']; - $def_options = &$GLOBALS['_PEAR_default_error_options']; - $stack[] = array($def_mode, $def_options); - switch ($mode) { - case PEAR_ERROR_EXCEPTION: - case PEAR_ERROR_RETURN: - case PEAR_ERROR_PRINT: - case PEAR_ERROR_TRIGGER: - case PEAR_ERROR_DIE: - case null: - $def_mode = $mode; - $def_options = $options; - break; - - case PEAR_ERROR_CALLBACK: - $def_mode = $mode; - // class/object method callback - if (is_callable($options)) { - $def_options = $options; - } else { - trigger_error("invalid error callback", E_USER_WARNING); - } - break; - - default: - trigger_error("invalid error mode", E_USER_WARNING); - break; - } - $stack[] = array($mode, $options); - return true; - } - - function staticPopErrorHandling() - { - $stack = &$GLOBALS['_PEAR_error_handler_stack']; - $setmode = &$GLOBALS['_PEAR_default_error_mode']; - $setoptions = &$GLOBALS['_PEAR_default_error_options']; - array_pop($stack); - list($mode, $options) = $stack[sizeof($stack) - 1]; - array_pop($stack); - switch ($mode) { - case PEAR_ERROR_EXCEPTION: - case PEAR_ERROR_RETURN: - case PEAR_ERROR_PRINT: - case PEAR_ERROR_TRIGGER: - case PEAR_ERROR_DIE: - case null: - $setmode = $mode; - $setoptions = $options; - break; - - case PEAR_ERROR_CALLBACK: - $setmode = $mode; - // class/object method callback - if (is_callable($options)) { - $setoptions = $options; - } else { - trigger_error("invalid error callback", E_USER_WARNING); - } - break; - - default: - trigger_error("invalid error mode", E_USER_WARNING); - break; - } - return true; - } - /** * Push a new error handler on top of the error handler options stack. With this * you can easily override the actual error handler for some code and restore * it later with popErrorHandling. * + * @param $object * @param mixed $mode (same as setErrorHandling) * @param mixed $options (same as setErrorHandling) * @@ -646,20 +549,20 @@ class PEAR * * @see PEAR::setErrorHandling */ - function pushErrorHandling($mode, $options = null) + protected static function _pushErrorHandling($object, $mode, $options = null) { $stack = &$GLOBALS['_PEAR_error_handler_stack']; - if (isset($this) && is_a($this, 'PEAR')) { - $def_mode = &$this->_default_error_mode; - $def_options = &$this->_default_error_options; + if ($object !== null) { + $def_mode = &$object->_default_error_mode; + $def_options = &$object->_default_error_options; } else { - $def_mode = &$GLOBALS['_PEAR_default_error_mode']; + $def_mode = &$GLOBALS['_PEAR_default_error_mode']; $def_options = &$GLOBALS['_PEAR_default_error_options']; } $stack[] = array($def_mode, $def_options); - if (isset($this) && is_a($this, 'PEAR')) { - $this->setErrorHandling($mode, $options); + if ($object !== null) { + $object->setErrorHandling($mode, $options); } else { PEAR::setErrorHandling($mode, $options); } @@ -668,20 +571,21 @@ class PEAR } /** - * Pop the last error handler used - * - * @return bool Always true - * - * @see PEAR::pushErrorHandling - */ - function popErrorHandling() + * Pop the last error handler used + * + * @param $object + * @return bool Always true + * + * @see PEAR::pushErrorHandling + */ + protected static function _popErrorHandling($object) { $stack = &$GLOBALS['_PEAR_error_handler_stack']; array_pop($stack); list($mode, $options) = $stack[sizeof($stack) - 1]; array_pop($stack); - if (isset($this) && is_a($this, 'PEAR')) { - $this->setErrorHandling($mode, $options); + if ($object !== null) { + $object->setErrorHandling($mode, $options); } else { PEAR::setErrorHandling($mode, $options); } @@ -689,65 +593,195 @@ class PEAR } /** - * OS independant PHP extension load. Remember to take care - * on the correct extension name for case sensitive OSes. - * - * @param string $ext The extension name - * @return bool Success or not on the dl() call - */ - function loadExtension($ext) + * Only here for backwards compatibility. + * E.g. Archive_Tar calls $this->PEAR() in its constructor. + * + * @param string $error_class Which class to use for error objects, + * defaults to PEAR_Error. + */ + public function PEAR($error_class = null) { - if (extension_loaded($ext)) { - return true; + self::__construct($error_class); + } + + /** + * Constructor. Registers this object in + * $_PEAR_destructor_object_list for destructor emulation if a + * destructor object exists. + * + * @param string $error_class (optional) which class to use for + * error objects, defaults to PEAR_Error. + * @access public + * @return void + */ + function __construct($error_class = null) + { + $classname = strtolower(get_class($this)); + if ($this->_debug) { + print "PEAR constructor called, class=$classname\n"; } - // if either returns true dl() will produce a FATAL error, stop that - if ( - function_exists('dl') === false || - ini_get('enable_dl') != 1 || - ini_get('safe_mode') == 1 - ) { - return false; + if ($error_class !== null) { + $this->_error_class = $error_class; } - if (OS_WINDOWS) { - $suffix = '.dll'; - } elseif (PHP_OS == 'HP-UX') { - $suffix = '.sl'; - } elseif (PHP_OS == 'AIX') { - $suffix = '.a'; - } elseif (PHP_OS == 'OSX') { - $suffix = '.bundle'; + while ($classname && strcasecmp($classname, "pear")) { + $destructor = "_$classname"; + if (method_exists($this, $destructor)) { + global $_PEAR_destructor_object_list; + $_PEAR_destructor_object_list[] = $this; + if (!isset($GLOBALS['_PEAR_SHUTDOWN_REGISTERED'])) { + register_shutdown_function("_PEAR_call_destructors"); + $GLOBALS['_PEAR_SHUTDOWN_REGISTERED'] = true; + } + break; + } else { + $classname = get_parent_class($classname); + } + } + } + + /** + * Destructor (the emulated type of...). Does nothing right now, + * but is included for forward compatibility, so subclass + * destructors should always call it. + * + * See the note in the class desciption about output from + * destructors. + * + * @access public + * @return void + */ + function _PEAR() + { + if ($this->_debug) { + printf("PEAR destructor called, class=%s\n", strtolower(get_class($this))); + } + } + + public function __call($method, $arguments) + { + if (!isset(self::$bivalentMethods[$method])) { + trigger_error( + 'Call to undefined method PEAR::' . $method . '()', E_USER_ERROR + ); + } + return call_user_func_array( + array(get_class(), '_' . $method), + array_merge(array($this), $arguments) + ); + } + + /** + * This method is used to tell which errors you expect to get. + * Expected errors are always returned with error mode + * PEAR_ERROR_RETURN. Expected error codes are stored in a stack, + * and this method pushes a new element onto it. The list of + * expected errors are in effect until they are popped off the + * stack with the popExpect() method. + * + * Note that this method can not be called statically + * + * @param mixed $code a single error code or an array of error codes to expect + * + * @return int the new depth of the "expected errors" stack + * @access public + */ + function expectError($code = '*') + { + if (is_array($code)) { + array_push($this->_expected_errors, $code); } else { - $suffix = '.so'; + array_push($this->_expected_errors, array($code)); } + return count($this->_expected_errors); + } - return @dl('php_'.$ext.$suffix) || @dl($ext.$suffix); + /** + * This method pops one element off the expected error codes + * stack. + * + * @return array the list of error codes that were popped + */ + function popExpect() + { + return array_pop($this->_expected_errors); } -} -if (PEAR_ZE2) { - include_once 'PEAR5.php'; + /** + * This method deletes all occurrences of the specified element from + * the expected error codes stack. + * + * @param mixed $error_code error code that should be deleted + * @return mixed list of error codes that were deleted or error + * @access public + * @since PHP 4.3.0 + */ + function delExpect($error_code) + { + $deleted = false; + if ((is_array($error_code) && (0 != count($error_code)))) { + // $error_code is a non-empty array here; we walk through it trying + // to unset all values + foreach ($error_code as $key => $error) { + $deleted = $this->_checkDelExpect($error) ? true : false; + } + + return $deleted ? true : PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME + } elseif (!empty($error_code)) { + // $error_code comes alone, trying to unset it + if ($this->_checkDelExpect($error_code)) { + return true; + } + + return PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME + } + + // $error_code is empty + return PEAR::raiseError("The expected error you submitted is empty"); // IMPROVE ME + } + + /** + * This method checks unsets an error code if available + * + * @param mixed error code + * @return bool true if the error code was unset, false otherwise + * @access private + * @since PHP 4.3.0 + */ + function _checkDelExpect($error_code) + { + $deleted = false; + foreach ($this->_expected_errors as $key => $error_array) { + if (in_array($error_code, $error_array)) { + unset($this->_expected_errors[$key][array_search($error_code, $error_array)]); + $deleted = true; + } + + // clean up empty arrays + if (0 == count($this->_expected_errors[$key])) { + unset($this->_expected_errors[$key]); + } + } + + return $deleted; + } } function _PEAR_call_destructors() { global $_PEAR_destructor_object_list; if (is_array($_PEAR_destructor_object_list) && - sizeof($_PEAR_destructor_object_list)) - { + sizeof($_PEAR_destructor_object_list)) { reset($_PEAR_destructor_object_list); - if (PEAR_ZE2) { - $destructLifoExists = PEAR5::getStaticProperty('PEAR', 'destructlifo'); - } else { - $destructLifoExists = PEAR::getStaticProperty('PEAR', 'destructlifo'); - } + + $destructLifoExists = PEAR::getStaticProperty('PEAR', 'destructlifo'); if ($destructLifoExists) { $_PEAR_destructor_object_list = array_reverse($_PEAR_destructor_object_list); } - while (list($k, $objref) = each($_PEAR_destructor_object_list)) { + foreach ($_PEAR_destructor_object_list as $k => $objref) { $classname = get_class($objref); while ($classname) { $destructor = "_$classname"; @@ -788,7 +822,7 @@ function _PEAR_call_destructors() * @author Gregory Beaver * @copyright 1997-2006 The PHP Group * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.9.4 + * @version Release: @package_version@ * @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 @@ -796,25 +830,44 @@ function _PEAR_call_destructors() class PEAR_Error { var $error_message_prefix = ''; - var $mode = PEAR_ERROR_RETURN; - var $level = E_USER_NOTICE; - var $code = -1; - var $message = ''; - var $userinfo = ''; - var $backtrace = null; + var $mode = PEAR_ERROR_RETURN; + var $level = E_USER_NOTICE; + var $code = -1; + var $message = ''; + var $userinfo = ''; + var $backtrace = null; + + /** + * Only here for backwards compatibility. + * + * Class "Cache_Error" still uses it, among others. + * + * @param string $message Message + * @param int $code Error code + * @param int $mode Error mode + * @param mixed $options See __construct() + * @param string $userinfo Additional user/debug info + */ + public function PEAR_Error( + $message = 'unknown error', $code = null, $mode = null, + $options = null, $userinfo = null + ) + { + self::__construct($message, $code, $mode, $options, $userinfo); + } /** * PEAR_Error constructor * - * @param string $message message + * @param string $message message * - * @param int $code (optional) error code + * @param int $code (optional) error code * - * @param int $mode (optional) error mode, one of: PEAR_ERROR_RETURN, + * @param int $mode (optional) error mode, one of: PEAR_ERROR_RETURN, * PEAR_ERROR_PRINT, PEAR_ERROR_DIE, PEAR_ERROR_TRIGGER, * PEAR_ERROR_CALLBACK or PEAR_ERROR_EXCEPTION * - * @param mixed $options (optional) error level, _OR_ in the case of + * @param mixed $options (optional) error level, _OR_ in the case of * PEAR_ERROR_CALLBACK, the callback function or object/method * tuple. * @@ -823,22 +876,18 @@ class PEAR_Error * @access public * */ - function PEAR_Error($message = 'unknown error', $code = null, - $mode = null, $options = null, $userinfo = null) + function __construct($message = 'unknown error', $code = null, + $mode = null, $options = null, $userinfo = null) { if ($mode === null) { $mode = PEAR_ERROR_RETURN; } - $this->message = $message; - $this->code = $code; - $this->mode = $mode; - $this->userinfo = $userinfo; + $this->message = $message; + $this->code = $code; + $this->mode = $mode; + $this->userinfo = $userinfo; - if (PEAR_ZE2) { - $skiptrace = PEAR5::getStaticProperty('PEAR_Error', 'skiptrace'); - } else { - $skiptrace = PEAR::getStaticProperty('PEAR_Error', 'skiptrace'); - } + $skiptrace = PEAR::getStaticProperty('PEAR_Error', 'skiptrace'); if (!$skiptrace) { $this->backtrace = debug_backtrace(); @@ -883,7 +932,8 @@ class PEAR_Error } else { $format = $options; } - die(sprintf($format, $msg)); + printf($format, $msg); + exit($code); } if ($this->mode & PEAR_ERROR_CALLBACK && is_callable($this->callback)) { @@ -896,6 +946,17 @@ class PEAR_Error } } + /** + * Get the error message from an error object. + * + * @return string full error message + * @access public + */ + function getMessage() + { + return ($this->error_message_prefix . $this->message); + } + /** * Get the error mode from an error object. * @@ -918,27 +979,16 @@ class PEAR_Error return $this->callback; } - /** - * Get the error message from an error object. - * - * @return string full error message - * @access public - */ - function getMessage() - { - return ($this->error_message_prefix . $this->message); - } - /** * Get error code from an error object * * @return int error code * @access public */ - function getCode() - { + function getCode() + { return $this->code; - } + } /** * Get the name of this error/exception. @@ -952,25 +1002,25 @@ class PEAR_Error } /** - * Get additional user-supplied information. + * Get additional debug information supplied by the application. * - * @return string user-supplied information + * @return string debug information * @access public */ - function getUserInfo() + function getDebugInfo() { - return $this->userinfo; + return $this->getUserInfo(); } /** - * Get additional debug information supplied by the application. + * Get additional user-supplied information. * - * @return string debug information + * @return string user-supplied information * @access public */ - function getDebugInfo() + function getUserInfo() { - return $this->getUserInfo(); + return $this->userinfo; } /** @@ -1015,23 +1065,23 @@ class PEAR_Error function toString() { $modes = array(); - $levels = array(E_USER_NOTICE => 'notice', - E_USER_WARNING => 'warning', - E_USER_ERROR => 'error'); + $levels = array(E_USER_NOTICE => 'notice', + E_USER_WARNING => 'warning', + E_USER_ERROR => 'error'); if ($this->mode & PEAR_ERROR_CALLBACK) { if (is_array($this->callback)) { $callback = (is_object($this->callback[0]) ? - strtolower(get_class($this->callback[0])) : - $this->callback[0]) . '::' . + strtolower(get_class($this->callback[0])) : + $this->callback[0]) . '::' . $this->callback[1]; } else { $callback = $this->callback; } - return sprintf('[%s: message="%s" code=%d mode=callback '. - 'callback=%s prefix="%s" info="%s"]', - strtolower(get_class($this)), $this->message, $this->code, - $callback, $this->error_message_prefix, - $this->userinfo); + return sprintf('[%s: message="%s" code=%d mode=callback ' . + 'callback=%s prefix="%s" info="%s"]', + strtolower(get_class($this)), $this->message, $this->code, + $callback, $this->error_message_prefix, + $this->userinfo); } if ($this->mode & PEAR_ERROR_PRINT) { $modes[] = 'print'; @@ -1045,12 +1095,12 @@ class PEAR_Error if ($this->mode & PEAR_ERROR_RETURN) { $modes[] = 'return'; } - return sprintf('[%s: message="%s" code=%d mode=%s level=%s '. - 'prefix="%s" info="%s"]', - strtolower(get_class($this)), $this->message, $this->code, - implode("|", $modes), $levels[$this->level], - $this->error_message_prefix, - $this->userinfo); + return sprintf('[%s: message="%s" code=%d mode=%s level=%s ' . + 'prefix="%s" info="%s"]', + strtolower(get_class($this)), $this->message, $this->code, + implode("|", $modes), $levels[$this->level], + $this->error_message_prefix, + $this->userinfo); } } diff --git a/extlib/PEAR/ErrorStack.php b/extlib/PEAR/ErrorStack.php index 0303f5273a..f166ccd437 100644 --- a/extlib/PEAR/ErrorStack.php +++ b/extlib/PEAR/ErrorStack.php @@ -1,7 +1,7 @@ * @copyright 2004-2008 Greg Beaver * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: ErrorStack.php 313023 2011-07-06 19:17:11Z dufuz $ * @link http://pear.php.net/package/PEAR_ErrorStack */ /** * Singleton storage - * + * * Format: *
  * array(
@@ -45,7 +44,7 @@ $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.
@@ -61,7 +60,7 @@ $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'] = array(
 
 /**
  * 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()
@@ -72,7 +71,7 @@ $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()
@@ -132,12 +131,11 @@ define('PEAR_ERRORSTACK_ERR_OBJTOSTRING', 2);
  * $local_stack = new PEAR_ErrorStack('MyPackage');
  * 
  * @author     Greg Beaver 
- * @version    1.9.4
+ * @version    @package_version@
  * @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 313023 2011-07-06 19:17:11Z dufuz $
  * @link       http://pear.php.net/package/PEAR_ErrorStack
  */
 class PEAR_ErrorStack {
@@ -167,14 +165,14 @@ class PEAR_ErrorStack {
      * @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
@@ -183,7 +181,7 @@ class PEAR_ErrorStack {
      * @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
@@ -194,43 +192,43 @@ class PEAR_ErrorStack {
      * @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,
+    function __construct($package, $msgCallback = false, $contextCallback = false,
                          $throwPEAR_Error = false)
     {
         $this->_package = $package;
@@ -238,10 +236,10 @@ class PEAR_ErrorStack {
         $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
@@ -250,12 +248,13 @@ class PEAR_ErrorStack {
      *                 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')
-    {
+    public static 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];
         }
@@ -276,7 +275,7 @@ class PEAR_ErrorStack {
 
     /**
      * Internal error handler for PEAR_ErrorStack class
-     * 
+     *
      * Dies if the error is an exception (and would have died anyway)
      * @access private
      */
@@ -293,24 +292,23 @@ class PEAR_ErrorStack {
             die($message);
         }
     }
-    
+
     /**
      * Set up a PEAR::Log object for all error stacks that don't have one
-     * @param Log $log 
-     * @static
+     * @param Log $log
      */
-    function setDefaultLogger(&$log)
+    public 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 
+     * @param Log $log
      */
     function setLogger(&$log)
     {
@@ -320,10 +318,10 @@ class PEAR_ErrorStack {
             $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
@@ -338,10 +336,10 @@ class PEAR_ErrorStack {
             }
         }
     }
-    
+
     /**
      * 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
@@ -350,17 +348,16 @@ class PEAR_ErrorStack {
     {
         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)
+    public static function setDefaultCallback($callback = false, $package = false)
     {
         if (!is_callable($callback)) {
             $callback = false;
@@ -368,14 +365,16 @@ class PEAR_ErrorStack {
         $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
+     * @return bool
+     * @return array|bool|callable|false|string
      */
     function setContextCallback($contextCallback)
     {
@@ -383,22 +382,23 @@ class PEAR_ErrorStack {
             return $this->_contextCallback = false;
         }
         if (!$contextCallback) {
-            $this->_contextCallback = array(&$this, 'getFileLine');
+            $this->_contextCallback = [&$this, 'getFileLine'];
         } else {
             if (is_callable($contextCallback)) {
                 $this->_contextCallback = $contextCallback;
             }
         }
+        return $this->_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
@@ -410,7 +410,7 @@ class PEAR_ErrorStack {
     {
         array_push($this->_errorCallback, $cb);
     }
-    
+
     /**
      * Remove a callback from the error callback stack
      * @see pushCallback()
@@ -423,7 +423,7 @@ class PEAR_ErrorStack {
         }
         return array_pop($this->_errorCallback);
     }
-    
+
     /**
      * Set a temporary overriding error callback for every package error stack
      *
@@ -432,20 +432,18 @@ class PEAR_ErrorStack {
      * @see PEAR_ERRORSTACK_PUSHANDLOG, PEAR_ERRORSTACK_PUSH, PEAR_ERRORSTACK_LOG
      * @see staticPopCallback(), pushCallback()
      * @param string|array $cb
-     * @static
      */
-    function staticPushCallback($cb)
+    public 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()
+    public static function staticPopCallback()
     {
         $ret = array_pop($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK']);
         if (!is_array($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'])) {
@@ -453,15 +451,15 @@ class PEAR_ErrorStack {
         }
         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
@@ -479,7 +477,7 @@ class PEAR_ErrorStack {
      * @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:
-     * 
+     *
      * 
      * array(
      *    'code' => $code,
@@ -492,7 +490,7 @@ class PEAR_ErrorStack {
      * //['repackage' => $err] repackaged error array/Exception class
      * );
      * 
-     * 
+     *
      * Normally, the previous array is returned.
      */
     function push($code, $level = 'error', $params = array(), $msg = false,
@@ -506,19 +504,19 @@ class PEAR_ErrorStack {
             }
             $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,
-               );
+            'code' => $code,
+            'params' => $params,
+            'package' => $this->_package,
+            'level' => $level,
+            'time' => $time,
+            'context' => $context,
+            'message' => $msg,
+        );
 
         if ($repackage) {
             $err['repackage'] = $repackage;
@@ -527,9 +525,9 @@ class PEAR_ErrorStack {
         // set up the error message, if necessary
         if ($this->_msgCallback) {
             $msg = call_user_func_array($this->_msgCallback,
-                                        array(&$this, $err));
+                array(&$this, $err));
             $err['message'] = $msg;
-        }        
+        }
         $push = $log = true;
         $die = false;
         // try the overriding callback first
@@ -551,18 +549,18 @@ class PEAR_ErrorStack {
         }
         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;
+                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
             }
         }
@@ -586,10 +584,10 @@ class PEAR_ErrorStack {
         }
         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
@@ -604,11 +602,11 @@ class PEAR_ErrorStack {
      *                          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)
-    {
+    public 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) {
@@ -619,7 +617,7 @@ class PEAR_ErrorStack {
         }
         return $s->push($code, $level, $params, $msg, $repackage, $backtrace);
     }
-    
+
     /**
      * Log an error using PEAR::Log
      * @param array $err Error array
@@ -654,10 +652,10 @@ class PEAR_ErrorStack {
         }
     }
 
-    
+
     /**
      * 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
@@ -681,7 +679,7 @@ class PEAR_ErrorStack {
      * @return boolean
      * @since PEAR1.5.0a1
      */
-    function staticPop($package)
+    static function staticPop($package)
     {
         if ($package) {
             if (!isset($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package])) {
@@ -689,11 +687,12 @@ class PEAR_ErrorStack {
             }
             return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]->pop();
         }
+        return false;
     }
 
     /**
      * Determine whether there are any errors on the stack
-     * @param string|array Level name.  Use to determine if any errors
+     * @param string|array|bool $level name.  Use to determine if any errors
      * of level (string), or levels (array) have been pushed
      * @return boolean
      */
@@ -704,10 +703,10 @@ class PEAR_ErrorStack {
         }
         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
@@ -741,7 +740,7 @@ class PEAR_ErrorStack {
         $this->_errorsByLevel = array();
         return $ret;
     }
-    
+
     /**
      * Determine whether there are any errors on a single error stack, or on any error stack
      *
@@ -750,9 +749,8 @@ class PEAR_ErrorStack {
      * @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)
+    public static function staticHasErrors($package = false, $level = false)
     {
         if ($package) {
             if (!isset($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package])) {
@@ -767,7 +765,7 @@ class PEAR_ErrorStack {
         }
         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
@@ -776,12 +774,13 @@ class PEAR_ErrorStack {
      * @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 
+     *
+     * @return array
      */
-    function staticGetErrors($purge = false, $level = false, $merge = false,
-                             $sortfunc = array('PEAR_ErrorStack', '_sortErrors'))
-    {
+    public static function staticGetErrors(
+        $purge = false, $level = false, $merge = false,
+        $sortfunc = array('PEAR_ErrorStack', '_sortErrors')
+    ) {
         $ret = array();
         if (!is_callable($sortfunc)) {
             $sortfunc = array('PEAR_ErrorStack', '_sortErrors');
@@ -801,12 +800,12 @@ class PEAR_ErrorStack {
         }
         return $ret;
     }
-    
+
     /**
      * Error sorting function, sorts by time
      * @access private
      */
-    function _sortErrors($a, $b)
+    public static function _sortErrors($a, $b)
     {
         if ($a['time'] == $b['time']) {
             return 0;
@@ -829,9 +828,8 @@ class PEAR_ErrorStack {
      * @param unused
      * @param integer backtrace frame.
      * @param array Results of debug_backtrace()
-     * @static
      */
-    function getFileLine($code, $params, $backtrace = null)
+    public static function getFileLine($code, $params, $backtrace = null)
     {
         if ($backtrace === null) {
             return false;
@@ -842,8 +840,8 @@ class PEAR_ErrorStack {
             $functionframe = 0;
         } else {
             while (isset($backtrace[$functionframe]['function']) &&
-                  $backtrace[$functionframe]['function'] == 'eval' &&
-                  isset($backtrace[$functionframe + 1])) {
+                $backtrace[$functionframe]['function'] == 'eval' &&
+                isset($backtrace[$functionframe + 1])) {
                 $functionframe++;
             }
         }
@@ -854,11 +852,11 @@ class PEAR_ErrorStack {
             $funcbacktrace = $backtrace[$functionframe];
             $filebacktrace = $backtrace[$frame];
             $ret = array('file' => $filebacktrace['file'],
-                         'line' => $filebacktrace['line']);
+                'line' => $filebacktrace['line']);
             // rearrange for eval'd code or create function errors
-            if (strpos($filebacktrace['file'], '(') && 
-            	  preg_match(';^(.*?)\((\d+)\) : (.*?)\\z;', $filebacktrace['file'],
-                  $matches)) {
+            if (strpos($filebacktrace['file'], '(') &&
+                preg_match(';^(.*?)\((\d+)\) : (.*?)\\z;', $filebacktrace['file'],
+                    $matches)) {
                 $ret['file'] = $matches[1];
                 $ret['line'] = $matches[2] + 0;
             }
@@ -878,35 +876,35 @@ class PEAR_ErrorStack {
         }
         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:
-     * 
+     *
      * 
      * $stack->push(ERROR_CODE, 'error', array(), 'server error 500');
      * 
-     * 
+     *
      * 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)
+    public static function getErrorMessage(&$stack, $err, $template = false)
     {
         if ($template) {
             $mainmsg = $template;
@@ -935,7 +933,7 @@ class PEAR_ErrorStack {
         }
         return $mainmsg;
     }
-    
+
     /**
      * Standard Error Message Template generator from code
      * @return string
@@ -947,39 +945,42 @@ class PEAR_ErrorStack {
         }
         return $this->_errorMsgs[$code];
     }
-    
+
     /**
      * Set the Error Message Template array
-     * 
+     *
      * The array format must be:
      * 
      * array(error code => 'message template',...)
      * 
- * + * * 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 + * + * Returns string via property + * @param $template + * @return null */ function setErrorMessageTemplate($template) { $this->_errorMsgs = $template; + return null; } - - + + /** * emulate PEAR::raiseError() - * + * * @return PEAR_Error */ function raiseError() { - require_once 'PEAR.php'; + 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')); -?> +$stack->pushCallback(array('PEAR_ErrorStack', '_handleError')); \ No newline at end of file diff --git a/extlib/PEAR/Exception.php b/extlib/PEAR/Exception.php index 4a0e7b86fa..8755a4242a 100644 --- a/extlib/PEAR/Exception.php +++ b/extlib/PEAR/Exception.php @@ -99,9 +99,9 @@ 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; + protected $cause; private $_trace; /** @@ -117,6 +117,7 @@ class PEAR_Exception extends Exception * @param string exception message * @param int|Exception|PEAR_Error|array|null exception cause * @param int|null exception code or null + * @throws PEAR_Exception */ public function __construct($message, $p2 = null, $p3 = null) { @@ -145,32 +146,6 @@ class PEAR_Exception extends Exception $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) { @@ -198,6 +173,32 @@ class PEAR_Exception extends Exception } } + /** + * @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++; + } + /** * Return specific error information that can be used for more detailed * error messages or translation. @@ -227,79 +228,6 @@ class PEAR_Exception extends Exception 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(); @@ -325,22 +253,22 @@ class PEAR_Exception extends Exception $trace = $this->getTraceSafe(); $causes = array(); $this->getCauseMessage($causes); - $html = '' . "\n"; + $html = '
' . "\n"; foreach ($causes as $i => $cause) { $html .= '\n"; + . str_repeat('-', $i) . ' ' . $cause['class'] . ': ' + . htmlspecialchars($cause['message']) . ' in ' . $cause['file'] . ' ' + . 'on line ' . $cause['line'] . '' + . "\n"; } $html .= '' . "\n" - . '' - . '' - . '' . "\n"; + . '' + . '' + . '' . "\n"; foreach ($trace as $k => $v) { $html .= '' - . '' - . '' . "\n"; + $html .= '(' . implode(', ', $args) . ')' + . '' + . '' . "\n"; } - $html .= '' - . '' - . '' . "\n" - . '
' - . str_repeat('-', $i) . ' ' . $cause['class'] . ': ' - . htmlspecialchars($cause['message']) . ' in ' . $cause['file'] . ' ' - . 'on line ' . $cause['line'] . '' - . "
Exception trace
#FunctionLocation
#FunctionLocation
' . $k . ''; + . ''; if (!empty($v['class'])) { $html .= $v['class'] . $v['type']; } @@ -350,7 +278,7 @@ class PEAR_Exception extends Exception 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_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 { @@ -361,19 +289,92 @@ class PEAR_Exception extends Exception } } } - $html .= '(' . implode(', ',$args) . ')' - . '' . (isset($v['file']) ? $v['file'] : 'unknown') - . ':' . (isset($v['line']) ? $v['line'] : 'unknown') - . '
' . (isset($v['file']) ? $v['file'] : 'unknown') + . ':' . (isset($v['line']) ? $v['line'] : 'unknown') + . '
' . ($k+1) . '{main} 
'; + $html .= '' . ($k + 1) . '' + . '{main}' + . ' ' . "\n" + . ''; return $html; } + /** + * 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 toText() { $causes = array(); @@ -381,8 +382,8 @@ class PEAR_Exception extends Exception $causeMsg = ''; foreach ($causes as $i => $cause) { $causeMsg .= str_repeat(' ', $i) . $cause['class'] . ': ' - . $cause['message'] . ' in ' . $cause['file'] - . ' on line ' . $cause['line'] . "\n"; + . $cause['message'] . ' in ' . $cause['file'] + . ' on line ' . $cause['line'] . "\n"; } return $causeMsg . $this->getTraceAsString(); } diff --git a/extlib/PEAR/FixPHP5PEARWarnings.php b/extlib/PEAR/FixPHP5PEARWarnings.php deleted file mode 100644 index be5dc3ce70..0000000000 --- a/extlib/PEAR/FixPHP5PEARWarnings.php +++ /dev/null @@ -1,7 +0,0 @@ - \ No newline at end of file diff --git a/extlib/PEAR5.php b/extlib/PEAR5.php deleted file mode 100644 index 428606780b..0000000000 --- a/extlib/PEAR5.php +++ /dev/null @@ -1,33 +0,0 @@ - * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: System.php 313024 2011-07-06 19:51:24Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 0.1 */ @@ -23,281 +22,41 @@ require_once 'Console/Getopt.php'; $GLOBALS['_System_temp_files'] = array(); /** -* System offers cross plattform compatible system functions -* -* Static functions for different operations. Should work under -* Unix and Windows. The names and usage has been taken from its respectively -* GNU commands. The functions will return (bool) false on error and will -* trigger the error with the PHP trigger_error() function (you can silence -* the error by prefixing a '@' sign after the function call, but this -* is not recommended practice. Instead use an error handler with -* {@link set_error_handler()}). -* -* Documentation on this class you can find in: -* http://pear.php.net/manual/ -* -* Example usage: -* if (!@System::rm('-r file1 dir1')) { -* print "could not delete file1 or dir1"; -* } -* -* In case you need to to pass file names with spaces, -* pass the params as an array: -* -* System::rm(array('-r', $file1, $dir1)); -* -* @category pear -* @package System -* @author Tomas V.V. Cox -* @copyright 1997-2006 The PHP Group -* @license http://opensource.org/licenses/bsd-license.php New BSD License -* @version Release: 1.9.4 -* @link http://pear.php.net/package/PEAR -* @since Class available since Release 0.1 -* @static -*/ + * System offers cross platform compatible system functions + * + * Static functions for different operations. Should work under + * Unix and Windows. The names and usage has been taken from its respectively + * GNU commands. The functions will return (bool) false on error and will + * trigger the error with the PHP trigger_error() function (you can silence + * the error by prefixing a '@' sign after the function call, but this + * is not recommended practice. Instead use an error handler with + * {@link set_error_handler()}). + * + * Documentation on this class you can find in: + * http://pear.php.net/manual/ + * + * Example usage: + * if (!@System::rm('-r file1 dir1')) { + * print "could not delete file1 or dir1"; + * } + * + * In case you need to to pass file names with spaces, + * pass the params as an array: + * + * System::rm(array('-r', $file1, $dir1)); + * + * @category pear + * @package System + * @author Tomas V.V. Cox + * @copyright 1997-2006 The PHP Group + * @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 + * @static + */ class System { - /** - * returns the commandline arguments of a function - * - * @param string $argv the commandline - * @param string $short_options the allowed option short-tags - * @param string $long_options the allowed option long-tags - * @return array the given options and there values - * @static - * @access private - */ - function _parseArgs($argv, $short_options, $long_options = null) - { - if (!is_array($argv) && $argv !== null) { - // Find all items, quoted or otherwise - preg_match_all("/(?:[\"'])(.*?)(?:['\"])|([^\s]+)/", $argv, $av); - $argv = $av[1]; - foreach ($av[2] as $k => $a) { - if (empty($a)) { - continue; - } - $argv[$k] = trim($a) ; - } - } - return Console_Getopt::getopt2($argv, $short_options, $long_options); - } - - /** - * Output errors with PHP trigger_error(). You can silence the errors - * with prefixing a "@" sign to the function call: @System::mkdir(..); - * - * @param mixed $error a PEAR error or a string with the error message - * @return bool false - * @static - * @access private - */ - function raiseError($error) - { - if (PEAR::isError($error)) { - $error = $error->getMessage(); - } - trigger_error($error, E_USER_WARNING); - return false; - } - - /** - * Creates a nested array representing the structure of a directory - * - * System::_dirToStruct('dir1', 0) => - * Array - * ( - * [dirs] => Array - * ( - * [0] => dir1 - * ) - * - * [files] => Array - * ( - * [0] => dir1/file2 - * [1] => dir1/file3 - * ) - * ) - * @param string $sPath Name of the directory - * @param integer $maxinst max. deep of the lookup - * @param integer $aktinst starting deep of the lookup - * @param bool $silent if true, do not emit errors. - * @return array the structure of the dir - * @static - * @access private - */ - function _dirToStruct($sPath, $maxinst, $aktinst = 0, $silent = false) - { - $struct = array('dirs' => array(), 'files' => array()); - if (($dir = @opendir($sPath)) === false) { - if (!$silent) { - System::raiseError("Could not open dir $sPath"); - } - return $struct; // XXX could not open error - } - - $struct['dirs'][] = $sPath = realpath($sPath); // XXX don't add if '.' or '..' ? - $list = array(); - while (false !== ($file = readdir($dir))) { - if ($file != '.' && $file != '..') { - $list[] = $file; - } - } - - closedir($dir); - natsort($list); - if ($aktinst < $maxinst || $maxinst == 0) { - foreach ($list as $val) { - $path = $sPath . DIRECTORY_SEPARATOR . $val; - if (is_dir($path) && !is_link($path)) { - $tmp = System::_dirToStruct($path, $maxinst, $aktinst+1, $silent); - $struct = array_merge_recursive($struct, $tmp); - } else { - $struct['files'][] = $path; - } - } - } - - return $struct; - } - - /** - * Creates a nested array representing the structure of a directory and files - * - * @param array $files Array listing files and dirs - * @return array - * @static - * @see System::_dirToStruct() - */ - function _multipleToStruct($files) - { - $struct = array('dirs' => array(), 'files' => array()); - settype($files, 'array'); - foreach ($files as $file) { - if (is_dir($file) && !is_link($file)) { - $tmp = System::_dirToStruct($file, 0); - $struct = array_merge_recursive($tmp, $struct); - } else { - if (!in_array($file, $struct['files'])) { - $struct['files'][] = $file; - } - } - } - return $struct; - } - - /** - * The rm command for removing files. - * Supports multiple files and dirs and also recursive deletes - * - * @param string $args the arguments for rm - * @return mixed PEAR_Error or true for success - * @static - * @access public - */ - function rm($args) - { - $opts = System::_parseArgs($args, 'rf'); // "f" does nothing but I like it :-) - if (PEAR::isError($opts)) { - return System::raiseError($opts); - } - foreach ($opts[0] as $opt) { - if ($opt[0] == 'r') { - $do_recursive = true; - } - } - $ret = true; - if (isset($do_recursive)) { - $struct = System::_multipleToStruct($opts[1]); - foreach ($struct['files'] as $file) { - if (!@unlink($file)) { - $ret = false; - } - } - - rsort($struct['dirs']); - foreach ($struct['dirs'] as $dir) { - if (!@rmdir($dir)) { - $ret = false; - } - } - } else { - foreach ($opts[1] as $file) { - $delete = (is_dir($file)) ? 'rmdir' : 'unlink'; - if (!@$delete($file)) { - $ret = false; - } - } - } - return $ret; - } - - /** - * Make directories. - * - * The -p option will create parent directories - * @param string $args the name of the director(y|ies) to create - * @return bool True for success - * @static - * @access public - */ - function mkDir($args) - { - $opts = System::_parseArgs($args, 'pm:'); - if (PEAR::isError($opts)) { - return System::raiseError($opts); - } - - $mode = 0777; // default mode - foreach ($opts[0] as $opt) { - if ($opt[0] == 'p') { - $create_parents = true; - } elseif ($opt[0] == 'm') { - // if the mode is clearly an octal number (starts with 0) - // convert it to decimal - if (strlen($opt[1]) && $opt[1]{0} == '0') { - $opt[1] = octdec($opt[1]); - } else { - // convert to int - $opt[1] += 0; - } - $mode = $opt[1]; - } - } - - $ret = true; - if (isset($create_parents)) { - foreach ($opts[1] as $dir) { - $dirstack = array(); - while ((!file_exists($dir) || !is_dir($dir)) && - $dir != DIRECTORY_SEPARATOR) { - array_unshift($dirstack, $dir); - $dir = dirname($dir); - } - - while ($newdir = array_shift($dirstack)) { - if (!is_writeable(dirname($newdir))) { - $ret = false; - break; - } - - if (!mkdir($newdir, $mode)) { - $ret = false; - } - } - } - } else { - foreach($opts[1] as $dir) { - if ((@file_exists($dir) || !is_dir($dir)) && !mkdir($dir, $mode)) { - $ret = false; - } - } - } - - return $ret; - } - /** * Concatenate files * @@ -306,14 +65,12 @@ class System * 2) System::cat('sample.txt test.txt > final.txt'); * 3) System::cat('sample.txt test.txt >> final.txt'); * - * Note: as the class use fopen, urls should work also (test that) + * Note: as the class use fopen, urls should work also * - * @param string $args the arguments + * @param string $args the arguments * @return boolean true on success - * @static - * @access public */ - function &cat($args) + public static function &cat($args) { $ret = null; $files = array(); @@ -325,11 +82,11 @@ class System for ($i = 0; $i < $count_args; $i++) { if ($args[$i] == '>') { $mode = 'wb'; - $outputfile = $args[$i+1]; + $outputfile = $args[$i + 1]; break; } elseif ($args[$i] == '>>') { $mode = 'ab+'; - $outputfile = $args[$i+1]; + $outputfile = $args[$i + 1]; break; } else { $files[] = $args[$i]; @@ -363,6 +120,22 @@ class System return $ret; } + /** + * Output errors with PHP trigger_error(). You can silence the errors + * with prefixing a "@" sign to the function call: @System::mkdir(..); + * + * @param mixed $error a PEAR error or a string with the error message + * @return bool false + */ + protected static function raiseError($error) + { + if (PEAR::isError($error)) { + $error = $error->getMessage(); + } + trigger_error($error, E_USER_WARNING); + return false; + } + /** * Creates temporary files or directories. This function will remove * the created files when the scripts finish its execution. @@ -381,13 +154,11 @@ class System * TMPDIR in Unix will be used. If these vars are also missing * c:\windows\temp or /tmp will be used. * - * @param string $args The arguments + * @param string $args The arguments * @return mixed the full path of the created (file|dir) or false * @see System::tmpdir() - * @static - * @access public */ - function mktemp($args = null) + public static function mktemp($args = null) { static $first_time = true; $opts = System::_parseArgs($args, 't:d'); @@ -408,7 +179,7 @@ class System $tmpdir = System::tmpdir(); } - if (!System::mkDir(array('-p', $tmpdir))) { + if (!System::mkDir(['-p', $tmpdir])) { return false; } @@ -421,9 +192,9 @@ class System } $GLOBALS['_System_temp_files'][] = $tmp; - if (isset($tmp_is_dir)) { + /*if (isset($tmp_is_dir)) { //$GLOBALS['_System_temp_files'][] = dirname($tmp); - } + }*/ if ($first_time) { PEAR::registerShutdownFunc(array('System', '_removeTmpFiles')); @@ -434,20 +205,45 @@ class System } /** - * Remove temporary files created my mkTemp. This function is executed - * at script shutdown time + * returns the commandline arguments of a function * - * @static - * @access private + * @param string $argv the commandline + * @param string $short_options the allowed option short-tags + * @param string $long_options the allowed option long-tags + * @return array the given options and there values */ - function _removeTmpFiles() + public static function _parseArgs($argv, $short_options, $long_options = null) { - if (count($GLOBALS['_System_temp_files'])) { - $delete = $GLOBALS['_System_temp_files']; - array_unshift($delete, '-r'); - System::rm($delete); - $GLOBALS['_System_temp_files'] = array(); + if (!is_array($argv) && $argv !== null) { + /* + // Quote all items that are a short option + $av = preg_split('/(\A| )--?[a-z0-9]+[ =]?((? $a) { + if (empty($a)) { + continue; + } + $argv[$k] = trim($a); + } } + + return (new Console_Getopt)->getopt2($argv, $short_options, $long_options); } /** @@ -456,10 +252,9 @@ class System * Note: php.ini-recommended removes the "E" from the variables_order setting, * making unavaible the $_ENV array, that s why we do tests with _ENV * - * @static * @return string The temporary directory on the system */ - function tmpdir() + public static function tmpdir() { if (OS_WINDOWS) { if ($var = isset($_ENV['TMP']) ? $_ENV['TMP'] : getenv('TMP')) { @@ -482,17 +277,222 @@ class System return realpath('/tmp'); } + /** + * Make directories. + * + * The -p option will create parent directories + * @param string $args the name of the director(y|ies) to create + * @return bool True for success + */ + public static function mkDir($args) + { + $opts = System::_parseArgs($args, 'pm:'); + if (PEAR::isError($opts)) { + return System::raiseError($opts); + } + + $mode = 0777; // default mode + foreach ($opts[0] as $opt) { + if ($opt[0] == 'p') { + $create_parents = true; + } elseif ($opt[0] == 'm') { + // if the mode is clearly an octal number (starts with 0) + // convert it to decimal + if (strlen($opt[1]) && $opt[1]{0} == '0') { + $opt[1] = octdec($opt[1]); + } else { + // convert to int + $opt[1] += 0; + } + $mode = $opt[1]; + } + } + + $ret = true; + if (isset($create_parents)) { + foreach ($opts[1] as $dir) { + $dirstack = array(); + while ((!file_exists($dir) || !is_dir($dir)) && + $dir != DIRECTORY_SEPARATOR) { + array_unshift($dirstack, $dir); + $dir = dirname($dir); + } + + while ($newdir = array_shift($dirstack)) { + if (!is_writeable(dirname($newdir))) { + $ret = false; + break; + } + + if (!mkdir($newdir, $mode)) { + $ret = false; + } + } + } + } else { + foreach ($opts[1] as $dir) { + if ((@file_exists($dir) || !is_dir($dir)) && !mkdir($dir, $mode)) { + $ret = false; + } + } + } + + return $ret; + } + + /** + * Remove temporary files created my mkTemp. This function is executed + * at script shutdown time + */ + public static function _removeTmpFiles() + { + if (count($GLOBALS['_System_temp_files'])) { + $delete = $GLOBALS['_System_temp_files']; + array_unshift($delete, '-r'); + System::rm($delete); + $GLOBALS['_System_temp_files'] = array(); + } + } + + /** + * The rm command for removing files. + * Supports multiple files and dirs and also recursive deletes + * + * @param string $args the arguments for rm + * @return mixed PEAR_Error or true for success + * @static + * @access public + */ + public static function rm($args) + { + $opts = System::_parseArgs($args, 'rf'); // "f" does nothing but I like it :-) + if (PEAR::isError($opts)) { + return System::raiseError($opts); + } + foreach ($opts[0] as $opt) { + if ($opt[0] == 'r') { + $do_recursive = true; + } + } + $ret = true; + if (isset($do_recursive)) { + $struct = System::_multipleToStruct($opts[1]); + foreach ($struct['files'] as $file) { + if (!@unlink($file)) { + $ret = false; + } + } + + rsort($struct['dirs']); + foreach ($struct['dirs'] as $dir) { + if (!@rmdir($dir)) { + $ret = false; + } + } + } else { + foreach ($opts[1] as $file) { + $delete = (is_dir($file)) ? 'rmdir' : 'unlink'; + if (!@$delete($file)) { + $ret = false; + } + } + } + return $ret; + } + + /** + * Creates a nested array representing the structure of a directory and files + * + * @param array $files Array listing files and dirs + * @return array + * @static + * @see System::_dirToStruct() + */ + protected static function _multipleToStruct($files) + { + $struct = array('dirs' => array(), 'files' => array()); + settype($files, 'array'); + foreach ($files as $file) { + if (is_dir($file) && !is_link($file)) { + $tmp = System::_dirToStruct($file, 0); + $struct = array_merge_recursive($tmp, $struct); + } else { + if (!in_array($file, $struct['files'])) { + $struct['files'][] = $file; + } + } + } + return $struct; + } + + /** + * Creates a nested array representing the structure of a directory + * + * System::_dirToStruct('dir1', 0) => + * Array + * ( + * [dirs] => Array + * ( + * [0] => dir1 + * ) + * + * [files] => Array + * ( + * [0] => dir1/file2 + * [1] => dir1/file3 + * ) + * ) + * @param string $sPath Name of the directory + * @param integer $maxinst max. deep of the lookup + * @param integer $aktinst starting deep of the lookup + * @param bool $silent if true, do not emit errors. + * @return array the structure of the dir + */ + protected static function _dirToStruct($sPath, $maxinst, $aktinst = 0, $silent = false) + { + $struct = array('dirs' => array(), 'files' => array()); + if (($dir = @opendir($sPath)) === false) { + if (!$silent) { + System::raiseError("Could not open dir $sPath"); + } + return $struct; // XXX could not open error + } + + $struct['dirs'][] = $sPath = realpath($sPath); // XXX don't add if '.' or '..' ? + $list = array(); + while (false !== ($file = readdir($dir))) { + if ($file != '.' && $file != '..') { + $list[] = $file; + } + } + + closedir($dir); + natsort($list); + if ($aktinst < $maxinst || $maxinst == 0) { + foreach ($list as $val) { + $path = $sPath . DIRECTORY_SEPARATOR . $val; + if (is_dir($path) && !is_link($path)) { + $tmp = System::_dirToStruct($path, $maxinst, $aktinst + 1, $silent); + $struct = array_merge_recursive($struct, $tmp); + } else { + $struct['files'][] = $path; + } + } + } + + return $struct; + } + /** * The "which" command (show the full path of a command) * * @param string $program The command to search for - * @param mixed $fallback Value to return if $program is not found + * @param mixed $fallback Value to return if $program is not found * * @return mixed A string with the full path or false if not found - * @static * @author Stig Bakken */ - function which($program, $fallback = false) + public static function which($program, $fallback = false) { // enforce API if (!is_string($program) || '' == $program) { @@ -504,36 +504,37 @@ class System $path_elements[] = dirname($program); $program = basename($program); } else { - // Honor safe mode - if (!ini_get('safe_mode') || !$path = ini_get('safe_mode_exec_dir')) { - $path = getenv('PATH'); - if (!$path) { - $path = getenv('Path'); // some OSes are just stupid enough to do this - } + $path = getenv('PATH'); + if (!$path) { + $path = getenv('Path'); // some OSes are just stupid enough to do this } + $path_elements = explode(PATH_SEPARATOR, $path); } if (OS_WINDOWS) { $exe_suffixes = getenv('PATHEXT') - ? explode(PATH_SEPARATOR, getenv('PATHEXT')) - : array('.exe','.bat','.cmd','.com'); + ? explode(PATH_SEPARATOR, getenv('PATHEXT')) + : array('.exe', '.bat', '.cmd', '.com'); // allow passing a command.exe param if (strpos($program, '.') !== false) { array_unshift($exe_suffixes, ''); } - // is_executable() is not available on windows for PHP4 - $pear_is_executable = (function_exists('is_executable')) ? 'is_executable' : 'is_file'; } else { $exe_suffixes = array(''); - $pear_is_executable = 'is_executable'; } foreach ($exe_suffixes as $suff) { foreach ($path_elements as $dir) { $file = $dir . DIRECTORY_SEPARATOR . $program . $suff; - if (@$pear_is_executable($file)) { + // It's possible to run a .bat on Windows that is_executable + // would return false for. The is_executable check is meaningless... + if (OS_WINDOWS) { return $file; + } else { + if (is_executable($file)) { + return $file; + } } } } @@ -552,19 +553,17 @@ class System * System::find("$dir -name *.php -name *.htm*"); * System::find("$dir -maxdepth 1"); * - * Params implmented: + * Params implemented: * $dir -> Start the search at this directory * -type d -> return only directories * -type f -> return only files * -maxdepth -> max depth of recursion * -name -> search pattern (bash style). Multiple -name param allowed * - * @param mixed Either array or string with the command line + * @param mixed Either array or string with the command line * @return array Array of found files - * @static - * */ - function find($args) + public static function find($args) { if (!is_array($args)) { $args = preg_split('/\s+/', $args, -1, PREG_SPLIT_NO_EMPTY); @@ -580,8 +579,8 @@ class System for ($i = 0; $i < $args_count; $i++) { switch ($args[$i]) { case '-type': - if (in_array($args[$i+1], array('d', 'f'))) { - if ($args[$i+1] == 'd') { + if (in_array($args[$i + 1], array('d', 'f'))) { + if ($args[$i + 1] == 'd') { $do_files = false; } else { $do_dirs = false; @@ -590,15 +589,15 @@ class System $i++; break; case '-name': - $name = preg_quote($args[$i+1], '#'); + $name = preg_quote($args[$i + 1], '#'); // our magic characters ? and * have just been escaped, // so now we change the escaped versions to PCRE operators $name = strtr($name, array('\?' => '.', '\*' => '.*')); - $patterns[] = '('.$name.')'; + $patterns[] = '(' . $name . ')'; $i++; break; case '-maxdepth': - $depth = $args[$i+1]; + $depth = $args[$i + 1]; break; } } @@ -612,7 +611,7 @@ class System } if (count($patterns)) { $dsq = preg_quote(DIRECTORY_SEPARATOR, '#'); - $pattern = '#(^|'.$dsq.')'.implode('|', $patterns).'($|'.$dsq.')#'; + $pattern = '#(^|' . $dsq . ')' . implode('|', $patterns) . '($|' . $dsq . ')#'; $ret = array(); $files_count = count($files); for ($i = 0; $i < $files_count; $i++) { @@ -626,4 +625,4 @@ class System } return $files; } -} \ No newline at end of file +}