Update PEAR to v1.10.9 and patch it so it works quietly

This commit is contained in:
Diogo Cordeiro 2019-04-28 23:39:36 +01:00
parent daa5f87fd4
commit b17e0b4169
7 changed files with 1414 additions and 1401 deletions

View File

@ -164,7 +164,7 @@ define('DB_ERROR_CONNECT_FAILED', -24);
/** /**
* The PHP extension needed for this DBMS could not be found * 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 * 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 * 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);
/**#@-*/ /**#@-*/
@ -444,7 +444,7 @@ class DB
* *
* @see DB_common::setOption() * @see DB_common::setOption()
*/ */
public static function factory($type, $options = false) public static function factory($type, $options = [])
{ {
if (!is_array($options)) { if (!is_array($options)) {
$options = array('persistent' => $options); $options = array('persistent' => $options);
@ -482,6 +482,21 @@ class DB
// }}} // }}}
// {{{ connect() // {{{ 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 * Create a new DB object including a connection to the specified database
* *
@ -567,136 +582,9 @@ class DB
return $obj; return $obj;
} }
// }}}
// {{{ apiVersion()
/**
* Return the DB API version
*
* @return string the DB API version number
*/
function apiVersion()
{
return '1.9.2';
}
// }}} // }}}
// {{{ isError() // {{{ 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_<driver> object
*
* @param mixed $value the value to test
*
* @return bool whether $value is a DB_<driver> 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 * Parse a data source name
* *
@ -778,7 +666,7 @@ class DB
// Get (if found): username and password // Get (if found): username and password
// $dsn => username:password@protocol+hostspec/database // $dsn => username:password@protocol+hostspec/database
if (($at = strrpos($dsn,'@')) !== false) { if (($at = strrpos($dsn, '@')) !== false) {
$str = substr($dsn, 0, $at); $str = substr($dsn, 0, $at);
$dsn = substr($dsn, $at + 1); $dsn = substr($dsn, $at + 1);
if (($pos = strpos($str, ':')) !== false) { if (($pos = strpos($str, ':')) !== false) {
@ -851,7 +739,7 @@ class DB
} }
// }}} // }}}
// {{{ getDSNString() // {{{ isConnection()
/** /**
* Returns the given DSN in a string format suitable for output. * Returns the given DSN in a string format suitable for output.
@ -860,7 +748,8 @@ class DB
* @param boolean true to hide the password, false to include it * @param boolean true to hide the password, false to include it
* @return string * @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 /* Calling parseDSN will ensure that we have all the array elements
* defined, and means that we deal with strings and array in the same * defined, and means that we deal with strings and array in the same
* manner. */ * manner. */
@ -879,25 +768,25 @@ class DB
// Now we just have to construct the actual string. This is ugly. // Now we just have to construct the actual string. This is ugly.
$dsnString = $dsnArray['phptype']; $dsnString = $dsnArray['phptype'];
if ($dsnArray['dbsyntax']) { if ($dsnArray['dbsyntax']) {
$dsnString .= '('.$dsnArray['dbsyntax'].')'; $dsnString .= '(' . $dsnArray['dbsyntax'] . ')';
} }
$dsnString .= '://' $dsnString .= '://'
.$dsnArray['username'] . $dsnArray['username']
.':' . ':'
.$dsnArray['password'] . $dsnArray['password']
.'@' . '@'
.$dsnArray['protocol']; . $dsnArray['protocol'];
if ($dsnArray['socket']) { if ($dsnArray['socket']) {
$dsnString .= '('.$dsnArray['socket'].')'; $dsnString .= '(' . $dsnArray['socket'] . ')';
} }
if ($dsnArray['protocol'] && $dsnArray['hostspec']) { if ($dsnArray['protocol'] && $dsnArray['hostspec']) {
$dsnString .= '+'; $dsnString .= '+';
} }
$dsnString .= $dsnArray['hostspec']; $dsnString .= $dsnArray['hostspec'];
if ($dsnArray['port']) { if ($dsnArray['port']) {
$dsnString .= ':'.$dsnArray['port']; $dsnString .= ':' . $dsnArray['port'];
} }
$dsnString .= '/'.$dsnArray['database']; $dsnString .= '/' . $dsnArray['database'];
/* Option handling. Unfortunately, parseDSN simply places options into /* Option handling. Unfortunately, parseDSN simply places options into
* the top-level array, so we'll first get rid of the fields defined by * the top-level array, so we'll first get rid of the fields defined by
@ -919,13 +808,125 @@ class DB
if (++$i > 1) { if (++$i > 1) {
$dsnString .= '&'; $dsnString .= '&';
} }
$dsnString .= $key.'='.$value; $dsnString .= $key . '=' . $value;
} }
} }
return $dsnString; return $dsnString;
} }
// }}}
// {{{ isManip()
/**
* Determines if a value is a DB_<driver> object
*
* @param mixed $value the value to test
*
* @return bool whether $value is a DB_<driver> 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';
}
// }}} // }}}
} }
@ -975,6 +976,9 @@ class DB_Error extends PEAR_Error
* Workaround to both avoid the "Redefining already defined constructor" * Workaround to both avoid the "Redefining already defined constructor"
* PHP error and provide backward compatibility in case someone is calling * PHP error and provide backward compatibility in case someone is calling
* DB_Error() dynamically * DB_Error() dynamically
* @param $method
* @param $arguments
* @return bool|mixed
*/ */
public function __call($method, $arguments) public function __call($method, $arguments)
{ {
@ -984,6 +988,7 @@ class DB_Error extends PEAR_Error
trigger_error( trigger_error(
'Call to undefined method DB_Error::' . $method . '()', E_USER_ERROR 'Call to undefined method DB_Error::' . $method . '()', E_USER_ERROR
); );
return false;
} }
// }}} // }}}
} }
@ -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) { if ($this->autofree) {
$this->free(); $this->free();
} }
@ -1212,7 +1216,7 @@ class DB_result
// The default mode is specified in the // The default mode is specified in the
// DB_common::fetchmode_object_class property // DB_common::fetchmode_object_class property
if ($object_class == 'stdClass') { if ($object_class == 'stdClass') {
$arr = (object) $arr; $arr = (object)$arr;
} else { } else {
$arr = new $object_class($arr); $arr = new $object_class($arr);
} }
@ -1228,6 +1232,25 @@ class DB_result
// }}} // }}}
// {{{ fetchInto() // {{{ 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 * Fetch a row of data into an array which is passed by reference
* *
@ -1276,8 +1299,7 @@ class DB_result
} }
} }
if ($this->row_counter >= ( if ($this->row_counter >= (
$this->limit_from + $this->limit_count)) $this->limit_from + $this->limit_count)) {
{
if ($this->autofree) { if ($this->autofree) {
$this->free(); $this->free();
} }
@ -1295,7 +1317,7 @@ class DB_result
// default mode specified in the // default mode specified in the
// DB_common::fetchmode_object_class property // DB_common::fetchmode_object_class property
if ($object_class == 'stdClass') { if ($object_class == 'stdClass') {
$arr = (object) $arr; $arr = (object)$arr;
} else { } else {
$arr = new $object_class($arr); $arr = new $object_class($arr);
} }
@ -1309,7 +1331,7 @@ class DB_result
} }
// }}} // }}}
// {{{ numCols() // {{{ numRows()
/** /**
* Get the the number of columns in a result set * 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 * Get the number of rows in a result set
@ -1332,8 +1354,7 @@ class DB_result
function numRows() function numRows()
{ {
if ($this->dbh->features['numrows'] === 'emulate' 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']) { if ($this->dbh->features['prepare']) {
$res = $this->dbh->query($this->query, $this->parameters); $res = $this->dbh->query($this->query, $this->parameters);
} else { } else {
@ -1376,7 +1397,7 @@ class DB_result
} }
// }}} // }}}
// {{{ nextResult() // {{{ free()
/** /**
* Get the next result if a batch of queries was executed * Get the next result if a batch of queries was executed
@ -1388,29 +1409,12 @@ class DB_result
return $this->dbh->nextResult($this->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() // {{{ tableInfo()
/** /**
* @param null $mode
* @return
* @see DB_common::tableInfo() * @see DB_common::tableInfo()
* @deprecated Method deprecated some time before Release 1.2 * @deprecated Method deprecated some time before Release 1.2
*/ */
@ -1500,5 +1504,3 @@ class DB_row
* c-basic-offset: 4 * c-basic-offset: 4
* End: * End:
*/ */
?>

File diff suppressed because it is too large Load Diff

View File

@ -23,7 +23,6 @@
* @author Greg Beaver <cellog@php.net> * @author Greg Beaver <cellog@php.net>
* @copyright 2004-2008 Greg Beaver * @copyright 2004-2008 Greg Beaver
* @license http://opensource.org/licenses/bsd-license.php New BSD License * @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 * @link http://pear.php.net/package/PEAR_ErrorStack
*/ */
@ -132,12 +131,11 @@ define('PEAR_ERRORSTACK_ERR_OBJTOSTRING', 2);
* $local_stack = new PEAR_ErrorStack('MyPackage'); * $local_stack = new PEAR_ErrorStack('MyPackage');
* </code> * </code>
* @author Greg Beaver <cellog@php.net> * @author Greg Beaver <cellog@php.net>
* @version 1.9.4 * @version @package_version@
* @package PEAR_ErrorStack * @package PEAR_ErrorStack
* @category Debugging * @category Debugging
* @copyright 2004-2008 Greg Beaver * @copyright 2004-2008 Greg Beaver
* @license http://opensource.org/licenses/bsd-license.php New BSD License * @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 * @link http://pear.php.net/package/PEAR_ErrorStack
*/ */
class PEAR_ErrorStack { class PEAR_ErrorStack {
@ -230,7 +228,7 @@ class PEAR_ErrorStack {
* defaults to {@link getFileLine()} * defaults to {@link getFileLine()}
* @param boolean $throwPEAR_Error * @param boolean $throwPEAR_Error
*/ */
function PEAR_ErrorStack($package, $msgCallback = false, $contextCallback = false, function __construct($package, $msgCallback = false, $contextCallback = false,
$throwPEAR_Error = false) $throwPEAR_Error = false)
{ {
$this->_package = $package; $this->_package = $package;
@ -250,12 +248,13 @@ class PEAR_ErrorStack {
* defaults to {@link getFileLine()} * defaults to {@link getFileLine()}
* @param boolean $throwPEAR_Error * @param boolean $throwPEAR_Error
* @param string $stackClass class to instantiate * @param string $stackClass class to instantiate
* @static *
* @return PEAR_ErrorStack * @return PEAR_ErrorStack
*/ */
function &singleton($package, $msgCallback = false, $contextCallback = false, public static function &singleton(
$throwPEAR_Error = false, $stackClass = 'PEAR_ErrorStack') $package, $msgCallback = false, $contextCallback = false,
{ $throwPEAR_Error = false, $stackClass = 'PEAR_ErrorStack'
) {
if (isset($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package])) { if (isset($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package])) {
return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]; return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package];
} }
@ -297,9 +296,8 @@ class PEAR_ErrorStack {
/** /**
* Set up a PEAR::Log object for all error stacks that don't have one * Set up a PEAR::Log object for all error stacks that don't have one
* @param Log $log * @param Log $log
* @static
*/ */
function setDefaultLogger(&$log) public static function setDefaultLogger(&$log)
{ {
if (is_object($log) && method_exists($log, 'log') ) { if (is_object($log) && method_exists($log, 'log') ) {
$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] = &$log; $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] = &$log;
@ -358,9 +356,8 @@ class PEAR_ErrorStack {
* messages for a singleton * messages for a singleton
* @param array|string Callback function/method * @param array|string Callback function/method
* @param string Package name, or false for all packages * @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)) { if (!is_callable($callback)) {
$callback = false; $callback = false;
@ -376,6 +373,8 @@ class PEAR_ErrorStack {
* information for an error. Passing in NULL will disable context generation * information for an error. Passing in NULL will disable context generation
* and remove the expensive call to debug_backtrace() * and remove the expensive call to debug_backtrace()
* @param array|string|null Callback function/method * @param array|string|null Callback function/method
* @return bool
* @return array|bool|callable|false|string
*/ */
function setContextCallback($contextCallback) function setContextCallback($contextCallback)
{ {
@ -383,12 +382,13 @@ class PEAR_ErrorStack {
return $this->_contextCallback = false; return $this->_contextCallback = false;
} }
if (!$contextCallback) { if (!$contextCallback) {
$this->_contextCallback = array(&$this, 'getFileLine'); $this->_contextCallback = [&$this, 'getFileLine'];
} else { } else {
if (is_callable($contextCallback)) { if (is_callable($contextCallback)) {
$this->_contextCallback = $contextCallback; $this->_contextCallback = $contextCallback;
} }
} }
return $this->_contextCallback;
} }
/** /**
@ -432,9 +432,8 @@ class PEAR_ErrorStack {
* @see PEAR_ERRORSTACK_PUSHANDLOG, PEAR_ERRORSTACK_PUSH, PEAR_ERRORSTACK_LOG * @see PEAR_ERRORSTACK_PUSHANDLOG, PEAR_ERRORSTACK_PUSH, PEAR_ERRORSTACK_LOG
* @see staticPopCallback(), pushCallback() * @see staticPopCallback(), pushCallback()
* @param string|array $cb * @param string|array $cb
* @static
*/ */
function staticPushCallback($cb) public static function staticPushCallback($cb)
{ {
array_push($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'], $cb); array_push($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'], $cb);
} }
@ -443,9 +442,8 @@ class PEAR_ErrorStack {
* Remove a temporary overriding error callback * Remove a temporary overriding error callback
* @see staticPushCallback() * @see staticPushCallback()
* @return array|string|false * @return array|string|false
* @static
*/ */
function staticPopCallback() public static function staticPopCallback()
{ {
$ret = array_pop($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK']); $ret = array_pop($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK']);
if (!is_array($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'])) { if (!is_array($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'])) {
@ -604,11 +602,11 @@ class PEAR_ErrorStack {
* to find error context * to find error context
* @return PEAR_Error|array if compatibility mode is on, a PEAR_Error is also * @return PEAR_Error|array if compatibility mode is on, a PEAR_Error is also
* thrown. see docs for {@link push()} * thrown. see docs for {@link push()}
* @static
*/ */
function staticPush($package, $code, $level = 'error', $params = array(), public static function staticPush(
$msg = false, $repackage = false, $backtrace = false) $package, $code, $level = 'error', $params = array(),
{ $msg = false, $repackage = false, $backtrace = false
) {
$s = &PEAR_ErrorStack::singleton($package); $s = &PEAR_ErrorStack::singleton($package);
if ($s->_contextCallback) { if ($s->_contextCallback) {
if (!$backtrace) { if (!$backtrace) {
@ -681,7 +679,7 @@ class PEAR_ErrorStack {
* @return boolean * @return boolean
* @since PEAR1.5.0a1 * @since PEAR1.5.0a1
*/ */
function staticPop($package) static function staticPop($package)
{ {
if ($package) { if ($package) {
if (!isset($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package])) { if (!isset($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package])) {
@ -689,11 +687,12 @@ class PEAR_ErrorStack {
} }
return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]->pop(); return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]->pop();
} }
return false;
} }
/** /**
* Determine whether there are any errors on the stack * 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 * of level (string), or levels (array) have been pushed
* @return boolean * @return boolean
*/ */
@ -750,9 +749,8 @@ class PEAR_ErrorStack {
* @param string|false Package name to check for errors * @param string|false Package name to check for errors
* @param string Level name to check for a particular severity * @param string Level name to check for a particular severity
* @return boolean * @return boolean
* @static
*/ */
function staticHasErrors($package = false, $level = false) public static function staticHasErrors($package = false, $level = false)
{ {
if ($package) { if ($package) {
if (!isset($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package])) { if (!isset($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package])) {
@ -776,12 +774,13 @@ class PEAR_ErrorStack {
* @param boolean $merge Set to return a flat array, not organized by package * @param boolean $merge Set to return a flat array, not organized by package
* @param array $sortfunc Function used to sort a merged array - default * @param array $sortfunc Function used to sort a merged array - default
* sorts by time, and should be good for most cases * sorts by time, and should be good for most cases
* @static *
* @return array * @return array
*/ */
function staticGetErrors($purge = false, $level = false, $merge = false, public static function staticGetErrors(
$sortfunc = array('PEAR_ErrorStack', '_sortErrors')) $purge = false, $level = false, $merge = false,
{ $sortfunc = array('PEAR_ErrorStack', '_sortErrors')
) {
$ret = array(); $ret = array();
if (!is_callable($sortfunc)) { if (!is_callable($sortfunc)) {
$sortfunc = array('PEAR_ErrorStack', '_sortErrors'); $sortfunc = array('PEAR_ErrorStack', '_sortErrors');
@ -806,7 +805,7 @@ class PEAR_ErrorStack {
* Error sorting function, sorts by time * Error sorting function, sorts by time
* @access private * @access private
*/ */
function _sortErrors($a, $b) public static function _sortErrors($a, $b)
{ {
if ($a['time'] == $b['time']) { if ($a['time'] == $b['time']) {
return 0; return 0;
@ -829,9 +828,8 @@ class PEAR_ErrorStack {
* @param unused * @param unused
* @param integer backtrace frame. * @param integer backtrace frame.
* @param array Results of debug_backtrace() * @param array Results of debug_backtrace()
* @static
*/ */
function getFileLine($code, $params, $backtrace = null) public static function getFileLine($code, $params, $backtrace = null)
{ {
if ($backtrace === null) { if ($backtrace === null) {
return false; return false;
@ -903,10 +901,10 @@ class PEAR_ErrorStack {
* @param PEAR_ErrorStack * @param PEAR_ErrorStack
* @param array * @param array
* @param string|false Pre-generated error message template * @param string|false Pre-generated error message template
* @static *
* @return string * @return string
*/ */
function getErrorMessage(&$stack, $err, $template = false) public static function getErrorMessage(&$stack, $err, $template = false)
{ {
if ($template) { if ($template) {
$mainmsg = $template; $mainmsg = $template;
@ -960,11 +958,15 @@ class PEAR_ErrorStack {
* for the error message. If the template is 'message %foo% was %bar%', and the * 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 * parameters are array('foo' => 'one', 'bar' => 'six'), the error message returned will
* be 'message one was six' * be 'message one was six'
* @return string *
* Returns string via property
* @param $template
* @return null
*/ */
function setErrorMessageTemplate($template) function setErrorMessageTemplate($template)
{ {
$this->_errorMsgs = $template; $this->_errorMsgs = $template;
return null;
} }
@ -975,11 +977,10 @@ class PEAR_ErrorStack {
*/ */
function raiseError() function raiseError()
{ {
require_once 'PEAR.php'; require_once '../PEAR.php';
$args = func_get_args(); $args = func_get_args();
return call_user_func_array(array('PEAR', 'raiseError'), $args); return call_user_func_array(array('PEAR', 'raiseError'), $args);
} }
} }
$stack = &PEAR_ErrorStack::singleton('PEAR_ErrorStack'); $stack = &PEAR_ErrorStack::singleton('PEAR_ErrorStack');
$stack->pushCallback(array('PEAR_ErrorStack', '_handleError')); $stack->pushCallback(array('PEAR_ErrorStack', '_handleError'));
?>

View File

@ -99,9 +99,9 @@ class PEAR_Exception extends Exception
const OBSERVER_PRINT = -2; const OBSERVER_PRINT = -2;
const OBSERVER_TRIGGER = -4; const OBSERVER_TRIGGER = -4;
const OBSERVER_DIE = -8; const OBSERVER_DIE = -8;
protected $cause;
private static $_observers = array(); private static $_observers = array();
private static $_uniqueid = 0; private static $_uniqueid = 0;
protected $cause;
private $_trace; private $_trace;
/** /**
@ -117,6 +117,7 @@ class PEAR_Exception extends Exception
* @param string exception message * @param string exception message
* @param int|Exception|PEAR_Error|array|null exception cause * @param int|Exception|PEAR_Error|array|null exception cause
* @param int|null exception code or null * @param int|null exception code or null
* @throws PEAR_Exception
*/ */
public function __construct($message, $p2 = null, $p3 = null) public function __construct($message, $p2 = null, $p3 = null)
{ {
@ -145,32 +146,6 @@ class PEAR_Exception extends Exception
$this->signal(); $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() private function signal()
{ {
foreach (self::$_observers as $func) { 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 * Return specific error information that can be used for more detailed
* error messages or translation. * error messages or translation.
@ -227,6 +228,80 @@ class PEAR_Exception extends Exception
return $this->cause; return $this->cause;
} }
public function getErrorClass()
{
$trace = $this->getTraceSafe();
return $trace[0]['class'];
}
public function getErrorMethod()
{
$trace = $this->getTraceSafe();
return $trace[0]['function'];
}
public function __toString()
{
if (isset($_SERVER['REQUEST_URI'])) {
return $this->toHtml();
}
return $this->toText();
}
public function toHtml()
{
$trace = $this->getTraceSafe();
$causes = array();
$this->getCauseMessage($causes);
$html = '<table style="border: 1px" cellspacing="0">' . "\n";
foreach ($causes as $i => $cause) {
$html .= '<tr><td colspan="3" style="background: #ff9999">'
. str_repeat('-', $i) . ' <b>' . $cause['class'] . '</b>: '
. htmlspecialchars($cause['message']) . ' in <b>' . $cause['file'] . '</b> '
. 'on line <b>' . $cause['line'] . '</b>'
. "</td></tr>\n";
}
$html .= '<tr><td colspan="3" style="background-color: #aaaaaa; text-align: center; font-weight: bold;">Exception trace</td></tr>' . "\n"
. '<tr><td style="text-align: center; background: #cccccc; width:20px; font-weight: bold;">#</td>'
. '<td style="text-align: center; background: #cccccc; font-weight: bold;">Function</td>'
. '<td style="text-align: center; background: #cccccc; font-weight: bold;">Location</td></tr>' . "\n";
foreach ($trace as $k => $v) {
$html .= '<tr><td style="text-align: center;">' . $k . '</td>'
. '<td>';
if (!empty($v['class'])) {
$html .= $v['class'] . $v['type'];
}
$html .= $v['function'];
$args = array();
if (!empty($v['args'])) {
foreach ($v['args'] as $arg) {
if (is_null($arg)) $args[] = 'null';
elseif (is_array($arg)) $args[] = 'Array';
elseif (is_object($arg)) $args[] = 'Object(' . get_class($arg) . ')';
elseif (is_bool($arg)) $args[] = $arg ? 'true' : 'false';
elseif (is_int($arg) || is_double($arg)) $args[] = $arg;
else {
$arg = (string)$arg;
$str = htmlspecialchars(substr($arg, 0, 16));
if (strlen($arg) > 16) $str .= '&hellip;';
$args[] = "'" . $str . "'";
}
}
}
$html .= '(' . implode(', ', $args) . ')'
. '</td>'
. '<td>' . (isset($v['file']) ? $v['file'] : 'unknown')
. ':' . (isset($v['line']) ? $v['line'] : 'unknown')
. '</td></tr>' . "\n";
}
$html .= '<tr><td style="text-align: center;">' . ($k + 1) . '</td>'
. '<td>{main}</td>'
. '<td>&nbsp;</td></tr>' . "\n"
. '</table>';
return $html;
}
/** /**
* Function must be public to call on caused exceptions * Function must be public to call on caused exceptions
* @param array * @param array
@ -294,86 +369,12 @@ class PEAR_Exception extends Exception
$this->_trace = $this->getTrace(); $this->_trace = $this->getTrace();
if (empty($this->_trace)) { if (empty($this->_trace)) {
$backtrace = debug_backtrace(); $backtrace = debug_backtrace();
$this->_trace = array($backtrace[count($backtrace)-1]); $this->_trace = array($backtrace[count($backtrace) - 1]);
} }
} }
return $this->_trace; return $this->_trace;
} }
public function getErrorClass()
{
$trace = $this->getTraceSafe();
return $trace[0]['class'];
}
public function getErrorMethod()
{
$trace = $this->getTraceSafe();
return $trace[0]['function'];
}
public function __toString()
{
if (isset($_SERVER['REQUEST_URI'])) {
return $this->toHtml();
}
return $this->toText();
}
public function toHtml()
{
$trace = $this->getTraceSafe();
$causes = array();
$this->getCauseMessage($causes);
$html = '<table style="border: 1px" cellspacing="0">' . "\n";
foreach ($causes as $i => $cause) {
$html .= '<tr><td colspan="3" style="background: #ff9999">'
. str_repeat('-', $i) . ' <b>' . $cause['class'] . '</b>: '
. htmlspecialchars($cause['message']) . ' in <b>' . $cause['file'] . '</b> '
. 'on line <b>' . $cause['line'] . '</b>'
. "</td></tr>\n";
}
$html .= '<tr><td colspan="3" style="background-color: #aaaaaa; text-align: center; font-weight: bold;">Exception trace</td></tr>' . "\n"
. '<tr><td style="text-align: center; background: #cccccc; width:20px; font-weight: bold;">#</td>'
. '<td style="text-align: center; background: #cccccc; font-weight: bold;">Function</td>'
. '<td style="text-align: center; background: #cccccc; font-weight: bold;">Location</td></tr>' . "\n";
foreach ($trace as $k => $v) {
$html .= '<tr><td style="text-align: center;">' . $k . '</td>'
. '<td>';
if (!empty($v['class'])) {
$html .= $v['class'] . $v['type'];
}
$html .= $v['function'];
$args = array();
if (!empty($v['args'])) {
foreach ($v['args'] as $arg) {
if (is_null($arg)) $args[] = 'null';
elseif (is_array($arg)) $args[] = 'Array';
elseif (is_object($arg)) $args[] = 'Object('.get_class($arg).')';
elseif (is_bool($arg)) $args[] = $arg ? 'true' : 'false';
elseif (is_int($arg) || is_double($arg)) $args[] = $arg;
else {
$arg = (string)$arg;
$str = htmlspecialchars(substr($arg, 0, 16));
if (strlen($arg) > 16) $str .= '&hellip;';
$args[] = "'" . $str . "'";
}
}
}
$html .= '(' . implode(', ',$args) . ')'
. '</td>'
. '<td>' . (isset($v['file']) ? $v['file'] : 'unknown')
. ':' . (isset($v['line']) ? $v['line'] : 'unknown')
. '</td></tr>' . "\n";
}
$html .= '<tr><td style="text-align: center;">' . ($k+1) . '</td>'
. '<td>{main}</td>'
. '<td>&nbsp;</td></tr>' . "\n"
. '</table>';
return $html;
}
public function toText() public function toText()
{ {
$causes = array(); $causes = array();

View File

@ -1,7 +0,0 @@
<?php
if ($skipmsg) {
$a = &new $ec($code, $mode, $options, $userinfo);
} else {
$a = &new $ec($message, $code, $mode, $options, $userinfo);
}
?>

View File

@ -1,33 +0,0 @@
<?php
/**
* This is only meant for PHP 5 to get rid of certain strict warning
* that doesn't get hidden since it's in the shutdown function
*/
class PEAR5
{
/**
* If you have a class that's mostly/entirely static, and you need static
* properties, you can use this method to simulate them. Eg. in your method(s)
* do this: $myVar = &PEAR5::getStaticProperty('myclass', 'myVar');
* You MUST use a reference, or they will not persist!
*
* @access public
* @param string $class The calling classname, to prevent clashes
* @param string $var The variable to retrieve.
* @return mixed A reference to the variable. If not set it will be
* auto initialised to NULL.
*/
static function &getStaticProperty($class, $var)
{
static $properties;
if (!isset($properties[$class])) {
$properties[$class] = array();
}
if (!array_key_exists($var, $properties[$class])) {
$properties[$class][$var] = null;
}
return $properties[$class][$var];
}
}

View File

@ -9,7 +9,6 @@
* @author Tomas V.V.Cox <cox@idecnet.com> * @author Tomas V.V.Cox <cox@idecnet.com>
* @copyright 1997-2009 The Authors * @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License * @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 * @link http://pear.php.net/package/PEAR
* @since File available since Release 0.1 * @since File available since Release 0.1
*/ */
@ -23,65 +22,102 @@ require_once 'Console/Getopt.php';
$GLOBALS['_System_temp_files'] = array(); $GLOBALS['_System_temp_files'] = array();
/** /**
* System offers cross plattform compatible system functions * System offers cross platform compatible system functions
* *
* Static functions for different operations. Should work under * Static functions for different operations. Should work under
* Unix and Windows. The names and usage has been taken from its respectively * 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 * GNU commands. The functions will return (bool) false on error and will
* trigger the error with the PHP trigger_error() function (you can silence * trigger the error with the PHP trigger_error() function (you can silence
* the error by prefixing a '@' sign after the function call, but this * the error by prefixing a '@' sign after the function call, but this
* is not recommended practice. Instead use an error handler with * is not recommended practice. Instead use an error handler with
* {@link set_error_handler()}). * {@link set_error_handler()}).
* *
* Documentation on this class you can find in: * Documentation on this class you can find in:
* http://pear.php.net/manual/ * http://pear.php.net/manual/
* *
* Example usage: * Example usage:
* if (!@System::rm('-r file1 dir1')) { * if (!@System::rm('-r file1 dir1')) {
* print "could not delete file1 or dir1"; * print "could not delete file1 or dir1";
* } * }
* *
* In case you need to to pass file names with spaces, * In case you need to to pass file names with spaces,
* pass the params as an array: * pass the params as an array:
* *
* System::rm(array('-r', $file1, $dir1)); * System::rm(array('-r', $file1, $dir1));
* *
* @category pear * @category pear
* @package System * @package System
* @author Tomas V.V. Cox <cox@idecnet.com> * @author Tomas V.V. Cox <cox@idecnet.com>
* @copyright 1997-2006 The PHP Group * @copyright 1997-2006 The PHP Group
* @license http://opensource.org/licenses/bsd-license.php New BSD License * @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 * @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1 * @since Class available since Release 0.1
* @static * @static
*/ */
class System class System
{ {
/** /**
* returns the commandline arguments of a function * Concatenate files
* *
* @param string $argv the commandline * Usage:
* @param string $short_options the allowed option short-tags * 1) $var = System::cat('sample.txt test.txt');
* @param string $long_options the allowed option long-tags * 2) System::cat('sample.txt test.txt > final.txt');
* @return array the given options and there values * 3) System::cat('sample.txt test.txt >> final.txt');
* @static *
* @access private * Note: as the class use fopen, urls should work also
*
* @param string $args the arguments
* @return boolean true on success
*/ */
function _parseArgs($argv, $short_options, $long_options = null) public static function &cat($args)
{ {
if (!is_array($argv) && $argv !== null) { $ret = null;
// Find all items, quoted or otherwise $files = array();
preg_match_all("/(?:[\"'])(.*?)(?:['\"])|([^\s]+)/", $argv, $av); if (!is_array($args)) {
$argv = $av[1]; $args = preg_split('/\s+/', $args, -1, PREG_SPLIT_NO_EMPTY);
foreach ($av[2] as $k => $a) { }
if (empty($a)) {
$count_args = count($args);
for ($i = 0; $i < $count_args; $i++) {
if ($args[$i] == '>') {
$mode = 'wb';
$outputfile = $args[$i + 1];
break;
} elseif ($args[$i] == '>>') {
$mode = 'ab+';
$outputfile = $args[$i + 1];
break;
} else {
$files[] = $args[$i];
}
}
$outputfd = false;
if (isset($mode)) {
if (!$outputfd = fopen($outputfile, $mode)) {
$err = System::raiseError("Could not open $outputfile");
return $err;
}
$ret = true;
}
foreach ($files as $file) {
if (!$fd = fopen($file, 'r')) {
System::raiseError("Could not open $file");
continue; continue;
} }
$argv[$k] = trim($a) ; while ($cont = fread($fd, 2048)) {
if (is_resource($outputfd)) {
fwrite($outputfd, $cont);
} else {
$ret .= $cont;
} }
} }
return Console_Getopt::getopt2($argv, $short_options, $long_options); fclose($fd);
}
if (is_resource($outputfd)) {
fclose($outputfd);
}
return $ret;
} }
/** /**
@ -90,10 +126,8 @@ class System
* *
* @param mixed $error a PEAR error or a string with the error message * @param mixed $error a PEAR error or a string with the error message
* @return bool false * @return bool false
* @static
* @access private
*/ */
function raiseError($error) protected static function raiseError($error)
{ {
if (PEAR::isError($error)) { if (PEAR::isError($error)) {
$error = $error->getMessage(); $error = $error->getMessage();
@ -103,134 +137,144 @@ class System
} }
/** /**
* Creates a nested array representing the structure of a directory * Creates temporary files or directories. This function will remove
* the created files when the scripts finish its execution.
* *
* System::_dirToStruct('dir1', 0) => * Usage:
* Array * 1) $tempfile = System::mktemp("prefix");
* ( * 2) $tempdir = System::mktemp("-d prefix");
* [dirs] => Array * 3) $tempfile = System::mktemp();
* ( * 4) $tempfile = System::mktemp("-t /var/tmp prefix");
* [0] => dir1
* )
* *
* [files] => Array * prefix -> The string that will be prepended to the temp name
* ( * (defaults to "tmp").
* [0] => dir1/file2 * -d -> A temporary dir will be created instead of a file.
* [1] => dir1/file3 * -t -> The target dir where the temporary (file|dir) will be created. If
* ) * this param is missing by default the env vars TMP on Windows or
* ) * TMPDIR in Unix will be used. If these vars are also missing
* @param string $sPath Name of the directory * c:\windows\temp or /tmp will be used.
* @param integer $maxinst max. deep of the lookup *
* @param integer $aktinst starting deep of the lookup * @param string $args The arguments
* @param bool $silent if true, do not emit errors. * @return mixed the full path of the created (file|dir) or false
* @return array the structure of the dir * @see System::tmpdir()
* @static
* @access private
*/ */
function _dirToStruct($sPath, $maxinst, $aktinst = 0, $silent = false) public static function mktemp($args = null)
{ {
$struct = array('dirs' => array(), 'files' => array()); static $first_time = true;
if (($dir = @opendir($sPath)) === false) { $opts = System::_parseArgs($args, 't:d');
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)) { if (PEAR::isError($opts)) {
return System::raiseError($opts); return System::raiseError($opts);
} }
foreach ($opts[0] as $opt) { foreach ($opts[0] as $opt) {
if ($opt[0] == 'r') { if ($opt[0] == 'd') {
$do_recursive = true; $tmp_is_dir = true;
} } elseif ($opt[0] == 't') {
} $tmpdir = $opt[1];
$ret = true;
if (isset($do_recursive)) {
$struct = System::_multipleToStruct($opts[1]);
foreach ($struct['files'] as $file) {
if (!@unlink($file)) {
$ret = false;
} }
} }
rsort($struct['dirs']); $prefix = (isset($opts[1][0])) ? $opts[1][0] : 'tmp';
foreach ($struct['dirs'] as $dir) { if (!isset($tmpdir)) {
if (!@rmdir($dir)) { $tmpdir = System::tmpdir();
$ret = false; }
if (!System::mkDir(['-p', $tmpdir])) {
return false;
}
$tmp = tempnam($tmpdir, $prefix);
if (isset($tmp_is_dir)) {
unlink($tmp); // be careful possible race condition here
if (!mkdir($tmp, 0700)) {
return System::raiseError("Unable to create temporary directory $tmpdir");
} }
} }
} else {
foreach ($opts[1] as $file) { $GLOBALS['_System_temp_files'][] = $tmp;
$delete = (is_dir($file)) ? 'rmdir' : 'unlink'; /*if (isset($tmp_is_dir)) {
if (!@$delete($file)) { //$GLOBALS['_System_temp_files'][] = dirname($tmp);
$ret = false; }*/
if ($first_time) {
PEAR::registerShutdownFunc(array('System', '_removeTmpFiles'));
$first_time = false;
}
return $tmp;
}
/**
* 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
*/
public static function _parseArgs($argv, $short_options, $long_options = null)
{
if (!is_array($argv) && $argv !== null) {
/*
// Quote all items that are a short option
$av = preg_split('/(\A| )--?[a-z0-9]+[ =]?((?<!\\\\)((,\s*)|((?<!,)\s+))?)/i', $argv, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_OFFSET_CAPTURE);
$offset = 0;
foreach ($av as $a) {
$b = trim($a[0]);
if ($b{0} == '"' || $b{0} == "'") {
continue;
}
$escape = escapeshellarg($b);
$pos = $a[1] + $offset;
$argv = substr_replace($argv, $escape, $pos, strlen($b));
$offset += 2;
}
*/
// 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 (new Console_Getopt)->getopt2($argv, $short_options, $long_options);
} }
return $ret;
/**
* Get the path of the temporal directory set in the system
* by looking in its environments variables.
* 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
*
* @return string The temporary directory on the system
*/
public static function tmpdir()
{
if (OS_WINDOWS) {
if ($var = isset($_ENV['TMP']) ? $_ENV['TMP'] : getenv('TMP')) {
return $var;
}
if ($var = isset($_ENV['TEMP']) ? $_ENV['TEMP'] : getenv('TEMP')) {
return $var;
}
if ($var = isset($_ENV['USERPROFILE']) ? $_ENV['USERPROFILE'] : getenv('USERPROFILE')) {
return $var;
}
if ($var = isset($_ENV['windir']) ? $_ENV['windir'] : getenv('windir')) {
return $var;
}
return getenv('SystemRoot') . '\temp';
}
if ($var = isset($_ENV['TMPDIR']) ? $_ENV['TMPDIR'] : getenv('TMPDIR')) {
return $var;
}
return realpath('/tmp');
} }
/** /**
@ -239,10 +283,8 @@ class System
* The -p option will create parent directories * The -p option will create parent directories
* @param string $args the name of the director(y|ies) to create * @param string $args the name of the director(y|ies) to create
* @return bool True for success * @return bool True for success
* @static
* @access public
*/ */
function mkDir($args) public static function mkDir($args)
{ {
$opts = System::_parseArgs($args, 'pm:'); $opts = System::_parseArgs($args, 'pm:');
if (PEAR::isError($opts)) { if (PEAR::isError($opts)) {
@ -288,7 +330,7 @@ class System
} }
} }
} else { } else {
foreach($opts[1] as $dir) { foreach ($opts[1] as $dir) {
if ((@file_exists($dir) || !is_dir($dir)) && !mkdir($dir, $mode)) { if ((@file_exists($dir) || !is_dir($dir)) && !mkdir($dir, $mode)) {
$ret = false; $ret = false;
} }
@ -298,149 +340,11 @@ class System
return $ret; return $ret;
} }
/**
* Concatenate files
*
* Usage:
* 1) $var = System::cat('sample.txt test.txt');
* 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)
*
* @param string $args the arguments
* @return boolean true on success
* @static
* @access public
*/
function &cat($args)
{
$ret = null;
$files = array();
if (!is_array($args)) {
$args = preg_split('/\s+/', $args, -1, PREG_SPLIT_NO_EMPTY);
}
$count_args = count($args);
for ($i = 0; $i < $count_args; $i++) {
if ($args[$i] == '>') {
$mode = 'wb';
$outputfile = $args[$i+1];
break;
} elseif ($args[$i] == '>>') {
$mode = 'ab+';
$outputfile = $args[$i+1];
break;
} else {
$files[] = $args[$i];
}
}
$outputfd = false;
if (isset($mode)) {
if (!$outputfd = fopen($outputfile, $mode)) {
$err = System::raiseError("Could not open $outputfile");
return $err;
}
$ret = true;
}
foreach ($files as $file) {
if (!$fd = fopen($file, 'r')) {
System::raiseError("Could not open $file");
continue;
}
while ($cont = fread($fd, 2048)) {
if (is_resource($outputfd)) {
fwrite($outputfd, $cont);
} else {
$ret .= $cont;
}
}
fclose($fd);
}
if (is_resource($outputfd)) {
fclose($outputfd);
}
return $ret;
}
/**
* Creates temporary files or directories. This function will remove
* the created files when the scripts finish its execution.
*
* Usage:
* 1) $tempfile = System::mktemp("prefix");
* 2) $tempdir = System::mktemp("-d prefix");
* 3) $tempfile = System::mktemp();
* 4) $tempfile = System::mktemp("-t /var/tmp prefix");
*
* prefix -> The string that will be prepended to the temp name
* (defaults to "tmp").
* -d -> A temporary dir will be created instead of a file.
* -t -> The target dir where the temporary (file|dir) will be created. If
* this param is missing by default the env vars TMP on Windows or
* 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
* @return mixed the full path of the created (file|dir) or false
* @see System::tmpdir()
* @static
* @access public
*/
function mktemp($args = null)
{
static $first_time = true;
$opts = System::_parseArgs($args, 't:d');
if (PEAR::isError($opts)) {
return System::raiseError($opts);
}
foreach ($opts[0] as $opt) {
if ($opt[0] == 'd') {
$tmp_is_dir = true;
} elseif ($opt[0] == 't') {
$tmpdir = $opt[1];
}
}
$prefix = (isset($opts[1][0])) ? $opts[1][0] : 'tmp';
if (!isset($tmpdir)) {
$tmpdir = System::tmpdir();
}
if (!System::mkDir(array('-p', $tmpdir))) {
return false;
}
$tmp = tempnam($tmpdir, $prefix);
if (isset($tmp_is_dir)) {
unlink($tmp); // be careful possible race condition here
if (!mkdir($tmp, 0700)) {
return System::raiseError("Unable to create temporary directory $tmpdir");
}
}
$GLOBALS['_System_temp_files'][] = $tmp;
if (isset($tmp_is_dir)) {
//$GLOBALS['_System_temp_files'][] = dirname($tmp);
}
if ($first_time) {
PEAR::registerShutdownFunc(array('System', '_removeTmpFiles'));
$first_time = false;
}
return $tmp;
}
/** /**
* Remove temporary files created my mkTemp. This function is executed * Remove temporary files created my mkTemp. This function is executed
* at script shutdown time * at script shutdown time
*
* @static
* @access private
*/ */
function _removeTmpFiles() public static function _removeTmpFiles()
{ {
if (count($GLOBALS['_System_temp_files'])) { if (count($GLOBALS['_System_temp_files'])) {
$delete = $GLOBALS['_System_temp_files']; $delete = $GLOBALS['_System_temp_files'];
@ -451,35 +355,132 @@ class System
} }
/** /**
* Get the path of the temporal directory set in the system * The rm command for removing files.
* by looking in its environments variables. * Supports multiple files and dirs and also recursive deletes
* 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
* *
* @param string $args the arguments for rm
* @return mixed PEAR_Error or true for success
* @static * @static
* @return string The temporary directory on the system * @access public
*/ */
function tmpdir() public static function rm($args)
{ {
if (OS_WINDOWS) { $opts = System::_parseArgs($args, 'rf'); // "f" does nothing but I like it :-)
if ($var = isset($_ENV['TMP']) ? $_ENV['TMP'] : getenv('TMP')) { if (PEAR::isError($opts)) {
return $var; return System::raiseError($opts);
} }
if ($var = isset($_ENV['TEMP']) ? $_ENV['TEMP'] : getenv('TEMP')) { foreach ($opts[0] as $opt) {
return $var; if ($opt[0] == 'r') {
$do_recursive = true;
} }
if ($var = isset($_ENV['USERPROFILE']) ? $_ENV['USERPROFILE'] : getenv('USERPROFILE')) {
return $var;
} }
if ($var = isset($_ENV['windir']) ? $_ENV['windir'] : getenv('windir')) { $ret = true;
return $var; if (isset($do_recursive)) {
$struct = System::_multipleToStruct($opts[1]);
foreach ($struct['files'] as $file) {
if (!@unlink($file)) {
$ret = false;
} }
return getenv('SystemRoot') . '\temp';
} }
if ($var = isset($_ENV['TMPDIR']) ? $_ENV['TMPDIR'] : getenv('TMPDIR')) {
return $var; rsort($struct['dirs']);
foreach ($struct['dirs'] as $dir) {
if (!@rmdir($dir)) {
$ret = false;
} }
return realpath('/tmp'); }
} 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;
} }
/** /**
@ -489,10 +490,9 @@ class System
* @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 * @return mixed A string with the full path or false if not found
* @static
* @author Stig Bakken <ssb@php.net> * @author Stig Bakken <ssb@php.net>
*/ */
function which($program, $fallback = false) public static function which($program, $fallback = false)
{ {
// enforce API // enforce API
if (!is_string($program) || '' == $program) { if (!is_string($program) || '' == $program) {
@ -504,36 +504,37 @@ class System
$path_elements[] = dirname($program); $path_elements[] = dirname($program);
$program = basename($program); $program = basename($program);
} else { } else {
// Honor safe mode
if (!ini_get('safe_mode') || !$path = ini_get('safe_mode_exec_dir')) {
$path = getenv('PATH'); $path = getenv('PATH');
if (!$path) { if (!$path) {
$path = getenv('Path'); // some OSes are just stupid enough to do this $path = getenv('Path'); // some OSes are just stupid enough to do this
} }
}
$path_elements = explode(PATH_SEPARATOR, $path); $path_elements = explode(PATH_SEPARATOR, $path);
} }
if (OS_WINDOWS) { if (OS_WINDOWS) {
$exe_suffixes = getenv('PATHEXT') $exe_suffixes = getenv('PATHEXT')
? explode(PATH_SEPARATOR, getenv('PATHEXT')) ? explode(PATH_SEPARATOR, getenv('PATHEXT'))
: array('.exe','.bat','.cmd','.com'); : array('.exe', '.bat', '.cmd', '.com');
// allow passing a command.exe param // allow passing a command.exe param
if (strpos($program, '.') !== false) { if (strpos($program, '.') !== false) {
array_unshift($exe_suffixes, ''); 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 { } else {
$exe_suffixes = array(''); $exe_suffixes = array('');
$pear_is_executable = 'is_executable';
} }
foreach ($exe_suffixes as $suff) { foreach ($exe_suffixes as $suff) {
foreach ($path_elements as $dir) { foreach ($path_elements as $dir) {
$file = $dir . DIRECTORY_SEPARATOR . $program . $suff; $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; return $file;
} else {
if (is_executable($file)) {
return $file;
}
} }
} }
} }
@ -552,7 +553,7 @@ class System
* System::find("$dir -name *.php -name *.htm*"); * System::find("$dir -name *.php -name *.htm*");
* System::find("$dir -maxdepth 1"); * System::find("$dir -maxdepth 1");
* *
* Params implmented: * Params implemented:
* $dir -> Start the search at this directory * $dir -> Start the search at this directory
* -type d -> return only directories * -type d -> return only directories
* -type f -> return only files * -type f -> return only files
@ -561,10 +562,8 @@ class System
* *
* @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 * @return array Array of found files
* @static
*
*/ */
function find($args) public static function find($args)
{ {
if (!is_array($args)) { if (!is_array($args)) {
$args = preg_split('/\s+/', $args, -1, PREG_SPLIT_NO_EMPTY); $args = preg_split('/\s+/', $args, -1, PREG_SPLIT_NO_EMPTY);
@ -580,8 +579,8 @@ class System
for ($i = 0; $i < $args_count; $i++) { for ($i = 0; $i < $args_count; $i++) {
switch ($args[$i]) { switch ($args[$i]) {
case '-type': case '-type':
if (in_array($args[$i+1], array('d', 'f'))) { if (in_array($args[$i + 1], array('d', 'f'))) {
if ($args[$i+1] == 'd') { if ($args[$i + 1] == 'd') {
$do_files = false; $do_files = false;
} else { } else {
$do_dirs = false; $do_dirs = false;
@ -590,15 +589,15 @@ class System
$i++; $i++;
break; break;
case '-name': case '-name':
$name = preg_quote($args[$i+1], '#'); $name = preg_quote($args[$i + 1], '#');
// our magic characters ? and * have just been escaped, // our magic characters ? and * have just been escaped,
// so now we change the escaped versions to PCRE operators // so now we change the escaped versions to PCRE operators
$name = strtr($name, array('\?' => '.', '\*' => '.*')); $name = strtr($name, array('\?' => '.', '\*' => '.*'));
$patterns[] = '('.$name.')'; $patterns[] = '(' . $name . ')';
$i++; $i++;
break; break;
case '-maxdepth': case '-maxdepth':
$depth = $args[$i+1]; $depth = $args[$i + 1];
break; break;
} }
} }
@ -612,7 +611,7 @@ class System
} }
if (count($patterns)) { if (count($patterns)) {
$dsq = preg_quote(DIRECTORY_SEPARATOR, '#'); $dsq = preg_quote(DIRECTORY_SEPARATOR, '#');
$pattern = '#(^|'.$dsq.')'.implode('|', $patterns).'($|'.$dsq.')#'; $pattern = '#(^|' . $dsq . ')' . implode('|', $patterns) . '($|' . $dsq . ')#';
$ret = array(); $ret = array();
$files_count = count($files); $files_count = count($files);
for ($i = 0; $i < $files_count; $i++) { for ($i = 0; $i < $files_count; $i++) {