Nouveaux fichiers

This commit is contained in:
Rodolphe Quiedeville 2004-06-30 16:05:55 +00:00
parent 5ee1b78ed8
commit 177deca5de
2 changed files with 1784 additions and 0 deletions

View File

@ -0,0 +1,816 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4: */
// +----------------------------------------------------------------------+
// | PHP Version 4 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2003 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.02 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/2_02.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Authors: Martin Jansen <mj@php.net> |
// +----------------------------------------------------------------------+
//
// $Id$
//
require_once DOL_DOCUMENT_ROOT."/includes/pear/PEAR.php";
//require_once "PEAR.php";
define("AUTH_IDLED", -1);
define("AUTH_EXPIRED", -2);
define("AUTH_WRONG_LOGIN", -3);
/**
* PEAR::Auth
*
* The PEAR::Auth class provides methods for creating an
* authentication system using PHP.
*
* @author Martin Jansen <mj@php.net>
* @package Auth
* @version $Revision$
*/
class DOLIAuth {
/**
* Auth lifetime in seconds
*
* If this variable is set to 0, auth never expires
*
* @var integer
* @see setExpire(), checkAuth()
*/
var $expire = 0;
/**
* Has the auth session expired?
*
* @var bool
* @see checkAuth(), drawLogin()
*/
var $expired = false;
/**
* Maximum time of idleness in seconds
*
* The difference to $expire is, that the idletime gets
* refreshed each time, checkAuth() is called. If this
* variable is set to 0, idle time is never checked.
*
* @var integer
* @see setIdle(), checkAuth()
*/
var $idle = 0;
/**
* Is the maximum idletime over?
*
* @var boolean
* @see checkAuth(), drawLogin();
*/
var $idled = false;
/**
* Storage object
*
* @var object
* @see Auth(), validateLogin()
*/
var $storage = "";
/**
* Function defined by the user, that creates the login screen
*
* @var string
*/
var $loginFunction = "";
/**
* Should the login form be displayed?
*
* @var bool
* @see setShowlogin()
*/
var $showLogin = true;
/**
* Current authentication status
*
* @var string
*/
var $status = "";
/**
* Username
*
* @var string
*/
var $username = "";
/**
* Password
*
* @var string
*/
var $password = "";
/**
* Login callback function name
*
* @var string
* @see setLoginCallback()
*/
var $loginCallback = "";
/**
* Logout callback function name
*
* @var string
* @see setLogoutCallback()
*/
var $logoutCallback = "";
// {{{ Constructor
/**
* Constructor
*
* Set up the storage driver.
*
* @param string Type of the storage driver
* @param mixed Additional options for the storage driver
* (example: if you are using DB as the storage
* driver, you have to pass the dsn string here)
*
* @param string Name of the function that creates the login form
* @param boolean Should the login form be displayed if neccessary?
* @return void
*/
function DOLIAuth($storageDriver, $options = "", $loginFunction = "", $showLogin = true)
{
if ($loginFunction != "" && function_exists($loginFunction)) {
$this->loginFunction = $loginFunction;
}
if (is_bool($showLogin)) {
$this->showLogin = $showLogin;
}
if (is_object($storageDriver)) {
$this->storage =& $storageDriver;
}
else{
$this->storage = $this->_factory($storageDriver, $options);
}
}
// }}}
// {{{ _factory()
/**
* Return a storage driver based on $driver and $options
*
* @access private
* @static
* @param string $driver Type of storage class to return
* @param string $options Optional parameters for the storage class
* @return object Object Storage object
*/
function _factory($driver, $options = "")
{
$storage_path = "Auth/Container/" . $driver . ".php";
$storage_class = "Auth_Container_" . $driver;
require_once $storage_path;
return new $storage_class($options);
}
// }}}
// {{{ assignData()
/**
* Assign data from login form to internal values
*
* This function takes the values for username and password
* from $HTTP_POST_VARS and assigns them to internal variables.
* If you wish to use another source apart from $HTTP_POST_VARS,
* you have to derive this function.
*
* @access private
* @global $HTTP_POST_VARS
* @see Auth
* @return void
*/
function assignData()
{
$post = &$this->_importGlobalVariable("post");
if (isset($post['username']) && $post['username'] != "") {
$this->username = (get_magic_quotes_gpc() == 1 ? stripslashes($post['username']) : $post['username']);
}
if (isset($post['password']) && $post['password'] != "") {
$this->password = (get_magic_quotes_gpc() == 1 ? stripslashes($post['password']) : $post['password'] );
}
}
// }}}
// {{{ start()
/**
* Start new auth session
*
* @access public
* @return void
*/
function start()
{
$this->assignData();
session_start();
if (!$this->checkAuth()) {
$this->login();
}
}
// }}}
// {{{ login()
/**
* Login function
*
* @access private
* @return void
*/
function login()
{
$login_ok = false;
/**
* When the user has already entered a username,
* we have to validate it.
*/
if (!empty($this->username)) {
if (true === $this->storage->fetchData($this->username, $this->password)) {
$login_ok = true;
}
}
if (!empty($this->username) && $login_ok) {
$this->setAuth($this->username);
if (!empty($this->loginCallback)) {
call_user_func($this->loginCallback,$this->username);
}
}
/**
* If the login failed or the user entered no username,
* output the login screen again.
*/
if (!empty($this->username) && !$login_ok) {
$this->status = AUTH_WRONG_LOGIN;
}
if ((empty($this->username) || !$login_ok) && $this->showLogin) {
$this->drawLogin($this->storage->activeUser);
return;
}
}
// }}}
// {{{ setExpire()
/**
* Set the maximum expire time
*
* @access public
* @param integer time in seconds
* @param bool add time to current expire time or not
* @return void
*/
function setExpire($time, $add = false)
{
if ($add) {
$this->expire += $time;
} else {
$this->expire = $time;
}
}
// }}}
// {{{ setIdle()
/**
* Set the maximum idle time
*
* @access public
* @param integer time in seconds
* @param bool add time to current maximum idle time or not
* @return void
*/
function setIdle($time, $add = false)
{
if ($add) {
$this->idle += $time;
} else {
$this->idle = $time;
}
}
// }}}
// {{{ setSessionname()
/**
* Set name of the session to a customized value.
*
* If you are using multiple instances of PEAR::Auth
* on the same domain, you can change the name of
* session per application via this function.
*
* @access public
* @param string New name for the session
* @return void
*/
function setSessionname($name = "PHPSESSID")
{
@session_name($name);
}
// }}}
// {{{ setShowLogin()
/**
* Should the login form be displayed if neccessary?
*
* @access public
* @param bool show login form or not
* @return void
*/
function setShowLogin($showLogin = true)
{
$this->showLogin = $showLogin;
}
/**
* Register a callback function to be called on user login.
* The function will receive a single parameter, the username.
*
* @access public
* @param string callback function name
* @return void
* @see setLogoutCallback()
*/
function setLoginCallback($loginCallback)
{
$this->loginCallback = $loginCallback;
}
/**
* Register a callback function to be called on user logout.
* The function will receive a single parameter, the username.
*
* @access public
* @param string callback function name
* @return void
* @see setLoginCallback()
*/
function setLogoutCallback($logoutCallback)
{
$this->logoutCallback = $logoutCallback;
}
// }}}
// {{{ setAuthData()
/**
* Register additional information that is to be stored
* in the session.
*
* @access public
* @param string Name of the data field
* @param mixed Value of the data field
* @param boolean Should existing data be overwritten? (default
* is true)
* @return void
*/
function setAuthData($name, $value, $overwrite = true)
{
$session = &DOLIAuth::_importGlobalVariable("session");
if (!empty($session['auth']['data'][$name]) && $overwrite == false) {
return;
}
$session['auth']['data'][$name] = $value;
}
// }}}
// {{{ getAuthData()
/**
* Get additional information that is stored in the session.
*
* If no value for the first parameter is passed, the method will
* return all data that is currently stored.
*
* @access public
* @param string Name of the data field
* @return mixed Value of the data field.
*/
function getAuthData($name = null)
{
$session = &DOLIAuth::_importGlobalVariable("session");
if (is_null($name)) {
return $session['auth']['data'];
}
if (isset($session['auth']['data'][$name])) {
return $session['auth']['data'][$name];
} else {
return null;
}
}
// }}}
// {{{ setAuth()
/**
* Register variable in a session telling that the user
* has logged in successfully
*
* @access public
* @param string Username
* @return void
*/
function setAuth($username)
{
$session = &DOLIAuth::_importGlobalVariable("session");
if (!isset($session['auth']) && !isset($_SESSION)) {
session_register("auth");
}
if (!isset($session['auth']) || !is_array($session['auth'])) {
$session['auth'] = array();
}
if(!isset($session['auth']['data'])){
$session['auth']['data'] = array();
}
$session['auth']['registered'] = true;
$session['auth']['username'] = $username;
$session['auth']['timestamp'] = time();
$session['auth']['idle'] = time();
}
// }}}
// {{{ checkAuth()
/**
* Checks if there is a session with valid auth information.
*
* @access private
* @return boolean Whether or not the user is authenticated.
*/
function checkAuth()
{
$session = &$this->_importGlobalVariable("session");
if (isset($session['auth'])) {
/** Check if authentication session is expired */
if ($this->expire > 0 &&
isset($session['auth']['timestamp']) &&
($session['auth']['timestamp'] + $this->expire) < time()) {
$this->logout();
$this->expired = true;
$this->status = AUTH_EXPIRED;
return false;
}
/** Check if maximum idle time is reached */
if ($this->idle > 0 &&
isset($session['auth']['idle']) &&
($session['auth']['idle'] + $this->idle) < time()) {
$this->logout();
$this->idled = true;
$this->status = AUTH_IDLED;
return false;
}
if (isset($session['auth']['registered']) &&
isset($session['auth']['username']) &&
$session['auth']['registered'] == true &&
$session['auth']['username'] != "") {
DOLIAuth::updateIdle();
return true;
}
}
return false;
}
// }}}
// {{{ getAuth()
/**
* Has the user been authenticated?
*
* @access public
* @return bool True if the user is logged in, otherwise false.
*/
function getAuth()
{
$session = &$this->_importGlobalVariable("session");
if (!empty($session) &&
(isset($session['auth']['registered']) &&
$session['auth']['registered'] === true))
{
return true;
} else {
return false;
}
}
// }}}
// {{{ drawLogin()
/**
* Draw the login form
*
* Normally you will not use this output in your application,
* because you can pass a different function name to the
* constructor. For more information on this, please
* consult the documentation.
*
* @access private
* @param string Username if already entered
* @return void
*/
function drawLogin($username = "")
{
if ($this->loginFunction != "") {
call_user_func($this->loginFunction, $username, $this->status);
} else {
$server = &$this->_importGlobalVariable("server");
echo "<center>\n";
if (!empty($this->status) && $this->status == AUTH_EXPIRED) {
echo "<i>Your session expired. Please login again!</i>\n";
} else if (!empty($this->status) && $this->status == AUTH_IDLED) {
echo "<i>You have been idle for too long. Please login again!</i>\n";
} else if (!empty ($this->status) && $this->status == AUTH_WRONG_LOGIN) {
echo "<i>Wrong login data!</i>\n";
}
DOLIPEAR::raiseError("You are using the built-in login screen of PEAR::Auth.<br/>See the <a href=\"http://pear.php.net/manual/\">manual</a> for details on how to create your own login function.", null);
echo "<form method=\"post\" action=\"" . $server['PHP_SELF'] . "\">\n";
echo "<table border=\"0\" cellpadding=\"2\" cellspacing=\"0\">\n";
echo "<tr>\n";
echo " <td colspan=\"2\" bgcolor=\"#eeeeee\"><b>Login:</b></td>\n";
echo "</tr>\n";
echo "<tr>\n";
echo " <td>Username:</td>\n";
echo " <td><input type=\"text\" name=\"username\" value=\"" . $username . "\"></td>\n";
echo "</tr>\n";
echo "<tr>\n";
echo " <td>Password:</td>\n";
echo " <td><input type=\"password\" name=\"password\"></td>\n";
echo "</tr>\n";
echo "<tr>\n";
echo " <td colspan=\"2\" bgcolor=\"#eeeeee\"><input type=\"submit\"></td>\n";
echo "</tr>\n";
echo "</table>\n";
echo "</form>\n";
echo "</center>\n\n";
}
}
// }}}
// {{{ logout()
/**
* Logout function
*
* This function clears any auth tokens in the currently
* active session and executes the logout callback function,
* if any
*
* @access public
* @return void
*/
function logout()
{
$session = &$this->_importGlobalVariable("session");
if (!empty($this->logoutCallback)) {
call_user_func($this->logoutCallback, $session['auth']['username']);
}
$this->username = "";
$this->password = "";
$session['auth'] = array();
if (isset($_SESSION)) {
unset($session['auth']);
} else {
session_unregister("auth");
}
}
// }}}
// {{{ updateIdle()
/**
* Update the idletime
*
* @access private
* @return void
*/
function updateIdle()
{
$session = &$this->_importGlobalVariable("session");
$session['auth']['idle'] = time();
}
// }}}
// {{{ getUsername()
/**
* Get the username
*
* @access public
* @return string
*/
function getUsername()
{
$session = &$this->_importGlobalVariable("session");
if (!isset($session['auth']['username'])) {
return "";
}
return $session['auth']['username'];
}
// }}}
// {{{ getStatus()
/**
* Get the current status
*
* @access public
* @return string
*/
function getStatus()
{
return $this->status;
}
// }}}
// {{{ sessionValidThru()
/**
* Returns the time up to the session is valid
*
* @access public
* @return integer
*/
function sessionValidThru()
{
$session = &$this->_importGlobalVariable("session");
if (!isset($session['auth']['idle'])) {
return 0;
}
return ($session['auth']['idle'] + $this->idle);
}
// }}}
// {{{ listUsers()
/**
* List all users that are currently available in the storage
* container
*
* @access public
* @return array
*/
function listUsers()
{
return $this->storage->listUsers();
}
// }}}
// {{{ addUser()
/**
* Add user to the storage container
*
* @access public
* @param string Username
* @param string Password
* @param mixed Additional parameters
* @return mixed True on success, PEAR error object on error
* and AUTH_METHOD_NOT_SUPPORTED otherwise.
*/
function addUser($username, $password, $additional = "")
{
return $this->storage->addUser($username, $password, $additional);
}
// }}}
// {{{ removeUser()
/**
* Remove user from the storage container
*
* @access public
* @param string Username
* @return mixed True on success, PEAR error object on error
* and AUTH_METHOD_NOT_SUPPORTED otherwise.
*/
function removeUser($username)
{
return $this->storage->removeUser($username);
}
// }}}
// {{{ _importGlobalVariable()
/**
* Import variables from special namespaces.
*
* @access private
* @param string Type of variable (server, session, post)
* @return array
*/
function &_importGlobalVariable($variable)
{
$var = null;
switch (strtolower($variable)) {
case "server" :
if (isset($_SERVER)) {
$var = &$_SERVER;
} else {
$var = &$GLOBALS['HTTP_SERVER_VARS'];
}
break;
case "session" :
if (isset($_SESSION)) {
$var = &$_SESSION;
} else {
$var = &$GLOBALS['HTTP_SESSION_VARS'];
}
break;
case "post" :
if (isset($_POST)) {
$var = &$_POST;
} else {
$var = &$GLOBALS['HTTP_POST_VARS'];
}
break;
case "cookie" :
if (isset($_COOKIE)) {
$var = &$_COOKIE;
} else {
$var = &$GLOBALS['HTTP_COOKIE_VARS'];
}
break;
case "get" :
if (isset($_GET)) {
$var = &$_GET;
} else {
$var = &$GLOBALS['HTTP_GET_VARS'];
}
break;
default:
break;
}
return $var;
}
// }}}
}
?>

View File

@ -0,0 +1,968 @@
<?php
//
// +----------------------------------------------------------------------+
// | PEAR, the PHP Extension and Application Repository |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2003 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.0 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available through the world-wide-web at the following url: |
// | http://www.php.net/license/3_0.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Authors: Sterling Hughes <sterling@php.net> |
// | Stig Bakken <ssb@php.net> |
// | Tomas V.V.Cox <cox@idecnet.com> |
// +----------------------------------------------------------------------+
//
// $Id$
//
define('DOLIPEAR_ERROR_RETURN', 1);
define('DOLIPEAR_ERROR_PRINT', 2);
define('DOLIPEAR_ERROR_TRIGGER', 4);
define('DOLIPEAR_ERROR_DIE', 8);
define('DOLIPEAR_ERROR_CALLBACK', 16);
define('DOLIPEAR_ERROR_EXCEPTION', 32);
define('DOLIPEAR_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('DOLIPEAR_OS', 'Windows');
} else {
define('OS_WINDOWS', false);
define('OS_UNIX', true);
define('DOLIPEAR_OS', 'Unix'); // blatant assumption
}
$GLOBALS['_DOLIPEAR_default_error_mode'] = DOLIPEAR_ERROR_RETURN;
$GLOBALS['_DOLIPEAR_default_error_options'] = E_USER_NOTICE;
$GLOBALS['_DOLIPEAR_destructor_object_list'] = array();
$GLOBALS['_DOLIPEAR_shutdown_funcs'] = array();
$GLOBALS['_DOLIPEAR_error_handler_stack'] = array();
ini_set('track_errors', true);
/**
* Base class for other DOLIPEAR classes. Provides rudimentary
* emulation of destructors.
*
* If you want a destructor in your class, inherit DOLIPEAR and make a
* destructor method called _yourclassname (same name as the
* constructor, but with a "_" prefix). Also, in your constructor you
* have to call the DOLIPEAR constructor: $this->DOLIPEAR();.
* The destructor method will be called without parameters. Note that
* at in some SAPI implementations (such as Apache), any output during
* the request shutdown (in which destructors are called) seems to be
* discarded. If you need to get any debug information from your
* destructor, use error_log(), syslog() or something similar.
*
* IMPORTANT! To use the emulated destructors you need to create the
* objects by reference: $obj =& new DOLIPEAR_child;
*
* @since PHP 4.0.2
* @author Stig Bakken <ssb@php.net>
* @see http://pear.php.net/manual/
*/
class DOLIPEAR
{
// {{{ properties
/**
* Whether to enable internal debug messages.
*
* @var bool
* @access private
*/
var $_debug = false;
/**
* Default error mode for this object.
*
* @var int
* @access private
*/
var $_default_error_mode = null;
/**
* Default error options used for this object when error mode
* is DOLIPEAR_ERROR_TRIGGER.
*
* @var int
* @access private
*/
var $_default_error_options = null;
/**
* Default error handler (callback) for this object, if error mode is
* DOLIPEAR_ERROR_CALLBACK.
*
* @var string
* @access private
*/
var $_default_error_handler = '';
/**
* Which class to use for error objects.
*
* @var string
* @access private
*/
var $_error_class = 'DOLIPEAR_Error';
/**
* An array of expected errors.
*
* @var array
* @access private
*/
var $_expected_errors = array();
// }}}
// {{{ constructor
/**
* Constructor. Registers this object in
* $_DOLIPEAR_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 DOLIPEAR_Error.
* @access public
* @return void
*/
function DOLIPEAR($error_class = null)
{
$classname = get_class($this);
if ($this->_debug) {
print "DOLIPEAR constructor called, class=$classname\n";
}
if ($error_class !== null) {
$this->_error_class = $error_class;
}
while ($classname) {
$destructor = "_$classname";
if (method_exists($this, $destructor)) {
global $_DOLIPEAR_destructor_object_list;
$_DOLIPEAR_destructor_object_list[] = &$this;
break;
} else {
$classname = get_parent_class($classname);
}
}
}
// }}}
// {{{ destructor
/**
* 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 _DOLIPEAR() {
if ($this->_debug) {
printf("DOLIPEAR destructor called, class=%s\n", get_class($this));
}
}
// }}}
// {{{ getStaticProperty()
/**
* 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 = &DOLIPEAR::getStaticProperty('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)
{
static $properties;
return $properties[$class][$var];
}
// }}}
// {{{ registerShutdownFunc()
/**
* 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())
{
$GLOBALS['_DOLIPEAR_shutdown_funcs'][] = array($func, $args);
}
// }}}
// {{{ isError()
/**
* Tell whether a value is a DOLIPEAR error.
*
* @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)
{
if (is_object($data) && (get_class($data) == 'pear_error' ||
is_subclass_of($data, 'pear_error'))) {
if (is_null($code)) {
return true;
} elseif (is_string($code)) {
return $data->getMessage() == $code;
} else {
return $data->getCode() == $code;
}
}
return false;
}
// }}}
// {{{ setErrorHandling()
/**
* Sets how errors generated by this object should be handled.
* Can be invoked both in objects and statically. If called
* statically, setErrorHandling sets the default behaviour for all
* DOLIPEAR objects. If called in an object, setErrorHandling sets
* the default behaviour for that object.
*
* @param int $mode
* One of DOLIPEAR_ERROR_RETURN, DOLIPEAR_ERROR_PRINT,
* DOLIPEAR_ERROR_TRIGGER, DOLIPEAR_ERROR_DIE,
* DOLIPEAR_ERROR_CALLBACK or DOLIPEAR_ERROR_EXCEPTION.
*
* @param mixed $options
* When $mode is DOLIPEAR_ERROR_TRIGGER, this is the error level (one
* of E_USER_NOTICE, E_USER_WARNING or E_USER_ERROR).
*
* When $mode is DOLIPEAR_ERROR_CALLBACK, this parameter is expected
* to be the callback function or method. A callback
* function is a string with the name of the function, a
* callback method is an array of two elements: the element
* at index 0 is the object, and the element at index 1 is
* the name of the method to call in the object.
*
* When $mode is DOLIPEAR_ERROR_PRINT or DOLIPEAR_ERROR_DIE, this is
* a printf format string used when printing the error
* message.
*
* @access public
* @return void
* @see DOLIPEAR_ERROR_RETURN
* @see DOLIPEAR_ERROR_PRINT
* @see DOLIPEAR_ERROR_TRIGGER
* @see DOLIPEAR_ERROR_DIE
* @see DOLIPEAR_ERROR_CALLBACK
* @see DOLIPEAR_ERROR_EXCEPTION
*
* @since PHP 4.0.5
*/
function setErrorHandling($mode = null, $options = null)
{
if (isset($this)) {
$setmode = &$this->_default_error_mode;
$setoptions = &$this->_default_error_options;
} else {
$setmode = &$GLOBALS['_DOLIPEAR_default_error_mode'];
$setoptions = &$GLOBALS['_DOLIPEAR_default_error_options'];
}
switch ($mode) {
case DOLIPEAR_ERROR_RETURN:
case DOLIPEAR_ERROR_PRINT:
case DOLIPEAR_ERROR_TRIGGER:
case DOLIPEAR_ERROR_DIE:
case DOLIPEAR_ERROR_EXCEPTION:
case null:
$setmode = $mode;
$setoptions = $options;
break;
case DOLIPEAR_ERROR_CALLBACK:
$setmode = $mode;
if ((is_string($options) && function_exists($options)) ||
(is_array($options) && method_exists(@$options[0], @$options[1])))
{
$setoptions = $options;
} else {
trigger_error("invalid error callback", E_USER_WARNING);
}
break;
default:
trigger_error("invalid error mode", E_USER_WARNING);
break;
}
}
// }}}
// {{{ expectError()
/**
* This method is used to tell which errors you expect to get.
* Expected errors are always returned with error mode
* DOLIPEAR_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 sizeof($this->_expected_errors);
}
// }}}
// {{{ popExpect()
/**
* 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);
}
// }}}
// {{{ _checkDelExpect()
/**
* 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;
}
// }}}
// {{{ delExpect()
/**
* 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) {
if ($this->_checkDelExpect($error)) {
$deleted = true;
} else {
$deleted = false;
}
}
return $deleted ? true : DOLIPEAR::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;
} else {
return DOLIPEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME
}
} else {
// $error_code is empty
return DOLIPEAR::raiseError("The expected error you submitted is empty"); // IMPROVE ME
}
}
// }}}
// {{{ raiseError()
/**
* 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 mixed $message a text error message or a DOLIPEAR error object
*
* @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 DOLIPEAR_ERROR_RETURN, DOLIPEAR_ERROR_PRINT,
* DOLIPEAR_ERROR_TRIGGER, DOLIPEAR_ERROR_DIE,
* DOLIPEAR_ERROR_CALLBACK, DOLIPEAR_ERROR_EXCEPTION.
*
* @param mixed $options If $mode is DOLIPEAR_ERROR_TRIGGER, this parameter
* specifies the PHP-internal error level (one of
* E_USER_NOTICE, E_USER_WARNING or E_USER_ERROR).
* If $mode is DOLIPEAR_ERROR_CALLBACK, this
* parameter specifies the callback function or
* method. In other error modes this parameter
* is ignored.
*
* @param string $userinfo If you need to pass along for example debug
* information, this parameter is meant for that.
*
* @param string $error_class The returned error object will be
* instantiated from this class, if specified.
*
* @param bool $skipmsg If true, raiseError will only pass error codes,
* the error message parameter will be dropped.
*
* @access public
* @return object a DOLIPEAR error object
* @see DOLIPEAR::setErrorHandling
* @since PHP 4.0.5
*/
function raiseError($message = null,
$code = null,
$mode = null,
$options = null,
$userinfo = null,
$error_class = null,
$skipmsg = false)
{
// The error is yet a DOLIPEAR error object
if (is_object($message)) {
$code = $message->getCode();
$userinfo = $message->getUserInfo();
$error_class = $message->getType();
$message = $message->getMessage();
}
if (isset($this) && isset($this->_expected_errors) && sizeof($this->_expected_errors) > 0 && sizeof($exp = end($this->_expected_errors))) {
if ($exp[0] == "*" ||
(is_int(reset($exp)) && in_array($code, $exp)) ||
(is_string(reset($exp)) && in_array($message, $exp))) {
$mode = DOLIPEAR_ERROR_RETURN;
}
}
// 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
} elseif (isset($GLOBALS['_DOLIPEAR_default_error_mode'])) {
$mode = $GLOBALS['_DOLIPEAR_default_error_mode'];
$options = $GLOBALS['_DOLIPEAR_default_error_options'];
}
}
if ($error_class !== null) {
$ec = $error_class;
} elseif (isset($this) && isset($this->_error_class)) {
$ec = $this->_error_class;
} else {
$ec = 'DOLIPEAR_Error';
}
if ($skipmsg) {
return new $ec($code, $mode, $options, $userinfo);
} else {
return new $ec($message, $code, $mode, $options, $userinfo);
}
}
// }}}
// {{{ throwError()
/**
* Simpler form of raiseError with fewer options. In most cases
* message, code and userinfo are enough.
*
* @param string $message
*
*/
function &throwError($message = null,
$code = null,
$userinfo = null)
{
if (isset($this) && is_subclass_of($this, 'DOLIPEAR_Error')) {
return $this->raiseError($message, $code, null, null, $userinfo);
} else {
return DOLIPEAR::raiseError($message, $code, null, null, $userinfo);
}
}
// }}}
// {{{ pushErrorHandling()
/**
* 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 mixed $mode (same as setErrorHandling)
* @param mixed $options (same as setErrorHandling)
*
* @return bool Always true
*
* @see DOLIPEAR::setErrorHandling
*/
function pushErrorHandling($mode, $options = null)
{
$stack = &$GLOBALS['_DOLIPEAR_error_handler_stack'];
if (isset($this)) {
$def_mode = &$this->_default_error_mode;
$def_options = &$this->_default_error_options;
} else {
$def_mode = &$GLOBALS['_DOLIPEAR_default_error_mode'];
$def_options = &$GLOBALS['_DOLIPEAR_default_error_options'];
}
$stack[] = array($def_mode, $def_options);
if (isset($this)) {
$this->setErrorHandling($mode, $options);
} else {
DOLIPEAR::setErrorHandling($mode, $options);
}
$stack[] = array($mode, $options);
return true;
}
// }}}
// {{{ popErrorHandling()
/**
* Pop the last error handler used
*
* @return bool Always true
*
* @see DOLIPEAR::pushErrorHandling
*/
function popErrorHandling()
{
$stack = &$GLOBALS['_DOLIPEAR_error_handler_stack'];
array_pop($stack);
list($mode, $options) = $stack[sizeof($stack) - 1];
array_pop($stack);
if (isset($this)) {
$this->setErrorHandling($mode, $options);
} else {
DOLIPEAR::setErrorHandling($mode, $options);
}
return true;
}
// }}}
// {{{ loadExtension()
/**
* 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)
{
if (!extension_loaded($ext)) {
// if either returns true dl() will produce a FATAL error, stop that
if ((ini_get('enable_dl') != 1) || (ini_get('safe_mode') == 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);
}
return true;
}
// }}}
}
// {{{ _DOLIPEAR_call_destructors()
function _DOLIPEAR_call_destructors()
{
global $_DOLIPEAR_destructor_object_list;
if (is_array($_DOLIPEAR_destructor_object_list) &&
sizeof($_DOLIPEAR_destructor_object_list))
{
reset($_DOLIPEAR_destructor_object_list);
while (list($k, $objref) = each($_DOLIPEAR_destructor_object_list)) {
$classname = get_class($objref);
while ($classname) {
$destructor = "_$classname";
if (method_exists($objref, $destructor)) {
$objref->$destructor();
break;
} else {
$classname = get_parent_class($classname);
}
}
}
// Empty the object list to ensure that destructors are
// not called more than once.
$_DOLIPEAR_destructor_object_list = array();
}
// Now call the shutdown functions
if (is_array($GLOBALS['_DOLIPEAR_shutdown_funcs']) AND !empty($GLOBALS['_DOLIPEAR_shutdown_funcs'])) {
foreach ($GLOBALS['_DOLIPEAR_shutdown_funcs'] as $value) {
call_user_func_array($value[0], $value[1]);
}
}
}
// }}}
class DOLIPEAR_Error
{
// {{{ properties
var $error_message_prefix = '';
var $mode = DOLIPEAR_ERROR_RETURN;
var $level = E_USER_NOTICE;
var $code = -1;
var $message = '';
var $userinfo = '';
var $backtrace = null;
// }}}
// {{{ constructor
/**
* DOLIPEAR_Error constructor
*
* @param string $message message
*
* @param int $code (optional) error code
*
* @param int $mode (optional) error mode, one of: DOLIPEAR_ERROR_RETURN,
* DOLIPEAR_ERROR_PRINT, DOLIPEAR_ERROR_DIE, DOLIPEAR_ERROR_TRIGGER,
* DOLIPEAR_ERROR_CALLBACK or DOLIPEAR_ERROR_EXCEPTION
*
* @param mixed $options (optional) error level, _OR_ in the case of
* DOLIPEAR_ERROR_CALLBACK, the callback function or object/method
* tuple.
*
* @param string $userinfo (optional) additional user/debug info
*
* @access public
*
*/
function DOLIPEAR_Error($message = 'unknown error', $code = null,
$mode = null, $options = null, $userinfo = null)
{
if ($mode === null) {
$mode = DOLIPEAR_ERROR_RETURN;
}
$this->message = $message;
$this->code = $code;
$this->mode = $mode;
$this->userinfo = $userinfo;
if (function_exists("debug_backtrace")) {
$this->backtrace = debug_backtrace();
}
if ($mode & DOLIPEAR_ERROR_CALLBACK) {
$this->level = E_USER_NOTICE;
$this->callback = $options;
} else {
if ($options === null) {
$options = E_USER_NOTICE;
}
$this->level = $options;
$this->callback = null;
}
if ($this->mode & DOLIPEAR_ERROR_PRINT) {
if (is_null($options) || is_int($options)) {
$format = "%s";
} else {
$format = $options;
}
printf($format, $this->getMessage());
}
if ($this->mode & DOLIPEAR_ERROR_TRIGGER) {
trigger_error($this->getMessage(), $this->level);
}
if ($this->mode & DOLIPEAR_ERROR_DIE) {
$msg = $this->getMessage();
if (is_null($options) || is_int($options)) {
$format = "%s";
if (substr($msg, -1) != "\n") {
$msg .= "\n";
}
} else {
$format = $options;
}
die(sprintf($format, $msg));
}
if ($this->mode & DOLIPEAR_ERROR_CALLBACK) {
if (is_string($this->callback) && strlen($this->callback)) {
call_user_func($this->callback, $this);
} elseif (is_array($this->callback) &&
sizeof($this->callback) == 2 &&
is_object($this->callback[0]) &&
is_string($this->callback[1]) &&
strlen($this->callback[1])) {
call_user_func($this->callback, $this);
}
}
if (DOLIPEAR_ZE2 && $this->mode & DOLIPEAR_ERROR_EXCEPTION) {
eval('throw $this;');
}
}
// }}}
// {{{ getMode()
/**
* Get the error mode from an error object.
*
* @return int error mode
* @access public
*/
function getMode() {
return $this->mode;
}
// }}}
// {{{ getCallback()
/**
* Get the callback function/method from an error object.
*
* @return mixed callback function or object/method array
* @access public
*/
function getCallback() {
return $this->callback;
}
// }}}
// {{{ getMessage()
/**
* Get the error message from an error object.
*
* @return string full error message
* @access public
*/
function getMessage()
{
return ($this->error_message_prefix . $this->message);
}
// }}}
// {{{ getCode()
/**
* Get error code from an error object
*
* @return int error code
* @access public
*/
function getCode()
{
return $this->code;
}
// }}}
// {{{ getType()
/**
* Get the name of this error/exception.
*
* @return string error/exception name (type)
* @access public
*/
function getType()
{
return get_class($this);
}
// }}}
// {{{ getUserInfo()
/**
* Get additional user-supplied information.
*
* @return string user-supplied information
* @access public
*/
function getUserInfo()
{
return $this->userinfo;
}
// }}}
// {{{ getDebugInfo()
/**
* Get additional debug information supplied by the application.
*
* @return string debug information
* @access public
*/
function getDebugInfo()
{
return $this->getUserInfo();
}
// }}}
// {{{ getBacktrace()
/**
* Get the call backtrace from where the error was generated.
* Supported with PHP 4.3.0 or newer.
*
* @param int $frame (optional) what frame to fetch
* @return array Backtrace, or NULL if not available.
* @access public
*/
function getBacktrace($frame = null)
{
if ($frame === null) {
return $this->backtrace;
}
return $this->backtrace[$frame];
}
// }}}
// {{{ addUserInfo()
function addUserInfo($info)
{
if (empty($this->userinfo)) {
$this->userinfo = $info;
} else {
$this->userinfo .= " ** $info";
}
}
// }}}
// {{{ toString()
/**
* Make a string representation of this object.
*
* @return string a string with an object summary
* @access public
*/
function toString() {
$modes = array();
$levels = array(E_USER_NOTICE => 'notice',
E_USER_WARNING => 'warning',
E_USER_ERROR => 'error');
if ($this->mode & DOLIPEAR_ERROR_CALLBACK) {
if (is_array($this->callback)) {
$callback = get_class($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"]',
get_class($this), $this->message, $this->code,
$callback, $this->error_message_prefix,
$this->userinfo);
}
if ($this->mode & DOLIPEAR_ERROR_PRINT) {
$modes[] = 'print';
}
if ($this->mode & DOLIPEAR_ERROR_TRIGGER) {
$modes[] = 'trigger';
}
if ($this->mode & DOLIPEAR_ERROR_DIE) {
$modes[] = 'die';
}
if ($this->mode & DOLIPEAR_ERROR_RETURN) {
$modes[] = 'return';
}
return sprintf('[%s: message="%s" code=%d mode=%s level=%s '.
'prefix="%s" info="%s"]',
get_class($this), $this->message, $this->code,
implode("|", $modes), $levels[$this->level],
$this->error_message_prefix,
$this->userinfo);
}
// }}}
}
register_shutdown_function("_DOLIPEAR_call_destructors");
/*
* Local Variables:
* mode: php
* tab-width: 4
* c-basic-offset: 4
* End:
*/
?>