From: Steve Sutton Date: Mon, 14 Jul 2014 20:29:49 +0000 (-0400) Subject: Now the form works X-Git-Tag: v1.0^2~25^2 X-Git-Url: http://cvs2.gaslightmedia.com/gitweb/?a=commitdiff_plain;h=64169af64e5e0bd384572aeb75e1720b1c94f364;p=web%2FBigFore.git Now the form works I have the form working with a small update to our common pear library. --- diff --git a/glmPEAR/Admin.php b/glmPEAR/Admin.php deleted file mode 100755 index 5f4f44e..0000000 --- a/glmPEAR/Admin.php +++ /dev/null @@ -1,696 +0,0 @@ - - * @author Helgi Þormar Þorbjörnsson - * @author Lukas Smith - * @author Arnaud Limbourg - * @author Christian Dickmann - * @author Matt Scifo - * @author Bjoern Kraus - * @copyright 2002-2006 Markus Wolff - * @license http://www.gnu.org/licenses/lgpl.txt - * @version CVS: $Id: Admin.php,v 1.1.1.1 2008/04/28 15:20:46 jamie Exp $ - * @link http://pear.php.net/LiveUser_Admin - */ - -require_once 'LiveUser.php'; -require_once 'LiveUser/Admin/Storage.php'; - -/**#@+ - * Error related constants definition - * - * @var int - */ -define('LIVEUSER_ADMIN_ERROR', -1); -define('LIVEUSER_ADMIN_ERROR_FILTER', -2); -define('LIVEUSER_ADMIN_ERROR_DATA', -3); -define('LIVEUSER_ADMIN_ERROR_QUERY_BUILDER', -4); -define('LIVEUSER_ADMIN_ERROR_ALREADY_ASSIGNED', -5); -define('LIVEUSER_ADMIN_ERROR_NOT_SUPPORTED', -6); -/**#@-*/ - -/** - * A unified admin class - * - * Simple usage: - * - * - * $admin = LiveUser_Admin::factory($conf); - * $filters = array( - * 'perm_user_id' => '3' - * ); - * $found = $admin->getUsers($filters); - * - * if ($found) { - * var_dump($admin->perm->getRights()); - * } - * - * - * @see LiveUser::factory() - * - * @category authentication - * @package LiveUser_Admin - * @author Lukas Smith - * @author Arnaud Limbourg - * @author Helgi Þormar Þorbjörnsson - * @copyright 2002-2006 Markus Wolff - * @license http://www.gnu.org/licenses/lgpl.txt - * @version Release: @package_version@ - * @link http://pear.php.net/LiveUser_Admin - */ -class LiveUser_Admin -{ - /** - * Name of the current selected auth container - * - * @var string - * @access public - */ - var $authContainerName; - - /** - * Array containing the auth objects. - * - * @var array - * @access private - */ - var $_authContainers = array(); - - /** - * Admin perm object - * - * @var LiveUser_Admin_Perm_Simple - * @access public - */ - var $perm = null; - - /** - * Auth admin object - * - * @var LiveUser_Admin_Auth_Common - * @access public - */ - var $auth = null; - - /** - * Configuration array - * - * @var array - * @access private - */ - var $_conf = null; - - /** - * Error codes to message mapping array - * - * @var array - * @access private - */ - var $_errorMessages = array( - LIVEUSER_ADMIN_ERROR => 'An error occurred %msg%', - LIVEUSER_ADMIN_ERROR_FILTER => 'There\'s something obscure with the filter array, key %key%', - LIVEUSER_ADMIN_ERROR_DATA => 'There\'s something obscure with the data array, key %key%', - LIVEUSER_ADMIN_ERROR_QUERY_BUILDER => 'Couldn\'t create the query, reason: %reason%', - LIVEUSER_ADMIN_ERROR_ALREADY_ASSIGNED => 'That given %field1% has already been assigned to %field2%', - LIVEUSER_ADMIN_ERROR_NOT_SUPPORTED => 'This method is not supported' - ); - - /** - * PEAR::Log object used for error logging by ErrorStack - * - * @var Log - * @access public - */ - var $log = null; - - /** - * - * @param bool|log boolean value to denote if the debug mode should be - enabled, or instance of a PEAR_ErrorStack compatible Log object - * @return LiveUser_Admin - * - * @access public - * @see init - */ - function LiveUser_Admin(&$debug) - { - $this->stack = &PEAR_ErrorStack::singleton('LiveUser_Admin'); - - if ($debug) { - $log =& LiveUser::PEARLogFactory($debug); - if ($log) { - $this->log =& $log; - $this->stack->setLogger($this->log); - } - } - - $this->stack->setErrorMessageTemplate($this->_errorMessages); - } - - /** - * - * @param array configuration array - * @return LiveUser_Admin|bool - * - * @access public - * @see init - */ - function &factory(&$conf) - { - $debug = false; - if (array_key_exists('debug', $conf)) { - $debug =& $conf['debug']; - } - - $obj = &new LiveUser_Admin($debug); - - if (is_array($conf)) { - $obj->_conf =& $conf; - } - - return $obj; - } - - /** - * - * @param array configuration array - * @return LiveUser_Admin|bool - * - * @access public - * @see factory - */ - function &singleton(&$conf) - { - static $instance; - - if (!isset($instance)) { - if (!$conf) { - return false; - } - $obj = &LiveUser_Admin::factory($conf); - $instance =& $obj; - } - - return $instance; - } - - /** - * Sets the current auth container to the one with the given auth container name - * - * Upon success it will return the auth instance. You can then - * access the auth backend container by using the - * auth property of this class or the auth object directly - * - * e.g.: $admin->auth->addUser(); or $auth->addUser(); - * - * @param string auth container name - * @return LiveUser_Admin_Auth_Common|bool auth instance upon success, false otherwise - * - * @access public - */ - function &setAdminAuthContainer($authName) - { - if (!array_key_exists($authName, $this->_authContainers) - || !is_object($this->_authContainers[$authName]) - ) { - if (!isset($this->_conf['authContainers'][$authName])) { - $this->stack->push(LIVEUSER_ADMIN_ERROR, 'exception', - array('msg' => 'Could not create auth container instance')); - $result = false; - return $result; - } - $auth = &LiveUser::authFactory( - $this->_conf['authContainers'][$authName], - $authName, - 'LiveUser_Admin_' - ); - if ($auth === false) { - $this->stack->push(LIVEUSER_ADMIN_ERROR, 'exception', - array('msg' => 'Could not instanciate auth container: '.$authName)); - return $auth; - } - $this->_authContainers[$authName] = &$auth; - } - $this->authContainerName = $authName; - $this->auth = &$this->_authContainers[$authName]; - return $this->auth; - } - - /** - * Sets the perm container - * - * Upon success it will return a perm instance. You can then - * access the perm backend container by using the - * perm properties of this class or the perm object directly. - * - * e.g.: $admin->perm->addUser(); or $perm->addUser(); - * - * @return LiveUser_Admin_Perm_Simple|bool auth instance upon success, false otherwise - * - * @access public - */ - function &setAdminPermContainer() - { - if (!array_key_exists('permContainer', $this->_conf)) { - $this->stack->push(LIVEUSER_ADMIN_ERROR, 'exception', - array('msg' => 'Could not create perm container instance')); - $result = false; - return $result; - } - - $perm = &LiveUser::permFactory($this->_conf['permContainer'], 'LiveUser_Admin_'); - if ($perm === false) { - $this->stack->push(LIVEUSER_ADMIN_ERROR, 'exception', - array('msg' => 'Could not instanciate perm container of type: '.$this->_conf['permContainer']['type'])); - return $perm; - } - $this->perm = &$perm; - - return $this->perm; - } - - /** - * Setup backend container. - * - * Upon success it will return true. You can then - * access the backend container by using the auth - * and perm properties of this class. - * - * e.g.: $admin->perm->getUsers(); - * - * @param int user auth id - * @param string auth container name - * @return bool true upon success, false otherwise - * - * @access public - */ - function init($authUserId = null, $authName = null) - { - if (!is_array($this->_conf)) { - $this->stack->push(LIVEUSER_ADMIN_ERROR, 'exception', - array('msg' => 'Missing configuration array')); - return false; - } - - if (is_null($authName)) { - if (is_null($authUserId)) { - reset($this->_conf['authContainers']); - $authName = key($this->_conf['authContainers']); - } else { - foreach ($this->_conf['authContainers'] as $key => $value) { - if (!isset($this->_authContainers[$key]) - || !is_object($this->_authContainers[$key]) - ) { - $auth = &LiveUser::authFactory($value, $key, 'LiveUser_Admin_'); - if ($auth === false) { - $this->stack->push(LIVEUSER_ADMIN_ERROR, 'exception', - array('msg' => 'Could not instanciate auth container: '.$key)); - return $auth; - } - $this->_authContainers[$key] =& $auth; - } - - if (!is_null($authUserId)) { - $match = $this->_authContainers[$key]->getUsers( - array('filters' => array('auth_user_id' => $authUserId)) - ); - if (is_array($match) && count($match) > 0) { - $authName = $key; - break; - } - } - } - } - if (!isset($authName)) { - $this->stack->push(LIVEUSER_ADMIN_ERROR, 'exception', - array('msg' => 'Could not determine what auth container to use')); - return false; - } - } - - if (!$this->setAdminAuthContainer($authName)) { - return false; - } - - if (!isset($this->perm) || !is_object($this->perm)) { - if (!$this->setAdminPermContainer()) { - return false; - } - } - - return true; - } - - /** - * Add a user to both containers. - * - * @param array auth user data and perm type - * @return int|bool perm user id or false - * - * @access public - */ - function addUser($data) - { - if (!is_object($this->auth) || !is_object($this->perm)) { - $this->stack->push(LIVEUSER_ADMIN_ERROR, 'exception', - array('msg' => 'Perm and/or Auth container not set.')); - return false; - } - - if (array_key_exists('perm_type', $data)) { - $type = $data['perm_type']; - unset($data['perm_type']); - } else { - $type = LIVEUSER_USER_TYPE_ID; - } - - $authUserId = $this->auth->addUser($data); - if (!$authUserId) { - return false; - } - - $data = array( - 'auth_user_id' => $authUserId, - 'auth_container_name' => $this->authContainerName, - 'perm_type' => $type - ); - return $this->perm->addUser($data); - } - - /** - * Changes user data for both containers. - * - * @param array auth user data and perm type - * @param int permission user id - * @return int|bool affected rows on success or false otherwise - * - * @access public - */ - function updateUser($data, $permUserId) - { - if (!is_object($this->auth) || !is_object($this->perm)) { - $this->stack->push(LIVEUSER_ADMIN_ERROR, 'exception', - array('msg' => 'Perm and/or Auth container not set.')); - return false; - } - - $permData = $this->perm->getUsers( - array( - 'fields' => array('auth_user_id', 'auth_container_name'), - 'filters' => array('perm_user_id' => $permUserId), - 'select' => 'row', - ) - ); - - if (!$permData) { - $this->stack->push(LIVEUSER_ADMIN_ERROR, 'exception', - array('msg' => 'Could not find user in the permission backend')); - return false; - } - - $updateData = array(); - if (array_key_exists('perm_type', $data)) { - $updateData['perm_type'] = $data['perm_type']; - unset($data['perm_type']); - } - - $this->setAdminAuthContainer($permData['auth_container_name']); - $filters = array('auth_user_id' => $permData['auth_user_id']); - $result = $this->auth->updateUser($data, $filters); - - if ($result === false) { - return false; - } - - if (array_key_exists('auth_user_id', $data) - && $permData['auth_user_id'] != $data['auth_user_id'] - ) { - $updateData['auth_user_id'] = $data['auth_user_id']; - } - if (empty($updateData)) { - return $result; - } - - $filters = array('perm_user_id' => $permUserId); - return $this->perm->updateUser($updateData, $filters); - } - - /** - * Removes user from both Perm and Auth containers - * - * @param int Perm ID - * @return int|bool affected rows on success or false otherwise - * - * @access public - */ - function removeUser($permUserId) - { - if (!is_object($this->auth) || !is_object($this->perm)) { - $this->stack->push(LIVEUSER_ADMIN_ERROR, 'exception', - array('msg' => 'Perm and/or Auth container not set.')); - return false; - } - - $permData = $this->perm->getUsers( - array( - 'fields' => array('auth_user_id', 'auth_container_name'), - 'filters' => array('perm_user_id' => $permUserId), - 'select' => 'row', - ) - ); - - if (!$permData) { - $this->stack->push(LIVEUSER_ADMIN_ERROR, 'exception', - array('msg' => 'Could not find user in the permission backend')); - return false; - } - - $filters = array('perm_user_id' => $permUserId); - $result = $this->perm->removeUser($filters); - - if ($result === false) { - return false; - } - - $this->setAdminAuthContainer($permData['auth_container_name']); - $filters = array('auth_user_id' => $permData['auth_user_id']); - return $this->auth->removeUser($filters); - } - - /** - * Finds and gets full userinfo by filtering inside the given container - * Note that this method is not particularily efficient, as it fetches - * the data in the primary container in a single call, but requires one call - * to the secondary container for every user returned from the primary container - * - * @param array params (as for getUsers() - * with an additional optional key 'container' 'perm' (default) or - 'auth' to determine the primary and secondary container. - data is first fetched from the primary container and then - combined with data from the secondary container if available - * @return array|bool array with userinfo if found on success or false otherwise - * - * @access public - */ - function getUsers($params = array()) - { - $params = LiveUser_Admin_Storage::setSelectDefaultParams($params); - - if ($params['select'] != 'row' && $params['select'] != 'all') { - $this->stack->push(LIVEUSER_ADMIN_ERROR, 'exception', - array('msg' => 'Select must be "row" or "all"')); - return false; - } - - if (array_key_exists('container', $params) - && $params['container'] == 'auth' - ) { - return $this->_getUsersByAuth($params); - } - return $this->_getUsersByPerm($params); - } - - /** - * Finds and gets full userinfo by filtering inside the perm container - * - * @param array perm params (as for getUsers() from the perm container - * @return array|bool Array with userinfo if found on success or false otherwise - * - * @access private - */ - function _getUsersByPerm($permParams = array()) - { - if (!is_object($this->perm)) { - $this->stack->push(LIVEUSER_ADMIN_ERROR, 'exception', - array('msg' => 'Perm container not set.')); - return false; - } - - $first = ($permParams['select'] == 'row'); - $permUsers = $this->perm->getUsers($permParams); - if (!$permUsers) { - return $permUsers; - } - - if ($first) { - $permUsers = array($permUsers); - } - - $users = array(); - foreach ($permUsers as $permData) { - if (!$this->setAdminAuthContainer($permData['auth_container_name'])) { - $this->stack->push(LIVEUSER_ADMIN_ERROR, 'exception', - array('msg' => 'Auth container could not be set.')); - return false; - } - - $authParams = array( - 'filters' => array('auth_user_id' => $permData['auth_user_id']), - 'select' => 'row', - ); - $authData = $this->auth->getUsers($authParams); - if (!$authData) { - continue; - } - - if ($first) { - return LiveUser::arrayMergeClobber($permData, $authData); - } - $users[] = LiveUser::arrayMergeClobber($permData, $authData); - } - - return $users; - } - - /** - * Finds and gets full userinfo by filtering inside the auth container - * - * @param array auth params (as for getUsers() from the auth container - * @return array|bool Array with userinfo if found on success or false otherwise - * - * @access private - */ - function _getUsersByAuth($authParams = array()) - { - if (!is_object($this->auth) || !is_object($this->perm)) { - $this->stack->push(LIVEUSER_ADMIN_ERROR, 'exception', - array('msg' => 'Perm and/or Auth container not set.')); - return false; - } - - $first = ($authParams['select'] == 'row'); - $authUsers = $this->auth->getUsers($authParams); - if (!$authUsers) { - return $authUsers; - } - - if ($first) { - $authUsers = array($authUsers); - } - - $users = array(); - foreach ($authUsers as $authData) { - $permParams = array( - 'filters' => array( - 'auth_user_id' => $authData['auth_user_id'], - 'auth_container_name' => $this->authContainerName, - ), - 'select' => 'row', - ); - $permData = $this->perm->getUsers($permParams); - if (!$permData) { - continue; - } - - if ($first) { - return LiveUser::arrayMergeClobber($authData, $permData); - } - $users[] = LiveUser::arrayMergeClobber($authData, $permData); - } - - return $users; - } - - /** - * Wrapper method to get the Error Stack - * - * @return array an array of the errors - * - * @access public - */ - function getErrors() - { - if (is_object($this->stack)) { - return $this->stack->getErrors(); - } - return false; - } - - /** - * Calls a method using the __call() magic method on perm or auth - * - * @param string method name - * @param array arguments - * @return mixed returned value - * - * @access private - */ - function __call($method, $params) - { - if (is_object($this->perm) && method_exists($this->perm, $method)) { - return call_user_func_array(array(&$this->perm, $method), $params); - } - if (is_object($this->auth) && method_exists($this->auth, $method)) { - return call_user_func_array(array(&$this->auth, $method), $params); - } - trigger_error(sprintf('Call to undefined function: %s::%s().', get_class($this), $method), E_USER_ERROR); - } -} diff --git a/glmPEAR/Auth.php b/glmPEAR/Auth.php deleted file mode 100755 index 754e887..0000000 --- a/glmPEAR/Auth.php +++ /dev/null @@ -1,1291 +0,0 @@ - - * @author Adam Ashley - * @copyright 2001-2006 The PHP Group - * @license http://www.php.net/license/3_01.txt PHP License 3.01 - * @version CVS: $Id: Auth.php,v 1.1.1.1 2008/04/28 15:20:46 jamie Exp $ - * @link http://pear.php.net/package/Auth - */ - -/** - * Returned if session exceeds idle time - */ -define('AUTH_IDLED', -1); -/** - * Returned if session has expired - */ -define('AUTH_EXPIRED', -2); -/** - * Returned if container is unable to authenticate user/password pair - */ -define('AUTH_WRONG_LOGIN', -3); -/** - * Returned if a container method is not supported. - */ -define('AUTH_METHOD_NOT_SUPPORTED', -4); -/** - * Returned if new Advanced security system detects a breach - */ -define('AUTH_SECURITY_BREACH', -5); -/** - * Returned if checkAuthCallback says session should not continue. - */ -define('AUTH_CALLBACK_ABORT', -6); - -/** - * Auth Log level - INFO - */ -define('AUTH_LOG_INFO', 6); -/** - * Auth Log level - DEBUG - */ -define('AUTH_LOG_DEBUG', 7); - - -/** - * PEAR::Auth - * - * The PEAR::Auth class provides methods for creating an - * authentication system using PHP. - * - * @category Authentication - * @package Auth - * @author Martin Jansen - * @author Adam Ashley - * @copyright 2001-2006 The PHP Group - * @license http://www.php.net/license/3_01.txt PHP License 3.01 - * @version Release: 1.5.4 File: $Revision: 1.1.1.1 $ - * @link http://pear.php.net/package/Auth - */ -class Auth { - - // {{{ properties - - /** - * 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() - */ - var $expired = false; - - /** - * Maximum idletime in seconds - * - * The difference to $expire is, that the idletime gets - * refreshed each time checkAuth() is called. If this - * variable is set to 0, idletime is never checked. - * - * @var integer - * @see setIdle(), checkAuth() - */ - var $idle = 0; - - /** - * Is the maximum idletime over? - * - * @var boolean - * @see checkAuth() - */ - var $idled = false; - - /** - * Storage object - * - * @var object - * @see Auth(), validateLogin() - */ - var $storage = ''; - - /** - * User-defined function that creates the login screen - * - * @var string - */ - var $loginFunction = ''; - - /** - * Should the login form be displayed - * - * @var bool - * @see setShowlogin() - */ - var $showLogin = true; - - /** - * Is Login Allowed from this page - * - * @var bool - * @see setAllowLogin - */ - var $allowLogin = true; - - /** - * Current authentication status - * - * @var string - */ - var $status = ''; - - /** - * Username - * - * @var string - */ - var $username = ''; - - /** - * Password - * - * @var string - */ - var $password = ''; - - /** - * checkAuth callback function name - * - * @var string - * @see setCheckAuthCallback() - */ - var $checkAuthCallback = ''; - - /** - * Login callback function name - * - * @var string - * @see setLoginCallback() - */ - var $loginCallback = ''; - - /** - * Failed Login callback function name - * - * @var string - * @see setFailedLoginCallback() - */ - var $loginFailedCallback = ''; - - /** - * Logout callback function name - * - * @var string - * @see setLogoutCallback() - */ - var $logoutCallback = ''; - - /** - * Auth session-array name - * - * @var string - */ - var $_sessionName = '_authsession'; - - /** - * Package Version - * - * @var string - */ - var $version = "@version@"; - - /** - * Flag to use advanced security - * When set extra checks will be made to see if the - * user's IP or useragent have changed across requests. - * Turned off by default to preserve BC. - * - * @var boolean - */ - var $advancedsecurity = false; - - /** - * Username key in POST array - * - * @var string - */ - var $_postUsername = 'username'; - - /** - * Password key in POST array - * - * @var string - */ - var $_postPassword = 'password'; - - /** - * Holds a reference to the session auth variable - * @var array - */ - var $session; - - /** - * Holds a reference to the global server variable - * @var array - */ - var $server; - - /** - * Holds a reference to the global post variable - * @var array - */ - var $post; - - /** - * Holds a reference to the global cookie variable - * @var array - */ - var $cookie; - - /** - * A hash to hold various superglobals as reference - * @var array - */ - var $authdata; - - /** - * How many times has checkAuth been called - * @var int - */ - var $authChecks = 0; - - /** - * PEAR::Log object - * - * @var object Log - */ - var $logger = null; - - /** - * Whether to enable logging of behaviour - * - * @var boolean - */ - var $enableLogging = false; - - /** - * Whether to regenerate session id everytime start is called - * - * @var boolean - */ - var $regenerateSessionId = false; - - // }}} - // {{{ Auth() [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 Auth($storageDriver, $options = '', $loginFunction = '', $showLogin = true) - { - $this->applyAuthOptions($options); - - // Start the session suppress error if already started - if(!session_id()){ - @session_start(); - if(!session_id()) { - // Throw error - include_once 'PEAR.php'; - PEAR::throwError('Session could not be started by Auth, ' - .'possibly headers are already sent, try putting ' - .'ob_start in the beginning of your script'); - } - } - - // Make Sure Auth session variable is there - if(!isset($_SESSION[$this->_sessionName])) { - $_SESSION[$this->_sessionName] = array(); - } - - // Assign Some globals to internal references, this will replace _importGlobalVariable - $this->session =& $_SESSION[$this->_sessionName]; - $this->server =& $_SERVER; - $this->post =& $_POST; - $this->cookie =& $_COOKIE; - - if ($loginFunction != '' && is_callable($loginFunction)) { - $this->loginFunction = $loginFunction; - } - - if (is_bool($showLogin)) { - $this->showLogin = $showLogin; - } - - if (is_object($storageDriver)) { - $this->storage =& $storageDriver; - // Pass a reference to auth to the container, ugly but works - // this is used by the DB container to use method setAuthData not staticaly. - $this->storage->_auth_obj =& $this; - } else { - // $this->storage = $this->_factory($storageDriver, $options); - // - $this->storage_driver = $storageDriver; - $this->storage_options =& $options; - } - } - - // }}} - // {{{ applyAuthOptions() - - /** - * Set the Auth options - * - * Some options which are Auth specific will be applied - * the rest will be left for usage by the container - * - * @param array An array of Auth options - * @return array The options which were not applied - * @access private - */ - function &applyAuthOptions(&$options) - { - if(is_array($options)){ - if (!empty($options['sessionName'])) { - $this->_sessionName = $options['sessionName']; - unset($options['sessionName']); - } - if (isset($options['allowLogin'])) { - $this->allowLogin = $options['allowLogin']; - unset($options['allowLogin']); - } - if (!empty($options['postUsername'])) { - $this->_postUsername = $options['postUsername']; - unset($options['postUsername']); - } - if (!empty($options['postPassword'])) { - $this->_postPassword = $options['postPassword']; - unset($options['postPassword']); - } - if (isset($options['advancedsecurity'])) { - $this->advancedsecurity = $options['advancedsecurity']; - unset($options['advancedsecurity']); - } - if (isset($options['enableLogging'])) { - $this->enableLogging = $options['enableLogging']; - unset($options['enableLogging']); - } - if (isset($options['regenerateSessionId']) && is_bool($options['regenerateSessionId'])) { - $this->regenerateSessionId = $options['regenerateSessionId']; - } - } - return($options); - } - - // }}} - // {{{ _loadStorage() - - /** - * Load Storage Driver if not already loaded - * - * Suspend storage instantiation to make Auth lighter to use - * for calls which do not require login - * - * @return bool True if the conainer is loaded, false if the container - * is already loaded - * @access private - */ - function _loadStorage() - { - if(!is_object($this->storage)) { - $this->storage =& $this->_factory($this->storage_driver, - $this->storage_options); - $this->storage->_auth_obj =& $this; - $this->log('Loaded storage container ('.$this->storage_driver.')', AUTH_LOG_DEBUG); - return(true); - } - return(false); - } - - // }}} - // {{{ _factory() - - /** - * Return a storage driver based on $driver and $options - * - * @static - * @param string $driver Type of storage class to return - * @param string $options Optional parameters for the storage class - * @return object Object Storage object - * @access private - */ - function &_factory($driver, $options = '') - { - $storage_class = 'Auth_Container_' . $driver; - include_once 'Auth/Container/' . $driver . '.php'; - $obj =& new $storage_class($options); - return $obj; - } - - // }}} - // {{{ assignData() - - /** - * Assign data from login form to internal values - * - * This function takes the values for username and password - * from $HTTP_POST_VARS/$_POST and assigns them to internal variables. - * If you wish to use another source apart from $HTTP_POST_VARS/$_POST, - * you have to derive this function. - * - * @global $HTTP_POST_VARS, $_POST - * @see Auth - * @return void - * @access private - */ - function assignData() - { - $this->log('Auth::assignData() called.', AUTH_LOG_DEBUG); - - if ( isset($this->post[$this->_postUsername]) - && $this->post[$this->_postUsername] != '') { - $this->username = (get_magic_quotes_gpc() == 1 - ? stripslashes($this->post[$this->_postUsername]) - : $this->post[$this->_postUsername]); - } - if ( isset($this->post[$this->_postPassword]) - && $this->post[$this->_postPassword] != '') { - $this->password = (get_magic_quotes_gpc() == 1 - ? stripslashes($this->post[$this->_postPassword]) - : $this->post[$this->_postPassword] ); - } - } - - // }}} - // {{{ start() - - /** - * Start new auth session - * - * @return void - * @access public - */ - function start() - { - $this->log('Auth::start() called.', AUTH_LOG_DEBUG); - - // #10729 - Regenerate session id here if we are generating it on every - // page load. - if ($this->regenerateSessionId) { - session_regenerate_id(true); - } - - $this->assignData(); - if (!$this->checkAuth() && $this->allowLogin) { - $this->login(); - } - } - - // }}} - // {{{ login() - - /** - * Login function - * - * @return void - * @access private - */ - function login() - { - $this->log('Auth::login() called.', AUTH_LOG_DEBUG); - - $login_ok = false; - $this->_loadStorage(); - - // Check if using challenge response - (isset($this->post['authsecret']) && $this->post['authsecret'] == 1) - ? $usingChap = true - : $usingChap = 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, $usingChap)) { - $this->session['challengekey'] = md5($this->username.$this->password); - $login_ok = true; - $this->log('Successful login.', AUTH_LOG_INFO); - } - } - - if (!empty($this->username) && $login_ok) { - $this->setAuth($this->username); - if (is_callable($this->loginCallback)) { - $this->log('Calling loginCallback ('.$this->loginCallback.').', AUTH_LOG_DEBUG); - call_user_func_array($this->loginCallback, array($this->username, &$this)); - } - } - - // If the login failed or the user entered no username, - // output the login screen again. - if (!empty($this->username) && !$login_ok) { - $this->log('Incorrect login.', AUTH_LOG_INFO); - $this->status = AUTH_WRONG_LOGIN; - if (is_callable($this->loginFailedCallback)) { - $this->log('Calling loginFailedCallback ('.$this->loginFailedCallback.').', AUTH_LOG_DEBUG); - call_user_func_array($this->loginFailedCallback, array($this->username, &$this)); - } - } - - if ((empty($this->username) || !$login_ok) && $this->showLogin) { - $this->log('Rendering Login Form.', AUTH_LOG_INFO); - if (is_callable($this->loginFunction)) { - $this->log('Calling loginFunction ('.$this->loginFunction.').', AUTH_LOG_DEBUG); - call_user_func_array($this->loginFunction, array($this->username, $this->status, &$this)); - } else { - // BC fix Auth used to use drawLogin for this - // call is sub classes implement this - if (is_callable(array($this, 'drawLogin'))) { - $this->log('Calling Auth::drawLogin()', AUTH_LOG_DEBUG); - return $this->drawLogin($this->username, $this); - } - - $this->log('Using default Auth_Frontend_Html', AUTH_LOG_DEBUG); - - // New Login form - include_once 'Auth/Frontend/Html.php'; - return Auth_Frontend_Html::render($this, $this->username); - } - } else { - return; - } - } - - // }}} - // {{{ setExpire() - - /** - * Set the maximum expire time - * - * @param integer time in seconds - * @param bool add time to current expire time or not - * @return void - * @access public - */ - function setExpire($time, $add = false) - { - $add ? $this->expire += $time : $this->expire = $time; - } - - // }}} - // {{{ setIdle() - - /** - * Set the maximum idle time - * - * @param integer time in seconds - * @param bool add time to current maximum idle time or not - * @return void - * @access public - */ - function setIdle($time, $add = false) - { - $add ? $this->idle += $time : $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. - * This will chnage the name of the session variable - * auth uses to store it's data in the session - * - * @param string New name for the session - * @return void - * @access public - */ - function setSessionName($name = 'session') - { - $this->_sessionName = '_auth_'.$name; - // Make Sure Auth session variable is there - if(!isset($_SESSION[$this->_sessionName])) { - $_SESSION[$this->_sessionName] = array(); - } - $this->session =& $_SESSION[$this->_sessionName]; - } - - // }}} - // {{{ setShowLogin() - - /** - * Should the login form be displayed if neccessary? - * - * @param bool show login form or not - * @return void - * @access public - */ - function setShowLogin($showLogin = true) - { - $this->showLogin = $showLogin; - } - - // }}} - // {{{ setAllowLogin() - - /** - * Should the login form be displayed if neccessary? - * - * @param bool show login form or not - * @return void - * @access public - */ - function setAllowLogin($allowLogin = true) - { - $this->allowLogin = $allowLogin; - } - - // }}} - // {{{ setCheckAuthCallback() - - /** - * Register a callback function to be called whenever the validity of the login is checked - * The function will receive two parameters, the username and a reference to the auth object. - * - * @param string callback function name - * @return void - * @access public - * @since Method available since Release 1.4.3 - */ - function setCheckAuthCallback($checkAuthCallback) - { - $this->checkAuthCallback = $checkAuthCallback; - } - - // }}} - // {{{ setLoginCallback() - - /** - * Register a callback function to be called on user login. - * The function will receive two parameters, the username and a reference to the auth object. - * - * @param string callback function name - * @return void - * @see setLogoutCallback() - * @access public - */ - function setLoginCallback($loginCallback) - { - $this->loginCallback = $loginCallback; - } - - // }}} - // {{{ setFailedLoginCallback() - - /** - * Register a callback function to be called on failed user login. - * The function will receive two parameters, the username and a reference to the auth object. - * - * @param string callback function name - * @return void - * @access public - */ - function setFailedLoginCallback($loginFailedCallback) - { - $this->loginFailedCallback = $loginFailedCallback; - } - - // }}} - // {{{ setLogoutCallback() - - /** - * Register a callback function to be called on user logout. - * The function will receive three parameters, the username and a reference to the auth object. - * - * @param string callback function name - * @return void - * @see setLoginCallback() - * @access public - */ - function setLogoutCallback($logoutCallback) - { - $this->logoutCallback = $logoutCallback; - } - - // }}} - // {{{ setAuthData() - - /** - * Register additional information that is to be stored - * in the session. - * - * @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 - * @access public - */ - function setAuthData($name, $value, $overwrite = true) - { - if (!empty($this->session['data'][$name]) && $overwrite == false) { - return; - } - $this->session['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. - * - * @param string Name of the data field - * @return mixed Value of the data field. - * @access public - */ - function getAuthData($name = null) - { - if (!isset($this->session['data'])) { - return null; - } - if(!isset($name)) { - return $this->session['data']; - } - if (isset($name) && isset($this->session['data'][$name])) { - return $this->session['data'][$name]; - } - return null; - } - - // }}} - // {{{ setAuth() - - /** - * Register variable in a session telling that the user - * has logged in successfully - * - * @param string Username - * @return void - * @access public - */ - function setAuth($username) - { - $this->log('Auth::setAuth() called.', AUTH_LOG_DEBUG); - - // #10729 - Regenerate session id here only if generating at login only - // Don't do it if we are regenerating on every request so we don't - // regenerate it twice in one request. - if (!$this->regenerateSessionId) { - // #2021 - Change the session id to avoid session fixation attacks php 4.3.3 > - session_regenerate_id(true); - } - - if (!isset($this->session) || !is_array($this->session)) { - $this->session = array(); - } - - if (!isset($this->session['data'])) { - $this->session['data'] = array(); - } - - $this->session['sessionip'] = isset($this->server['REMOTE_ADDR']) - ? $this->server['REMOTE_ADDR'] - : ''; - $this->session['sessionuseragent'] = isset($this->server['HTTP_USER_AGENT']) - ? $this->server['HTTP_USER_AGENT'] - : ''; - $this->session['sessionforwardedfor'] = isset($this->server['HTTP_X_FORWARDED_FOR']) - ? $this->server['HTTP_X_FORWARDED_FOR'] - : ''; - - // This should be set by the container to something more safe - // Like md5(passwd.microtime) - if(empty($this->session['challengekey'])) { - $this->session['challengekey'] = md5($username.microtime()); - } - - $this->session['challengecookie'] = md5($this->session['challengekey'].microtime()); - setcookie('authchallenge', $this->session['challengecookie']); - - $this->session['registered'] = true; - $this->session['username'] = $username; - $this->session['timestamp'] = time(); - $this->session['idle'] = time(); - } - - // }}} - // {{{ setAdvancedSecurity() - - /** - * Enables advanced security checks - * - * Currently only ip change and useragent change - * are detected - * @todo Add challenge cookies - Create a cookie which changes every time - * and contains some challenge key which the server can verify with - * a session var cookie might need to be crypted (user pass) - * @param bool Enable or disable - * @return void - * @access public - */ - function setAdvancedSecurity($flag=true) - { - $this->advancedsecurity = $flag; - } - - // }}} - // {{{ checkAuth() - - /** - * Checks if there is a session with valid auth information. - * - * @access public - * @return boolean Whether or not the user is authenticated. - */ - function checkAuth() - { - $this->log('Auth::checkAuth() called.', AUTH_LOG_DEBUG); - $this->authChecks++; - if (isset($this->session)) { - // Check if authentication session is expired - if ( $this->expire > 0 - && isset($this->session['timestamp']) - && ($this->session['timestamp'] + $this->expire) < time()) { - $this->log('Session Expired', AUTH_LOG_INFO); - $this->expired = true; - $this->status = AUTH_EXPIRED; - $this->logout(); - return false; - } - - // Check if maximum idle time is reached - if ( $this->idle > 0 - && isset($this->session['idle']) - && ($this->session['idle'] + $this->idle) < time()) { - $this->log('Session Idle Time Reached', AUTH_LOG_INFO); - $this->idled = true; - $this->status = AUTH_IDLED; - $this->logout(); - return false; - } - - if ( isset($this->session['registered']) - && isset($this->session['username']) - && $this->session['registered'] == true - && $this->session['username'] != '') { - Auth::updateIdle(); - - if ($this->advancedsecurity) { - $this->log('Advanced Security Mode Enabled.', AUTH_LOG_DEBUG); - - // Only Generate the challenge once - if($this->authChecks == 1) { - $this->log('Generating new Challenge Cookie.', AUTH_LOG_DEBUG); - $this->session['challengecookieold'] = $this->session['challengecookie']; - $this->session['challengecookie'] = md5($this->session['challengekey'].microtime()); - setcookie('authchallenge', $this->session['challengecookie']); - } - - // Check for ip change - if ( isset($this->server['REMOTE_ADDR']) - && $this->session['sessionip'] != $this->server['REMOTE_ADDR']) { - $this->log('Security Breach. Remote IP Address changed.', AUTH_LOG_INFO); - // Check if the IP of the user has changed, if so we - // assume a man in the middle attack and log him out - $this->expired = true; - $this->status = AUTH_SECURITY_BREACH; - $this->logout(); - return false; - } - - // Check for ip change (if connected via proxy) - if ( isset($this->server['HTTP_X_FORWARDED_FOR']) - && $this->session['sessionforwardedfor'] != $this->server['HTTP_X_FORWARDED_FOR']) { - $this->log('Security Breach. Forwarded For IP Address changed.', AUTH_LOG_INFO); - // Check if the IP of the user connecting via proxy has - // changed, if so we assume a man in the middle attack - // and log him out. - $this->expired = true; - $this->status = AUTH_SECURITY_BREACH; - $this->logout(); - return false; - } - - // Check for useragent change - if ( isset($this->server['HTTP_USER_AGENT']) - && $this->session['sessionuseragent'] != $this->server['HTTP_USER_AGENT']) { - $this->log('Security Breach. User Agent changed.', AUTH_LOG_INFO); - // Check if the User-Agent of the user has changed, if - // so we assume a man in the middle attack and log him out - $this->expired = true; - $this->status = AUTH_SECURITY_BREACH; - $this->logout(); - return false; - } - - // Check challenge cookie here, if challengecookieold is not set - // this is the first time and check is skipped - // TODO when user open two pages similtaneuly (open in new window,open - // in tab) auth breach is caused find out a way around that if possible - if ( isset($this->session['challengecookieold']) - && $this->session['challengecookieold'] != $this->cookie['authchallenge']) { - $this->log('Security Breach. Challenge Cookie mismatch.', AUTH_LOG_INFO); - $this->expired = true; - $this->status = AUTH_SECURITY_BREACH; - $this->logout(); - $this->login(); - return false; - } - } - - if (is_callable($this->checkAuthCallback)) { - $this->log('Calling checkAuthCallback ('.$this->checkAuthCallback.').', AUTH_LOG_DEBUG); - $checkCallback = call_user_func_array($this->checkAuthCallback, array($this->username, &$this)); - if ($checkCallback == false) { - $this->log('checkAuthCallback failed.', AUTH_LOG_INFO); - $this->expired = true; - $this->status = AUTH_CALLBACK_ABORT; - $this->logout(); - return false; - } - } - - $this->log('Session OK.', AUTH_LOG_INFO); - return true; - } - } - $this->log('Unable to locate session storage.', AUTH_LOG_DEBUG); - return false; - } - - // }}} - // {{{ staticCheckAuth() [static] - - /** - * Statically checks if there is a session with valid auth information. - * - * @access public - * @see checkAuth - * @return boolean Whether or not the user is authenticated. - * @static - */ - function staticCheckAuth($options = null) - { - static $staticAuth; - if(!isset($staticAuth)) { - $staticAuth = new Auth('null', $options); - } - $staticAuth->log('Auth::staticCheckAuth() called', AUTH_LOG_DEBUG); - return $staticAuth->checkAuth(); - } - - // }}} - // {{{ getAuth() - - /** - * Has the user been authenticated? - * - * @access public - * @return bool True if the user is logged in, otherwise false. - */ - function getAuth() - { - $this->log('Auth::getAuth() called.', AUTH_LOG_DEBUG); - return $this->checkAuth(); - } - - // }}} - // {{{ 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() - { - $this->log('Auth::logout() called.', AUTH_LOG_DEBUG); - - if (is_callable($this->logoutCallback) && isset($this->session['username'])) { - $this->log('Calling logoutCallback ('.$this->logoutCallback.').', AUTH_LOG_DEBUG); - call_user_func_array($this->logoutCallback, array($this->session['username'], &$this)); - } - - $this->username = ''; - $this->password = ''; - - $this->session = null; - } - - // }}} - // {{{ updateIdle() - - /** - * Update the idletime - * - * @access private - * @return void - */ - function updateIdle() - { - $this->session['idle'] = time(); - } - - // }}} - // {{{ getUsername() - - /** - * Get the username - * - * @return string - * @access public - */ - function getUsername() - { - if (isset($this->session['username'])) { - return($this->session['username']); - } - return(''); - } - - // }}} - // {{{ getStatus() - - /** - * Get the current status - * - * @return string - * @access public - */ - function getStatus() - { - return $this->status; - } - - // }}} - // {{{ getPostUsernameField() - - /** - * Gets the post varible used for the username - * - * @return string - * @access public - */ - function getPostUsernameField() - { - return($this->_postUsername); - } - - // }}} - // {{{ getPostPasswordField() - - /** - * Gets the post varible used for the username - * - * @return string - * @access public - */ - function getPostPasswordField() - { - return($this->_postPassword); - } - - // }}} - // {{{ sessionValidThru() - - /** - * Returns the time up to the session is valid - * - * @access public - * @return integer - */ - function sessionValidThru() - { - if (!isset($this->session['idle'])) { - return 0; - } - if ($this->idle == 0) { - return 0; - } - return ($this->session['idle'] + $this->idle); - } - - // }}} - // {{{ listUsers() - - /** - * List all users that are currently available in the storage - * container - * - * @access public - * @return array - */ - function listUsers() - { - $this->log('Auth::listUsers() called.', AUTH_LOG_DEBUG); - $this->_loadStorage(); - 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 = '') - { - $this->log('Auth::addUser() called.', AUTH_LOG_DEBUG); - $this->_loadStorage(); - 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) - { - $this->log('Auth::removeUser() called.', AUTH_LOG_DEBUG); - $this->_loadStorage(); - return $this->storage->removeUser($username); - } - - // }}} - // {{{ changePassword() - - /** - * Change password for user in the storage container - * - * @access public - * @param string Username - * @param string The new password - * @return mixed True on success, PEAR error object on error - * and AUTH_METHOD_NOT_SUPPORTED otherwise. - */ - function changePassword($username, $password) - { - $this->log('Auth::changePassword() called', AUTH_LOG_DEBUG); - $this->_loadStorage(); - return $this->storage->changePassword($username, $password); - } - - // }}} - // {{{ log() - - /** - * Log a message from the Auth system - * - * @access public - * @param string The message to log - * @param string The log level to log the message under. See the Log documentation for more info. - * @return boolean - */ - function log($message, $level = AUTH_LOG_DEBUG) - { - if (!$this->enableLogging) return false; - - $this->_loadLogger(); - - $this->logger->log('AUTH: '.$message, $level); - } - - // }}} - // {{{ _loadLogger() - - /** - * Load Log object if not already loaded - * - * Suspend logger instantiation to make Auth lighter to use - * for calls which do not require logging - * - * @return bool True if the logger is loaded, false if the logger - * is already loaded - * @access private - */ - function _loadLogger() - { - if(is_null($this->logger)) { - if (!class_exists('Log')) { - include_once 'Log.php'; - } - $this->logger =& Log::singleton('null', - null, - 'auth['.getmypid().']', - array(), - AUTH_LOG_DEBUG); - return(true); - } - return(false); - } - - // }}} - // {{{ attachLogObserver() - - /** - * Attach an Observer to the Auth Log Source - * - * @param object Log_Observer A Log Observer instance - * @return boolean - */ - function attachLogObserver(&$observer) { - - $this->_loadLogger(); - - return $this->logger->attach($observer); - - } - - // }}} - -} -?> diff --git a/glmPEAR/Auth/Anonymous.php b/glmPEAR/Auth/Anonymous.php deleted file mode 100755 index a549204..0000000 --- a/glmPEAR/Auth/Anonymous.php +++ /dev/null @@ -1,138 +0,0 @@ - - * @author Adam Ashley - * @copyright 2001-2006 The PHP Group - * @license http://www.php.net/license/3_01.txt PHP License 3.01 - * @version CVS: $Id: Anonymous.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ - * @link http://pear.php.net/package/Auth - * @since File available since Release 1.3.0 - */ - -/** - * Include Auth package - */ -require_once 'Auth.php'; - -/** - * Anonymous Authentication - * - * This class provides anonymous authentication if username and password - * were not supplied - * - * @category Authentication - * @package Auth - * @author Yavor Shahpasov - * @author Adam Ashley - * @copyright 2001-2006 The PHP Group - * @license http://www.php.net/license/3_01.txt PHP License 3.01 - * @version Release: 1.5.4 File: $Revision: 1.1.1.1 $ - * @link http://pear.php.net/package/Auth - * @since Class available since Release 1.3.0 - */ -class Auth_Anonymous extends Auth -{ - - // {{{ properties - - /** - * Whether to allow anonymous authentication - * - * @var boolean - */ - var $allow_anonymous = true; - - /** - * Username to use for anonymous user - * - * @var string - */ - var $anonymous_username = 'anonymous'; - - // }}} - // {{{ Auth_Anonymous() [constructor] - - /** - * Pass all parameters to Parent Auth class - * - * 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 - * @see Auth::Auth() - */ - function Auth_Anonymous($storageDriver, $options = '', $loginFunction = '', $showLogin = true) { - parent::Auth($storageDriver, $options, $loginFunction, $showLogin); - } - - // }}} - // {{{ login() - - /** - * Login function - * - * If no username & password is passed then login as the username - * provided in $this->anonymous_username else call standard login() - * function. - * - * @return void - * @access private - * @see Auth::login() - */ - function login() { - if ( $this->allow_anonymous - && empty($this->username) - && empty($this->password) ) { - $this->setAuth($this->anonymous_username); - if (is_callable($this->loginCallback)) { - call_user_func_array($this->loginCallback, array($this->username, $this) ); - } - } else { - // Call normal login system - parent::login(); - } - } - - // }}} - // {{{ forceLogin() - - /** - * Force the user to login - * - * Calling this function forces the user to provide a real username and - * password before continuing. - * - * @return void - */ - function forceLogin() { - $this->allow_anonymous = false; - if( !empty($this->session['username']) && $this->session['username'] == $this->anonymous_username ) { - $this->logout(); - } - } - - // }}} - -} - -?> diff --git a/glmPEAR/Auth/Auth.php b/glmPEAR/Auth/Auth.php deleted file mode 100755 index e1a02e9..0000000 --- a/glmPEAR/Auth/Auth.php +++ /dev/null @@ -1,30 +0,0 @@ - - * @copyright 2001-2006 The PHP Group - * @license http://www.php.net/license/3_01.txt PHP License 3.01 - * @version CVS: $Id: Auth.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ - * @link http://pear.php.net/package/Auth - * @deprecated File deprecated since Release 1.2.0 - */ - -/** - * Include Auth package - */ -require_once 'Auth.php'; - -?> diff --git a/glmPEAR/Auth/Common.php b/glmPEAR/Auth/Common.php deleted file mode 100755 index 2c3114b..0000000 --- a/glmPEAR/Auth/Common.php +++ /dev/null @@ -1,331 +0,0 @@ - - * @author Helgi Þormar Þorbjörnsson - * @author Lukas Smith - * @author Arnaud Limbourg - * @author Christian Dickmann - * @author Matt Scifo - * @author Bjoern Kraus - * @copyright 2002-2006 Markus Wolff - * @license http://www.gnu.org/licenses/lgpl.txt - * @version CVS: $Id: Common.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ - * @link http://pear.php.net/LiveUser_Admin - */ - -/** - * Base class for authentication backends. - * - * @category authentication - * @package LiveUser_Admin - * @author Lukas Smith - * @copyright 2002-2006 Markus Wolff - * @license http://www.gnu.org/licenses/lgpl.txt - * @version Release: @package_version@ - * @link http://pear.php.net/LiveUser_Admin - */ -class LiveUser_Admin_Auth_Common -{ - /** - * Error stack - * - * @var object PEAR_ErrorStack - * @access public - */ - var $stack = null; - - /** - * Storage Container - * - * @var LiveUser_Admin_Storage - * @access private - */ - var $_storage = null; - - /** - * Key (method names), with array lists of selectable tables for the given method - * - * @var array - * @access public - */ - var $selectable_tables = array( - 'getUsers' => array('users'), - ); - - /** - * Set posible encryption modes. - * - * @access private - * @var array - */ - var $encryptionModes = array( - 'MD5' => 'MD5', - 'RC4' => 'RC4', - 'PLAIN' => 'PLAIN', - 'SHA1' => 'SHA1' - ); - - /** - * Defines the algorithm used for encrypting/decrypting - * passwords. Default: "MD5". - * - * @access private - * @var string - */ - var $passwordEncryptionMode = 'MD5'; - - /** - * Defines the secret to use for encryption if needed - * - * @access protected - * @var string - */ - var $secret; - - /** - * The name associated with this auth container. The name is used - * when adding users from this container to the reference table - * in the permission container. This way it is possible to see - * from which auth container the user data is coming from. - * - * @var string - * @access public - */ - var $containerName = null; - - /** - * Class constructor. Feel free to override in backend subclasses. - * - * @access protected - */ - function LiveUser_Admin_Auth_Common() - { - $this->stack = &PEAR_ErrorStack::singleton('LiveUser_Admin'); - } - - /** - * Initialize the storage container - * - * @access public - * @param array contains configuration of the container - * @param string name of container - * @return bool true on success or false on failure - */ - function init(&$conf, $containerName) - { - $this->containerName = $containerName; - if (!array_key_exists('storage', $conf)) { - $this->stack->push(LIVEUSER_ADMIN_ERROR, 'exception', - array('msg' => 'Missing storage configuration array')); - return false; - } - - if (is_array($conf)) { - $keys = array_keys($conf); - foreach ($keys as $key) { - if (isset($this->$key)) { - $this->$key =& $conf[$key]; - } - } - } - - $storageConf = array(); - $storageConf[$conf['type']] =& $conf['storage']; - $this->_storage = LiveUser::storageFactory($storageConf, 'LiveUser_Admin_Auth_'); - if ($this->_storage === false) { - $this->stack->push(LIVEUSER_ADMIN_ERROR, 'exception', - array('msg' => 'Could not instanciate auth storage container: '.$conf['type'])); - return false; - } - - return true; - } - - /** - * Decrypts a password so that it can be compared with the user input. - * Uses the algorithm defined in the passwordEncryptionMode property. - * - * @param string the encrypted password - * @return string the decrypted password - * - * @access public - */ - function decryptPW($encryptedPW) - { - return LiveUser::decryptPW($encryptedPW, $this->passwordEncryptionMode, $this->secret); - } - - /** - * Encrypts a password for storage in a backend container. - * Uses the algorithm defined in the passwordEncryptionMode property. - * - * @param string encryption type - * @return string the encrypted password - * - * @access public - */ - function encryptPW($plainPW) - { - return LiveUser::encryptPW($plainPW, $this->passwordEncryptionMode, $this->secret); - } - - /** - * Add a user - * - * @param array containing atleast the key-value-pairs of all required - * columns in the users table - * @return int|bool false on error, true (or new id) on success - * - * @access public - */ - function addUser($data) - { - // todo: does this work? - if (array_key_exists('passwd', $data)) { - $data['passwd'] = $this->encryptPW($data['passwd']); - } - $result = $this->_storage->insert('users', $data); - // todo: notify observer - return $result; - } - - /** - * Update a user - * - * @param array containing the key value pairs of columns to update - * @param array key values pairs (value may be a string or an array) - * This will construct the WHERE clause of your update - * Be careful, if you leave this blank no WHERE clause - * will be used and all users will be affected by the update - * @return int|bool false on error, the affected rows on success - * - * @access public - */ - function updateUser($data, $filters) - { - if (array_key_exists('passwd', $data)) { - $data['passwd'] = $this->encryptPW($data['passwd']); - } - $result = $this->_storage->update('users', $data, $filters); - // todo: notify observer - return $result; - } - - /** - * Remove a user - * - * @param array key values pairs (value may be a string or an array) - * This will construct the WHERE clause of your update - * Be careful, if you leave this blank no WHERE clause - * will be used and all users will be affected by the update - * @return int|bool false on error, the affected rows on success - * - * @access public - */ - function removeUser($filters) - { - $result = $this->_storage->delete('users', $filters); - // todo: notify observer - return $result; - } - - /** - * Fetches users - * - * @param array containing key-value pairs for: - * 'fields' - ordered array containing the fields to fetch - * if empty all fields from the user table are fetched - * 'filters' - key values pairs (value may be a string or an array) - * 'orders' - key value pairs (values 'ASC' or 'DESC') - * 'rekey' - if set to true, returned array will have the - * first column as its first dimension - * 'group' - if set to true and $rekey is set to true, then - * all values with the same first column will be - * wrapped in an array - * 'limit' - number of rows to select - * 'offset' - first row to select - * 'select' - determines what query method to use: - * 'one' -> queryOne, 'row' -> queryRow, - * 'col' -> queryCol, 'all' ->queryAll (default) - * 'selectable_tables' - array list of tables that may be - * joined to in this query, the first element is - * the root table from which the joins are done - * @return bool|array false on failure or array with selected data - * - * @access public - */ - function getUsers($params = array()) - { - $selectable_tables = array(); - if (array_key_exists('selectable_tables', $params)) { - $selectable_tables = $params['selectable_tables']; - } elseif (array_key_exists('getUsers', $this->selectable_tables)) { - $selectable_tables = $this->selectable_tables['getUsers']; - } - $root_table = reset($selectable_tables); - - $params = LiveUser_Admin_Storage::setSelectDefaultParams($params); - - return $this->_storage->select($params['select'], $params['fields'], - $params['filters'], $params['orders'], $params['rekey'], $params['group'], - $params['limit'], $params['offset'], $root_table, $selectable_tables); - } - - /** - * properly disconnect from resources - * - * @access public - */ - function disconnect() - { - $this->_storage->disconnect(); - } -} diff --git a/glmPEAR/Auth/Controller.php b/glmPEAR/Auth/Controller.php deleted file mode 100755 index 43392c4..0000000 --- a/glmPEAR/Auth/Controller.php +++ /dev/null @@ -1,302 +0,0 @@ - - * @author Adam Ashley - * @copyright 2001-2006 The PHP Group - * @license http://www.php.net/license/3_01.txt PHP License 3.01 - * @version CVS: $Id: Controller.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ - * @link http://pear.php.net/package/Auth - * @since File available since Release 1.3.0 - */ - -/** - * Controlls access to a group of php access - * and redirects to a predefined login page as - * needed - * - * In all pages - * - * include_once('Auth.php'); - * include_once('Auth/Controller.php'); - * $_auth = new Auth('File', 'passwd'); - * $authController = new Auth_Controller($_auth, 'login.php', 'index.php'); - * $authController->start(); - * - * - * In login.php - * - * include_once('Auth.php'); - * include_once('Auth/Controller.php'); - * $_auth = new Auth('File', 'passwd'); - * $authController = new Auth_Controller($_auth, 'login.php', 'index.php'); - * $authController->start(); - * if( $authController->isAuthorised() ){ - * $authController->redirectBack(); - * } - * - * - * @category Authentication - * @author Yavor Shahpasov - * @author Adam Ashley - * @copyright 2001-2006 The PHP Group - * @license http://www.php.net/license/3_01.txt PHP License 3.01 - * @version Release: 1.5.4 File: $Revision: 1.1.1.1 $ - * @link http://pear.php.net/package/Auth - * @since Class available since Release 1.3.0 - */ -class Auth_Controller -{ - - // {{{ properties - - /** - * The Auth instance this controller is managing - * - * @var object Auth - */ - var $auth = null; - - /** - * The login URL - * @var string - * */ - var $login = null; - - /** - * The default index page to use when the caller page is not set - * - * @var string - */ - var $default = null; - - /** - * If this is set to true after a succesfull login the - * Auth_Controller::redirectBack() is invoked automatically - * - * @var boolean - */ - var $autoRedirectBack = false; - - // }}} - // {{{ Auth_Controller() [constructor] - - /** - * Constructor - * - * @param Auth An auth instance - * @param string The login page - * @param string The default page to go to if return page is not set - * @param array Some rules about which urls need to be sent to the login page - * @return void - * @todo Add a list of urls which need redirection - */ - function Auth_Controller(&$auth_obj, $login='login.php', $default='index.php', $accessList=array()) - { - $this->auth =& $auth_obj; - $this->_loginPage = $login; - $this->_defaultPage = $default; - @session_start(); - if (!empty($_GET['return']) && $_GET['return'] && !strstr($_GET['return'], $this->_loginPage)) { - $this->auth->setAuthData('returnUrl', $_GET['return']); - } - - if(!empty($_GET['authstatus']) && $this->auth->status == '') { - $this->auth->status = $_GET['authstatus']; - } - } - - // }}} - // {{{ setAutoRedirectBack() - - /** - * Enables auto redirection when login is done - * - * @param bool Sets the autoRedirectBack flag to this - * @see Auth_Controller::autoRedirectBack - * @return void - */ - function setAutoRedirectBack($flag = true) - { - $this->autoRedirectBack = $flag; - } - - // }}} - // {{{ redirectBack() - - /** - * Redirects Back to the calling page - * - * @return void - */ - function redirectBack() - { - // If redirectback go there - // else go to the default page - - $returnUrl = $this->auth->getAuthData('returnUrl'); - if(!$returnUrl) { - $returnUrl = $this->_defaultPage; - } - - // Add some entropy to the return to make it unique - // avoind problems with cached pages and proxies - if(strpos($returnUrl, '?') === false) { - $returnUrl .= '?'; - } - $returnUrl .= uniqid(''); - - // Track the auth status - if($this->auth->status != '') { - $url .= '&authstatus='.$this->auth->status; - } - header('Location:'.$returnUrl); - print("You could not be redirected to $returnUrl"); - } - - // }}} - // {{{ redirectLogin() - - /** - * Redirects to the login Page if not authorised - * - * put return page on the query or in auth - * - * @return void - */ - function redirectLogin() - { - // Go to the login Page - - // For Auth, put some check to avoid infinite redirects, this should at least exclude - // the login page - - $url = $this->_loginPage; - if(strpos($url, '?') === false) { - $url .= '?'; - } - - if(!strstr($_SERVER['PHP_SELF'], $this->_loginPage)) { - $url .= 'return='.urlencode($_SERVER['PHP_SELF']); - } - - // Track the auth status - if($this->auth->status != '') { - $url .= '&authstatus='.$this->auth->status; - } - - header('Location:'.$url); - print("You could not be redirected to $url"); - } - - // }}} - // {{{ start() - - /** - * Starts the Auth Procedure - * - * If the page requires login the user is redirected to the login page - * otherwise the Auth::start is called to initialize Auth - * - * @return void - * @todo Implement an access list which specifies which urls/pages need login and which do not - */ - function start() - { - // Check the accessList here - // ACL should be a list of urls with allow/deny - // If allow set allowLogin to false - // Some wild card matching should be implemented ?,* - if(!strstr($_SERVER['PHP_SELF'], $this->_loginPage) && !$this->auth->checkAuth()) { - $this->redirectLogin(); - } else { - $this->auth->start(); - // Logged on and on login page - if(strstr($_SERVER['PHP_SELF'], $this->_loginPage) && $this->auth->checkAuth()){ - $this->autoRedirectBack ? - $this->redirectBack() : - null ; - } - } - - - } - - // }}} - // {{{ isAuthorised() - - /** - * Checks is the user is logged on - * @see Auth::checkAuth() - */ - function isAuthorised() - { - return($this->auth->checkAuth()); - } - - // }}} - // {{{ checkAuth() - - /** - * Proxy call to auth - * @see Auth::checkAuth() - */ - function checkAuth() - { - return($this->auth->checkAuth()); - } - - // }}} - // {{{ logout() - - /** - * Proxy call to auth - * @see Auth::logout() - */ - function logout() - { - return($this->auth->logout()); - } - - // }}} - // {{{ getUsername() - - /** - * Proxy call to auth - * @see Auth::getUsername() - */ - function getUsername() - { - return($this->auth->getUsername()); - } - - // }}} - // {{{ getStatus() - - /** - * Proxy call to auth - * @see Auth::getStatus() - */ - function getStatus() - { - return($this->auth->getStatus()); - } - - // }}} - -} - -?> diff --git a/glmPEAR/Auth/DB.php b/glmPEAR/Auth/DB.php deleted file mode 100755 index fe26003..0000000 --- a/glmPEAR/Auth/DB.php +++ /dev/null @@ -1,92 +0,0 @@ - - * @author Helgi Þormar Þorbjörnsson - * @author Lukas Smith - * @author Arnaud Limbourg - * @author Christian Dickmann - * @author Matt Scifo - * @author Bjoern Kraus - * @copyright 2002-2006 Markus Wolff - * @license http://www.gnu.org/licenses/lgpl.txt - * @version CVS: $Id: DB.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ - * @link http://pear.php.net/LiveUser_Admin - */ - -/** - * DB admin container for maintaining Auth/DB - * - * @package LiveUser - * @category authentication - */ - -/** - * Require parent class definition and PEAR::DB class. - */ -require_once 'LiveUser/Admin/Auth/Common.php'; - -/** - * This is a PEAR::DB backend container driver for the LiveUser Admin auth class. - * It does not contain any logic and simply extends the common driver - * - * @category authentication - * @package LiveUser_Admin - * @author Bjoern Kraus - * @author Lukas Smith - * @copyright 2002-2006 Markus Wolff - * @license http://www.gnu.org/licenses/lgpl.txt - * @version Release: @package_version@ - * @link http://pear.php.net/LiveUser_Admin - */ -class LiveUser_Admin_Auth_DB extends LiveUser_Admin_Auth_Common -{ -} -?> diff --git a/glmPEAR/Auth/MDB.php b/glmPEAR/Auth/MDB.php deleted file mode 100755 index ecd5da0..0000000 --- a/glmPEAR/Auth/MDB.php +++ /dev/null @@ -1,90 +0,0 @@ - - * @author Helgi Þormar Þorbjörnsson - * @author Lukas Smith - * @author Arnaud Limbourg - * @author Christian Dickmann - * @author Matt Scifo - * @author Bjoern Kraus - * @copyright 2002-2006 Markus Wolff - * @license http://www.gnu.org/licenses/lgpl.txt - * @version CVS: $Id: MDB.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ - * @link http://pear.php.net/LiveUser_Admin - */ -/** - * MDB admin container for maintaining Auth/MDB - * - * @package LiveUser - * @category authentication - */ - -/** - * Require parent class definition and PEAR::MDB class. - */ -require_once 'LiveUser/Admin/Auth/Common.php'; - -/** - * This is a PEAR::MDB backend container driver for the LiveUser Admin auth class. - * It does not contain any logic and simply extends the common driver - * - * @category authentication - * @package LiveUser_Admin - * @author Lukas Smith - * @copyright 2002-2006 Markus Wolff - * @license http://www.gnu.org/licenses/lgpl.txt - * @version Release: @package_version@ - * @link http://pear.php.net/LiveUser_Admin - */ -class LiveUser_Admin_Auth_MDB extends LiveUser_Admin_Auth_Common -{ -} -?> diff --git a/glmPEAR/Auth/MDB2.php b/glmPEAR/Auth/MDB2.php deleted file mode 100755 index 758b953..0000000 --- a/glmPEAR/Auth/MDB2.php +++ /dev/null @@ -1,84 +0,0 @@ - - * @author Helgi Þormar Þorbjörnsson - * @author Lukas Smith - * @author Arnaud Limbourg - * @author Christian Dickmann - * @author Matt Scifo - * @author Bjoern Kraus - * @copyright 2002-2006 Markus Wolff - * @license http://www.gnu.org/licenses/lgpl.txt - * @version CVS: $Id: MDB2.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ - * @link http://pear.php.net/LiveUser_Admin - */ - -/** - * Require parent class definition and PEAR::MDB2 class. - */ -require_once 'LiveUser/Admin/Auth/Common.php'; - -/** - * This is a PEAR::MDB2 backend container driver for the LiveUser Admin auth class. - * It does not contain any logic and simply extends the common driver - * - * @category authentication - * @package LiveUser_Admin - * @author Lukas Smith - * @copyright 2002-2006 Markus Wolff - * @license http://www.gnu.org/licenses/lgpl.txt - * @version Release: @package_version@ - * @link http://pear.php.net/LiveUser_Admin - */ -class LiveUser_Admin_Auth_MDB2 extends LiveUser_Admin_Auth_Common -{ -} -?> diff --git a/glmPEAR/Auth/PDO.php b/glmPEAR/Auth/PDO.php deleted file mode 100755 index 0898d36..0000000 --- a/glmPEAR/Auth/PDO.php +++ /dev/null @@ -1,92 +0,0 @@ - - * @author Helgi Þormar Þorbjörnsson - * @author Lukas Smith - * @author Arnaud Limbourg - * @author Christian Dickmann - * @author Matt Scifo - * @author Bjoern Kraus - * @copyright 2002-2006 Markus Wolff - * @license http://www.gnu.org/licenses/lgpl.txt - * @version CVS: $Id: PDO.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ - * @link http://pear.php.net/LiveUser_Admin - */ - -/** - * PDO admin container for maintaining Auth/PDO - * - * @package LiveUser - * @category authentication - */ - -/** - * Require parent class definition and PEAR::DB class. - */ -require_once 'LiveUser/Admin/Auth/Common.php'; - -/** - * This is a PECL::PDO backend container driver for the LiveUser Admin auth class. - * It does not contain any logic and simply extends the common driver - * - * @category authentication - * @package LiveUser_Admin - * @author Bjoern Kraus - * @author Lukas Smith - * @copyright 2002-2006 Markus Wolff - * @license http://www.gnu.org/licenses/lgpl.txt - * @version Release: @package_version@ - * @link http://pear.php.net/LiveUser_Admin - */ -class LiveUser_Admin_Auth_PDO extends LiveUser_Admin_Auth_Common -{ -} -?> diff --git a/glmPEAR/Auth/PEARAuth.php b/glmPEAR/Auth/PEARAuth.php deleted file mode 100755 index 575eb1a..0000000 --- a/glmPEAR/Auth/PEARAuth.php +++ /dev/null @@ -1,179 +0,0 @@ - - * @author Helgi Þormar Þorbjörnsson - * @author Lukas Smith - * @author Arnaud Limbourg - * @author Pierre-Alain Joye - * @author Bjoern Kraus - * @copyright 2002-2006 Markus Wolff - * @license http://www.gnu.org/licenses/lgpl.txt - * @version CVS: $Id: PEARAuth.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ - * @link http://pear.php.net/LiveUser - */ - -/** - * Require parent class definition and PEAR::Auth class. - */ -require_once 'LiveUser/Auth/Common.php'; -require_once 'Auth.php'; - -/** - * PEAR_Auth container for Authentication - * - * This is a PEAR::Auth backend driver for the LiveUser class. - * The general options to setup the PEAR::Auth class can be passed to the constructor. - * To choose the right auth container and options, you have to set 'container' - * and 'options' respectively in the storage array. - * - * Requirements: - * - File "LiveUser.php" (contains the parent class "LiveUser") - * - PEAR::Auth must be installed in your PEAR directory - * - Array of setup options must be passed to the constructor. - * - * @category authentication - * @package LiveUser - * @author Bjoern Kraus - * @copyright 2002-2006 Markus Wolff - * @license http://www.gnu.org/licenses/lgpl.txt - * @version Release: @package_version@ - * @link http://pear.php.net/LiveUser - */ -class LiveUser_Auth_PEARAuth extends LiveUser_Auth_Common -{ - /** - * Contains the PEAR::Auth object. - * - * @var Auth - * @access private - */ - var $pearAuth = false; - - /** - * Contains name of the auth container - * - * @var string - * @access private - */ - var $container = false; - - /** - * Contains array options - * - * @var array - * @access private - */ - var $options = false; - - /** - * Load the storage container - * - * @param array array containing the configuration. - * @param string name of the container that should be used - * @return bool true on success or false on failure - * - * @access public - */ - function init(&$conf, $containerName) - { - parent::init($conf, $containerName); - - if (!is_a($this->pearAuth, 'auth') && $this->container) { - $pearAuth = &new Auth($this->container, $this->options, '', false); - if (PEAR::isError($pearAuth)) { - $this->stack->push(LIVEUSER_ERROR_INIT_ERROR, 'error', - array('container' => 'could not connect: '.$pearAuth->getMessage(), - 'debug' => $pearAuth->getUserInfo())); - return false; - } - $this->pearAuth =& $pearAuth; - } - - if (!is_a($this->pearAuth, 'auth')) { - $this->stack->push(LIVEUSER_ERROR_INIT_ERROR, 'error', - array('container' => 'storage layer configuration missing')); - return false; - } - - return true; - } - - /** - * Does nothing - * - * @return bool true on success or false on failure - * - * @access private - */ - function _updateUserData() - { - return true; - } - - /** - * Reads user data from the given data source - * Starts and verifies the PEAR::Auth login process - * - * @param string user handle - * @param string user password - * @param bool|int if the user data should be read using the auth user id - * @return bool true on success or false on failure - * - * @access public - */ - function readUserData($handle = '', $passwd = '', $auth_user_id = false) - { - $this->pearAuth->username = ($auth_user_id !== false) ? $auth_user_id : $handle; - $this->pearAuth->password = $passwd; - $this->pearAuth->start(); - - if (!$this->pearAuth->getAuth()) { - return null; - } - - // User was found, read data into class variables and set return value to true - $this->propertyValues['auth_user_id'] = $this->pearAuth->getUsername(); - $this->propertyValues['handle'] = $this->pearAuth->getUsername(); - $this->propertyValues['passwd'] = $this->encryptPW($this->pearAuth->password); - if (!array_key_exists('is_active', $this->tables['users']['fields'])) { - $this->propertyValues['is_active'] = true; - } - if (!array_key_exists('lastlogin', $this->tables['users']['fields'])) { - $this->propertyValues['lastlogin'] = null; - } - return true; - } -} -?> diff --git a/glmPEAR/Auth/Session.php b/glmPEAR/Auth/Session.php deleted file mode 100755 index 3203668..0000000 --- a/glmPEAR/Auth/Session.php +++ /dev/null @@ -1,134 +0,0 @@ - - * @author Helgi Þormar Þorbjörnsson - * @author Lukas Smith - * @author Arnaud Limbourg - * @author Pierre-Alain Joye - * @author Bjoern Kraus - * @copyright 2002-2006 Markus Wolff - * @license http://www.gnu.org/licenses/lgpl.txt - * @version CVS: $Id: Session.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ - * @link http://pear.php.net/LiveUser - */ - -require_once 'LiveUser/Auth/Common.php'; - -/** - * Session based container for Authentication - * - * This is a backend driver for a simple session based anonymous LiveUser class. - * - * Requirements: - * - File "LiveUser.php" (contains the parent class "LiveUser") - * - * @category authentication - * @package LiveUser - * @author Lukas Smith - * @copyright 2002-2006 Markus Wolff - * @license http://www.gnu.org/licenses/lgpl.txt - * @version Release: @package_version@ - * @link http://pear.php.net/LiveUser - */ -class LiveUser_Auth_Session extends LiveUser_Auth_Common -{ - /** - * name of the key containing the Session phrase inside the auth session array - * - * @var string - * @access public - */ - var $sessionKey = 'password'; - - /** - * Load the storage container - * - * @param array array containing the configuration. - * @param string name of the container that should be used - * @return bool true on success or false on failure - * - * @access public - */ - function init(&$conf, $containerName) - { - parent::init($conf, $containerName); - - return true; - } - - /** - * Does nothing - * - * @return bool true on success or false on failure - * - * @access private - */ - function _updateUserData() - { - return true; - } - - /** - * Reads user data from the given data source - * Compares $passwd with a string inside the $_SESSION array - * - * @param string user handle - * @param string user password - * @param bool|int if the user data should be read using the auth user id - * @return bool true on success or false on failure - * - * @access public - */ - function readUserData($handle = '', $passwd = '', $auth_user_id = false) - { - if (!$auth_user_id) { - if (!is_null($this->tables['users']['fields']['passwd'])) { - if (!array_key_exists($this->alias['passwd'], $_SESSION) - || $_SESSION[$this->alias['passwd']] !== $passwd - ) { - return false; - } - } - $this->propertyValues = $this->tables['users']['fields']; - $this->propertyValues['handle'] = $handle; - $this->propertyValues['passwd'] = $passwd; - $this->propertyValues['is_active'] = true; - $this->propertyValues['lastlogin'] = time(); - } - - return true; - } -} -?> \ No newline at end of file diff --git a/glmPEAR/Auth/Storage/DB.php b/glmPEAR/Auth/Storage/DB.php deleted file mode 100755 index 21faea0..0000000 --- a/glmPEAR/Auth/Storage/DB.php +++ /dev/null @@ -1,99 +0,0 @@ - - * @permor Helgi Þormar Þorbjörnsson - * @permor Lukas Smith - * @permor Arnaud Limbourg - * @permor Christian Dickmann - * @permor Matt Scifo - * @permor Bjoern Kraus - * @copyright 2002-2006 Markus Wolff - * @license http://www.gnu.org/licenses/lgpl.txt - * @version CVS: $Id: DB.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ - * @link http://pear.php.net/LiveUser_Admin - */ - -/** - * Require parent class definition. - */ -require_once 'LiveUser/Admin/Storage/DB.php'; - -/** - * This is a PEAR::DB backend storage driver for the LiveUser Admin auth class. - * All it does is read the Globals.php file and the container and database config on - * - * @category authentication - * @package LiveUser_Admin - * @permor Lukas Smith - * @permor Bjoern Kraus - * @copyright 2002-2006 Markus Wolff - * @license http://www.gnu.org/licenses/lgpl.txt - * @version Release: @package_version@ - * @link http://pear.php.net/LiveUser_Admin - */ -class LiveUser_Admin_Auth_Storage_DB extends LiveUser_Admin_Storage_DB -{ - /** - * Initializes database storage container. - * - * @param array Storage Configuration - * @return void - * - * @access public - * @uses LiveUser_Admin_Storage_DB::init - */ - function init(&$storageConf) - { - require_once 'LiveUser/Auth/Storage/Globals.php'; - parent::init($storageConf, $GLOBALS['_LiveUser']['auth']); - } -} -?> diff --git a/glmPEAR/Auth/Storage/Globals.php b/glmPEAR/Auth/Storage/Globals.php deleted file mode 100755 index 4cb9166..0000000 --- a/glmPEAR/Auth/Storage/Globals.php +++ /dev/null @@ -1,81 +0,0 @@ - - * @author Helgi Þormar Þorbjörnsson - * @author Lukas Smith - * @author Arnaud Limbourg - * @author Pierre-Alain Joye - * @author Bjoern Kraus - * @copyright 2002-2006 Markus Wolff - * @license http://www.gnu.org/licenses/lgpl.txt - * @version CVS: $Id: Globals.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ - * @link http://pear.php.net/LiveUser - */ - - -/** - * This file holds all our default table/fields name/types/relations, - * if they should be checked and more which are needed by both - * LiveUser and LiveUser_Admin - * - * You can add to those table or modify options via our table/field - * options in the config. - */ - - -$GLOBALS['_LiveUser']['auth']['tables'] = array( - 'users' => array( - 'fields' => array( - 'auth_user_id' => 'seq', - 'handle' => 'unique', - 'passwd' => true, - ), - ), -); - -$GLOBALS['_LiveUser']['auth']['fields'] = array( - 'auth_user_id' => 'text', - 'handle' => 'text', - 'passwd' => 'text', -); - -$GLOBALS['_LiveUser']['auth']['alias'] = array( - 'auth_user_id' => 'auth_user_id', - 'handle' => 'handle', - 'passwd' => 'passwd', - 'users' => 'users', -); - -?> \ No newline at end of file diff --git a/glmPEAR/Auth/Storage/MDB.php b/glmPEAR/Auth/Storage/MDB.php deleted file mode 100755 index bb21ef4..0000000 --- a/glmPEAR/Auth/Storage/MDB.php +++ /dev/null @@ -1,100 +0,0 @@ - - * @author Helgi Þormar Þorbjörnsson - * @author Lukas Smith - * @author Arnaud Limbourg - * @author Christian Dickmann - * @author Matt Scifo - * @author Bjoern Kraus - * @copyright 2002-2006 Markus Wolff - * @license http://www.gnu.org/licenses/lgpl.txt - * @version CVS: $Id: MDB.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ - * @link http://pear.php.net/LiveUser_Admin - */ - - -/** - * Require parent class definition. - */ -require_once 'LiveUser/Admin/Storage/MDB.php'; - -/** - * This is a PEAR::MDB backend storage driver for the LiveUser Admin auth class. - * All it does is read the Globals.php file and the container and database config on - * - * @category authentication - * @package LiveUser_Admin - * @permor Lukas Smith - * @permor Bjoern Kraus - * @copyright 2002-2006 Markus Wolff - * @license http://www.gnu.org/licenses/lgpl.txt - * @version Release: @package_version@ - * @link http://pear.php.net/LiveUser_Admin - */ -class LiveUser_Admin_Auth_Storage_MDB extends LiveUser_Admin_Storage_MDB -{ - /** - * Initializes database storage container. - * - * @param array Storage Configuration - * @return void - * - * @access public - * @uses LiveUser_Admin_Storage_DB::init - */ - function init(&$storageConf) - { - require_once 'LiveUser/Auth/Storage/Globals.php'; - parent::init($storageConf, $GLOBALS['_LiveUser']['auth']); - } -} -?> diff --git a/glmPEAR/Auth/Storage/MDB2.php b/glmPEAR/Auth/Storage/MDB2.php deleted file mode 100755 index 1085bf7..0000000 --- a/glmPEAR/Auth/Storage/MDB2.php +++ /dev/null @@ -1,100 +0,0 @@ - - * @author Helgi Þormar Þorbjörnsson - * @author Lukas Smith - * @author Arnaud Limbourg - * @author Christian Dickmann - * @author Matt Scifo - * @author Bjoern Kraus - * @copyright 2002-2006 Markus Wolff - * @license http://www.gnu.org/licenses/lgpl.txt - * @version CVS: $Id: MDB2.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ - * @link http://pear.php.net/LiveUser_Admin - */ - - -/** - * Require parent class definition. - */ -require_once 'LiveUser/Admin/Storage/MDB2.php'; - -/** - * This is a PEAR::MDB2 backend storage driver for the LiveUser Admin auth class. - * All it does is read the Globals.php file and the container and database config on - * - * @category authentication - * @package LiveUser_Admin - * @permor Lukas Smith - * @permor Bjoern Kraus - * @copyright 2002-2006 Markus Wolff - * @license http://www.gnu.org/licenses/lgpl.txt - * @version Release: @package_version@ - * @link http://pear.php.net/LiveUser_Admin - */ -class LiveUser_Admin_Auth_Storage_MDB2 extends LiveUser_Admin_Storage_MDB2 -{ - /** - * Initializes database storage container. - * - * @param array Storage Configuration - * @return void - * - * @access public - * @uses LiveUser_Admin_Storage_DB::init - */ - function init(&$storageConf) - { - require_once 'LiveUser/Auth/Storage/Globals.php'; - parent::init($storageConf, $GLOBALS['_LiveUser']['auth']); - } -} -?> diff --git a/glmPEAR/Auth/Storage/PDO.php b/glmPEAR/Auth/Storage/PDO.php deleted file mode 100755 index 39c9205..0000000 --- a/glmPEAR/Auth/Storage/PDO.php +++ /dev/null @@ -1,99 +0,0 @@ - - * @permor Helgi Þormar Þorbjörnsson - * @permor Lukas Smith - * @permor Arnaud Limbourg - * @permor Christian Dickmann - * @permor Matt Scifo - * @permor Bjoern Kraus - * @copyright 2002-2006 Markus Wolff - * @license http://www.gnu.org/licenses/lgpl.txt - * @version CVS: $Id: PDO.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ - * @link http://pear.php.net/LiveUser_Admin - */ - -/** - * Require parent class definition. - */ -require_once 'LiveUser/Admin/Storage/PDO.php'; - -/** - * This is a PECL::PDO backend storage driver for the LiveUser Admin auth class. - * All it does is read the Globals.php file and the container and database config on - * - * @category authentication - * @package LiveUser_Admin - * @permor Lukas Smith - * @permor Bjoern Kraus - * @copyright 2002-2006 Markus Wolff - * @license http://www.gnu.org/licenses/lgpl.txt - * @version Release: @package_version@ - * @link http://pear.php.net/LiveUser_Admin - */ -class LiveUser_Admin_Auth_Storage_PDO extends LiveUser_Admin_Storage_PDO -{ - /** - * Initializes database storage container. - * - * @param array Storage Configuration - * @return void - * - * @access public - * @uses LiveUser_Admin_Storage_PDO::init - */ - function init(&$storageConf) - { - require_once 'LiveUser/Auth/Storage/Globals.php'; - parent::init($storageConf, $GLOBALS['_LiveUser']['auth']); - } -} -?> diff --git a/glmPEAR/Auth/XML.php b/glmPEAR/Auth/XML.php deleted file mode 100755 index e3f1668..0000000 --- a/glmPEAR/Auth/XML.php +++ /dev/null @@ -1,275 +0,0 @@ - - * @author Helgi Þormar Þorbjörnsson - * @author Lukas Smith - * @author Arnaud Limbourg - * @author Pierre-Alain Joye - * @author Bjoern Kraus - * @copyright 2002-2006 Markus Wolff - * @license http://www.gnu.org/licenses/lgpl.txt - * @version CVS: $Id: XML.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ - * @link http://pear.php.net/LiveUser - */ - -/** - * Require parent class definition and XML::Tree class. - */ -require_once 'LiveUser/Auth/Common.php'; -require_once 'XML/Tree.php'; - -/** - * XML driver for authentication - * - * This is a XML backend driver for the LiveUser class. - * - * @category authentication - * @package LiveUser - * @author Björn Kraus - * @copyright 2002-2006 Markus Wolff - * @license http://www.gnu.org/licenses/lgpl.txt - * @version Release: @package_version@ - * @link http://pear.php.net/LiveUser - */ -class LiveUser_Auth_XML extends LiveUser_Auth_Common -{ - /** - * XML file in which the auth data is stored. - * - * @var string - * @access private - */ - var $file = ''; - - /** - * XML::Tree object. - * - * @var XML_Tree - * @access private - */ - var $tree = false; - - /** - * XML::Tree object of the user logged in. - * - * @var XML_Tree - * @access private - * @see readUserData() - */ - var $userObj = null; - - /** - * Load the storage container - * - * @param array array containing the configuration. - * @param string name of the container that should be used - * @return bool true on success or false on failure - * - * @access public - */ - function init(&$conf, $containerName) - { - parent::init($conf, $containerName); - - if (!is_file($this->file)) { - if (!is_file(getenv('DOCUMENT_ROOT') . $this->file)) { - $this->stack->push(LIVEUSER_ERROR_MISSING_DEPS, 'exception', array(), - "Perm initialisation failed. Can't find xml file."); - return false; - } - $this->file = getenv('DOCUMENT_ROOT') . $this->file; - } - - $tree =& new XML_Tree($this->file); - $err =& $tree->getTreeFromFile(); - if (PEAR::isError($err)) { - $this->stack->push(LIVEUSER_ERROR, 'exception', array(), - "Perm initialisation failed. Can't get tree from file"); - return false; - } - $this->tree =& $tree; - - if (!is_a($this->tree, 'xml_tree')) { - $this->stack->push(LIVEUSER_ERROR_INIT_ERROR, 'error', - array('container' => 'storage layer configuration missing')); - return false; - } - - return true; - } - - /** - * Writes current values for user back to the database. - * - * @return bool true on success or false on failure - * - * @access private - */ - function _updateUserData() - { - if (!array_key_exists('lastlogin', $this->tables['users']['fields'])) { - return true; - } - - $index = 0; - foreach ($this->userObj->children as $value) { - if ($value->name == $this->alias['lastlogin']) { - $el =& $this->userObj->getElement(array($index)); - $el->setContent($this->currentLogin); - } - $index++; - } - - $success = false; - do { - if (!is_writable($this->file)) { - $errorMsg = 'Auth freeze failure. Cannot write to the xml file'; - break; - } - $fp = fopen($this->file, 'wb'); - if (!$fp) { - $errorMsg = "Auth freeze failure. Failed to open the xml file."; - break; - } - if (!flock($fp, LOCK_EX)) { - $errorMsg = "Auth freeze failure. Couldn't get an exclusive lock on the file."; - break; - } - if (!fwrite($fp, $this->tree->get())) { - $errorMsg = "Auth freeze failure. Write error when writing back the file."; - break; - } - @fflush($fp); - $success = true; - } while (false); - - @flock($fp, LOCK_UN); - @fclose($fp); - - if (!$success) { - $this->stack->push(LIVEUSER_ERROR, 'exception', - array(), 'Cannot read XML Auth file: '.$errorMsg); - } - - return $success; - } - - /** - * Reads user data from the given data source - * If only $handle is given, it will read the data - * from the first user with that handle and return - * true on success. - * If $handle and $passwd are given, it will try to - * find the first user with both handle and password - * matching and return true on success (this allows - * multiple users having the same handle but different - * passwords - yep, some people want this). - * if only an auth_user_id is passed it will try to read the data based on the id - * If no match is found, false is being returned. - * - * @param string user handle - * @param string user password - * @param bool|int if the user data should be read using the auth user id - * @return bool true on success or false on failure - * - * @access public - */ - function readUserData($handle = '', $passwd = '', $auth_user_id = false) - { - $success = false; - $index = 0; - - foreach ($this->tree->root->children as $user) { - $result = array(); - $names = array_flip($this->alias); - foreach ($user->children as $value) { - if (array_key_exists($value->name, $names)) { - $result[$names[$value->name]] = $value->content; - } - } - - if ($auth_user_id) { - if (array_key_exists('auth_user_id', $result) - && $auth_user_id === $result['auth_user_id'] - ) { - $success = true; - break; - } - } elseif (array_key_exists('handle', $result) && $handle === $result['handle']) { - if (!is_null($this->tables['users']['fields']['passwd'])) { - if (array_key_exists('passwd', $result) - && $this->encryptPW($passwd) === $result['passwd'] - ) { - $success = true; - break; - } elseif (is_string($this->tables['users']['fields']['handle'])) { - // dont look for any further matching handles - break; - } - } else { - $success = true; - break; - } - } - - $index++; - } - - if (!$success) { - return null; - } - - $this->propertyValues = $result; - - $this->userObj =& $this->tree->root->getElement(array($index)); - - return true; - } - - /** - * Properly disconnect from resources - * - * @return bool true on success or false on failure - * - * @access public - */ - function disconnect() - { - $this->tree = false; - $this->userObj = null; - return true; - } -} -?> diff --git a/glmPEAR/Cache/Lite.php b/glmPEAR/Cache/Lite.php deleted file mode 100755 index 89a213e..0000000 --- a/glmPEAR/Cache/Lite.php +++ /dev/null @@ -1,826 +0,0 @@ - -* -* Nota : A chinese documentation (thanks to RainX ) is -* available at : -* http://rainx.phpmore.com/manual/cache_lite.html -* -* @package Cache_Lite -* @category Caching -* @version $Id: Lite.php,v 1.1.1.1 2008/04/28 15:20:46 jamie Exp $ -* @author Fabien MARTY -*/ - -define('CACHE_LITE_ERROR_RETURN', 1); -define('CACHE_LITE_ERROR_DIE', 8); - -class Cache_Lite -{ - - // --- Private properties --- - - /** - * Directory where to put the cache files - * (make sure to add a trailing slash) - * - * @var string $_cacheDir - */ - var $_cacheDir = '/tmp/'; - - /** - * Enable / disable caching - * - * (can be very usefull for the debug of cached scripts) - * - * @var boolean $_caching - */ - var $_caching = true; - - /** - * Cache lifetime (in seconds) - * - * If null, the cache is valid forever. - * - * @var int $_lifeTime - */ - var $_lifeTime = 3600; - - /** - * Enable / disable fileLocking - * - * (can avoid cache corruption under bad circumstances) - * - * @var boolean $_fileLocking - */ - var $_fileLocking = true; - - /** - * Timestamp of the last valid cache - * - * @var int $_refreshTime - */ - var $_refreshTime; - - /** - * File name (with path) - * - * @var string $_file - */ - var $_file; - - /** - * File name (without path) - * - * @var string $_fileName - */ - var $_fileName; - - /** - * Enable / disable write control (the cache is read just after writing to detect corrupt entries) - * - * Enable write control will lightly slow the cache writing but not the cache reading - * Write control can detect some corrupt cache files but maybe it's not a perfect control - * - * @var boolean $_writeControl - */ - var $_writeControl = true; - - /** - * Enable / disable read control - * - * If enabled, a control key is embeded in cache file and this key is compared with the one - * calculated after the reading. - * - * @var boolean $_writeControl - */ - var $_readControl = true; - - /** - * Type of read control (only if read control is enabled) - * - * Available values are : - * 'md5' for a md5 hash control (best but slowest) - * 'crc32' for a crc32 hash control (lightly less safe but faster, better choice) - * 'strlen' for a length only test (fastest) - * - * @var boolean $_readControlType - */ - var $_readControlType = 'crc32'; - - /** - * Pear error mode (when raiseError is called) - * - * (see PEAR doc) - * - * @see setToDebug() - * @var int $_pearErrorMode - */ - var $_pearErrorMode = CACHE_LITE_ERROR_RETURN; - - /** - * Current cache id - * - * @var string $_id - */ - var $_id; - - /** - * Current cache group - * - * @var string $_group - */ - var $_group; - - /** - * Enable / Disable "Memory Caching" - * - * NB : There is no lifetime for memory caching ! - * - * @var boolean $_memoryCaching - */ - var $_memoryCaching = false; - - /** - * Enable / Disable "Only Memory Caching" - * (be carefull, memory caching is "beta quality") - * - * @var boolean $_onlyMemoryCaching - */ - var $_onlyMemoryCaching = false; - - /** - * Memory caching array - * - * @var array $_memoryCachingArray - */ - var $_memoryCachingArray = array(); - - /** - * Memory caching counter - * - * @var int $memoryCachingCounter - */ - var $_memoryCachingCounter = 0; - - /** - * Memory caching limit - * - * @var int $memoryCachingLimit - */ - var $_memoryCachingLimit = 1000; - - /** - * File Name protection - * - * if set to true, you can use any cache id or group name - * if set to false, it can be faster but cache ids and group names - * will be used directly in cache file names so be carefull with - * special characters... - * - * @var boolean $fileNameProtection - */ - var $_fileNameProtection = true; - - /** - * Enable / disable automatic serialization - * - * it can be used to save directly datas which aren't strings - * (but it's slower) - * - * @var boolean $_serialize - */ - var $_automaticSerialization = false; - - /** - * Disable / Tune the automatic cleaning process - * - * The automatic cleaning process destroy too old (for the given life time) - * cache files when a new cache file is written. - * 0 => no automatic cache cleaning - * 1 => systematic cache cleaning - * x (integer) > 1 => automatic cleaning randomly 1 times on x cache write - * - * @var int $_automaticCleaning - */ - var $_automaticCleaningFactor = 0; - - /** - * Nested directory level - * - * Set the hashed directory structure level. 0 means "no hashed directory - * structure", 1 means "one level of directory", 2 means "two levels"... - * This option can speed up Cache_Lite only when you have many thousands of - * cache file. Only specific benchs can help you to choose the perfect value - * for you. Maybe, 1 or 2 is a good start. - * - * @var int $_hashedDirectoryLevel - */ - var $_hashedDirectoryLevel = 0; - - /** - * Umask for hashed directory structure - * - * @var int $_hashedDirectoryUmask - */ - var $_hashedDirectoryUmask = 0700; - - /** - * API break for error handling in CACHE_LITE_ERROR_RETURN mode - * - * In CACHE_LITE_ERROR_RETURN mode, error handling was not good because - * for example save() method always returned a boolean (a PEAR_Error object - * would be better in CACHE_LITE_ERROR_RETURN mode). To correct this without - * breaking the API, this option (false by default) can change this handling. - * - * @var boolean - */ - var $_errorHandlingAPIBreak = false; - - // --- Public methods --- - - /** - * Constructor - * - * $options is an assoc. Available options are : - * $options = array( - * 'cacheDir' => directory where to put the cache files (string), - * 'caching' => enable / disable caching (boolean), - * 'lifeTime' => cache lifetime in seconds (int), - * 'fileLocking' => enable / disable fileLocking (boolean), - * 'writeControl' => enable / disable write control (boolean), - * 'readControl' => enable / disable read control (boolean), - * 'readControlType' => type of read control 'crc32', 'md5', 'strlen' (string), - * 'pearErrorMode' => pear error mode (when raiseError is called) (cf PEAR doc) (int), - * 'memoryCaching' => enable / disable memory caching (boolean), - * 'onlyMemoryCaching' => enable / disable only memory caching (boolean), - * 'memoryCachingLimit' => max nbr of records to store into memory caching (int), - * 'fileNameProtection' => enable / disable automatic file name protection (boolean), - * 'automaticSerialization' => enable / disable automatic serialization (boolean), - * 'automaticCleaningFactor' => distable / tune automatic cleaning process (int), - * 'hashedDirectoryLevel' => level of the hashed directory system (int), - * 'hashedDirectoryUmask' => umask for hashed directory structure (int), - * 'errorHandlingAPIBreak' => API break for better error handling ? (boolean) - * ); - * - * @param array $options options - * @access public - */ - function Cache_Lite($options = array(NULL)) - { - foreach($options as $key => $value) { - $this->setOption($key, $value); - } - } - - /** - * Generic way to set a Cache_Lite option - * - * see Cache_Lite constructor for available options - * - * @var string $name name of the option - * @var mixed $value value of the option - * @access public - */ - function setOption($name, $value) - { - $availableOptions = array('errorHandlingAPIBreak', 'hashedDirectoryUmask', 'hashedDirectoryLevel', 'automaticCleaningFactor', 'automaticSerialization', 'fileNameProtection', 'memoryCaching', 'onlyMemoryCaching', 'memoryCachingLimit', 'cacheDir', 'caching', 'lifeTime', 'fileLocking', 'writeControl', 'readControl', 'readControlType', 'pearErrorMode'); - if (in_array($name, $availableOptions)) { - $property = '_'.$name; - $this->$property = $value; - } - } - - /** - * Test if a cache is available and (if yes) return it - * - * @param string $id cache id - * @param string $group name of the cache group - * @param boolean $doNotTestCacheValidity if set to true, the cache validity won't be tested - * @return string data of the cache (else : false) - * @access public - */ - function get($id, $group = 'default', $doNotTestCacheValidity = false) - { - $this->_id = $id; - $this->_group = $group; - $data = false; - if ($this->_caching) { - $this->_setRefreshTime(); - $this->_setFileName($id, $group); - clearstatcache(); - if ($this->_memoryCaching) { - if (isset($this->_memoryCachingArray[$this->_file])) { - if ($this->_automaticSerialization) { - return unserialize($this->_memoryCachingArray[$this->_file]); - } - return $this->_memoryCachingArray[$this->_file]; - } - if ($this->_onlyMemoryCaching) { - return false; - } - } - if (($doNotTestCacheValidity) || (is_null($this->_refreshTime))) { - if (file_exists($this->_file)) { - $data = $this->_read(); - } - } else { - if ((file_exists($this->_file)) && (@filemtime($this->_file) > $this->_refreshTime)) { - $data = $this->_read(); - } - } - if (($data) and ($this->_memoryCaching)) { - $this->_memoryCacheAdd($data); - } - if (($this->_automaticSerialization) and (is_string($data))) { - $data = unserialize($data); - } - return $data; - } - return false; - } - - /** - * Save some data in a cache file - * - * @param string $data data to put in cache (can be another type than strings if automaticSerialization is on) - * @param string $id cache id - * @param string $group name of the cache group - * @return boolean true if no problem (else : false or a PEAR_Error object) - * @access public - */ - function save($data, $id = NULL, $group = 'default') - { - if ($this->_caching) { - if ($this->_automaticSerialization) { - $data = serialize($data); - } - if (isset($id)) { - $this->_setFileName($id, $group); - } - if ($this->_memoryCaching) { - $this->_memoryCacheAdd($data); - if ($this->_onlyMemoryCaching) { - return true; - } - } - if ($this->_automaticCleaningFactor>0) { - $rand = rand(1, $this->_automaticCleaningFactor); - if ($rand==1) { - $this->clean(false, 'old'); - } - } - if ($this->_writeControl) { - $res = $this->_writeAndControl($data); - if (is_bool($res)) { - if ($res) { - return true; - } - // if $res if false, we need to invalidate the cache - @touch($this->_file, time() - 2*abs($this->_lifeTime)); - return false; - } - } else { - $res = $this->_write($data); - } - if (is_object($res)) { - // $res is a PEAR_Error object - if (!($this->_errorHandlingAPIBreak)) { - return false; // we return false (old API) - } - } - return $res; - } - return false; - } - - /** - * Remove a cache file - * - * @param string $id cache id - * @param string $group name of the cache group - * @return boolean true if no problem - * @access public - */ - function remove($id, $group = 'default') - { - $this->_setFileName($id, $group); - if ($this->_memoryCaching) { - if (isset($this->_memoryCachingArray[$this->_file])) { - unset($this->_memoryCachingArray[$this->_file]); - $this->_memoryCachingCounter = $this->_memoryCachingCounter - 1; - } - if ($this->_onlyMemoryCaching) { - return true; - } - } - return $this->_unlink($this->_file); - } - - /** - * Clean the cache - * - * if no group is specified all cache files will be destroyed - * else only cache files of the specified group will be destroyed - * - * @param string $group name of the cache group - * @param string $mode flush cache mode : 'old', 'ingroup', 'notingroup', - * 'callback_myFunction' - * @return boolean true if no problem - * @access public - */ - function clean($group = false, $mode = 'ingroup') - { - return $this->_cleanDir($this->_cacheDir, $group, $mode); - } - - /** - * Set to debug mode - * - * When an error is found, the script will stop and the message will be displayed - * (in debug mode only). - * - * @access public - */ - function setToDebug() - { - $this->setOption('pearErrorMode', CACHE_LITE_ERROR_DIE); - } - - /** - * Set a new life time - * - * @param int $newLifeTime new life time (in seconds) - * @access public - */ - function setLifeTime($newLifeTime) - { - $this->_lifeTime = $newLifeTime; - $this->_setRefreshTime(); - } - - /** - * Save the state of the caching memory array into a cache file cache - * - * @param string $id cache id - * @param string $group name of the cache group - * @access public - */ - function saveMemoryCachingState($id, $group = 'default') - { - if ($this->_caching) { - $array = array( - 'counter' => $this->_memoryCachingCounter, - 'array' => $this->_memoryCachingArray - ); - $data = serialize($array); - $this->save($data, $id, $group); - } - } - - /** - * Load the state of the caching memory array from a given cache file cache - * - * @param string $id cache id - * @param string $group name of the cache group - * @param boolean $doNotTestCacheValidity if set to true, the cache validity won't be tested - * @access public - */ - function getMemoryCachingState($id, $group = 'default', $doNotTestCacheValidity = false) - { - if ($this->_caching) { - if ($data = $this->get($id, $group, $doNotTestCacheValidity)) { - $array = unserialize($data); - $this->_memoryCachingCounter = $array['counter']; - $this->_memoryCachingArray = $array['array']; - } - } - } - - /** - * Return the cache last modification time - * - * BE CAREFUL : THIS METHOD IS FOR HACKING ONLY ! - * - * @return int last modification time - */ - function lastModified() - { - return @filemtime($this->_file); - } - - /** - * Trigger a PEAR error - * - * To improve performances, the PEAR.php file is included dynamically. - * The file is so included only when an error is triggered. So, in most - * cases, the file isn't included and perfs are much better. - * - * @param string $msg error message - * @param int $code error code - * @access public - */ - function raiseError($msg, $code) - { - include_once('PEAR.php'); - return PEAR::raiseError($msg, $code, $this->_pearErrorMode); - } - - /** - * Extend the life of a valid cache file - * - * see http://pear.php.net/bugs/bug.php?id=6681 - * - * @access public - */ - function extendLife() - { - @touch($this->_file); - } - - // --- Private methods --- - - /** - * Compute & set the refresh time - * - * @access private - */ - function _setRefreshTime() - { - if (is_null($this->_lifeTime)) { - $this->_refreshTime = null; - } else { - $this->_refreshTime = time() - $this->_lifeTime; - } - } - - /** - * Remove a file - * - * @param string $file complete file path and name - * @return boolean true if no problem - * @access private - */ - function _unlink($file) - { - if (!@unlink($file)) { - return $this->raiseError('Cache_Lite : Unable to remove cache !', -3); - } - return true; - } - - /** - * Recursive function for cleaning cache file in the given directory - * - * @param string $dir directory complete path (with a trailing slash) - * @param string $group name of the cache group - * @param string $mode flush cache mode : 'old', 'ingroup', 'notingroup', - 'callback_myFunction' - * @return boolean true if no problem - * @access private - */ - function _cleanDir($dir, $group = false, $mode = 'ingroup') - { - if ($this->_fileNameProtection) { - $motif = ($group) ? 'cache_'.md5($group).'_' : 'cache_'; - } else { - $motif = ($group) ? 'cache_'.$group.'_' : 'cache_'; - } - if ($this->_memoryCaching) { - foreach($this->_memoryCachingArray as $key => $v) { - if (strpos($key, $motif) !== false) { - unset($this->_memoryCachingArray[$key]); - $this->_memoryCachingCounter = $this->_memoryCachingCounter - 1; - } - } - if ($this->_onlyMemoryCaching) { - return true; - } - } - if (!($dh = opendir($dir))) { - return $this->raiseError('Cache_Lite : Unable to open cache directory !', -4); - } - $result = true; - while ($file = readdir($dh)) { - if (($file != '.') && ($file != '..')) { - if (substr($file, 0, 6)=='cache_') { - $file2 = $dir . $file; - if (is_file($file2)) { - switch (substr($mode, 0, 9)) { - case 'old': - // files older than lifeTime get deleted from cache - if (!is_null($this->_lifeTime)) { - if ((mktime() - @filemtime($file2)) > $this->_lifeTime) { - $result = ($result and ($this->_unlink($file2))); - } - } - break; - case 'notingrou': - if (strpos($file2, $motif) === false) { - $result = ($result and ($this->_unlink($file2))); - } - break; - case 'callback_': - $func = substr($mode, 9, strlen($mode) - 9); - if ($func($file2, $group)) { - $result = ($result and ($this->_unlink($file2))); - } - break; - case 'ingroup': - default: - if (strpos($file2, $motif) !== false) { - $result = ($result and ($this->_unlink($file2))); - } - break; - } - } - if ((is_dir($file2)) and ($this->_hashedDirectoryLevel>0)) { - $result = ($result and ($this->_cleanDir($file2 . '/', $group, $mode))); - } - } - } - } - return $result; - } - - /** - * Add some date in the memory caching array - * - * @param string $data data to cache - * @access private - */ - function _memoryCacheAdd($data) - { - $this->_memoryCachingArray[$this->_file] = $data; - if ($this->_memoryCachingCounter >= $this->_memoryCachingLimit) { - list($key, ) = each($this->_memoryCachingArray); - unset($this->_memoryCachingArray[$key]); - } else { - $this->_memoryCachingCounter = $this->_memoryCachingCounter + 1; - } - } - - /** - * Make a file name (with path) - * - * @param string $id cache id - * @param string $group name of the group - * @access private - */ - function _setFileName($id, $group) - { - - if ($this->_fileNameProtection) { - $suffix = 'cache_'.md5($group).'_'.md5($id); - } else { - $suffix = 'cache_'.$group.'_'.$id; - } - $root = $this->_cacheDir; - if ($this->_hashedDirectoryLevel>0) { - $hash = md5($suffix); - for ($i=0 ; $i<$this->_hashedDirectoryLevel ; $i++) { - $root = $root . 'cache_' . substr($hash, 0, $i + 1) . '/'; - } - } - $this->_fileName = $suffix; - $this->_file = $root.$suffix; - } - - /** - * Read the cache file and return the content - * - * @return string content of the cache file (else : false or a PEAR_Error object) - * @access private - */ - function _read() - { - $fp = @fopen($this->_file, "rb"); - if ($this->_fileLocking) @flock($fp, LOCK_SH); - if ($fp) { - clearstatcache(); - $length = @filesize($this->_file); - $mqr = get_magic_quotes_runtime(); - set_magic_quotes_runtime(0); - if ($this->_readControl) { - $hashControl = @fread($fp, 32); - $length = $length - 32; - } - if ($length) { - $data = @fread($fp, $length); - } else { - $data = ''; - } - set_magic_quotes_runtime($mqr); - if ($this->_fileLocking) @flock($fp, LOCK_UN); - @fclose($fp); - if ($this->_readControl) { - $hashData = $this->_hash($data, $this->_readControlType); - if ($hashData != $hashControl) { - if (!(is_null($this->_lifeTime))) { - @touch($this->_file, time() - 2*abs($this->_lifeTime)); - } else { - @unlink($this->_file); - } - return false; - } - } - return $data; - } - return $this->raiseError('Cache_Lite : Unable to read cache !', -2); - } - - /** - * Write the given data in the cache file - * - * @param string $data data to put in cache - * @return boolean true if ok (a PEAR_Error object else) - * @access private - */ - function _write($data) - { - if ($this->_hashedDirectoryLevel > 0) { - $hash = md5($this->_fileName); - $root = $this->_cacheDir; - for ($i=0 ; $i<$this->_hashedDirectoryLevel ; $i++) { - $root = $root . 'cache_' . substr($hash, 0, $i + 1) . '/'; - if (!(@is_dir($root))) { - @mkdir($root, $this->_hashedDirectoryUmask); - } - } - } - $fp = @fopen($this->_file, "wb"); - if ($fp) { - if ($this->_fileLocking) @flock($fp, LOCK_EX); - if ($this->_readControl) { - @fwrite($fp, $this->_hash($data, $this->_readControlType), 32); - } - $mqr = get_magic_quotes_runtime(); - set_magic_quotes_runtime(0); - @fwrite($fp, $data); - set_magic_quotes_runtime($mqr); - if ($this->_fileLocking) @flock($fp, LOCK_UN); - @fclose($fp); - return true; - } - return $this->raiseError('Cache_Lite : Unable to write cache file : '.$this->_file, -1); - } - - /** - * Write the given data in the cache file and control it just after to avoir corrupted cache entries - * - * @param string $data data to put in cache - * @return boolean true if the test is ok (else : false or a PEAR_Error object) - * @access private - */ - function _writeAndControl($data) - { - $result = $this->_write($data); - if (is_object($result)) { - return $result; # We return the PEAR_Error object - } - $dataRead = $this->_read(); - if (is_object($dataRead)) { - return $dataRead; # We return the PEAR_Error object - } - if ((is_bool($dataRead)) && (!$dataRead)) { - return false; - } - return ($dataRead==$data); - } - - /** - * Make a control key with the string containing datas - * - * @param string $data data - * @param string $controlType type of control 'md5', 'crc32' or 'strlen' - * @return string control key - * @access private - */ - function _hash($data, $controlType) - { - switch ($controlType) { - case 'md5': - return md5($data); - case 'crc32': - return sprintf('% 32d', crc32($data)); - case 'strlen': - return sprintf('% 32d', strlen($data)); - default: - return $this->raiseError('Unknown controlType ! (available values are only \'md5\', \'crc32\', \'strlen\')', -5); - } - } - -} - -?> diff --git a/glmPEAR/Cache/Lite/File.php b/glmPEAR/Cache/Lite/File.php deleted file mode 100755 index e0e4572..0000000 --- a/glmPEAR/Cache/Lite/File.php +++ /dev/null @@ -1,92 +0,0 @@ - -*/ - -require_once('Cache/Lite.php'); - -class Cache_Lite_File extends Cache_Lite -{ - - // --- Private properties --- - - /** - * Complete path of the file used for controlling the cache lifetime - * - * @var string $_masterFile - */ - var $_masterFile = ''; - - /** - * Masterfile mtime - * - * @var int $_masterFile_mtime - */ - var $_masterFile_mtime = 0; - - // --- Public methods ---- - - /** - * Constructor - * - * $options is an assoc. To have a look at availables options, - * see the constructor of the Cache_Lite class in 'Cache_Lite.php' - * - * Comparing to Cache_Lite constructor, there is another option : - * $options = array( - * (...) see Cache_Lite constructor - * 'masterFile' => complete path of the file used for controlling the cache lifetime(string) - * ); - * - * @param array $options options - * @access public - */ - function Cache_Lite_File($options = array(NULL)) - { - $options['lifetime'] = 0; - $this->Cache_Lite($options); - if (isset($options['masterFile'])) { - $this->_masterFile = $options['masterFile']; - } else { - return $this->raiseError('Cache_Lite_File : masterFile option must be set !'); - } - if (!($this->_masterFile_mtime = @filemtime($this->_masterFile))) { - return $this->raiseError('Cache_Lite_File : Unable to read masterFile : '.$this->_masterFile, -3); - } - } - - /** - * Test if a cache is available and (if yes) return it - * - * @param string $id cache id - * @param string $group name of the cache group - * @return string data of the cache (or false if no cache available) - * @access public - */ - function get($id, $group = 'default') - { - if ($data = parent::get($id, $group, true)) { - if ($filemtime = $this->lastModified()) { - if ($filemtime > $this->_masterFile_mtime) { - return $data; - } - } - } - return false; - } - -} - -?> diff --git a/glmPEAR/Cache/Lite/Function.php b/glmPEAR/Cache/Lite/Function.php deleted file mode 100755 index 58d3d6a..0000000 --- a/glmPEAR/Cache/Lite/Function.php +++ /dev/null @@ -1,211 +0,0 @@ - -* @author Fabien MARTY -*/ - -require_once('Cache/Lite.php'); - -class Cache_Lite_Function extends Cache_Lite -{ - - // --- Private properties --- - - /** - * Default cache group for function caching - * - * @var string $_defaultGroup - */ - var $_defaultGroup = 'Cache_Lite_Function'; - - /** - * Don't cache the method call when its output contains the string "NOCACHE" - * - * if set to true, the output of the method will never be displayed (because the output is used - * to control the cache) - * - * @var boolean $_dontCacheWhenTheOutputContainsNOCACHE - */ - var $_dontCacheWhenTheOutputContainsNOCACHE = false; - - /** - * Don't cache the method call when its result is false - * - * @var boolean $_dontCacheWhenTheResultIsFalse - */ - var $_dontCacheWhenTheResultIsFalse = false; - - /** - * Don't cache the method call when its result is null - * - * @var boolean $_dontCacheWhenTheResultIsNull - */ - var $_dontCacheWhenTheResultIsNull = false; - - /** - * Debug the Cache_Lite_Function caching process - * - * @var boolean $_debugCacheLiteFunction - */ - var $_debugCacheLiteFunction = false; - - // --- Public methods ---- - - /** - * Constructor - * - * $options is an assoc. To have a look at availables options, - * see the constructor of the Cache_Lite class in 'Cache_Lite.php' - * - * Comparing to Cache_Lite constructor, there is another option : - * $options = array( - * (...) see Cache_Lite constructor - * 'debugCacheLiteFunction' => (bool) debug the caching process, - * 'defaultGroup' => default cache group for function caching (string), - * 'dontCacheWhenTheOutputContainsNOCACHE' => (bool) don't cache when the function output contains "NOCACHE", - * 'dontCacheWhenTheResultIsFalse' => (bool) don't cache when the function result is false, - * 'dontCacheWhenTheResultIsNull' => (bool don't cache when the function result is null - * ); - * - * @param array $options options - * @access public - */ - function Cache_Lite_Function($options = array(NULL)) - { - $availableOptions = array('debugCacheLiteFunction', 'defaultGroup', 'dontCacheWhenTheOutputContainsNOCACHE', 'dontCacheWhenTheResultIsFalse', 'dontCacheWhenTheResultIsNull'); - while (list($name, $value) = each($options)) { - if (in_array($name, $availableOptions)) { - $property = '_'.$name; - $this->$property = $value; - } - } - reset($options); - $this->Cache_Lite($options); - } - - /** - * Calls a cacheable function or method (or not if there is already a cache for it) - * - * Arguments of this method are read with func_get_args. So it doesn't appear - * in the function definition. Synopsis : - * call('functionName', $arg1, $arg2, ...) - * (arg1, arg2... are arguments of 'functionName') - * - * @return mixed result of the function/method - * @access public - */ - function call() - { - $arguments = func_get_args(); - $id = $this->_makeId($arguments); - $data = $this->get($id, $this->_defaultGroup); - if ($data !== false) { - if ($this->_debugCacheLiteFunction) { - echo "Cache hit !\n"; - } - $array = unserialize($data); - $output = $array['output']; - $result = $array['result']; - } else { - if ($this->_debugCacheLiteFunction) { - echo "Cache missed !\n"; - } - ob_start(); - ob_implicit_flush(false); - $target = array_shift($arguments); - if (is_array($target)) { - // in this case, $target is for example array($obj, 'method') - $object = $target[0]; - $method = $target[1]; - $result = call_user_func_array(array(&$object, $method), $arguments); - } else { - if (strstr($target, '::')) { // classname::staticMethod - list($class, $method) = explode('::', $target); - $result = call_user_func_array(array($class, $method), $arguments); - } else if (strstr($target, '->')) { // object->method - // use a stupid name ($objet_123456789 because) of problems where the object - // name is the same as this var name - list($object_123456789, $method) = explode('->', $target); - global $$object_123456789; - $result = call_user_func_array(array($$object_123456789, $method), $arguments); - } else { // function - $result = call_user_func_array($target, $arguments); - } - } - $output = ob_get_contents(); - ob_end_clean(); - if ($this->_dontCacheWhenTheResultIsFalse) { - if ((is_bool($result)) && (!($result))) { - echo($output); - return $result; - } - } - if ($this->_dontCacheWhenTheResultIsNull) { - if (is_null($result)) { - echo($output); - return $result; - } - } - if ($this->_dontCacheWhenTheOutputContainsNOCACHE) { - if (strpos($output, 'NOCACHE') > -1) { - return $result; - } - } - $array['output'] = $output; - $array['result'] = $result; - $this->save(serialize($array), $id, $this->_defaultGroup); - } - echo($output); - return $result; - } - - /** - * Drop a cache file - * - * Arguments of this method are read with func_get_args. So it doesn't appear - * in the function definition. Synopsis : - * remove('functionName', $arg1, $arg2, ...) - * (arg1, arg2... are arguments of 'functionName') - * - * @return boolean true if no problem - * @access public - */ - function drop() - { - $id = $this->_makeId(func_get_args()); - return $this->remove($id, $this->_defaultGroup); - } - - /** - * Make an id for the cache - * - * @var array result of func_get_args for the call() or the remove() method - * @return string id - * @access private - */ - function _makeId($arguments) - { - $id = serialize($arguments); // Generate a cache id - if (!$this->_fileNameProtection) { - $id = md5($id); - // if fileNameProtection is set to false, then the id has to be hashed - // because it's a very bad file name in most cases - } - return $id; - } - -} - -?> diff --git a/glmPEAR/Cache/Lite/Output.php b/glmPEAR/Cache/Lite/Output.php deleted file mode 100755 index ad93a6c..0000000 --- a/glmPEAR/Cache/Lite/Output.php +++ /dev/null @@ -1,72 +0,0 @@ - -*/ - -require_once('Cache/Lite.php'); - -class Cache_Lite_Output extends Cache_Lite -{ - - // --- Public methods --- - - /** - * Constructor - * - * $options is an assoc. To have a look at availables options, - * see the constructor of the Cache_Lite class in 'Cache_Lite.php' - * - * @param array $options options - * @access public - */ - function Cache_Lite_Output($options) - { - $this->Cache_Lite($options); - } - - /** - * Start the cache - * - * @param string $id cache id - * @param string $group name of the cache group - * @param boolean $doNotTestCacheValidity if set to true, the cache validity won't be tested - * @return boolean true if the cache is hit (false else) - * @access public - */ - function start($id, $group = 'default', $doNotTestCacheValidity = false) - { - $data = $this->get($id, $group, $doNotTestCacheValidity); - if ($data !== false) { - echo($data); - return true; - } - ob_start(); - ob_implicit_flush(false); - return false; - } - - /** - * Stop the cache - * - * @access public - */ - function end() - { - $data = ob_get_contents(); - ob_end_clean(); - $this->save($data, $this->_id, $this->_group); - echo($data); - } - -} - - -?> diff --git a/glmPEAR/Calendar/Calendar.php b/glmPEAR/Calendar/Calendar.php deleted file mode 100755 index 3b5a882..0000000 --- a/glmPEAR/Calendar/Calendar.php +++ /dev/null @@ -1,685 +0,0 @@ - | -// | Lorenzo Alberton | -// +----------------------------------------------------------------------+ -// -// $Id: Calendar.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ -// -/** - * @package Calendar - * @version $Id: Calendar.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ - */ - -/** - * Allows Calendar include path to be redefined - */ -if (!defined('CALENDAR_ROOT')) { - define('CALENDAR_ROOT', 'Calendar'.DIRECTORY_SEPARATOR); -} - -/** - * Constant which defines the calculation engine to use - */ -if (!defined('CALENDAR_ENGINE')) { - define('CALENDAR_ENGINE', 'UnixTS'); -} - -/** - * Define Calendar Month states - */ -define('CALENDAR_USE_MONTH', 1); -define('CALENDAR_USE_MONTH_WEEKDAYS', 2); -define('CALENDAR_USE_MONTH_WEEKS', 3); - -/** - * Contains a factory method to return a Singleton instance of a class - * implementing the Calendar_Engine_Interface.
- * Note: this class must be modified to "register" alternative - * Calendar_Engines. The engine used can be controlled with the constant - * CALENDAR_ENGINE - * @see Calendar_Engine_Interface - * @package Calendar - * @access protected - */ -class Calendar_Engine_Factory -{ - /** - * Returns an instance of the engine - * @return object instance of a calendar calculation engine - * @access protected - */ - function & getEngine() - { - static $engine = false; - switch (CALENDAR_ENGINE) { - case 'PearDate': - $class = 'Calendar_Engine_PearDate'; - break; - case 'UnixTS': - default: - $class = 'Calendar_Engine_UnixTS'; - break; - } - if (!$engine) { - if (!class_exists($class)) { - require_once CALENDAR_ROOT.'Engine'.DIRECTORY_SEPARATOR.CALENDAR_ENGINE.'.php'; - } - $engine = new $class; - } - return $engine; - } -} - -/** - * Base class for Calendar API. This class should not be instantiated - * directly. - * @abstract - * @package Calendar - */ -class Calendar -{ - /** - * Instance of class implementing calendar engine interface - * @var object - * @access private - */ - var $cE; - - /** - * Instance of Calendar_Validator (lazy initialized when isValid() or - * getValidor() is called - * @var Calendar_Validator - * @access private - */ - var $validator; - - /** - * Year for this calendar object e.g. 2003 - * @access private - * @var int - */ - var $year; - - /** - * Month for this calendar object e.g. 9 - * @access private - * @var int - */ - var $month; - - /** - * Day of month for this calendar object e.g. 23 - * @access private - * @var int - */ - var $day; - - /** - * Hour of day for this calendar object e.g. 13 - * @access private - * @var int - */ - var $hour; - - /** - * Minute of hour this calendar object e.g. 46 - * @access private - * @var int - */ - var $minute; - - /** - * Second of minute this calendar object e.g. 34 - * @access private - * @var int - */ - var $second; - - /** - * Marks this calendar object as selected (e.g. 'today') - * @access private - * @var boolean - */ - var $selected = false; - - /** - * Collection of child calendar objects created from subclasses - * of Calendar. Type depends on the object which created them. - * @access private - * @var array - */ - var $children = array(); - - /** - * Constructs the Calendar - * @param int year - * @param int month - * @param int day - * @param int hour - * @param int minute - * @param int second - * @access protected - */ - function Calendar($y = 2000, $m = 1, $d = 1, $h = 0, $i = 0, $s = 0) - { - static $cE = null; - if (!isset($cE)) { - $cE = & Calendar_Engine_Factory::getEngine(); - } - $this->cE = & $cE; - $this->year = (int)$y; - $this->month = (int)$m; - $this->day = (int)$d; - $this->hour = (int)$h; - $this->minute = (int)$i; - $this->second = (int)$s; - } - - /** - * Defines the calendar by a timestamp (Unix or ISO-8601), replacing values - * passed to the constructor - * @param int|string Unix or ISO-8601 timestamp - * @return void - * @access public - */ - function setTimestamp($ts) - { - $this->year = $this->cE->stampToYear($ts); - $this->month = $this->cE->stampToMonth($ts); - $this->day = $this->cE->stampToDay($ts); - $this->hour = $this->cE->stampToHour($ts); - $this->minute = $this->cE->stampToMinute($ts); - $this->second = $this->cE->stampToSecond($ts); - } - - /** - * Returns a timestamp from the current date / time values. Format of - * timestamp depends on Calendar_Engine implementation being used - * @return int|string timestamp - * @access public - */ - function getTimestamp() - { - return $this->cE->dateToStamp( - $this->year, $this->month, $this->day, - $this->hour, $this->minute, $this->second); - } - - /** - * Defines calendar object as selected (e.g. for today) - * @param boolean state whether Calendar subclass - * @return void - * @access public - */ - function setSelected($state = true) - { - $this->selected = $state; - } - - /** - * True if the calendar subclass object is selected (e.g. today) - * @return boolean - * @access public - */ - function isSelected() - { - return $this->selected; - } - - /** - * Adjusts the date (helper method) - * @return void - * @access public - */ - function adjust() - { - $stamp = $this->getTimeStamp(); - $this->year = $this->cE->stampToYear($stamp); - $this->month = $this->cE->stampToMonth($stamp); - $this->day = $this->cE->stampToDay($stamp); - $this->hour = $this->cE->stampToHour($stamp); - $this->minute = $this->cE->stampToMinute($stamp); - $this->second = $this->cE->stampToSecond($stamp); - } - - /** - * Returns the date as an associative array (helper method) - * @param mixed timestamp (leave empty for current timestamp) - * @return array - * @access public - */ - function toArray($stamp=null) - { - if (is_null($stamp)) { - $stamp = $this->getTimeStamp(); - } - return array( - 'year' => $this->cE->stampToYear($stamp), - 'month' => $this->cE->stampToMonth($stamp), - 'day' => $this->cE->stampToDay($stamp), - 'hour' => $this->cE->stampToHour($stamp), - 'minute' => $this->cE->stampToMinute($stamp), - 'second' => $this->cE->stampToSecond($stamp) - ); - } - - /** - * Returns the value as an associative array (helper method) - * @param string type of date object that return value represents - * @param string $format ['int' | 'array' | 'timestamp' | 'object'] - * @param mixed timestamp (depending on Calendar engine being used) - * @param int integer default value (i.e. give me the answer quick) - * @return mixed - * @access private - */ - function returnValue($returnType, $format, $stamp, $default) - { - switch (strtolower($format)) { - case 'int': - return $default; - case 'array': - return $this->toArray($stamp); - break; - case 'object': - require_once CALENDAR_ROOT.'Factory.php'; - return Calendar_Factory::createByTimestamp($returnType,$stamp); - break; - case 'timestamp': - default: - return $stamp; - break; - } - } - - /** - * Abstract method for building the children of a calendar object. - * Implemented by Calendar subclasses - * @param array containing Calendar objects to select (optional) - * @return boolean - * @access public - * @abstract - */ - function build($sDates = array()) - { - require_once 'PEAR.php'; - PEAR::raiseError( - 'Calendar::build is abstract', null, PEAR_ERROR_TRIGGER, - E_USER_NOTICE, 'Calendar::build()'); - return false; - } - - /** - * Abstract method for selected data objects called from build - * @param array - * @return boolean - * @access public - * @abstract - */ - function setSelection($sDates) - { - require_once 'PEAR.php'; - PEAR::raiseError( - 'Calendar::setSelection is abstract', null, PEAR_ERROR_TRIGGER, - E_USER_NOTICE, 'Calendar::setSelection()'); - return false; - } - - /** - * Iterator method for fetching child Calendar subclass objects - * (e.g. a minute from an hour object). On reaching the end of - * the collection, returns false and resets the collection for - * further iteratations. - * @return mixed either an object subclass of Calendar or false - * @access public - */ - function fetch() - { - $child = each($this->children); - if ($child) { - return $child['value']; - } else { - reset($this->children); - return false; - } - } - - /** - * Fetches all child from the current collection of children - * @return array - * @access public - */ - function fetchAll() - { - return $this->children; - } - - /** - * Get the number Calendar subclass objects stored in the internal - * collection. - * @return int - * @access public - */ - function size() - { - return count($this->children); - } - - /** - * Determine whether this date is valid, with the bounds determined by - * the Calendar_Engine. The call is passed on to - * Calendar_Validator::isValid - * @return boolean - * @access public - */ - function isValid() - { - $validator = & $this->getValidator(); - return $validator->isValid(); - } - - /** - * Returns an instance of Calendar_Validator - * @return Calendar_Validator - * @access public - */ - function & getValidator() - { - if (!isset($this->validator)) { - require_once CALENDAR_ROOT.'Validator.php'; - $this->validator = & new Calendar_Validator($this); - } - return $this->validator; - } - - /** - * Returns a reference to the current Calendar_Engine being used. Useful - * for Calendar_Table_Helper and Calendar_Validator - * @return object implementing Calendar_Engine_Inteface - * @access protected - */ - function & getEngine() - { - return $this->cE; - } - - /** - * Set the CALENDAR_FIRST_DAY_OF_WEEK constant to the $firstDay value - * if the constant is not set yet. - * @throws E_USER_WARNING this method throws a WARNING if the - * CALENDAR_FIRST_DAY_OF_WEEK constant is already defined and - * the $firstDay parameter is set to a different value - * @param integer $firstDay first day of the week (0=sunday, 1=monday, ...) - * @return integer - * @access protected - */ - function defineFirstDayOfWeek($firstDay = null) - { - if (defined('CALENDAR_FIRST_DAY_OF_WEEK')) { - if (!is_null($firstDay) && ($firstDay != CALENDAR_FIRST_DAY_OF_WEEK)) { - $msg = 'CALENDAR_FIRST_DAY_OF_WEEK constant already defined.' - .' The $firstDay parameter will be ignored.'; - trigger_error($msg, E_USER_WARNING); - } - return CALENDAR_FIRST_DAY_OF_WEEK; - } - if (is_null($firstDay)) { - $firstDay = $this->cE->getFirstDayOfWeek( - $this->thisYear(), - $this->thisMonth(), - $this->thisDay() - ); - } - define ('CALENDAR_FIRST_DAY_OF_WEEK', $firstDay); - return CALENDAR_FIRST_DAY_OF_WEEK; - } - - /** - * Returns the value for the previous year - * @param string return value format ['int' | 'timestamp' | 'object' | 'array'] - * @return int e.g. 2002 or timestamp - * @access public - */ - function prevYear($format = 'int') - { - $ts = $this->cE->dateToStamp($this->year-1, 1, 1, 0, 0, 0); - return $this->returnValue('Year', $format, $ts, $this->year-1); - } - - /** - * Returns the value for this year - * @param string return value format ['int' | 'timestamp' | 'object' | 'array'] - * @return int e.g. 2003 or timestamp - * @access public - */ - function thisYear($format = 'int') - { - $ts = $this->cE->dateToStamp($this->year, 1, 1, 0, 0, 0); - return $this->returnValue('Year', $format, $ts, $this->year); - } - - /** - * Returns the value for next year - * @param string return value format ['int' | 'timestamp' | 'object' | 'array'] - * @return int e.g. 2004 or timestamp - * @access public - */ - function nextYear($format = 'int') - { - $ts = $this->cE->dateToStamp($this->year+1, 1, 1, 0, 0, 0); - return $this->returnValue('Year', $format, $ts, $this->year+1); - } - - /** - * Returns the value for the previous month - * @param string return value format ['int' | 'timestamp' | 'object' | 'array'] - * @return int e.g. 4 or Unix timestamp - * @access public - */ - function prevMonth($format = 'int') - { - $ts = $this->cE->dateToStamp($this->year, $this->month-1, 1, 0, 0, 0); - return $this->returnValue('Month', $format, $ts, $this->cE->stampToMonth($ts)); - } - - /** - * Returns the value for this month - * @param string return value format ['int' | 'timestamp' | 'object' | 'array'] - * @return int e.g. 5 or timestamp - * @access public - */ - function thisMonth($format = 'int') - { - $ts = $this->cE->dateToStamp($this->year, $this->month, 1, 0, 0, 0); - return $this->returnValue('Month', $format, $ts, $this->month); - } - - /** - * Returns the value for next month - * @param string return value format ['int' | 'timestamp' | 'object' | 'array'] - * @return int e.g. 6 or timestamp - * @access public - */ - function nextMonth($format = 'int') - { - $ts = $this->cE->dateToStamp($this->year, $this->month+1, 1, 0, 0, 0); - return $this->returnValue('Month', $format, $ts, $this->cE->stampToMonth($ts)); - } - - /** - * Returns the value for the previous day - * @param string return value format ['int' | 'timestamp' | 'object' | 'array'] - * @return int e.g. 10 or timestamp - * @access public - */ - function prevDay($format = 'int') - { - $ts = $this->cE->dateToStamp( - $this->year, $this->month, $this->day-1, 0, 0, 0); - return $this->returnValue('Day', $format, $ts, $this->cE->stampToDay($ts)); - } - - /** - * Returns the value for this day - * @param string return value format ['int' | 'timestamp' | 'object' | 'array'] - * @return int e.g. 11 or timestamp - * @access public - */ - function thisDay($format = 'int') - { - $ts = $this->cE->dateToStamp( - $this->year, $this->month, $this->day, 0, 0, 0); - return $this->returnValue('Day', $format, $ts, $this->day); - } - - /** - * Returns the value for the next day - * @param string return value format ['int' | 'timestamp' | 'object' | 'array'] - * @return int e.g. 12 or timestamp - * @access public - */ - function nextDay($format = 'int') - { - $ts = $this->cE->dateToStamp( - $this->year, $this->month, $this->day+1, 0, 0, 0); - return $this->returnValue('Day', $format, $ts, $this->cE->stampToDay($ts)); - } - - /** - * Returns the value for the previous hour - * @param string return value format ['int' | 'timestamp' | 'object' | 'array'] - * @return int e.g. 13 or timestamp - * @access public - */ - function prevHour($format = 'int') - { - $ts = $this->cE->dateToStamp( - $this->year, $this->month, $this->day, $this->hour-1, 0, 0); - return $this->returnValue('Hour', $format, $ts, $this->cE->stampToHour($ts)); - } - - /** - * Returns the value for this hour - * @param string return value format ['int' | 'timestamp' | 'object' | 'array'] - * @return int e.g. 14 or timestamp - * @access public - */ - function thisHour($format = 'int') - { - $ts = $this->cE->dateToStamp( - $this->year, $this->month, $this->day, $this->hour, 0, 0); - return $this->returnValue('Hour', $format, $ts, $this->hour); - } - - /** - * Returns the value for the next hour - * @param string return value format ['int' | 'timestamp' | 'object' | 'array'] - * @return int e.g. 14 or timestamp - * @access public - */ - function nextHour($format = 'int') - { - $ts = $this->cE->dateToStamp( - $this->year, $this->month, $this->day, $this->hour+1, 0, 0); - return $this->returnValue('Hour', $format, $ts, $this->cE->stampToHour($ts)); - } - - /** - * Returns the value for the previous minute - * @param string return value format ['int' | 'timestamp' | 'object' | 'array'] - * @return int e.g. 23 or timestamp - * @access public - */ - function prevMinute($format = 'int') - { - $ts = $this->cE->dateToStamp( - $this->year, $this->month, $this->day, - $this->hour, $this->minute-1, 0); - return $this->returnValue('Minute', $format, $ts, $this->cE->stampToMinute($ts)); - } - - /** - * Returns the value for this minute - * @param string return value format ['int' | 'timestamp' | 'object' | 'array'] - * @return int e.g. 24 or timestamp - * @access public - */ - function thisMinute($format = 'int') - { - $ts = $this->cE->dateToStamp( - $this->year, $this->month, $this->day, - $this->hour, $this->minute, 0); - return $this->returnValue('Minute', $format, $ts, $this->minute); - } - - /** - * Returns the value for the next minute - * @param string return value format ['int' | 'timestamp' | 'object' | 'array'] - * @return int e.g. 25 or timestamp - * @access public - */ - function nextMinute($format = 'int') - { - $ts = $this->cE->dateToStamp( - $this->year, $this->month, $this->day, - $this->hour, $this->minute+1, 0); - return $this->returnValue('Minute', $format, $ts, $this->cE->stampToMinute($ts)); - } - - /** - * Returns the value for the previous second - * @param string return value format ['int' | 'timestamp' | 'object' | 'array'] - * @return int e.g. 43 or timestamp - * @access public - */ - function prevSecond($format = 'int') - { - $ts = $this->cE->dateToStamp( - $this->year, $this->month, $this->day, - $this->hour, $this->minute, $this->second-1); - return $this->returnValue('Second', $format, $ts, $this->cE->stampToSecond($ts)); - } - - /** - * Returns the value for this second - * @param string return value format ['int' | 'timestamp' | 'object' | 'array'] - * @return int e.g. 44 or timestamp - * @access public - */ - function thisSecond($format = 'int') - { - $ts = $this->cE->dateToStamp( - $this->year, $this->month, $this->day, - $this->hour, $this->minute, $this->second); - return $this->returnValue('Second', $format, $ts, $this->second); - } - - /** - * Returns the value for the next second - * @param string return value format ['int' | 'timestamp' | 'object' | 'array'] - * @return int e.g. 45 or timestamp - * @access public - */ - function nextSecond($format = 'int') - { - $ts = $this->cE->dateToStamp( - $this->year, $this->month, $this->day, - $this->hour, $this->minute, $this->second+1); - return $this->returnValue('Second', $format, $ts, $this->cE->stampToSecond($ts)); - } -} -?> \ No newline at end of file diff --git a/glmPEAR/Calendar/Day.php b/glmPEAR/Calendar/Day.php deleted file mode 100755 index e79803f..0000000 --- a/glmPEAR/Calendar/Day.php +++ /dev/null @@ -1,197 +0,0 @@ - | -// +----------------------------------------------------------------------+ -// -// $Id: Day.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ -// -/** - * @package Calendar - * @version $Id: Day.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ - */ - -/** - * Allows Calendar include path to be redefined - * @ignore - */ -if (!defined('CALENDAR_ROOT')) { - define('CALENDAR_ROOT', 'Calendar'.DIRECTORY_SEPARATOR); -} - -/** - * Load Calendar base class - */ -require_once CALENDAR_ROOT.'Calendar.php'; - -/** - * Represents a Day and builds Hours. - * - * require_once 'Calendar'.DIRECTORY_SEPARATOR.'Day.php'; - * $Day = & new Calendar_Day(2003, 10, 21); // Oct 21st 2003 - * while ($Hour = & $Day->fetch()) { - * echo $Hour->thisHour().'
'; - * } - *
- * @package Calendar - * @access public - */ -class Calendar_Day extends Calendar -{ - /** - * Marks the Day at the beginning of a week - * @access private - * @var boolean - */ - var $first = false; - - /** - * Marks the Day at the end of a week - * @access private - * @var boolean - */ - var $last = false; - - - /** - * Used for tabular calendars - * @access private - * @var boolean - */ - var $empty = false; - - /** - * Constructs Calendar_Day - * @param int year e.g. 2003 - * @param int month e.g. 8 - * @param int day e.g. 15 - * @access public - */ - function Calendar_Day($y, $m, $d) - { - Calendar::Calendar($y, $m, $d); - } - - /** - * Builds the Hours of the Day - * @param array (optional) Caledar_Hour objects representing selected dates - * @return boolean - * @access public - */ - function build($sDates = array()) - { - require_once CALENDAR_ROOT.'Hour.php'; - - $hID = $this->cE->getHoursInDay($this->year, $this->month, $this->day); - for ($i=0; $i < $hID; $i++) { - $this->children[$i]= - new Calendar_Hour($this->year, $this->month, $this->day, $i); - } - if (count($sDates) > 0) { - $this->setSelection($sDates); - } - return true; - } - - /** - * Called from build() - * @param array - * @return void - * @access private - */ - function setSelection($sDates) - { - foreach ($sDates as $sDate) { - if ($this->year == $sDate->thisYear() - && $this->month == $sDate->thisMonth() - && $this->day == $sDate->thisDay()) - { - $key = (int)$sDate->thisHour(); - if (isset($this->children[$key])) { - $sDate->setSelected(); - $this->children[$key] = $sDate; - } - } - } - } - - /** - * Defines Day object as first in a week - * Only used by Calendar_Month_Weekdays::build() - * @param boolean state - * @return void - * @access private - */ - function setFirst ($state = true) - { - $this->first = $state; - } - - /** - * Defines Day object as last in a week - * Used only following Calendar_Month_Weekdays::build() - * @param boolean state - * @return void - * @access private - */ - function setLast($state = true) - { - $this->last = $state; - } - - /** - * Returns true if Day object is first in a Week - * Only relevant when Day is created by Calendar_Month_Weekdays::build() - * @return boolean - * @access public - */ - function isFirst() { - return $this->first; - } - - /** - * Returns true if Day object is last in a Week - * Only relevant when Day is created by Calendar_Month_Weekdays::build() - * @return boolean - * @access public - */ - function isLast() - { - return $this->last; - } - - /** - * Defines Day object as empty - * Only used by Calendar_Month_Weekdays::build() - * @param boolean state - * @return void - * @access private - */ - function setEmpty ($state = true) - { - $this->empty = $state; - } - - /** - * @return boolean - * @access public - */ - function isEmpty() - { - return $this->empty; - } -} -?> \ No newline at end of file diff --git a/glmPEAR/Calendar/Decorator.php b/glmPEAR/Calendar/Decorator.php deleted file mode 100755 index 66fc1ef..0000000 --- a/glmPEAR/Calendar/Decorator.php +++ /dev/null @@ -1,558 +0,0 @@ - | -// +----------------------------------------------------------------------+ -// -// $Id: Decorator.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ -// -/** - * @package Calendar - * @version $Id: Decorator.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ - */ -/** - * Decorates any calendar class. - * Create a subclass of this class for your own "decoration". - * Used for "selections" - * - * class DayDecorator extends Calendar_Decorator - * { - * function thisDay($format = 'int') - * { -.* $day = parent::thisDay('timestamp'); -.* return date('D', $day); - * } - * } - * $Day = & new Calendar_Day(2003, 10, 25); - * $DayDecorator = & new DayDecorator($Day); - * echo $DayDecorator->thisDay(); // Outputs "Sat" - * - * @abstract - * @package Calendar - */ -class Calendar_Decorator -{ - /** - * Subclass of Calendar being decorated - * @var object - * @access private - */ - var $calendar; - - /** - * Constructs the Calendar_Decorator - * @param object subclass to Calendar to decorate - */ - function Calendar_Decorator(& $calendar) - { - $this->calendar = & $calendar; - } - - /** - * Defines the calendar by a Unix timestamp, replacing values - * passed to the constructor - * @param int Unix timestamp - * @return void - * @access public - */ - function setTimestamp($ts) - { - $this->calendar->setTimestamp($ts); - } - - /** - * Returns a timestamp from the current date / time values. Format of - * timestamp depends on Calendar_Engine implementation being used - * @return int timestamp - * @access public - */ - function getTimestamp() - { - return $this->calendar->getTimeStamp(); - } - - /** - * Defines calendar object as selected (e.g. for today) - * @param boolean state whether Calendar subclass - * @return void - * @access public - */ - function setSelected($state = true) - { - $this->calendar->setSelected($state = true); - } - - /** - * True if the calendar subclass object is selected (e.g. today) - * @return boolean - * @access public - */ - function isSelected() - { - return $this->calendar->isSelected(); - } - - /** - * Adjusts the date (helper method) - * @return void - * @access public - */ - function adjust() - { - $this->calendar->adjust(); - } - - /** - * Returns the date as an associative array (helper method) - * @param mixed timestamp (leave empty for current timestamp) - * @return array - * @access public - */ - function toArray($stamp=null) - { - return $this->calendar->toArray($stamp); - } - - /** - * Returns the value as an associative array (helper method) - * @param string type of date object that return value represents - * @param string $format ['int' | 'array' | 'timestamp' | 'object'] - * @param mixed timestamp (depending on Calendar engine being used) - * @param int integer default value (i.e. give me the answer quick) - * @return mixed - * @access private - */ - function returnValue($returnType, $format, $stamp, $default) - { - return $this->calendar->returnValue($returnType, $format, $stamp, $default); - } - - /** - * Defines Day object as first in a week - * Only used by Calendar_Month_Weekdays::build() - * @param boolean state - * @return void - * @access private - */ - function setFirst ($state = true) - { - if ( method_exists($this->calendar,'setFirst') ) { - $this->calendar->setFirst($state); - } - } - - /** - * Defines Day object as last in a week - * Used only following Calendar_Month_Weekdays::build() - * @param boolean state - * @return void - * @access private - */ - function setLast($state = true) - { - if ( method_exists($this->calendar,'setLast') ) { - $this->calendar->setLast($state); - } - } - - /** - * Returns true if Day object is first in a Week - * Only relevant when Day is created by Calendar_Month_Weekdays::build() - * @return boolean - * @access public - */ - function isFirst() { - if ( method_exists($this->calendar,'isFirst') ) { - return $this->calendar->isFirst(); - } - } - - /** - * Returns true if Day object is last in a Week - * Only relevant when Day is created by Calendar_Month_Weekdays::build() - * @return boolean - * @access public - */ - function isLast() - { - if ( method_exists($this->calendar,'isLast') ) { - return $this->calendar->isLast(); - } - } - - /** - * Defines Day object as empty - * Only used by Calendar_Month_Weekdays::build() - * @param boolean state - * @return void - * @access private - */ - function setEmpty ($state = true) - { - if ( method_exists($this->calendar,'setEmpty') ) { - $this->calendar->setEmpty($state); - } - } - - /** - * @return boolean - * @access public - */ - function isEmpty() - { - if ( method_exists($this->calendar,'isEmpty') ) { - return $this->calendar->isEmpty(); - } - } - - /** - * Build the children - * @param array containing Calendar objects to select (optional) - * @return boolean - * @access public - * @abstract - */ - function build($sDates = array()) - { - $this->calendar->build($sDates); - } - - /** - * Iterator method for fetching child Calendar subclass objects - * (e.g. a minute from an hour object). On reaching the end of - * the collection, returns false and resets the collection for - * further iteratations. - * @return mixed either an object subclass of Calendar or false - * @access public - */ - function fetch() - { - return $this->calendar->fetch(); - } - - /** - * Fetches all child from the current collection of children - * @return array - * @access public - */ - function fetchAll() - { - return $this->calendar->fetchAll(); - } - - /** - * Get the number Calendar subclass objects stored in the internal - * collection. - * @return int - * @access public - */ - function size() - { - return $this->calendar->size(); - } - - /** - * Determine whether this date is valid, with the bounds determined by - * the Calendar_Engine. The call is passed on to - * Calendar_Validator::isValid - * @return boolean - * @access public - */ - function isValid() - { - return $this->calendar->isValid(); - } - - /** - * Returns an instance of Calendar_Validator - * @return Calendar_Validator - * @access public - */ - function & getValidator() - { - $validator = $this->calendar->getValidator(); - return $validator; - } - - /** - * Returns a reference to the current Calendar_Engine being used. Useful - * for Calendar_Table_Helper and Calendar_Validator - * @return object implementing Calendar_Engine_Inteface - * @access private - */ - function & getEngine() - { - return $this->calendar->getEngine(); - } - - /** - * Returns the value for the previous year - * @param string return value format ['int' | 'timestamp' | 'object' | 'array'] - * @return int e.g. 2002 or timestamp - * @access public - */ - function prevYear($format = 'int') - { - return $this->calendar->prevYear($format); - } - - /** - * Returns the value for this year - * @param string return value format ['int' | 'timestamp' | 'object' | 'array'] - * @return int e.g. 2003 or timestamp - * @access public - */ - function thisYear($format = 'int') - { - return $this->calendar->thisYear($format); - } - - /** - * Returns the value for next year - * @param string return value format ['int' | 'timestamp' | 'object' | 'array'] - * @return int e.g. 2004 or timestamp - * @access public - */ - function nextYear($format = 'int') - { - return $this->calendar->nextYear($format); - } - - /** - * Returns the value for the previous month - * @param string return value format ['int' | 'timestamp' | 'object' | 'array'] - * @return int e.g. 4 or Unix timestamp - * @access public - */ - function prevMonth($format = 'int') - { - return $this->calendar->prevMonth($format); - } - - /** - * Returns the value for this month - * @param string return value format ['int' | 'timestamp' | 'object' | 'array'] - * @return int e.g. 5 or timestamp - * @access public - */ - function thisMonth($format = 'int') - { - return $this->calendar->thisMonth($format); - } - - /** - * Returns the value for next month - * @param string return value format ['int' | 'timestamp' | 'object' | 'array'] - * @return int e.g. 6 or timestamp - * @access public - */ - function nextMonth($format = 'int') - { - return $this->calendar->nextMonth($format); - } - - /** - * Returns the value for the previous week - * @param string return value format ['int' | 'timestamp' | 'object' | 'array'] - * @return int e.g. 4 or Unix timestamp - * @access public - */ - function prevWeek($format = 'n_in_month') - { - if ( method_exists($this->calendar,'prevWeek') ) { - return $this->calendar->prevWeek($format); - } else { - require_once 'PEAR.php'; - PEAR::raiseError( - 'Cannot call prevWeek on Calendar object of type: '. - get_class($this->calendar), 133, PEAR_ERROR_TRIGGER, - E_USER_NOTICE, 'Calendar_Decorator::prevWeek()'); - return false; - } - } - - /** - * Returns the value for this week - * @param string return value format ['int' | 'timestamp' | 'object' | 'array'] - * @return int e.g. 5 or timestamp - * @access public - */ - function thisWeek($format = 'n_in_month') - { - if ( method_exists($this->calendar,'thisWeek') ) { - return $this->calendar->thisWeek($format); - } else { - require_once 'PEAR.php'; - PEAR::raiseError( - 'Cannot call thisWeek on Calendar object of type: '. - get_class($this->calendar), 133, PEAR_ERROR_TRIGGER, - E_USER_NOTICE, 'Calendar_Decorator::thisWeek()'); - return false; - } - } - - /** - * Returns the value for next week - * @param string return value format ['int' | 'timestamp' | 'object' | 'array'] - * @return int e.g. 6 or timestamp - * @access public - */ - function nextWeek($format = 'n_in_month') - { - if ( method_exists($this->calendar,'nextWeek') ) { - return $this->calendar->nextWeek($format); - } else { - require_once 'PEAR.php'; - PEAR::raiseError( - 'Cannot call thisWeek on Calendar object of type: '. - get_class($this->calendar), 133, PEAR_ERROR_TRIGGER, - E_USER_NOTICE, 'Calendar_Decorator::nextWeek()'); - return false; - } - } - - /** - * Returns the value for the previous day - * @param string return value format ['int' | 'timestamp' | 'object' | 'array'] - * @return int e.g. 10 or timestamp - * @access public - */ - function prevDay($format = 'int') { - return $this->calendar->prevDay($format); - } - - /** - * Returns the value for this day - * @param string return value format ['int' | 'timestamp' | 'object' | 'array'] - * @return int e.g. 11 or timestamp - * @access public - */ - function thisDay($format = 'int') - { - return $this->calendar->thisDay($format); - } - - /** - * Returns the value for the next day - * @param string return value format ['int' | 'timestamp' | 'object' | 'array'] - * @return int e.g. 12 or timestamp - * @access public - */ - function nextDay($format = 'int') - { - return $this->calendar->nextDay($format); - } - - /** - * Returns the value for the previous hour - * @param string return value format ['int' | 'timestamp' | 'object' | 'array'] - * @return int e.g. 13 or timestamp - * @access public - */ - function prevHour($format = 'int') - { - return $this->calendar->prevHour($format); - } - - /** - * Returns the value for this hour - * @param string return value format ['int' | 'timestamp' | 'object' | 'array'] - * @return int e.g. 14 or timestamp - * @access public - */ - function thisHour($format = 'int') - { - return $this->calendar->thisHour($format); - } - - /** - * Returns the value for the next hour - * @param string return value format ['int' | 'timestamp' | 'object' | 'array'] - * @return int e.g. 14 or timestamp - * @access public - */ - function nextHour($format = 'int') - { - return $this->calendar->nextHour($format); - } - - /** - * Returns the value for the previous minute - * @param string return value format ['int' | 'timestamp' | 'object' | 'array'] - * @return int e.g. 23 or timestamp - * @access public - */ - function prevMinute($format = 'int') - { - return $this->calendar->prevMinute($format); - } - - /** - * Returns the value for this minute - * @param string return value format ['int' | 'timestamp' | 'object' | 'array'] - * @return int e.g. 24 or timestamp - * @access public - */ - function thisMinute($format = 'int') - { - return $this->calendar->thisMinute($format); - } - - /** - * Returns the value for the next minute - * @param string return value format ['int' | 'timestamp' | 'object' | 'array'] - * @return int e.g. 25 or timestamp - * @access public - */ - function nextMinute($format = 'int') - { - return $this->calendar->nextMinute($format); - } - - /** - * Returns the value for the previous second - * @param string return value format ['int' | 'timestamp' | 'object' | 'array'] - * @return int e.g. 43 or timestamp - * @access public - */ - function prevSecond($format = 'int') - { - return $this->calendar->prevSecond($format); - } - - /** - * Returns the value for this second - * @param string return value format ['int' | 'timestamp' | 'object' | 'array'] - * @return int e.g. 44 or timestamp - * @access public - */ - function thisSecond($format = 'int') - { - return $this->calendar->thisSecond($format); - } - - /** - * Returns the value for the next second - * @param string return value format ['int' | 'timestamp' | 'object' | 'array'] - * @return int e.g. 45 or timestamp - * @access public - */ - function nextSecond($format = 'int') - { - return $this->calendar->nextSecond($format); - } -} -?> \ No newline at end of file diff --git a/glmPEAR/Calendar/Decorator/Textual.php b/glmPEAR/Calendar/Decorator/Textual.php deleted file mode 100755 index 33a8763..0000000 --- a/glmPEAR/Calendar/Decorator/Textual.php +++ /dev/null @@ -1,169 +0,0 @@ - | -// | Lorenzo Alberton | -// +----------------------------------------------------------------------+ -// -// $Id: Textual.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ -// -/** - * @package Calendar - * @version $Id: Textual.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ - */ - -/** - * Allows Calendar include path to be redefined - * @ignore - */ -if (!defined('CALENDAR_ROOT')) { - define('CALENDAR_ROOT', 'Calendar'.DIRECTORY_SEPARATOR); -} - -/** - * Load Calendar decorator base class - */ -require_once CALENDAR_ROOT.'Decorator.php'; - -/** - * Load the Uri utility - */ -require_once CALENDAR_ROOT.'Util'.DIRECTORY_SEPARATOR.'Textual.php'; - -/** - * Decorator to help with fetching textual representations of months and - * days of the week. - * Note: for performance you should prefer Calendar_Util_Textual unless you - * have a specific need to use a decorator - * @package Calendar - * @access public - */ -class Calendar_Decorator_Textual extends Calendar_Decorator -{ - /** - * Constructs Calendar_Decorator_Textual - * @param object subclass of Calendar - * @access public - */ - function Calendar_Decorator_Textual(&$Calendar) - { - parent::Calendar_Decorator($Calendar); - } - - /** - * Returns an array of 12 month names (first index = 1) - * @param string (optional) format of returned months (one,two,short or long) - * @return array - * @access public - * @static - */ - function monthNames($format='long') - { - return Calendar_Util_Textual::monthNames($format); - } - - /** - * Returns an array of 7 week day names (first index = 0) - * @param string (optional) format of returned days (one,two,short or long) - * @return array - * @access public - * @static - */ - function weekdayNames($format='long') - { - return Calendar_Util_Textual::weekdayNames($format); - } - - /** - * Returns textual representation of the previous month of the decorated calendar object - * @param string (optional) format of returned months (one,two,short or long) - * @return string - * @access public - */ - function prevMonthName($format='long') - { - return Calendar_Util_Textual::prevMonthName($this->calendar,$format); - } - - /** - * Returns textual representation of the month of the decorated calendar object - * @param string (optional) format of returned months (one,two,short or long) - * @return string - * @access public - */ - function thisMonthName($format='long') - { - return Calendar_Util_Textual::thisMonthName($this->calendar,$format); - } - - /** - * Returns textual representation of the next month of the decorated calendar object - * @param string (optional) format of returned months (one,two,short or long) - * @return string - * @access public - */ - function nextMonthName($format='long') - { - return Calendar_Util_Textual::nextMonthName($this->calendar,$format); - } - - /** - * Returns textual representation of the previous day of week of the decorated calendar object - * @param string (optional) format of returned months (one,two,short or long) - * @return string - * @access public - */ - function prevDayName($format='long') - { - return Calendar_Util_Textual::prevDayName($this->calendar,$format); - } - - /** - * Returns textual representation of the day of week of the decorated calendar object - * @param string (optional) format of returned months (one,two,short or long) - * @return string - * @access public - */ - function thisDayName($format='long') - { - return Calendar_Util_Textual::thisDayName($this->calendar,$format); - } - - /** - * Returns textual representation of the next day of week of the decorated calendar object - * @param string (optional) format of returned months (one,two,short or long) - * @return string - * @access public - */ - function nextDayName($format='long') - { - return Calendar_Util_Textual::nextDayName($this->calendar,$format); - } - - /** - * Returns the days of the week using the order defined in the decorated - * calendar object. Only useful for Calendar_Month_Weekdays, Calendar_Month_Weeks - * and Calendar_Week. Otherwise the returned array will begin on Sunday - * @param string (optional) format of returned months (one,two,short or long) - * @return array ordered array of week day names - * @access public - */ - function orderedWeekdays($format='long') - { - return Calendar_Util_Textual::orderedWeekdays($this->calendar,$format); - } -} -?> \ No newline at end of file diff --git a/glmPEAR/Calendar/Decorator/Uri.php b/glmPEAR/Calendar/Decorator/Uri.php deleted file mode 100755 index 58de002..0000000 --- a/glmPEAR/Calendar/Decorator/Uri.php +++ /dev/null @@ -1,151 +0,0 @@ - | -// | Lorenzo Alberton | -// +----------------------------------------------------------------------+ -// -// $Id: Uri.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ -// -/** - * @package Calendar - * @version $Id: Uri.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ - */ - -/** - * Allows Calendar include path to be redefined - * @ignore - */ -if (!defined('CALENDAR_ROOT')) { - define('CALENDAR_ROOT', 'Calendar'.DIRECTORY_SEPARATOR); -} - -/** - * Load Calendar decorator base class - */ -require_once CALENDAR_ROOT.'Decorator.php'; - -/** - * Load the Uri utility - */ -require_once CALENDAR_ROOT.'Util'.DIRECTORY_SEPARATOR.'Uri.php'; - -/** - * Decorator to help with building HTML links for navigating the calendar
- * Note: for performance you should prefer Calendar_Util_Uri unless you - * have a specific need to use a decorator - * - * $Day = new Calendar_Day(2003, 10, 23); - * $Uri = & new Calendar_Decorator_Uri($Day); - * $Uri->setFragments('year', 'month', 'day'); - * echo $Uri->getPrev(); // Displays year=2003&month=10&day=22 - * - * @see Calendar_Util_Uri - * @package Calendar - * @access public - */ -class Calendar_Decorator_Uri extends Calendar_Decorator -{ - - /** - * @var Calendar_Util_Uri - * @access private - */ - var $Uri; - - /** - * Constructs Calendar_Decorator_Uri - * @param object subclass of Calendar - * @access public - */ - function Calendar_Decorator_Uri(&$Calendar) - { - parent::Calendar_Decorator($Calendar); - } - - /** - * Sets the URI fragment names - * @param string URI fragment for year - * @param string (optional) URI fragment for month - * @param string (optional) URI fragment for day - * @param string (optional) URI fragment for hour - * @param string (optional) URI fragment for minute - * @param string (optional) URI fragment for second - * @return void - * @access public - */ - function setFragments($y, $m=null, $d=null, $h=null, $i=null, $s=null) { - $this->Uri = & new Calendar_Util_Uri($y, $m, $d, $h, $i, $s); - } - - /** - * Sets the separator string between fragments - * @param string separator e.g. / - * @return void - * @access public - */ - function setSeparator($separator) - { - $this->Uri->separator = $separator; - } - - /** - * Puts Uri decorator into "scalar mode" - URI variable names are not - * returned - * @param boolean (optional) - * @return void - * @access public - */ - function setScalar($state=true) - { - $this->Uri->scalar = $state; - } - - /** - * Gets the URI string for the previous calendar unit - * @param string calendar unit to fetch uri for (year,month,week or day etc) - * @return string - * @access public - */ - function prev($method) - { - return $this->Uri->prev($this, $method); - } - - /** - * Gets the URI string for the current calendar unit - * @param string calendar unit to fetch uri for (year,month,week or day etc) - * @return string - * @access public - */ - function this($method) - { - return $this->Uri->this($this, $method); - } - - /** - * Gets the URI string for the next calendar unit - * @param string calendar unit to fetch uri for (year,month,week or day etc) - * @return string - * @access public - */ - function next($method) - { - return $this->Uri->next($this, $method); - } - -} -?> \ No newline at end of file diff --git a/glmPEAR/Calendar/Decorator/Weekday.php b/glmPEAR/Calendar/Decorator/Weekday.php deleted file mode 100755 index 45a9630..0000000 --- a/glmPEAR/Calendar/Decorator/Weekday.php +++ /dev/null @@ -1,148 +0,0 @@ - | -// | Lorenzo Alberton | -// +----------------------------------------------------------------------+ -// -// $Id: Weekday.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ -// -/** - * @package Calendar - * @version $Id: Weekday.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ - */ - -/** - * Allows Calendar include path to be redefined - * @ignore - */ -if (!defined('CALENDAR_ROOT')) { - define('CALENDAR_ROOT', 'Calendar'.DIRECTORY_SEPARATOR); -} - -/** - * Load Calendar decorator base class - */ -require_once CALENDAR_ROOT.'Decorator.php'; - -/** - * Load a Calendar_Day - */ -require_once CALENDAR_ROOT.'Day.php'; -/** - * Decorator for fetching the day of the week - * - * $Day = new Calendar_Day(2003, 10, 23); - * $Weekday = & new Calendar_Decorator_Weekday($Day); - * $Weekday->setFirstDay(0); // Set first day of week to Sunday (default Mon) - * echo $Weekday->thisWeekDay(); // Displays 5 - fifth day of week relative to Sun - * - * @package Calendar - * @access public - */ -class Calendar_Decorator_Weekday extends Calendar_Decorator -{ - /** - * First day of week - * @var int (default = 1 for Monday) - * @access private - */ - var $firstDay = 1; - - /** - * Constructs Calendar_Decorator_Weekday - * @param object subclass of Calendar - * @access public - */ - function Calendar_Decorator_Weekday(& $Calendar) - { - parent::Calendar_Decorator($Calendar); - } - - /** - * Sets the first day of the week (0 = Sunday, 1 = Monday (default) etc) - * @param int first day of week - * @return void - * @access public - */ - function setFirstDay($firstDay) { - $this->firstDay = (int)$firstDay; - } - - /** - * Returns the previous weekday - * @param string (default = 'int') return value format - * @return int numeric day of week or timestamp - * @access public - */ - function prevWeekDay($format = 'int') - { - $ts = $this->calendar->prevDay('timestamp'); - $Day = new Calendar_Day(2000,1,1); - $Day->setTimeStamp($ts); - $day = $this->calendar->cE->getDayOfWeek($Day->thisYear(),$Day->thisMonth(),$Day->thisDay()); - $day = $this->adjustWeekScale($day); - return $this->returnValue('Day', $format, $ts, $day); - } - - /** - * Returns the current weekday - * @param string (default = 'int') return value format - * @return int numeric day of week or timestamp - * @access public - */ - function thisWeekDay($format = 'int') - { - $ts = $this->calendar->thisDay('timestamp'); - $day = $this->calendar->cE->getDayOfWeek($this->calendar->year,$this->calendar->month,$this->calendar->day); - $day = $this->adjustWeekScale($day); - return $this->returnValue('Day', $format, $ts, $day); - } - - /** - * Returns the next weekday - * @param string (default = 'int') return value format - * @return int numeric day of week or timestamp - * @access public - */ - function nextWeekDay($format = 'int') - { - $ts = $this->calendar->nextDay('timestamp'); - $Day = new Calendar_Day(2000,1,1); - $Day->setTimeStamp($ts); - $day = $this->calendar->cE->getDayOfWeek($Day->thisYear(),$Day->thisMonth(),$Day->thisDay()); - $day = $this->adjustWeekScale($day); - return $this->returnValue('Day', $format, $ts, $day); - } - - /** - * Adjusts the day of the week relative to the first day of the week - * @param int day of week calendar from Calendar_Engine - * @return int day of week adjusted to first day - * @access private - */ - function adjustWeekScale($dayOfWeek) { - $dayOfWeek = $dayOfWeek - $this->firstDay; - if ( $dayOfWeek >= 0 ) { - return $dayOfWeek; - } else { - return $this->calendar->cE->getDaysInWeek( - $this->calendar->year,$this->calendar->month,$this->calendar->day - ) + $dayOfWeek; - } - } -} -?> \ No newline at end of file diff --git a/glmPEAR/Calendar/Decorator/Wrapper.php b/glmPEAR/Calendar/Decorator/Wrapper.php deleted file mode 100755 index 41e37c0..0000000 --- a/glmPEAR/Calendar/Decorator/Wrapper.php +++ /dev/null @@ -1,90 +0,0 @@ - | -// | Lorenzo Alberton | -// +----------------------------------------------------------------------+ -// -// $Id: Wrapper.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ -// -/** - * @package Calendar - * @version $Id: Wrapper.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ - */ - -/** - * Allows Calendar include path to be redefined - * @ignore - */ -if (!defined('CALENDAR_ROOT')) { - define('CALENDAR_ROOT', 'Calendar'.DIRECTORY_SEPARATOR); -} - -/** - * Load Calendar decorator base class - */ -require_once CALENDAR_ROOT.'Decorator.php'; - -/** - * Decorator to help with wrapping built children in another decorator - * @package Calendar - * @access public - */ -class Calendar_Decorator_Wrapper extends Calendar_Decorator -{ - /** - * Constructs Calendar_Decorator_Wrapper - * @param object subclass of Calendar - * @access public - */ - function Calendar_Decorator_Wrapper(&$Calendar) - { - parent::Calendar_Decorator($Calendar); - } - - /** - * Wraps objects returned from fetch in the named Decorator class - * @param string name of Decorator class to wrap with - * @return object instance of named decorator - * @access public - */ - function & fetch($decorator) - { - $Calendar = parent::fetch(); - if ($Calendar) { - $ret =& new $decorator($Calendar); - } else { - $ret = false; - } - return $ret; - } - - /** - * Wraps the returned calendar objects from fetchAll in the named decorator - * @param string name of Decorator class to wrap with - * @return array - * @access public - */ - function fetchAll($decorator) - { - $children = parent::fetchAll(); - foreach ($children as $key => $Calendar) { - $children[$key] = & new $decorator($Calendar); - } - return $children; - } -} -?> \ No newline at end of file diff --git a/glmPEAR/Calendar/Engine/Interface.php b/glmPEAR/Calendar/Engine/Interface.php deleted file mode 100755 index 49a77df..0000000 --- a/glmPEAR/Calendar/Engine/Interface.php +++ /dev/null @@ -1,293 +0,0 @@ - | -// +----------------------------------------------------------------------+ -// -// $Id: Interface.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ -// -/** - * @package Calendar - * @version $Id: Interface.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ - */ -/** - * The methods the classes implementing the Calendar_Engine must implement. - * Note this class is not used but simply to help development - * @package Calendar - * @access protected - */ -class Calendar_Engine_Interface -{ - /** - * Provides a mechansim to make sure parsing of timestamps - * into human dates is only performed once per timestamp. - * Typically called "internally" by methods like stampToYear. - * Return value can vary, depending on the specific implementation - * @param int timestamp (depending on implementation) - * @return mixed - * @access protected - */ - function stampCollection($stamp) - { - } - - /** - * Returns a numeric year given a timestamp - * @param int timestamp (depending on implementation) - * @return int year (e.g. 2003) - * @access protected - */ - function stampToYear($stamp) - { - } - - /** - * Returns a numeric month given a timestamp - * @param int timestamp (depending on implementation) - * @return int month (e.g. 9) - * @access protected - */ - function stampToMonth($stamp) - { - } - - /** - * Returns a numeric day given a timestamp - * @param int timestamp (depending on implementation) - * @return int day (e.g. 15) - * @access protected - */ - function stampToDay($stamp) - { - } - - /** - * Returns a numeric hour given a timestamp - * @param int timestamp (depending on implementation) - * @return int hour (e.g. 13) - * @access protected - */ - function stampToHour($stamp) - { - } - - /** - * Returns a numeric minute given a timestamp - * @param int timestamp (depending on implementation) - * @return int minute (e.g. 34) - * @access protected - */ - function stampToMinute($stamp) - { - } - - /** - * Returns a numeric second given a timestamp - * @param int timestamp (depending on implementation) - * @return int second (e.g. 51) - * @access protected - */ - function stampToSecond($stamp) - { - } - - /** - * Returns a timestamp. Can be worth "caching" generated - * timestamps in a static variable, identified by the - * params this method accepts, to timestamp will only - * be calculated once. - * @param int year (e.g. 2003) - * @param int month (e.g. 9) - * @param int day (e.g. 13) - * @param int hour (e.g. 13) - * @param int minute (e.g. 34) - * @param int second (e.g. 53) - * @return int (depends on implementation) - * @access protected - */ - function dateToStamp($y,$m,$d,$h,$i,$s) - { - } - - /** - * The upper limit on years that the Calendar Engine can work with - * @return int (e.g. 2037) - * @access protected - */ - function getMaxYears() - { - } - - /** - * The lower limit on years that the Calendar Engine can work with - * @return int (e.g 1902) - * @access protected - */ - function getMinYears() - { - } - - /** - * Returns the number of months in a year - * @param int (optional) year to get months for - * @return int (e.g. 12) - * @access protected - */ - function getMonthsInYear($y=null) - { - } - - /** - * Returns the number of days in a month, given year and month - * @param int year (e.g. 2003) - * @param int month (e.g. 9) - * @return int days in month - * @access protected - */ - function getDaysInMonth($y, $m) - { - } - - /** - * Returns numeric representation of the day of the week in a month, - * given year and month - * @param int year (e.g. 2003) - * @param int month (e.g. 9) - * @return int - * @access protected - */ - function getFirstDayInMonth ($y, $m) - { - } - - /** - * Returns the number of days in a week - * @param int year (2003) - * @param int month (9) - * @param int day (4) - * @return int (e.g. 7) - * @access protected - */ - function getDaysInWeek($y=NULL, $m=NULL, $d=NULL) - { - } - - /** - * Returns the number of the week in the year (ISO-8601), given a date - * @param int year (2003) - * @param int month (9) - * @param int day (4) - * @return int week number - * @access protected - */ - function getWeekNInYear($y, $m, $d) - { - } - - /** - * Returns the number of the week in the month, given a date - * @param int year (2003) - * @param int month (9) - * @param int day (4) - * @param int first day of the week (default: 1 - monday) - * @return int week number - * @access protected - */ - function getWeekNInMonth($y, $m, $d, $firstDay=1) - { - } - - /** - * Returns the number of weeks in the month - * @param int year (2003) - * @param int month (9) - * @param int first day of the week (default: 1 - monday) - * @return int weeks number - * @access protected - */ - function getWeeksInMonth($y, $m) - { - } - - /** - * Returns the number of the day of the week (0=sunday, 1=monday...) - * @param int year (2003) - * @param int month (9) - * @param int day (4) - * @return int weekday number - * @access protected - */ - function getDayOfWeek($y, $m, $d) - { - } - - /** - * Returns the numeric values of the days of the week. - * @param int year (2003) - * @param int month (9) - * @param int day (4) - * @return array list of numeric values of days in week, beginning 0 - * @access protected - */ - function getWeekDays($y=NULL, $m=NULL, $d=NULL) - { - } - - /** - * Returns the default first day of the week as an integer. Must be a - * member of the array returned from getWeekDays - * @param int year (2003) - * @param int month (9) - * @param int day (4) - * @return int (e.g. 1 for Monday) - * @see getWeekDays - * @access protected - */ - function getFirstDayOfWeek($y=NULL, $m=NULL, $d=NULL) - { - } - - /** - * Returns the number of hours in a day
- * @param int (optional) day to get hours for - * @return int (e.g. 24) - * @access protected - */ - function getHoursInDay($y=null,$m=null,$d=null) - { - } - - /** - * Returns the number of minutes in an hour - * @param int (optional) hour to get minutes for - * @return int - * @access protected - */ - function getMinutesInHour($y=null,$m=null,$d=null,$h=null) - { - } - - /** - * Returns the number of seconds in a minutes - * @param int (optional) minute to get seconds for - * @return int - * @access protected - */ - function getSecondsInMinute($y=null,$m=null,$d=null,$h=null,$i=null) - { - } -} -?> \ No newline at end of file diff --git a/glmPEAR/Calendar/Engine/PearDate.php b/glmPEAR/Calendar/Engine/PearDate.php deleted file mode 100755 index 6f3f992..0000000 --- a/glmPEAR/Calendar/Engine/PearDate.php +++ /dev/null @@ -1,407 +0,0 @@ - | -// +----------------------------------------------------------------------+ -// -// $Id: PearDate.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ -// -/** - * @package Calendar - * @version $Id: PearDate.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ - */ -/** - * Load PEAR::Date class - */ -require_once 'Date.php'; - -/** - * Performs calendar calculations based on the PEAR::Date class - * Timestamps are in the ISO-8601 format (YYYY-MM-DD HH:MM:SS) - * @package Calendar - * @access protected - */ -class Calendar_Engine_PearDate /* implements Calendar_Engine_Interface */ -{ - /** - * Makes sure a given timestamp is only ever parsed once - * Uses a static variable to prevent date() being used twice - * for a date which is already known - * @param mixed Any timestamp format recognized by Pear::Date - * @return object Pear::Date object - * @access protected - */ - function stampCollection($stamp) - { - static $stamps = array(); - if (!isset($stamps[$stamp])) { - $stamps[$stamp] = new Date($stamp); - } - return $stamps[$stamp]; - } - - /** - * Returns a numeric year given a iso-8601 datetime - * @param string iso-8601 datetime (YYYY-MM-DD HH:MM:SS) - * @return int year (e.g. 2003) - * @access protected - */ - function stampToYear($stamp) - { - $date = Calendar_Engine_PearDate::stampCollection($stamp); - return (int)$date->year; - } - - /** - * Returns a numeric month given a iso-8601 datetime - * @param string iso-8601 datetime (YYYY-MM-DD HH:MM:SS) - * @return int month (e.g. 9) - * @access protected - */ - function stampToMonth($stamp) - { - $date = Calendar_Engine_PearDate::stampCollection($stamp); - return (int)$date->month; - } - - /** - * Returns a numeric day given a iso-8601 datetime - * @param string iso-8601 datetime (YYYY-MM-DD HH:MM:SS) - * @return int day (e.g. 15) - * @access protected - */ - function stampToDay($stamp) - { - $date = Calendar_Engine_PearDate::stampCollection($stamp); - return (int)$date->day; - } - - /** - * Returns a numeric hour given a iso-8601 datetime - * @param string iso-8601 datetime (YYYY-MM-DD HH:MM:SS) - * @return int hour (e.g. 13) - * @access protected - */ - function stampToHour($stamp) - { - $date = Calendar_Engine_PearDate::stampCollection($stamp); - return (int)$date->hour; - } - - /** - * Returns a numeric minute given a iso-8601 datetime - * @param string iso-8601 datetime (YYYY-MM-DD HH:MM:SS) - * @return int minute (e.g. 34) - * @access protected - */ - function stampToMinute($stamp) - { - $date = Calendar_Engine_PearDate::stampCollection($stamp); - return (int)$date->minute; - } - - /** - * Returns a numeric second given a iso-8601 datetime - * @param string iso-8601 datetime (YYYY-MM-DD HH:MM:SS) - * @return int second (e.g. 51) - * @access protected - */ - function stampToSecond($stamp) - { - $date = Calendar_Engine_PearDate::stampCollection($stamp); - return (int)$date->second; - } - - /** - * Returns a iso-8601 datetime - * @param int year (2003) - * @param int month (9) - * @param int day (13) - * @param int hour (13) - * @param int minute (34) - * @param int second (53) - * @return string iso-8601 datetime - * @access protected - */ - function dateToStamp($y, $m, $d, $h=0, $i=0, $s=0) - { - $r = array(); - Calendar_Engine_PearDate::adjustDate($y, $m, $d, $h, $i, $s); - $key = $y.$m.$d.$h.$i.$s; - if (!isset($r[$key])) { - $r[$key] = sprintf("%04d-%02d-%02d %02d:%02d:%02d", - $y, $m, $d, $h, $i, $s); - } - return $r[$key]; - } - - /** - * Set the correct date values (useful for math operations on dates) - * @param int year (2003) - * @param int month (9) - * @param int day (13) - * @param int hour (13) - * @param int minute (34) - * @param int second (53) - * @access protected - */ - function adjustDate(&$y, &$m, &$d, &$h, &$i, &$s) - { - if ($s < 0) { - $m -= floor($s / 60); - $s = -$s % 60; - } - if ($s > 60) { - $m += floor($s / 60); - $s %= 60; - } - if ($i < 0) { - $h -= floor($i / 60); - $i = -$i % 60; - } - if ($i > 60) { - $h += floor($i / 60); - $i %= 60; - } - if ($h < 0) { - $d -= floor($h / 24); - $h = -$h % 24; - } - if ($h > 24) { - $d += floor($h / 24); - $h %= 24; - } - for(; $m < 1; $y--, $m+=12); - for(; $m > 12; $y++, $m-=12); - - while ($d < 1) { - if ($m > 1) { - $m--; - } else { - $m = 12; - $y--; - } - $d += Date_Calc::daysInMonth($m, $y); - } - for ($max_days = Date_Calc::daysInMonth($m, $y); $d > $max_days; ) { - $d -= $max_days; - if ($m < 12) { - $m++; - } else { - $m = 1; - $y++; - } - } - } - - /** - * The upper limit on years that the Calendar Engine can work with - * @return int 9999 - * @access protected - */ - function getMaxYears() - { - return 9999; - } - - /** - * The lower limit on years that the Calendar Engine can work with - * @return int 0 - * @access protected - */ - function getMinYears() - { - return 0; - } - - /** - * Returns the number of months in a year - * @return int (12) - * @access protected - */ - function getMonthsInYear($y=null) - { - return 12; - } - - /** - * Returns the number of days in a month, given year and month - * @param int year (2003) - * @param int month (9) - * @return int days in month - * @access protected - */ - function getDaysInMonth($y, $m) - { - return (int)Date_Calc::daysInMonth($m, $y); - } - - /** - * Returns numeric representation of the day of the week in a month, - * given year and month - * @param int year (2003) - * @param int month (9) - * @return int from 0 to 7 - * @access protected - */ - function getFirstDayInMonth($y, $m) - { - return (int)Date_Calc::dayOfWeek(1, $m, $y); - } - - /** - * Returns the number of days in a week - * @param int year (2003) - * @param int month (9) - * @param int day (4) - * @return int (7) - * @access protected - */ - function getDaysInWeek($y=NULL, $m=NULL, $d=NULL) - { - return 7; - } - - /** - * Returns the number of the week in the year (ISO-8601), given a date - * @param int year (2003) - * @param int month (9) - * @param int day (4) - * @return int week number - * @access protected - */ - function getWeekNInYear($y, $m, $d) - { - return Date_Calc::weekOfYear($d, $m, $y); //beware, Date_Calc doesn't follow ISO-8601 standard! - } - - /** - * Returns the number of the week in the month, given a date - * @param int year (2003) - * @param int month (9) - * @param int day (4) - * @param int first day of the week (default: monday) - * @return int week number - * @access protected - */ - function getWeekNInMonth($y, $m, $d, $firstDay=1) - { - $weekEnd = ($firstDay == 0) ? $this->getDaysInWeek()-1 : $firstDay-1; - $end_of_week = (int)Date_Calc::nextDayOfWeek($weekEnd, 1, $m, $y, '%e', true); - $w = 1; - while ($d > $end_of_week) { - ++$w; - $end_of_week += $this->getDaysInWeek(); - } - return $w; - } - - /** - * Returns the number of weeks in the month - * @param int year (2003) - * @param int month (9) - * @param int first day of the week (default: monday) - * @return int weeks number - * @access protected - */ - function getWeeksInMonth($y, $m, $firstDay=1) - { - $FDOM = Date_Calc::firstOfMonthWeekday($m, $y); - if ($FDOM == 0) { - $FDOM = $this->getDaysInWeek(); - } - if ($FDOM > $firstDay) { - $daysInTheFirstWeek = $this->getDaysInWeek() - $FDOM + $firstDay; - $weeks = 1; - } else { - $daysInTheFirstWeek = $firstDay - $FDOM; - $weeks = 0; - } - $daysInTheFirstWeek %= $this->getDaysInWeek(); - return (int)(ceil(($this->getDaysInMonth($y, $m) - $daysInTheFirstWeek) / - $this->getDaysInWeek()) + $weeks); - } - - /** - * Returns the number of the day of the week (0=sunday, 1=monday...) - * @param int year (2003) - * @param int month (9) - * @param int day (4) - * @return int weekday number - * @access protected - */ - function getDayOfWeek($y, $m, $d) - { - return Date_Calc::dayOfWeek($d, $m, $y); - } - - /** - * Returns a list of integer days of the week beginning 0 - * @param int year (2003) - * @param int month (9) - * @param int day (4) - * @return array (0, 1, 2, 3, 4, 5, 6) 1 = Monday - * @access protected - */ - function getWeekDays($y=NULL, $m=NULL, $d=NULL) - { - return array(0, 1, 2, 3, 4, 5, 6); - } - - /** - * Returns the default first day of the week - * @param int year (2003) - * @param int month (9) - * @param int day (4) - * @return int (default 1 = Monday) - * @access protected - */ - function getFirstDayOfWeek($y=NULL, $m=NULL, $d=NULL) - { - return 1; - } - - /** - * Returns the number of hours in a day - * @return int (24) - * @access protected - */ - function getHoursInDay($y=null,$m=null,$d=null) - { - return 24; - } - - /** - * Returns the number of minutes in an hour - * @return int (60) - * @access protected - */ - function getMinutesInHour($y=null,$m=null,$d=null,$h=null) - { - return 60; - } - - /** - * Returns the number of seconds in a minutes - * @return int (60) - * @access protected - */ - function getSecondsInMinute($y=null,$m=null,$d=null,$h=null,$i=null) - { - return 60; - } -} -?> \ No newline at end of file diff --git a/glmPEAR/Calendar/Engine/UnixTS.php b/glmPEAR/Calendar/Engine/UnixTS.php deleted file mode 100755 index 01efd1b..0000000 --- a/glmPEAR/Calendar/Engine/UnixTS.php +++ /dev/null @@ -1,365 +0,0 @@ - | -// +----------------------------------------------------------------------+ -// -// $Id: UnixTS.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ -// -/** - * @package Calendar - * @version $Id: UnixTS.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ - */ -/** - * Performs calendar calculations based on the PHP date() function and - * Unix timestamps (using PHP's mktime() function). - * @package Calendar - * @access protected - */ -class Calendar_Engine_UnixTS /* implements Calendar_Engine_Interface */ -{ - /** - * Makes sure a given timestamp is only ever parsed once - *
-     * array (
-     *  [0] => year (e.g 2003),
-     *  [1] => month (e.g 9),
-     *  [2] => day (e.g 6),
-     *  [3] => hour (e.g 14),
-     *  [4] => minute (e.g 34),
-     *  [5] => second (e.g 45),
-     *  [6] => num days in month (e.g. 31),
-     *  [7] => week in year (e.g. 50),
-     *  [8] => day in week (e.g. 0 for Sunday)
-     * )
-     * 
- * Uses a static variable to prevent date() being used twice - * for a date which is already known - * @param int Unix timestamp - * @return array - * @access protected - */ - function stampCollection($stamp) - { - static $stamps = array(); - if ( !isset($stamps[$stamp]) ) { - $date = @date('Y n j H i s t W w',$stamp); - $stamps[$stamp] = sscanf($date, "%d %d %d %d %d %d %d %d %d"); - } - return $stamps[$stamp]; - } - - /** - * Returns a numeric year given a timestamp - * @param int Unix timestamp - * @return int year (e.g. 2003) - * @access protected - */ - function stampToYear($stamp) - { - $date = Calendar_Engine_UnixTS::stampCollection($stamp); - return (int)$date[0]; - } - - /** - * Returns a numeric month given a timestamp - * @param int Unix timestamp - * @return int month (e.g. 9) - * @access protected - */ - function stampToMonth($stamp) - { - $date = Calendar_Engine_UnixTS::stampCollection($stamp); - return (int)$date[1]; - } - - /** - * Returns a numeric day given a timestamp - * @param int Unix timestamp - * @return int day (e.g. 15) - * @access protected - */ - function stampToDay($stamp) - { - $date = Calendar_Engine_UnixTS::stampCollection($stamp); - return (int)$date[2]; - } - - /** - * Returns a numeric hour given a timestamp - * @param int Unix timestamp - * @return int hour (e.g. 13) - * @access protected - */ - function stampToHour($stamp) - { - $date = Calendar_Engine_UnixTS::stampCollection($stamp); - return (int)$date[3]; - } - - /** - * Returns a numeric minute given a timestamp - * @param int Unix timestamp - * @return int minute (e.g. 34) - * @access protected - */ - function stampToMinute($stamp) - { - $date = Calendar_Engine_UnixTS::stampCollection($stamp); - return (int)$date[4]; - } - - /** - * Returns a numeric second given a timestamp - * @param int Unix timestamp - * @return int second (e.g. 51) - * @access protected - */ - function stampToSecond($stamp) - { - $date = Calendar_Engine_UnixTS::stampCollection($stamp); - return (int)$date[5]; - } - - /** - * Returns a timestamp - * @param int year (2003) - * @param int month (9) - * @param int day (13) - * @param int hour (13) - * @param int minute (34) - * @param int second (53) - * @return int Unix timestamp - * @access protected - */ - function dateToStamp($y, $m, $d, $h=0, $i=0, $s=0) - { - static $dates = array(); - if ( !isset($dates[$y][$m][$d][$h][$i][$s]) ) { - $dates[$y][$m][$d][$h][$i][$s] = @mktime($h, $i, $s, $m, $d, $y); - } - return $dates[$y][$m][$d][$h][$i][$s]; - } - - /** - * The upper limit on years that the Calendar Engine can work with - * @return int (2037) - * @access protected - */ - function getMaxYears() - { - return 2037; - } - - /** - * The lower limit on years that the Calendar Engine can work with - * @return int (1970 if it's Windows and 1902 for all other OSs) - * @access protected - */ - function getMinYears() - { - return $min = strpos(PHP_OS, 'WIN') === false ? 1902 : 1970; - } - - /** - * Returns the number of months in a year - * @return int (12) - * @access protected - */ - function getMonthsInYear($y=null) - { - return 12; - } - - /** - * Returns the number of days in a month, given year and month - * @param int year (2003) - * @param int month (9) - * @return int days in month - * @access protected - */ - function getDaysInMonth($y, $m) - { - $stamp = Calendar_Engine_UnixTS::dateToStamp($y,$m,1); - $date = Calendar_Engine_UnixTS::stampCollection($stamp); - return $date[6]; - } - - /** - * Returns numeric representation of the day of the week in a month, - * given year and month - * @param int year (2003) - * @param int month (9) - * @return int from 0 to 6 - * @access protected - */ - function getFirstDayInMonth($y, $m) - { - $stamp = Calendar_Engine_UnixTS::dateToStamp($y,$m,1); - $date = Calendar_Engine_UnixTS::stampCollection($stamp); - return $date[8]; - } - - /** - * Returns the number of days in a week - * @param int year (2003) - * @param int month (9) - * @param int day (4) - * @return int (7) - * @access protected - */ - function getDaysInWeek($y=NULL, $m=NULL, $d=NULL) - { - return 7; - } - - /** - * Returns the number of the week in the year (ISO-8601), given a date - * @param int year (2003) - * @param int month (9) - * @param int day (4) - * @return int week number - * @access protected - */ - function getWeekNInYear($y, $m, $d) - { - $stamp = Calendar_Engine_UnixTS::dateToStamp($y,$m,$d); - $date = Calendar_Engine_UnixTS::stampCollection($stamp); - return $date[7]; - } - - /** - * Returns the number of the week in the month, given a date - * @param int year (2003) - * @param int month (9) - * @param int day (4) - * @param int first day of the week (default: monday) - * @return int week number - * @access protected - */ - function getWeekNInMonth($y, $m, $d, $firstDay=1) - { - $weekEnd = ($firstDay == 0) ? $this->getDaysInWeek()-1 : $firstDay-1; - $end_of_week = 1; - while (@date('w', @mktime(0, 0, 0, $m, $end_of_week, $y)) != $weekEnd) { - ++$end_of_week; //find first weekend of the month - } - $w = 1; - while ($d > $end_of_week) { - ++$w; - $end_of_week += $this->getDaysInWeek(); - } - return $w; - } - - /** - * Returns the number of weeks in the month - * @param int year (2003) - * @param int month (9) - * @param int first day of the week (default: monday) - * @return int weeks number - * @access protected - */ - function getWeeksInMonth($y, $m, $firstDay=1) - { - $FDOM = $this->getFirstDayInMonth($y, $m); - if ($FDOM == 0) { - $FDOM = $this->getDaysInWeek(); - } - if ($FDOM > $firstDay) { - $daysInTheFirstWeek = $this->getDaysInWeek() - $FDOM + $firstDay; - $weeks = 1; - } else { - $daysInTheFirstWeek = $firstDay - $FDOM; - $weeks = 0; - } - $daysInTheFirstWeek %= $this->getDaysInWeek(); - return (int)(ceil(($this->getDaysInMonth($y, $m) - $daysInTheFirstWeek) / - $this->getDaysInWeek()) + $weeks); - } - - /** - * Returns the number of the day of the week (0=sunday, 1=monday...) - * @param int year (2003) - * @param int month (9) - * @param int day (4) - * @return int weekday number - * @access protected - */ - function getDayOfWeek($y, $m, $d) - { - $stamp = Calendar_Engine_UnixTS::dateToStamp($y,$m,$d); - $date = Calendar_Engine_UnixTS::stampCollection($stamp); - return $date[8]; - } - - /** - * Returns a list of integer days of the week beginning 0 - * @param int year (2003) - * @param int month (9) - * @param int day (4) - * @return array (0,1,2,3,4,5,6) 1 = Monday - * @access protected - */ - function getWeekDays($y=NULL, $m=NULL, $d=NULL) - { - return array(0, 1, 2, 3, 4, 5, 6); - } - - /** - * Returns the default first day of the week - * @param int year (2003) - * @param int month (9) - * @param int day (4) - * @return int (default 1 = Monday) - * @access protected - */ - function getFirstDayOfWeek($y=NULL, $m=NULL, $d=NULL) - { - return 1; - } - - /** - * Returns the number of hours in a day - * @return int (24) - * @access protected - */ - function getHoursInDay($y=null,$m=null,$d=null) - { - return 24; - } - - /** - * Returns the number of minutes in an hour - * @return int (60) - * @access protected - */ - function getMinutesInHour($y=null,$m=null,$d=null,$h=null) - { - return 60; - } - - /** - * Returns the number of seconds in a minutes - * @return int (60) - * @access protected - */ - function getSecondsInMinute($y=null,$m=null,$d=null,$h=null,$i=null) - { - return 60; - } -} -?> \ No newline at end of file diff --git a/glmPEAR/Calendar/Factory.php b/glmPEAR/Calendar/Factory.php deleted file mode 100755 index 562d479..0000000 --- a/glmPEAR/Calendar/Factory.php +++ /dev/null @@ -1,145 +0,0 @@ - | -// | Lorenzo Alberton | -// +----------------------------------------------------------------------+ -// -// $Id: Factory.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ -// -/** - * @package Calendar - * @version $Id: Factory.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ - */ - -/** - * Allows Calendar include path to be redefined - * @ignore - */ -if (!defined('CALENDAR_ROOT')) { - define('CALENDAR_ROOT', 'Calendar'.DIRECTORY_SEPARATOR); -} - -/** - * Load Calendar base class - */ -require_once CALENDAR_ROOT.'Calendar.php'; - -/** - * Contains a factory method to return a Singleton instance of a class - * implementing the Calendar_Engine_Interface.
- * For Month objects, to control type of month returned, use CALENDAR_MONTH_STATE - * constact e.g.; - * - * require_once 'Calendar/Factory.php'; - * define ('CALENDAR_MONTH_STATE',CALENDAR_USE_MONTH_WEEKDAYS); // Use Calendar_Month_Weekdays - * // define ('CALENDAR_MONTH_STATE',CALENDAR_USE_MONTH_WEEKS); // Use Calendar_Month_Weeks - * // define ('CALENDAR_MONTH_STATE',CALENDAR_USE_MONTH); // Use Calendar_Month - * - * It defaults to building Calendar_Month objects.
- * Use the constract CALENDAR_FIRST_DAY_OF_WEEK to control the first day of the week - * for Month or Week objects (e.g. 0 = Sunday, 6 = Saturday) - * @package Calendar - * @access protected - */ -class Calendar_Factory -{ - /** - * Creates a calendar object given the type and units - * @param string class of calendar object to create - * @param int year - * @param int month - * @param int day - * @param int hour - * @param int minute - * @param int second - * @return object subclass of Calendar - * @access public - * @static - */ - function create($type, $y = 2000, $m = 1, $d = 1, $h = 0, $i = 0, $s = 0) - { - $firstDay = defined('CALENDAR_FIRST_DAY_OF_WEEK') ? CALENDAR_FIRST_DAY_OF_WEEK : 1; - switch ($type) { - case 'Day': - require_once CALENDAR_ROOT.'Day.php'; - return new Calendar_Day($y,$m,$d); - case 'Month': - // Set default state for which month type to build - if (!defined('CALENDAR_MONTH_STATE')) { - define('CALENDAR_MONTH_STATE', CALENDAR_USE_MONTH); - } - switch (CALENDAR_MONTH_STATE) { - case CALENDAR_USE_MONTH_WEEKDAYS: - require_once CALENDAR_ROOT.'Month/Weekdays.php'; - $class = 'Calendar_Month_Weekdays'; - break; - case CALENDAR_USE_MONTH_WEEKS: - require_once CALENDAR_ROOT.'Month/Weeks.php'; - $class = 'Calendar_Month_Weeks'; - break; - case CALENDAR_USE_MONTH: - default: - require_once CALENDAR_ROOT.'Month.php'; - $class = 'Calendar_Month'; - break; - } - return new $class($y, $m, $firstDay); - case 'Week': - require_once CALENDAR_ROOT.'Week.php'; - return new Calendar_Week($y, $m, $d, $firstDay); - case 'Hour': - require_once CALENDAR_ROOT.'Hour.php'; - return new Calendar_Hour($y, $m, $d, $h); - case 'Minute': - require_once CALENDAR_ROOT.'Minute.php'; - return new Calendar_Minute($y, $m, $d, $h, $i); - case 'Second': - require_once CALENDAR_ROOT.'Second.php'; - return new Calendar_Second($y,$m,$d,$h,$i,$s); - case 'Year': - require_once CALENDAR_ROOT.'Year.php'; - return new Calendar_Year($y); - default: - require_once 'PEAR.php'; - PEAR::raiseError( - 'Calendar_Factory::create() unrecognised type: '.$type, null, PEAR_ERROR_TRIGGER, - E_USER_NOTICE, 'Calendar_Factory::create()'); - return false; - } - } - /** - * Creates an instance of a calendar object, given a type and timestamp - * @param string type of object to create - * @param mixed timestamp (depending on Calendar engine being used) - * @return object subclass of Calendar - * @access public - * @static - */ - function & createByTimestamp($type, $stamp) - { - $cE = & Calendar_Engine_Factory::getEngine(); - $y = $cE->stampToYear($stamp); - $m = $cE->stampToMonth($stamp); - $d = $cE->stampToDay($stamp); - $h = $cE->stampToHour($stamp); - $i = $cE->stampToMinute($stamp); - $s = $cE->stampToSecond($stamp); - $cal = Calendar_Factory::create($type, $y, $m, $d, $h, $i, $s); - return $cal; - } -} -?> \ No newline at end of file diff --git a/glmPEAR/Calendar/Hour.php b/glmPEAR/Calendar/Hour.php deleted file mode 100755 index 6ae70ba..0000000 --- a/glmPEAR/Calendar/Hour.php +++ /dev/null @@ -1,113 +0,0 @@ - | -// +----------------------------------------------------------------------+ -// -// $Id: Hour.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ -// -/** - * @package Calendar - * @version $Id: Hour.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ - */ - -/** - * Allows Calendar include path to be redefined - * @ignore - */ -if (!defined('CALENDAR_ROOT')) { - define('CALENDAR_ROOT', 'Calendar'.DIRECTORY_SEPARATOR); -} - -/** - * Load Calendar base class - */ -require_once CALENDAR_ROOT.'Calendar.php'; - -/** - * Represents an Hour and builds Minutes - * - * require_once 'Calendar'.DIRECTORY_SEPARATOR.'Hour.php'; - * $Hour = & new Calendar_Hour(2003, 10, 21, 15); // Oct 21st 2003, 3pm - * $Hour->build(); // Build Calendar_Minute objects - * while ($Minute = & $Hour->fetch()) { - * echo $Minute->thisMinute().'
'; - * } - *
- * @package Calendar - * @access public - */ -class Calendar_Hour extends Calendar -{ - /** - * Constructs Calendar_Hour - * @param int year e.g. 2003 - * @param int month e.g. 5 - * @param int day e.g. 11 - * @param int hour e.g. 13 - * @access public - */ - function Calendar_Hour($y, $m, $d, $h) - { - Calendar::Calendar($y, $m, $d, $h); - } - - /** - * Builds the Minutes in the Hour - * @param array (optional) Calendar_Minute objects representing selected dates - * @return boolean - * @access public - */ - function build($sDates=array()) - { - require_once CALENDAR_ROOT.'Minute.php'; - $mIH = $this->cE->getMinutesInHour($this->year, $this->month, $this->day, - $this->hour); - for ($i=0; $i < $mIH; $i++) { - $this->children[$i]= - new Calendar_Minute($this->year, $this->month, $this->day, - $this->hour, $i); - } - if (count($sDates) > 0) { - $this->setSelection($sDates); - } - return true; - } - - /** - * Called from build() - * @param array - * @return void - * @access private - */ - function setSelection($sDates) - { - foreach ($sDates as $sDate) { - if ($this->year == $sDate->thisYear() - && $this->month == $sDate->thisMonth() - && $this->day == $sDate->thisDay() - && $this->hour == $sDate->thisHour()) - { - $key = (int)$sDate->thisMinute(); - if (isset($this->children[$key])) { - $sDate->setSelected(); - $this->children[$key] = $sDate; - } - } - } - } -} -?> \ No newline at end of file diff --git a/glmPEAR/Calendar/Minute.php b/glmPEAR/Calendar/Minute.php deleted file mode 100755 index bf1b182..0000000 --- a/glmPEAR/Calendar/Minute.php +++ /dev/null @@ -1,114 +0,0 @@ - | -// +----------------------------------------------------------------------+ -// -// $Id: Minute.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ -// -/** - * @package Calendar - * @version $Id: Minute.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ - */ - -/** - * Allows Calendar include path to be redefined - * @ignore - */ -if (!defined('CALENDAR_ROOT')) { - define('CALENDAR_ROOT', 'Calendar'.DIRECTORY_SEPARATOR); -} - -/** - * Load Calendar base class - */ -require_once CALENDAR_ROOT.'Calendar.php'; - -/** - * Represents a Minute and builds Seconds - * - * require_once 'Calendar'.DIRECTORY_SEPARATOR.'Minute.php'; - * $Minute = & new Calendar_Minute(2003, 10, 21, 15, 31); // Oct 21st 2003, 3:31pm - * $Minute->build(); // Build Calendar_Second objects - * while ($Second = & $Minute->fetch()) { - * echo $Second->thisSecond().'
'; - * } - *
- * @package Calendar - * @access public - */ -class Calendar_Minute extends Calendar -{ - /** - * Constructs Minute - * @param int year e.g. 2003 - * @param int month e.g. 5 - * @param int day e.g. 11 - * @param int hour e.g. 13 - * @param int minute e.g. 31 - * @access public - */ - function Calendar_Minute($y, $m, $d, $h, $i) - { - Calendar::Calendar($y, $m, $d, $h, $i); - } - - /** - * Builds the Calendar_Second objects - * @param array (optional) Calendar_Second objects representing selected dates - * @return boolean - * @access public - */ - function build($sDates=array()) - { - require_once CALENDAR_ROOT.'Second.php'; - $sIM = $this->cE->getSecondsInMinute($this->year, $this->month, - $this->day, $this->hour, $this->minute); - for ($i=0; $i < $sIM; $i++) { - $this->children[$i] = new Calendar_Second($this->year, $this->month, - $this->day, $this->hour, $this->minute, $i); - } - if (count($sDates) > 0) { - $this->setSelection($sDates); - } - return true; - } - - /** - * Called from build() - * @param array - * @return void - * @access private - */ - function setSelection($sDates) - { - foreach ($sDates as $sDate) { - if ($this->year == $sDate->thisYear() - && $this->month == $sDate->thisMonth() - && $this->day == $sDate->thisDay() - && $this->hour == $sDate->thisHour() - && $this->minute == $sDate->thisMinute()) - { - $key = (int)$sDate->thisSecond(); - if (isset($this->children[$key])) { - $sDate->setSelected(); - $this->children[$key] = $sDate; - } - } - } - } -} -?> \ No newline at end of file diff --git a/glmPEAR/Calendar/Month.php b/glmPEAR/Calendar/Month.php deleted file mode 100755 index e02d5a6..0000000 --- a/glmPEAR/Calendar/Month.php +++ /dev/null @@ -1,114 +0,0 @@ - | -// +----------------------------------------------------------------------+ -// -// $Id: Month.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ -// -/** - * @package Calendar - * @version $Id: Month.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ - */ - -/** - * Allows Calendar include path to be redefined - * @ignore - */ -if (!defined('CALENDAR_ROOT')) { - define('CALENDAR_ROOT', 'Calendar'.DIRECTORY_SEPARATOR); -} - -/** - * Load Calendar base class - */ -require_once CALENDAR_ROOT.'Calendar.php'; - -/** - * Represents a Month and builds Days - * - * require_once 'Calendar/Month.php'; - * $Month = & new Calendar_Month(2003, 10); // Oct 2003 - * $Month->build(); // Build Calendar_Day objects - * while ($Day = & $Month->fetch()) { - * echo $Day->thisDay().'
'; - * } - *
- * @package Calendar - * @access public - */ -class Calendar_Month extends Calendar -{ - /** - * Constructs Calendar_Month - * @param int $y year e.g. 2003 - * @param int $m month e.g. 5 - * @param int $firstDay first day of the week [optional] - * @access public - */ - function Calendar_Month($y, $m, $firstDay=null) - { - Calendar::Calendar($y, $m); - $this->firstDay = $this->defineFirstDayOfWeek($firstDay); - } - - /** - * Builds Day objects for this Month. Creates as many Calendar_Day objects - * as there are days in the month - * @param array (optional) Calendar_Day objects representing selected dates - * @return boolean - * @access public - */ - function build($sDates=array()) - { - require_once CALENDAR_ROOT.'Day.php'; - $daysInMonth = $this->cE->getDaysInMonth($this->year, $this->month); - for ($i=1; $i<=$daysInMonth; $i++) { - $this->children[$i] = new Calendar_Day($this->year, $this->month, $i); - } - if (count($sDates) > 0) { - $this->setSelection($sDates); - } - return true; - } - - /** - * Called from build() - * @param array - * @return void - * @access private - */ - function setSelection($sDates) - { - foreach ($sDates as $sDate) { - if ($this->year == $sDate->thisYear() - && $this->month == $sDate->thisMonth() - ) { - $key = $sDate->thisDay(); - if (isset($this->children[$key])) { - $sDate->setSelected(); - $class = strtolower(get_class($sDate)); - if ($class == 'calendar_day' || $class == 'calendar_decorator') { - $sDate->setFirst($this->children[$key]->isFirst()); - $sDate->setLast($this->children[$key]->isLast()); - } - $this->children[$key] = $sDate; - } - } - } - } -} -?> \ No newline at end of file diff --git a/glmPEAR/Calendar/Month/Weekdays.php b/glmPEAR/Calendar/Month/Weekdays.php deleted file mode 100755 index 0b3a613..0000000 --- a/glmPEAR/Calendar/Month/Weekdays.php +++ /dev/null @@ -1,189 +0,0 @@ - | -// +----------------------------------------------------------------------+ -// -// $Id: Weekdays.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ -// -/** - * @package Calendar - * @version $Id: Weekdays.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ - */ - -/** - * Allows Calendar include path to be redefined - * @ignore - */ -if (!defined('CALENDAR_ROOT')) { - define('CALENDAR_ROOT', 'Calendar'.DIRECTORY_SEPARATOR); -} - -/** - * Load Calendar base class - */ -require_once CALENDAR_ROOT.'Calendar.php'; - -/** - * Load base month - */ -require_once CALENDAR_ROOT.'Month.php'; - -/** - * Represents a Month and builds Days in tabular form
- * - * require_once 'Calendar/Month/Weekdays.php'; - * $Month = & new Calendar_Month_Weekdays(2003, 10); // Oct 2003 - * $Month->build(); // Build Calendar_Day objects - * while ($Day = & $Month->fetch()) { - * if ($Day->isFirst()) { - * echo ''; - * } - * if ($Day->isEmpty()) { - * echo ' '; - * } else { - * echo ''.$Day->thisDay().''; - * } - * if ($Day->isLast()) { - * echo ''; - * } - * } - * - * @package Calendar - * @access public - */ -class Calendar_Month_Weekdays extends Calendar_Month -{ - /** - * Instance of Calendar_Table_Helper - * @var Calendar_Table_Helper - * @access private - */ - var $tableHelper; - - /** - * First day of the week - * @access private - * @var string - */ - var $firstDay; - - /** - * Constructs Calendar_Month_Weekdays - * @param int year e.g. 2003 - * @param int month e.g. 5 - * @param int (optional) first day of week (e.g. 0 for Sunday, 2 for Tuesday etc.) - * @access public - */ - function Calendar_Month_Weekdays($y, $m, $firstDay=null) - { - Calendar_Month::Calendar_Month($y, $m, $firstDay); - } - - /** - * Builds Day objects in tabular form, to allow display of calendar month - * with empty cells if the first day of the week does not fall on the first - * day of the month. - * @see Calendar_Day::isEmpty() - * @see Calendar_Day_Base::isFirst() - * @see Calendar_Day_Base::isLast() - * @param array (optional) Calendar_Day objects representing selected dates - * @return boolean - * @access public - */ - function build($sDates=array()) - { - require_once CALENDAR_ROOT.'Table/Helper.php'; - $this->tableHelper = & new Calendar_Table_Helper($this, $this->firstDay); - Calendar_Month::build($sDates); - $this->buildEmptyDaysBefore(); - $this->shiftDays(); - $this->buildEmptyDaysAfter(); - $this->setWeekMarkers(); - return true; - } - - /** - * Prepends empty days before the real days in the month - * @return void - * @access private - */ - function buildEmptyDaysBefore() - { - $eBefore = $this->tableHelper->getEmptyDaysBefore(); - for ($i=0; $i < $eBefore; $i++) { - $stamp = $this->cE->dateToStamp($this->year, $this->month, -$i); - $Day = new Calendar_Day( - $this->cE->stampToYear($stamp), - $this->cE->stampToMonth($stamp), - $this->cE->stampToDay($stamp)); - $Day->setEmpty(); - $Day->adjust(); - array_unshift($this->children, $Day); - } - } - - /** - * Shifts the array of children forward, if necessary - * @return void - * @access private - */ - function shiftDays() - { - if (isset ($this->children[0])) { - array_unshift($this->children, null); - unset($this->children[0]); - } - } - - /** - * Appends empty days after the real days in the month - * @return void - * @access private - */ - function buildEmptyDaysAfter() - { - $eAfter = $this->tableHelper->getEmptyDaysAfter(); - $sDOM = $this->tableHelper->getNumTableDaysInMonth(); - for ($i = 1; $i <= $sDOM-$eAfter; $i++) { - $Day = new Calendar_Day($this->year, $this->month+1, $i); - $Day->setEmpty(); - $Day->adjust(); - array_push($this->children, $Day); - } - } - - /** - * Sets the "markers" for the beginning and of a of week, in the - * built Calendar_Day children - * @return void - * @access private - */ - function setWeekMarkers() - { - $dIW = $this->cE->getDaysInWeek( - $this->thisYear(), - $this->thisMonth(), - $this->thisDay() - ); - $sDOM = $this->tableHelper->getNumTableDaysInMonth(); - for ($i=1; $i <= $sDOM; $i+= $dIW) { - $this->children[$i]->setFirst(); - $this->children[$i+($dIW-1)]->setLast(); - } - } -} -?> \ No newline at end of file diff --git a/glmPEAR/Calendar/Month/Weeks.php b/glmPEAR/Calendar/Month/Weeks.php deleted file mode 100755 index 05b3e6d..0000000 --- a/glmPEAR/Calendar/Month/Weeks.php +++ /dev/null @@ -1,139 +0,0 @@ - | -// | Lorenzo Alberton | -// +----------------------------------------------------------------------+ -// -// $Id: Weeks.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ -// -/** - * @package Calendar - * @version $Id: Weeks.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ - */ - -/** - * Allows Calendar include path to be redefined - * @ignore - */ -if (!defined('CALENDAR_ROOT')) { - define('CALENDAR_ROOT', 'Calendar'.DIRECTORY_SEPARATOR); -} - -/** - * Load Calendar base class - */ -require_once CALENDAR_ROOT.'Calendar.php'; - -/** - * Load base month - */ -require_once CALENDAR_ROOT.'Month.php'; - -/** - * Represents a Month and builds Weeks - * - * require_once 'Calendar'.DIRECTORY_SEPARATOR.'Month'.DIRECTORY_SEPARATOR.'Weeks.php'; - * $Month = & new Calendar_Month_Weeks(2003, 10); // Oct 2003 - * $Month->build(); // Build Calendar_Day objects - * while ($Week = & $Month->fetch()) { - * echo $Week->thisWeek().'
'; - * } - *
- * @package Calendar - * @access public - */ -class Calendar_Month_Weeks extends Calendar_Month -{ - /** - * Instance of Calendar_Table_Helper - * @var Calendar_Table_Helper - * @access private - */ - var $tableHelper; - - /** - * First day of the week - * @access private - * @var string - */ - var $firstDay; - - /** - * Constructs Calendar_Month_Weeks - * @param int year e.g. 2003 - * @param int month e.g. 5 - * @param int (optional) first day of week (e.g. 0 for Sunday, 2 for Tuesday etc.) - * @access public - */ - function Calendar_Month_Weeks($y, $m, $firstDay=null) - { - Calendar_Month::Calendar_Month($y, $m, $firstDay); - } - - /** - * Builds Calendar_Week objects for the Month. Note that Calendar_Week - * builds Calendar_Day object in tabular form (with Calendar_Day->empty) - * @param array (optional) Calendar_Week objects representing selected dates - * @return boolean - * @access public - */ - function build($sDates=array()) - { - require_once CALENDAR_ROOT.'Table/Helper.php'; - $this->tableHelper = & new Calendar_Table_Helper($this, $this->firstDay); - require_once CALENDAR_ROOT.'Week.php'; - $numWeeks = $this->tableHelper->getNumWeeks(); - for ($i=1, $d=1; $i<=$numWeeks; $i++, - $d+=$this->cE->getDaysInWeek( - $this->thisYear(), - $this->thisMonth(), - $this->thisDay()) ) { - $this->children[$i] = new Calendar_Week( - $this->year, $this->month, $d, $this->tableHelper->getFirstDay()); - } - //used to set empty days - $this->children[1]->setFirst(true); - $this->children[$numWeeks]->setLast(true); - - // Handle selected weeks here - if (count($sDates) > 0) { - $this->setSelection($sDates); - } - return true; - } - - /** - * Called from build() - * @param array - * @return void - * @access private - */ - function setSelection($sDates) - { - foreach ($sDates as $sDate) { - if ($this->year == $sDate->thisYear() - && $this->month == $sDate->thisMonth()) - { - $key = $sDate->thisWeek('n_in_month'); - if (isset($this->children[$key])) { - $this->children[$key]->setSelected(); - } - } - } - } -} -?> \ No newline at end of file diff --git a/glmPEAR/Calendar/Second.php b/glmPEAR/Calendar/Second.php deleted file mode 100755 index cbf83d9..0000000 --- a/glmPEAR/Calendar/Second.php +++ /dev/null @@ -1,98 +0,0 @@ - | -// +----------------------------------------------------------------------+ -// -// $Id: Second.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ -// -/** - * @package Calendar - * @version $Id: Second.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ - */ - -/** - * Allows Calendar include path to be redefined - * @ignore - */ -if (!defined('CALENDAR_ROOT')) { - define('CALENDAR_ROOT', 'Calendar'.DIRECTORY_SEPARATOR); -} - -/** - * Load Calendar base class - */ -require_once CALENDAR_ROOT.'Calendar.php'; - -/** - * Represents a Second
- * Note: Seconds do not build other objects - * so related methods are overridden to return NULL - * @package Calendar - */ -class Calendar_Second extends Calendar -{ - /** - * Constructs Second - * @param int year e.g. 2003 - * @param int month e.g. 5 - * @param int day e.g. 11 - * @param int hour e.g. 13 - * @param int minute e.g. 31 - * @param int second e.g. 45 - */ - function Calendar_Second($y, $m, $d, $h, $i, $s) - { - Calendar::Calendar($y, $m, $d, $h, $i, $s); - } - - /** - * Overwrite build - * @return NULL - */ - function build() - { - return null; - } - - /** - * Overwrite fetch - * @return NULL - */ - function fetch() - { - return null; - } - - /** - * Overwrite fetchAll - * @return NULL - */ - function fetchAll() - { - return null; - } - - /** - * Overwrite size - * @return NULL - */ - function size() - { - return null; - } -} -?> \ No newline at end of file diff --git a/glmPEAR/Calendar/Table/Helper.php b/glmPEAR/Calendar/Table/Helper.php deleted file mode 100755 index a111559..0000000 --- a/glmPEAR/Calendar/Table/Helper.php +++ /dev/null @@ -1,280 +0,0 @@ - | -// +----------------------------------------------------------------------+ -// -// $Id: Helper.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ -// -/** - * @package Calendar - * @version $Id: Helper.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ - */ - -/** - * Used by Calendar_Month_Weekdays, Calendar_Month_Weeks and Calendar_Week to - * help with building the calendar in tabular form - * @package Calendar - * @access protected - */ -class Calendar_Table_Helper -{ - /** - * Instance of the Calendar object being helped. - * @var object - * @access private - */ - var $calendar; - - /** - * Instance of the Calendar_Engine - * @var object - * @access private - */ - var $cE; - - /** - * First day of the week - * @access private - * @var string - */ - var $firstDay; - - /** - * The seven days of the week named - * @access private - * @var array - */ - var $weekDays; - - /** - * Days of the week ordered with $firstDay at the beginning - * @access private - * @var array - */ - var $daysOfWeek = array(); - - /** - * Days of the month built from days of the week - * @access private - * @var array - */ - var $daysOfMonth = array(); - - /** - * Number of weeks in month - * @var int - * @access private - */ - var $numWeeks = null; - - /** - * Number of emtpy days before real days begin in month - * @var int - * @access private - */ - var $emptyBefore = 0; - - /** - * Constructs Calendar_Table_Helper - * @param object Calendar_Month_Weekdays, Calendar_Month_Weeks, Calendar_Week - * @param int (optional) first day of the week e.g. 1 for Monday - * @access protected - */ - function Calendar_Table_Helper(& $calendar, $firstDay=null) - { - $this->calendar = & $calendar; - $this->cE = & $calendar->getEngine(); - if (is_null($firstDay)) { - $firstDay = $this->cE->getFirstDayOfWeek( - $this->calendar->thisYear(), - $this->calendar->thisMonth(), - $this->calendar->thisDay() - ); - } - $this->firstDay = $firstDay; - $this->setFirstDay(); - $this->setDaysOfMonth(); - } - - /** - * Constructs $this->daysOfWeek based on $this->firstDay - * @return void - * @access private - */ - function setFirstDay() - { - $weekDays = $this->cE->getWeekDays( - $this->calendar->thisYear(), - $this->calendar->thisMonth(), - $this->calendar->thisDay() - ); - $endDays = array(); - $tmpDays = array(); - $begin = false; - foreach ($weekDays as $day) { - if ($begin) { - $endDays[] = $day; - } else if ($day === $this->firstDay) { - $begin = true; - $endDays[] = $day; - } else { - $tmpDays[] = $day; - } - } - $this->daysOfWeek = array_merge($endDays, $tmpDays); - } - - /** - * Constructs $this->daysOfMonth - * @return void - * @access private - */ - function setDaysOfMonth() - { - $this->daysOfMonth = $this->daysOfWeek; - $daysInMonth = $this->cE->getDaysInMonth( - $this->calendar->thisYear(), $this->calendar->thisMonth()); - $firstDayInMonth = $this->cE->getFirstDayInMonth( - $this->calendar->thisYear(), $this->calendar->thisMonth()); - $this->emptyBefore=0; - foreach ($this->daysOfMonth as $dayOfWeek) { - if ($firstDayInMonth == $dayOfWeek) { - break; - } - $this->emptyBefore++; - } - $this->numWeeks = ceil( - ($daysInMonth + $this->emptyBefore) - / - $this->cE->getDaysInWeek( - $this->calendar->thisYear(), - $this->calendar->thisMonth(), - $this->calendar->thisDay() - ) - ); - for ($i=1; $i < $this->numWeeks; $i++) { - $this->daysOfMonth = - array_merge($this->daysOfMonth, $this->daysOfWeek); - } - } - - /** - * Returns the first day of the month - * @see Calendar_Engine_Interface::getFirstDayOfWeek() - * @return int - * @access protected - */ - function getFirstDay() - { - return $this->firstDay; - } - - /** - * Returns the order array of days in a week - * @return int - * @access protected - */ - function getDaysOfWeek() - { - return $this->daysOfWeek; - } - - /** - * Returns the number of tabular weeks in a month - * @return int - * @access protected - */ - function getNumWeeks() - { - return $this->numWeeks; - } - - /** - * Returns the number of real days + empty days - * @return int - * @access protected - */ - function getNumTableDaysInMonth() - { - return count($this->daysOfMonth); - } - - /** - * Returns the number of empty days before the real days begin - * @return int - * @access protected - */ - function getEmptyDaysBefore() - { - return $this->emptyBefore; - } - - /** - * Returns the index of the last real day in the month - * @todo Potential performance optimization with static - * @return int - * @access protected - */ - function getEmptyDaysAfter() - { - // Causes bug when displaying more than one month -// static $index; -// if (!isset($index)) { - $index = $this->getEmptyDaysBefore() + $this->cE->getDaysInMonth( - $this->calendar->thisYear(), $this->calendar->thisMonth()); -// } - return $index; - } - - /** - * Returns the index of the last real day in the month, relative to the - * beginning of the tabular week it is part of - * @return int - * @access protected - */ - function getEmptyDaysAfterOffset() - { - $eAfter = $this->getEmptyDaysAfter(); - return $eAfter - ( - $this->cE->getDaysInWeek( - $this->calendar->thisYear(), - $this->calendar->thisMonth(), - $this->calendar->thisDay() - ) * ($this->numWeeks-1) ); - } - - /** - * Returns the timestamp of the first day of the current week - */ - function getWeekStart($y, $m, $d, $firstDay=1) - { - $dow = $this->cE->getDayOfWeek($y, $m, $d); - if ($dow > $firstDay) { - $d -= ($dow - $firstDay); - } - if ($dow < $firstDay) { - $d -= ( - $this->cE->getDaysInWeek( - $this->calendar->thisYear(), - $this->calendar->thisMonth(), - $this->calendar->thisDay() - ) - $firstDay + $dow); - } - return $this->cE->dateToStamp($y, $m, $d); - } -} -?> \ No newline at end of file diff --git a/glmPEAR/Calendar/Util/Textual.php b/glmPEAR/Calendar/Util/Textual.php deleted file mode 100755 index dd78a04..0000000 --- a/glmPEAR/Calendar/Util/Textual.php +++ /dev/null @@ -1,239 +0,0 @@ - | -// | Lorenzo Alberton | -// +----------------------------------------------------------------------+ -// -// $Id: Textual.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ -// -/** - * @package Calendar - * @version $Id: Textual.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ - */ - -/** - * Allows Calendar include path to be redefined - * @ignore - */ -if (!defined('CALENDAR_ROOT')) { - define('CALENDAR_ROOT', 'Calendar'.DIRECTORY_SEPARATOR); -} - -/** - * Load Calendar decorator base class - */ -require_once CALENDAR_ROOT.'Decorator.php'; - -/** - * Static utlities to help with fetching textual representations of months and - * days of the week. - * @package Calendar - * @access public - */ -class Calendar_Util_Textual -{ - - /** - * Returns an array of 12 month names (first index = 1) - * @param string (optional) format of returned months (one,two,short or long) - * @return array - * @access public - * @static - */ - function monthNames($format='long') - { - $formats = array('one'=>'%b', 'two'=>'%b', 'short'=>'%b', 'long'=>'%B'); - if (!array_key_exists($format,$formats)) { - $format = 'long'; - } - $months = array(); - for ($i=1; $i<=12; $i++) { - $stamp = mktime(0, 0, 0, $i, 1, 2003); - $month = strftime($formats[$format], $stamp); - switch($format) { - case 'one': - $month = substr($month, 0, 1); - break; - case 'two': - $month = substr($month, 0, 2); - break; - } - $months[$i] = $month; - } - return $months; - } - - /** - * Returns an array of 7 week day names (first index = 0) - * @param string (optional) format of returned days (one,two,short or long) - * @return array - * @access public - * @static - */ - function weekdayNames($format='long') - { - $formats = array('one'=>'%a', 'two'=>'%a', 'short'=>'%a', 'long'=>'%A'); - if (!array_key_exists($format,$formats)) { - $format = 'long'; - } - $days = array(); - for ($i=0; $i<=6; $i++) { - $stamp = mktime(0, 0, 0, 11, $i+2, 2003); - $day = strftime($formats[$format], $stamp); - switch($format) { - case 'one': - $day = substr($day, 0, 1); - break; - case 'two': - $day = substr($day, 0, 2); - break; - } - $days[$i] = $day; - } - return $days; - } - - /** - * Returns textual representation of the previous month of the decorated calendar object - * @param object subclass of Calendar e.g. Calendar_Month - * @param string (optional) format of returned months (one,two,short or long) - * @return string - * @access public - * @static - */ - function prevMonthName($Calendar, $format='long') - { - $months = Calendar_Util_Textual::monthNames($format); - return $months[$Calendar->prevMonth()]; - } - - /** - * Returns textual representation of the month of the decorated calendar object - * @param object subclass of Calendar e.g. Calendar_Month - * @param string (optional) format of returned months (one,two,short or long) - * @return string - * @access public - * @static - */ - function thisMonthName($Calendar, $format='long') - { - $months = Calendar_Util_Textual::monthNames($format); - return $months[$Calendar->thisMonth()]; - } - - /** - * Returns textual representation of the next month of the decorated calendar object - * @param object subclass of Calendar e.g. Calendar_Month - * @param string (optional) format of returned months (one,two,short or long) - * @return string - * @access public - * @static - */ - function nextMonthName($Calendar, $format='long') - { - $months = Calendar_Util_Textual::monthNames($format); - return $months[$Calendar->nextMonth()]; - } - - /** - * Returns textual representation of the previous day of week of the decorated calendar object - * Note: Requires PEAR::Date - * @param object subclass of Calendar e.g. Calendar_Month - * @param string (optional) format of returned months (one,two,short or long) - * @return string - * @access public - * @static - */ - function prevDayName($Calendar, $format='long') - { - $days = Calendar_Util_Textual::weekdayNames($format); - $stamp = $Calendar->prevDay('timestamp'); - $cE = $Calendar->getEngine(); - require_once 'Date/Calc.php'; - $day = Date_Calc::dayOfWeek($cE->stampToDay($stamp), - $cE->stampToMonth($stamp), $cE->stampToYear($stamp)); - return $days[$day]; - } - - /** - * Returns textual representation of the day of week of the decorated calendar object - * Note: Requires PEAR::Date - * @param object subclass of Calendar e.g. Calendar_Month - * @param string (optional) format of returned months (one,two,short or long) - * @return string - * @access public - * @static - */ - function thisDayName($Calendar, $format='long') - { - $days = Calendar_Util_Textual::weekdayNames($format); - require_once 'Date/Calc.php'; - $day = Date_Calc::dayOfWeek($Calendar->thisDay(), $Calendar->thisMonth(), $Calendar->thisYear()); - return $days[$day]; - } - - /** - * Returns textual representation of the next day of week of the decorated calendar object - * @param object subclass of Calendar e.g. Calendar_Month - * @param string (optional) format of returned months (one,two,short or long) - * @return string - * @access public - * @static - */ - function nextDayName($Calendar, $format='long') - { - $days = Calendar_Util_Textual::weekdayNames($format); - $stamp = $Calendar->nextDay('timestamp'); - $cE = $Calendar->getEngine(); - require_once 'Date/Calc.php'; - $day = Date_Calc::dayOfWeek($cE->stampToDay($stamp), - $cE->stampToMonth($stamp), $cE->stampToYear($stamp)); - return $days[$day]; - } - - /** - * Returns the days of the week using the order defined in the decorated - * calendar object. Only useful for Calendar_Month_Weekdays, Calendar_Month_Weeks - * and Calendar_Week. Otherwise the returned array will begin on Sunday - * @param object subclass of Calendar e.g. Calendar_Month - * @param string (optional) format of returned months (one,two,short or long) - * @return array ordered array of week day names - * @access public - * @static - */ - function orderedWeekdays($Calendar, $format='long') - { - $days = Calendar_Util_Textual::weekdayNames($format); - - // Not so good - need methods to access this information perhaps... - if (isset($Calendar->tableHelper)) { - $ordereddays = $Calendar->tableHelper->daysOfWeek; - } else { - $ordereddays = array(0, 1, 2, 3, 4, 5, 6); - } - - $ordereddays = array_flip($ordereddays); - $i = 0; - $returndays = array(); - foreach ($ordereddays as $key => $value) { - $returndays[$i] = $days[$key]; - $i++; - } - return $returndays; - } -} -?> \ No newline at end of file diff --git a/glmPEAR/Calendar/Util/Uri.php b/glmPEAR/Calendar/Util/Uri.php deleted file mode 100755 index c88b2e4..0000000 --- a/glmPEAR/Calendar/Util/Uri.php +++ /dev/null @@ -1,169 +0,0 @@ - | -// | Lorenzo Alberton | -// +----------------------------------------------------------------------+ -// -// $Id: Uri.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ -// -/** - * @package Calendar - * @version $Id: Uri.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ - */ - -/** - * Utility to help building HTML links for navigating the calendar
- * - * $Day = new Calendar_Day(2003, 10, 23); - * $Uri = & new Calendar_Util_Uri('year', 'month', 'day'); - * echo $Uri->prev($Day,'month'); // Displays year=2003&month=10 - * echo $Uri->prev($Day,'day'); // Displays year=2003&month=10&day=22 - * $Uri->seperator = '/'; - * $Uri->scalar = true; - * echo $Uri->prev($Day,'month'); // Displays 2003/10 - * echo $Uri->prev($Day,'day'); // Displays 2003/10/22 - * - * @package Calendar - * @access public - */ -class Calendar_Util_Uri -{ - /** - * Uri fragments for year, month, day etc. - * @var array - * @access private - */ - var $uris = array(); - - /** - * String to separate fragments with. - * Set to just & for HTML. - * For a scalar URL you might use / as the seperator - * @var string (default XHTML &) - * @access public - */ - var $separator = '&'; - - /** - * To output a "scalar" string - variable names omitted. - * Used for urls like index.php/2004/8/12 - * @var boolean (default false) - * @access public - */ - var $scalar = false; - - /** - * Constructs Calendar_Decorator_Uri - * The term "fragment" means name of a calendar GET variables in the URL - * @param string URI fragment for year - * @param string (optional) URI fragment for month - * @param string (optional) URI fragment for day - * @param string (optional) URI fragment for hour - * @param string (optional) URI fragment for minute - * @param string (optional) URI fragment for second - * @access public - */ - function Calendar_Util_Uri($y, $m=null, $d=null, $h=null, $i=null, $s=null) - { - $this->setFragments($y, $m, $d, $h, $i, $s); - } - - /** - * Sets the URI fragment names - * @param string URI fragment for year - * @param string (optional) URI fragment for month - * @param string (optional) URI fragment for day - * @param string (optional) URI fragment for hour - * @param string (optional) URI fragment for minute - * @param string (optional) URI fragment for second - * @return void - * @access public - */ - function setFragments($y, $m=null, $d=null, $h=null, $i=null, $s=null) { - if (!is_null($y)) $this->uris['Year'] = $y; - if (!is_null($m)) $this->uris['Month'] = $m; - if (!is_null($d)) $this->uris['Day'] = $d; - if (!is_null($h)) $this->uris['Hour'] = $h; - if (!is_null($i)) $this->uris['Minute'] = $i; - if (!is_null($s)) $this->uris['Second'] = $s; - } - - /** - * Gets the URI string for the previous calendar unit - * @param object subclassed from Calendar e.g. Calendar_Month - * @param string calendar unit ( must be year, month, week, day, hour, minute or second) - * @return string - * @access public - */ - function prev($Calendar, $unit) - { - $method = 'prev'.$unit; - $stamp = $Calendar->{$method}('timestamp'); - return $this->buildUriString($Calendar, $method, $stamp); - } - - /** - * Gets the URI string for the current calendar unit - * @param object subclassed from Calendar e.g. Calendar_Month - * @param string calendar unit ( must be year, month, week, day, hour, minute or second) - * @return string - * @access public - */ - function this($Calendar, $unit) - { - $method = 'this'.$unit; - $stamp = $Calendar->{$method}('timestamp'); - return $this->buildUriString($Calendar, $method, $stamp); - } - - /** - * Gets the URI string for the next calendar unit - * @param object subclassed from Calendar e.g. Calendar_Month - * @param string calendar unit ( must be year, month, week, day, hour, minute or second) - * @return string - * @access public - */ - function next($Calendar, $unit) - { - $method = 'next'.$unit; - $stamp = $Calendar->{$method}('timestamp'); - return $this->buildUriString($Calendar, $method, $stamp); - } - - /** - * Build the URI string - * @param string method substring - * @param int timestamp - * @return string build uri string - * @access private - */ - function buildUriString($Calendar, $method, $stamp) - { - $uriString = ''; - $cE = & $Calendar->getEngine(); - $separator = ''; - foreach ($this->uris as $unit => $uri) { - $call = 'stampTo'.$unit; - $uriString .= $separator; - if (!$this->scalar) $uriString .= $uri.'='; - $uriString .= $cE->{$call}($stamp); - $separator = $this->separator; - } - return $uriString; - } -} -?> \ No newline at end of file diff --git a/glmPEAR/Calendar/Validator.php b/glmPEAR/Calendar/Validator.php deleted file mode 100755 index d78ea83..0000000 --- a/glmPEAR/Calendar/Validator.php +++ /dev/null @@ -1,335 +0,0 @@ - | -// +----------------------------------------------------------------------+ -// -// $Id: Validator.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ -// -/** - * @package Calendar - * @version $Id: Validator.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ - */ - -/** - * Validation Error Messages - */ -if (!defined('CALENDAR_VALUE_TOOSMALL')) { - define('CALENDAR_VALUE_TOOSMALL', 'Too small: min = '); -} -if (!defined('CALENDAR_VALUE_TOOLARGE')) { - define('CALENDAR_VALUE_TOOLARGE', 'Too large: max = '); -} - -/** - * Used to validate any given Calendar date object. Instances of this class - * can be obtained from any data object using the getValidator method - * @see Calendar::getValidator() - * @package Calendar - * @access public - */ -class Calendar_Validator -{ - /** - * Instance of the Calendar date object to validate - * @var object - * @access private - */ - var $calendar; - - /** - * Instance of the Calendar_Engine - * @var object - * @access private - */ - var $cE; - - /** - * Array of errors for validation failures - * @var array - * @access private - */ - var $errors = array(); - - /** - * Constructs Calendar_Validator - * @param object subclass of Calendar - * @access public - */ - function Calendar_Validator(& $calendar) - { - $this->calendar = & $calendar; - $this->cE = & $calendar->getEngine(); - } - - /** - * Calls all the other isValidXXX() methods in the validator - * @return boolean - * @access public - */ - function isValid() - { - $checks = array('isValidYear', 'isValidMonth', 'isValidDay', - 'isValidHour', 'isValidMinute', 'isValidSecond'); - $valid = true; - foreach ($checks as $check) { - if (!$this->{$check}()) { - $valid = false; - } - } - return $valid; - } - - /** - * Check whether this is a valid year - * @return boolean - * @access public - */ - function isValidYear() - { - $y = $this->calendar->thisYear(); - $min = $this->cE->getMinYears(); - if ($min > $y) { - $this->errors[] = new Calendar_Validation_Error( - 'Year', $y, CALENDAR_VALUE_TOOSMALL.$min); - return false; - } - $max = $this->cE->getMaxYears(); - if ($y > $max) { - $this->errors[] = new Calendar_Validation_Error( - 'Year', $y, CALENDAR_VALUE_TOOLARGE.$max); - return false; - } - return true; - } - - /** - * Check whether this is a valid month - * @return boolean - * @access public - */ - function isValidMonth() - { - $m = $this->calendar->thisMonth(); - $min = 1; - if ($min > $m) { - $this->errors[] = new Calendar_Validation_Error( - 'Month', $m, CALENDAR_VALUE_TOOSMALL.$min); - return false; - } - $max = $this->cE->getMonthsInYear($this->calendar->thisYear()); - if ($m > $max) { - $this->errors[] = new Calendar_Validation_Error( - 'Month', $m, CALENDAR_VALUE_TOOLARGE.$max); - return false; - } - return true; - } - - /** - * Check whether this is a valid day - * @return boolean - * @access public - */ - function isValidDay() - { - $d = $this->calendar->thisDay(); - $min = 1; - if ($min > $d) { - $this->errors[] = new Calendar_Validation_Error( - 'Day', $d, CALENDAR_VALUE_TOOSMALL.$min); - return false; - } - $max = $this->cE->getDaysInMonth( - $this->calendar->thisYear(), $this->calendar->thisMonth()); - if ($d > $max) { - $this->errors[] = new Calendar_Validation_Error( - 'Day', $d, CALENDAR_VALUE_TOOLARGE.$max); - return false; - } - return true; - } - - /** - * Check whether this is a valid hour - * @return boolean - * @access public - */ - function isValidHour() - { - $h = $this->calendar->thisHour(); - $min = 0; - if ($min > $h) { - $this->errors[] = new Calendar_Validation_Error( - 'Hour', $h, CALENDAR_VALUE_TOOSMALL.$min); - return false; - } - $max = ($this->cE->getHoursInDay($this->calendar->thisDay())-1); - if ($h > $max) { - $this->errors[] = new Calendar_Validation_Error( - 'Hour', $h, CALENDAR_VALUE_TOOLARGE.$max); - return false; - } - return true; - } - - /** - * Check whether this is a valid minute - * @return boolean - * @access public - */ - function isValidMinute() - { - $i = $this->calendar->thisMinute(); - $min = 0; - if ($min > $i) { - $this->errors[] = new Calendar_Validation_Error( - 'Minute', $i, CALENDAR_VALUE_TOOSMALL.$min); - return false; - } - $max = ($this->cE->getMinutesInHour($this->calendar->thisHour())-1); - if ($i > $max) { - $this->errors[] = new Calendar_Validation_Error( - 'Minute', $i, CALENDAR_VALUE_TOOLARGE.$max); - return false; - } - return true; - } - - /** - * Check whether this is a valid second - * @return boolean - * @access public - */ - function isValidSecond() - { - $s = $this->calendar->thisSecond(); - $min = 0; - if ($min > $s) { - $this->errors[] = new Calendar_Validation_Error( - 'Second', $s, CALENDAR_VALUE_TOOSMALL.$min); - return false; - } - $max = ($this->cE->getSecondsInMinute($this->calendar->thisMinute())-1); - if ($s > $max) { - $this->errors[] = new Calendar_Validation_Error( - 'Second', $s, CALENDAR_VALUE_TOOLARGE.$max); - return false; - } - return true; - } - - /** - * Iterates over any validation errors - * @return mixed either Calendar_Validation_Error or false - * @access public - */ - function fetch() - { - $error = each ($this->errors); - if ($error) { - return $error['value']; - } else { - reset($this->errors); - return false; - } - } -} - -/** - * For Validation Error messages - * @see Calendar::fetch() - * @package Calendar - * @access public - */ -class Calendar_Validation_Error -{ - /** - * Date unit (e.g. month,hour,second) which failed test - * @var string - * @access private - */ - var $unit; - - /** - * Value of unit which failed test - * @var int - * @access private - */ - var $value; - - /** - * Validation error message - * @var string - * @access private - */ - var $message; - - /** - * Constructs Calendar_Validation_Error - * @param string Date unit (e.g. month,hour,second) - * @param int Value of unit which failed test - * @param string Validation error message - * @access protected - */ - function Calendar_Validation_Error($unit,$value,$message) - { - $this->unit = $unit; - $this->value = $value; - $this->message = $message; - } - - /** - * Returns the Date unit - * @return string - * @access public - */ - function getUnit() - { - return $this->unit; - } - - /** - * Returns the value of the unit - * @return int - * @access public - */ - function getValue() - { - return $this->value; - } - - /** - * Returns the validation error message - * @return string - * @access public - */ - function getMessage() - { - return $this->message; - } - - /** - * Returns a string containing the unit, value and error message - * @return string - * @access public - */ - function toString () - { - return $this->unit.' = '.$this->value.' ['.$this->message.']'; - } -} -?> \ No newline at end of file diff --git a/glmPEAR/Calendar/Week.php b/glmPEAR/Calendar/Week.php deleted file mode 100755 index 81edf29..0000000 --- a/glmPEAR/Calendar/Week.php +++ /dev/null @@ -1,394 +0,0 @@ - | -// | Lorenzo Alberton | -// +----------------------------------------------------------------------+ -// -// $Id: Week.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ -// -/** - * @package Calendar - * @version $Id: Week.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ - */ - -/** - * Allows Calendar include path to be redefined - * @ignore - */ -if (!defined('CALENDAR_ROOT')) { - define('CALENDAR_ROOT', 'Calendar'.DIRECTORY_SEPARATOR); -} - -/** - * Load Calendar base class - */ -require_once CALENDAR_ROOT.'Calendar.php'; - -/** - * Represents a Week and builds Days in tabular format
- * - * require_once 'Calendar'.DIRECTORY_SEPARATOR.'Week.php'; - * $Week = & new Calendar_Week(2003, 10, 1); Oct 2003, 1st tabular week - * echo ''; - * while ($Day = & $Week->fetch()) { - * if ($Day->isEmpty()) { - * echo ' '; - * } else { - * echo ''.$Day->thisDay().''; - * } - * } - * echo ''; - * - * @package Calendar - * @access public - */ -class Calendar_Week extends Calendar -{ - /** - * Instance of Calendar_Table_Helper - * @var Calendar_Table_Helper - * @access private - */ - var $tableHelper; - - /** - * Stores the timestamp of the first day of this week - * @access private - * @var object - */ - var $thisWeek; - - /** - * Stores the timestamp of first day of previous week - * @access private - * @var object - */ - var $prevWeek; - - /** - * Stores the timestamp of first day of next week - * @access private - * @var object - */ - var $nextWeek; - - /** - * Used by build() to set empty days - * @access private - * @var boolean - */ - var $firstWeek = false; - - /** - * Used by build() to set empty days - * @access private - * @var boolean - */ - var $lastWeek = false; - - /** - * First day of the week (0=sunday, 1=monday...) - * @access private - * @var boolean - */ - var $firstDay = 1; - - /** - * Constructs Week - * @param int year e.g. 2003 - * @param int month e.g. 5 - * @param int a day of the desired week - * @param int (optional) first day of week (e.g. 0 for Sunday, 2 for Tuesday etc.) - * @access public - */ - function Calendar_Week($y, $m, $d, $firstDay=null) - { - require_once CALENDAR_ROOT.'Table/Helper.php'; - Calendar::Calendar($y, $m, $d); - $this->firstDay = $this->defineFirstDayOfWeek($firstDay); - $this->tableHelper = & new Calendar_Table_Helper($this, $this->firstDay); - $this->thisWeek = $this->tableHelper->getWeekStart($y, $m, $d, $this->firstDay); - $this->prevWeek = $this->tableHelper->getWeekStart($y, $m, $d - $this->cE->getDaysInWeek( - $this->thisYear(), - $this->thisMonth(), - $this->thisDay()), $this->firstDay); - $this->nextWeek = $this->tableHelper->getWeekStart($y, $m, $d + $this->cE->getDaysInWeek( - $this->thisYear(), - $this->thisMonth(), - $this->thisDay()), $this->firstDay); - } - - /** - * Defines the calendar by a timestamp (Unix or ISO-8601), replacing values - * passed to the constructor - * @param int|string Unix or ISO-8601 timestamp - * @return void - * @access public - */ - function setTimestamp($ts) - { - parent::setTimestamp($ts); - $this->thisWeek = $this->tableHelper->getWeekStart( - $this->year, $this->month, $this->day, $this->firstDay - ); - $this->prevWeek = $this->tableHelper->getWeekStart( - $this->year, $this->month, $this->day - $this->cE->getDaysInWeek( - $this->thisYear(), - $this->thisMonth(), - $this->thisDay()), $this->firstDay - ); - $this->nextWeek = $this->tableHelper->getWeekStart( - $this->year, $this->month, $this->day + $this->cE->getDaysInWeek( - $this->thisYear(), - $this->thisMonth(), - $this->thisDay()), $this->firstDay - ); - } - - /** - * Builds Calendar_Day objects for this Week - * @param array (optional) Calendar_Day objects representing selected dates - * @return boolean - * @access public - */ - function build($sDates = array()) - { - require_once CALENDAR_ROOT.'Day.php'; - $year = $this->cE->stampToYear($this->thisWeek); - $month = $this->cE->stampToMonth($this->thisWeek); - $day = $this->cE->stampToDay($this->thisWeek); - $end = $this->cE->getDaysInWeek( - $this->thisYear(), - $this->thisMonth(), - $this->thisDay() - ); - - for ($i=1; $i <= $end; $i++) { - $stamp = $this->cE->dateToStamp($year, $month, $day++); - $this->children[$i] = new Calendar_Day( - $this->cE->stampToYear($stamp), - $this->cE->stampToMonth($stamp), - $this->cE->stampToDay($stamp)); - } - - //set empty days (@see Calendar_Month_Weeks::build()) - if ($this->firstWeek) { - $eBefore = $this->tableHelper->getEmptyDaysBefore(); - for ($i=1; $i <= $eBefore; $i++) { - $this->children[$i]->setEmpty(); - } - } - if ($this->lastWeek) { - $eAfter = $this->tableHelper->getEmptyDaysAfterOffset(); - for ($i = $eAfter+1; $i <= $end; $i++) { - $this->children[$i]->setEmpty(); - } - } - - if (count($sDates) > 0) { - $this->setSelection($sDates); - } - return true; - } - - /** - * @param boolean - * @return void - * @access private - */ - function setFirst($state=true) - { - $this->firstWeek = $state; - } - - /** - * @param boolean - * @return void - * @access private - */ - function setLast($state=true) - { - $this->lastWeek = $state; - } - - /** - * Called from build() - * @param array - * @return void - * @access private - */ - function setSelection($sDates) - { - foreach ($sDates as $sDate) { - foreach ($this->children as $key => $child) { - if ($child->thisDay() == $sDate->thisDay() && - $child->thisMonth() == $sDate->thisMonth() && - $child->thisYear() == $sDate->thisYear() - ) { - $this->children[$key] = $sDate; - $this->children[$key]->setSelected(); - } - } - } - reset($this->children); - } - - /** - * Gets the value of the previous week, according to the requested format - * - * @param string $format ['timestamp' | 'n_in_month' | 'n_in_year' | 'array'] - * @return mixed - * @access public - */ - function prevWeek($format = 'n_in_month') - { - switch (strtolower($format)) { - case 'int': - case 'n_in_month': - return ($this->firstWeek) ? null : $this->thisWeek('n_in_month') -1; - break; - case 'n_in_year': - return $this->cE->getWeekNInYear( - $this->cE->stampToYear($this->prevWeek), - $this->cE->stampToMonth($this->prevWeek), - $this->cE->stampToDay($this->prevWeek)); - break; - case 'array': - return $this->toArray($this->prevWeek); - break; - case 'object': - require_once CALENDAR_ROOT.'Factory.php'; - return Calendar_Factory::createByTimestamp('Week', $this->prevWeek); - break; - case 'timestamp': - default: - return $this->prevWeek; - break; - } - } - - /** - * Gets the value of the current week, according to the requested format - * - * @param string $format ['timestamp' | 'n_in_month' | 'n_in_year' | 'array'] - * @return mixed - * @access public - */ - function thisWeek($format = 'n_in_month') - { - switch (strtolower($format)) { - case 'int': - case 'n_in_month': - if ($this->firstWeek) { - return 1; - } - if ($this->lastWeek) { - return $this->cE->getWeeksInMonth( - $this->thisYear(), - $this->thisMonth(), - $this->firstDay); - } - return $this->cE->getWeekNInMonth( - $this->thisYear(), - $this->thisMonth(), - $this->thisDay(), - $this->firstDay); - break; - case 'n_in_year': - return $this->cE->getWeekNInYear( - $this->cE->stampToYear($this->thisWeek), - $this->cE->stampToMonth($this->thisWeek), - $this->cE->stampToDay($this->thisWeek)); - break; - case 'array': - return $this->toArray($this->thisWeek); - break; - case 'object': - require_once CALENDAR_ROOT.'Factory.php'; - return Calendar_Factory::createByTimestamp('Week', $this->thisWeek); - break; - case 'timestamp': - default: - return $this->thisWeek; - break; - } - } - - /** - * Gets the value of the following week, according to the requested format - * - * @param string $format ['timestamp' | 'n_in_month' | 'n_in_year' | 'array'] - * @return mixed - * @access public - */ - function nextWeek($format = 'n_in_month') - { - switch (strtolower($format)) { - case 'int': - case 'n_in_month': - return ($this->lastWeek) ? null : $this->thisWeek('n_in_month') +1; - break; - case 'n_in_year': - return $this->cE->getWeekNInYear( - $this->cE->stampToYear($this->nextWeek), - $this->cE->stampToMonth($this->nextWeek), - $this->cE->stampToDay($this->nextWeek)); - break; - case 'array': - return $this->toArray($this->nextWeek); - break; - case 'object': - require_once CALENDAR_ROOT.'Factory.php'; - return Calendar_Factory::createByTimestamp('Week', $this->nextWeek); - break; - case 'timestamp': - default: - return $this->nextWeek; - break; - } - } - - /** - * Returns the instance of Calendar_Table_Helper. - * Called from Calendar_Validator::isValidWeek - * @return Calendar_Table_Helper - * @access protected - */ - function & getHelper() - { - return $this->tableHelper; - } - - /** - * Makes sure theres a value for $this->day - * @return void - * @access private - */ - function findFirstDay() - { - if (!count($this->children) > 0) { - $this->build(); - foreach ($this->children as $Day) { - if (!$Day->isEmpty()) { - $this->day = $Day->thisDay(); - break; - } - } - } - } -} -?> \ No newline at end of file diff --git a/glmPEAR/Calendar/Year.php b/glmPEAR/Calendar/Year.php deleted file mode 100755 index f54cd6a..0000000 --- a/glmPEAR/Calendar/Year.php +++ /dev/null @@ -1,113 +0,0 @@ - | -// +----------------------------------------------------------------------+ -// -// $Id: Year.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ -// -/** - * @package Calendar - * @version $Id: Year.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ - */ - -/** - * Allows Calendar include path to be redefined - * @ignore - */ -if (!defined('CALENDAR_ROOT')) { - define('CALENDAR_ROOT', 'Calendar'.DIRECTORY_SEPARATOR); -} - -/** - * Load Calendar base class - */ -require_once CALENDAR_ROOT.'Calendar.php'; - -/** - * Represents a Year and builds Months
- * - * require_once 'Calendar'.DIRECTORY_SEPARATOR.'Year.php'; - * $Year = & new Calendar_Year(2003, 10, 21); // 21st Oct 2003 - * $Year->build(); // Build Calendar_Month objects - * while ($Month = & $Year->fetch()) { - * echo $Month->thisMonth().'
'; - * } - *
- * @package Calendar - * @access public - */ -class Calendar_Year extends Calendar -{ - /** - * Constructs Calendar_Year - * @param int year e.g. 2003 - * @access public - */ - function Calendar_Year($y) - { - Calendar::Calendar($y); - } - - /** - * Builds the Months of the Year.
- * Note: by defining the constant CALENDAR_MONTH_STATE you can - * control what class of Calendar_Month is built e.g.; - * - * require_once 'Calendar/Calendar_Year.php'; - * define ('CALENDAR_MONTH_STATE',CALENDAR_USE_MONTH_WEEKDAYS); // Use Calendar_Month_Weekdays - * // define ('CALENDAR_MONTH_STATE',CALENDAR_USE_MONTH_WEEKS); // Use Calendar_Month_Weeks - * // define ('CALENDAR_MONTH_STATE',CALENDAR_USE_MONTH); // Use Calendar_Month - * - * It defaults to building Calendar_Month objects. - * @param array (optional) array of Calendar_Month objects representing selected dates - * @param int (optional) first day of week (e.g. 0 for Sunday, 2 for Tuesday etc.) - * @return boolean - * @access public - */ - function build($sDates = array(), $firstDay = null) - { - require_once CALENDAR_ROOT.'Factory.php'; - $this->firstDay = $this->defineFirstDayOfWeek($firstDay); - $monthsInYear = $this->cE->getMonthsInYear($this->thisYear()); - for ($i=1; $i <= $monthsInYear; $i++) { - $this->children[$i] = Calendar_Factory::create('Month', $this->year, $i); - } - if (count($sDates) > 0) { - $this->setSelection($sDates); - } - return true; - } - - /** - * Called from build() - * @param array - * @return void - * @access private - */ - function setSelection($sDates) { - foreach ($sDates as $sDate) { - if ($this->year == $sDate->thisYear()) { - $key = $sDate->thisMonth(); - if (isset($this->children[$key])) { - $sDate->setSelected(); - $this->children[$key] = $sDate; - } - } - } - } -} -?> \ No newline at end of file diff --git a/glmPEAR/Client.php b/glmPEAR/Client.php deleted file mode 100755 index a6b4b16..0000000 --- a/glmPEAR/Client.php +++ /dev/null @@ -1,583 +0,0 @@ - - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @category HTTP - * @package HTTP_Client - * @author Alexey Borzov - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Client.php,v 1.1.1.1 2008/04/28 15:20:46 jamie Exp $ - * @link http://pear.php.net/package/HTTP_Client - */ - -/* - * Do this define in your script if you wish HTTP_Client to follow browser - * quirks rather than HTTP specification (RFC2616). This means: - * - do a GET request after redirect with code 301, rather than use the - * same method as before redirect. - */ -// define('HTTP_CLIENT_QUIRK_MODE', true); - -/** - * Class for performing HTTP requests - */ -require_once 'HTTP/Request.php'; -/** - * Class used to store cookies and pass them between HTTP requests. - */ -require_once 'HTTP/Client/CookieManager.php'; - -/** - * A simple HTTP client class. - * - * The class wraps around HTTP_Request providing a higher-level - * API for performing multiple HTTP requests - * - * @category HTTP - * @package HTTP_Client - * @author Alexey Borzov - * @version Release: 1.1.1 - */ -class HTTP_Client -{ - /**#@+ - * @access private - */ - /** - * Cookie manager object - * @var HTTP_Client_CookieManager - */ - var $_cookieManager; - - /** - * Received HTTP responses - * @var array - */ - var $_responses; - - /** - * Default headers to send on every request - * @var array - */ - var $_defaultHeaders = array(); - - /** - * Default parameters for HTTP_Request's constructor - * @var array - */ - var $_defaultRequestParams = array(); - - /** - * How many redirects were done - * @var integer - */ - var $_redirectCount = 0; - - /** - * Maximum allowed redirects - * @var integer - */ - var $_maxRedirects = 5; - - /** - * Listeners attached to the client - * @var array - */ - var $_listeners = array(); - - /** - * Whether the listener should be propagated to Request objects - * @var array - */ - var $_propagate = array(); - - /** - * Whether to keep all the responses or just the most recent one - * @var boolean - */ - var $_isHistoryEnabled = true; - /**#@-*/ - - /** - * Constructor - * - * @access public - * @param array Parameters to pass to HTTP_Request's constructor - * @param array Default headers to send on every request - * @param HTTP_Client_CookieManager Cookie manager object to use - */ - function HTTP_Client($defaultRequestParams = null, $defaultHeaders = null, $cookieManager = null) - { - if (!empty($cookieManager) && is_a($cookieManager, 'HTTP_Client_CookieManager')) { - $this->_cookieManager = $cookieManager; - } else { - $this->_cookieManager =& new HTTP_Client_CookieManager(); - } - if (isset($defaultHeaders)) { - $this->setDefaultHeader($defaultHeaders); - } - if (isset($defaultRequestParams)) { - $this->setRequestParameter($defaultRequestParams); - } - } - - - /** - * Sets the maximum redirects that will be processed. - * - * Setting this to 0 disables redirect processing. If not 0 and the - * number of redirects in a request is bigger than this number, then an - * error will be raised. - * - * @access public - * @param int Max number of redirects to process - */ - function setMaxRedirects($value) - { - $this->_maxRedirects = $value; - } - - - /** - * Sets whether to keep all the responses or just the most recent one - * - * @access public - * @param bool Whether to enable history - */ - function enableHistory($enable) - { - $this->_isHistoryEnabled = (bool)$enable; - } - - /** - * Creates a HTTP_Request objects, applying all the necessary defaults - * - * @param string URL - * @param string Method, constants are defined in HTTP_Request - * @param array Extra headers to send - * @access private - * @return HTTP_Request Request object with all defaults applied - */ - function &_createRequest($url, $method = HTTP_REQUEST_METHOD_GET, $headers = array()) - { - $req =& new HTTP_Request($url, $this->_defaultRequestParams); - $req->setMethod($method); - foreach ($this->_defaultHeaders as $name => $value) { - $req->addHeader($name, $value); - } - foreach ($headers as $name => $value) { - $req->addHeader($name, $value); - } - $this->_cookieManager->passCookies($req); - foreach ($this->_propagate as $id => $propagate) { - if ($propagate) { - $req->attach($this->_listeners[$id]); - } - } - return $req; - } - - - /** - * Sends a 'HEAD' HTTP request - * - * @param string URL - * @param array Extra headers to send - * @access public - * @return integer HTTP response code - * @throws PEAR_Error - */ - function head($url, $headers = array()) - { - $request =& $this->_createRequest($url, HTTP_REQUEST_METHOD_HEAD, $headers); - return $this->_performRequest($request); - } - - - /** - * Sends a 'GET' HTTP request - * - * @param string URL - * @param mixed additional data to send - * @param boolean Whether the data is already urlencoded - * @param array Extra headers to send - * @access public - * @return integer HTTP response code - * @throws PEAR_Error - */ - function get($url, $data = null, $preEncoded = false, $headers = array()) - { - $request =& $this->_createRequest($url, HTTP_REQUEST_METHOD_GET, $headers); - if (is_array($data)) { - foreach ($data as $name => $value) { - $request->addQueryString($name, $value, $preEncoded); - } - } elseif (isset($data)) { - $request->addRawQueryString($data, $preEncoded); - } - return $this->_performRequest($request); - } - - - /** - * Sends a 'POST' HTTP request - * - * @param string URL - * @param mixed Data to send - * @param boolean Whether the data is already urlencoded - * @param array Files to upload. Elements of the array should have the form: - * array(name, filename(s)[, content type]), see HTTP_Request::addFile() - * @param array Extra headers to send - * @access public - * @return integer HTTP response code - * @throws PEAR_Error - */ - function post($url, $data, $preEncoded = false, $files = array(), $headers = array()) - { - $request =& $this->_createRequest($url, HTTP_REQUEST_METHOD_POST, $headers); - if (is_array($data)) { - foreach ($data as $name => $value) { - $request->addPostData($name, $value, $preEncoded); - } - } else { - $request->addRawPostData($data, $preEncoded); - } - foreach ($files as $fileData) { - $res = call_user_func_array(array(&$request, 'addFile'), $fileData); - if (PEAR::isError($res)) { - return $res; - } - } - return $this->_performRequest($request); - } - - - /** - * Sets default header(s) for HTTP requests - * - * @param mixed header name or array ('header name' => 'header value') - * @param string header value if $name is not an array - * @access public - */ - function setDefaultHeader($name, $value = null) - { - if (is_array($name)) { - $this->_defaultHeaders = array_merge($this->_defaultHeaders, $name); - } else { - $this->_defaultHeaders[$name] = $value; - } - } - - - /** - * Sets parameter(s) for HTTP requests - * - * @param mixed parameter name or array ('parameter name' => 'parameter value') - * @param string parameter value if $name is not an array - * @access public - */ - function setRequestParameter($name, $value = null) - { - if (is_array($name)) { - $this->_defaultRequestParams = array_merge($this->_defaultRequestParams, $name); - } else { - $this->_defaultRequestParams[$name] = $value; - } - } - - - /** - * Performs a request, processes redirects - * - * @param HTTP_Request Request object - * @access private - * @return integer HTTP response code - * @throws PEAR_Error - */ - function _performRequest(&$request) - { - // If this is not a redirect, notify the listeners of new request - if (0 == $this->_redirectCount && !empty($request->_url)) { - $this->_notify('request', $request->_url->getUrl()); - } - if (PEAR::isError($err = $request->sendRequest())) { - $this->_redirectCount = 0; - return $err; - } - $this->_pushResponse($request); - - $code = $request->getResponseCode(); - if ($this->_maxRedirects > 0) { - if (in_array($code, array(300, 301, 302, 303, 307))) { - if ('' == ($location = $request->getResponseHeader('Location'))) { - $this->_redirectCount = 0; - return PEAR::raiseError("No 'Location' field on redirect"); - } - // Bug #5759: do not try to follow non-HTTP redirects - if (null === ($redirectUrl = $this->_redirectUrl($request->_url, $location))) { - $this->_redirectCount = 0; - return $code; - } - // Redirect via tag, see request #5734 - } elseif (200 <= $code && $code < 300) { - $redirectUrl = $this->_getMetaRedirect($request); - } - } - if (!empty($redirectUrl)) { - if (++$this->_redirectCount > $this->_maxRedirects) { - $this->_redirectCount = 0; - return PEAR::raiseError('Too many redirects'); - } - // Notify of redirection - $this->_notify('httpRedirect', $redirectUrl); - // we access the private properties directly, as there are no accessors for them - switch ($request->_method) { - case HTTP_REQUEST_METHOD_POST: - if (302 == $code || 303 == $code || (301 == $code && defined('HTTP_CLIENT_QUIRK_MODE'))) { - return $this->get($redirectUrl); - } else { - $postFiles = array(); - foreach ($request->_postFiles as $name => $data) { - $postFiles[] = array($name, $data['name'], $data['type']); - } - return $this->post($redirectUrl, $request->_postData, true, $postFiles); - } - case HTTP_REQUEST_METHOD_HEAD: - return (303 == $code? $this->get($redirectUrl): $this->head($redirectUrl)); - case HTTP_REQUEST_METHOD_GET: - default: - return $this->get($redirectUrl); - } // switch - - } else { - $this->_redirectCount = 0; - if (400 >= $code) { - $this->_notify('httpSuccess'); - $this->setDefaultHeader('Referer', $request->_url->getUrl()); - // some result processing should go here - } else { - $this->_notify('httpError'); - } - } - return $code; - } - - - /** - * Returns the most recent HTTP response - * - * @access public - * @return array - */ - function ¤tResponse() - { - return $this->_responses[count($this->_responses) - 1]; - } - - - /** - * Saves the server's response to responses list - * - * @param HTTP_Request Request object already containing the response - * @access private - */ - function _pushResponse(&$request) - { - $this->_cookieManager->updateCookies($request); - $idx = $this->_isHistoryEnabled? count($this->_responses): 0; - $this->_responses[$idx] = array( - 'code' => $request->getResponseCode(), - 'headers' => $request->getResponseHeader(), - 'body' => $request->getResponseBody() - ); - } - - - /** - * Clears object's internal properties - * - * @access public - */ - function reset() - { - $this->_cookieManager->reset(); - $this->_responses = array(); - $this->_defaultHeaders = array(); - $this->_defaultRequestParams = array(); - } - - - /** - * Adds a Listener to the list of listeners that are notified of - * the object's events - * - * Events sent by HTTP_Client objects: - * - 'request': sent on HTTP request that is not a redirect - * - 'httpSuccess': sent when we receive a successfull 2xx response - * - 'httpRedirect': sent when we receive a redirection response - * - 'httpError': sent on 4xx, 5xx response - * - * @param HTTP_Request_Listener Listener to attach - * @param boolean Whether the listener should be attached - * to the created HTTP_Request objects - * @return boolean whether the listener was successfully attached - * @access public - */ - function attach(&$listener, $propagate = false) - { - if (!is_a($listener, 'HTTP_Request_Listener')) { - return false; - } - $this->_listeners[$listener->getId()] =& $listener; - $this->_propagate[$listener->getId()] = $propagate; - return true; - } - - - /** - * Removes a Listener from the list of listeners - * - * @param HTTP_Request_Listener Listener to detach - * @return boolean Whether the listener was successfully detached - * @access public - */ - function detach(&$listener) - { - if (!is_a($listener, 'HTTP_Request_Listener') || - !isset($this->_listeners[$listener->getId()])) { - return false; - } - unset($this->_listeners[$listener->getId()], $this->_propagate[$listener->getId()]); - return true; - } - - - /** - * Notifies all registered listeners of an event. - * - * @param string Event name - * @param mixed Additional data - * @access private - */ - function _notify($event, $data = null) - { - foreach (array_keys($this->_listeners) as $id) { - $this->_listeners[$id]->update($this, $event, $data); - } - } - - - /** - * Calculates the absolute URL of a redirect - * - * @param Net_Url Object containing the request URL - * @param string Value of the 'Location' response header - * @return string|null Absolute URL we are being redirected to, null in case of non-HTTP URL - * @access private - */ - function _redirectUrl($url, $location) - { - // If it begins with a scheme (as defined in RFC 2396) then it is absolute URI - if (preg_match('/^([a-zA-Z][a-zA-Z0-9+.-]*):/', $location, $matches)) { - // Bug #5759: we shouldn't try to follow non-HTTP redirects - if ('http' == strtolower($matches[1]) || 'https' == strtolower($matches[1])) { - return $location; - } else { - return null; - } - } else { - if ('/' == $location{0}) { - $url->path = Net_URL::resolvePath($location); - } elseif('/' == substr($url->path, -1)) { - $url->path = Net_URL::resolvePath($url->path . $location); - } else { - $dirname = (DIRECTORY_SEPARATOR == dirname($url->path)? '/': dirname($url->path)); - $url->path = Net_URL::resolvePath($dirname . '/' . $location); - } - $url->querystring = array(); - $url->anchor = ''; - return $url->getUrl(); - } - } - - - /** - * Returns the cookie manager object (e.g. for storing it somewhere) - * - * @return HTTP_Client_CookieManager - * @access public - */ - function getCookieManager() - { - return $this->_cookieManager; - } - - - /** - * Tries to extract a redirect URL from <> tag (request #5734) - * - * @param HTTP_Request A request object already containing the response - * @return string|null Absolute URI we are being redirected to, null if no redirect / invalid redirect - * @access private - */ - function _getMetaRedirect(&$request) - { - // Non-HTML response or empty response body - if ('text/html' != substr($request->getResponseHeader('content-type'), 0, 9) || - '' == ($body = $request->getResponseBody())) { - return null; - } - // No tag - if (!preg_match('!]*http-equiv\\s*=\\s*("Refresh"|\'Refresh\'|Refresh)[^>]*)>!is', $body, $matches)) { - return null; - } - // Just a refresh, no redirect - if (!preg_match('!content\\s*=\\s*("[^"]+"|\'[^\']+\'|\\S+)!is', $matches[1], $urlMatches)) { - return null; - } - $parts = explode(';', ('\'' == substr($urlMatches[1], 0, 1) || '"' == substr($urlMatches[1], 0, 1))? - substr($urlMatches[1], 1, -1): $urlMatches[1]); - if (empty($parts[1]) || !preg_match('/url\\s*=\\s*(\\S+)/is', $parts[1], $urlMatches)) { - return null; - } - // We do finally have an url... Now check that it's: - // a) HTTP, b) not to the same page - $previousUrl = $request->_url->getUrl(); - $redirectUrl = $this->_redirectUrl($request->_url, html_entity_decode($urlMatches[1])); - return (null === $redirectUrl || $redirectUrl == $previousUrl)? null: $redirectUrl; - } -} -?> diff --git a/glmPEAR/Client/CookieManager.php b/glmPEAR/Client/CookieManager.php deleted file mode 100755 index 96f06f3..0000000 --- a/glmPEAR/Client/CookieManager.php +++ /dev/null @@ -1,259 +0,0 @@ - - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @category HTTP - * @package HTTP_Client - * @author Alexey Borzov - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: CookieManager.php,v 1.1.1.1 2008/04/28 15:20:47 jamie Exp $ - * @link http://pear.php.net/package/HTTP_Client - */ - -/** - * Class used to store cookies and pass them between HTTP requests. - * - * @category HTTP - * @package HTTP_Client - * @author Alexey Borzov - * @version Release: 1.1.1 - */ -class HTTP_Client_CookieManager -{ - /** - * An array containing cookie values - * @var array - * @access private - */ - var $_cookies = array(); - - /** - * Whether session cookies should be serialized on object serialization - * @var boolean - * @access private - */ - var $_serializeSessionCookies = false; - - - /** - * Constructor - * - * @param boolean Whether session cookies should be serialized - * @access public - * @see serializeSessionCookies() - */ - function HTTP_Client_CookieManager($serializeSession = false) - { - $this->serializeSessionCookies($serializeSession); - } - - /** - * Sets whether session cookies should be serialized when serializing object - * - * @param boolean - * @access public - */ - function serializeSessionCookies($serialize) - { - $this->_serializeSessionCookies = (bool)$serialize; - } - - - /** - * Adds cookies to the request - * - * @access public - * @param HTTP_Request Request object - */ - function passCookies(&$request) - { - if (!empty($this->_cookies)) { - $url =& $request->_url; - // We do not check cookie's "expires" field, as we do not store deleted - // cookies in the array and our client does not work long enough for other - // cookies to expire. - $cookies = array(); - foreach ($this->_cookies as $cookie) { - if ($this->_domainMatch($url->host, $cookie['domain']) && (0 === strpos($url->path, $cookie['path'])) - && (empty($cookie['secure']) || $url->protocol == 'https')) { - $cookies[$cookie['name']][strlen($cookie['path'])] = $cookie['value']; - } - } - // cookies with longer paths go first - foreach ($cookies as $name => $values) { - krsort($values); - foreach ($values as $value) { - $request->addCookie($name, $value); - } - } - } - return true; - } - - - /** - * Explicitly adds cookie to the list - * - * @param array An array representing cookie, this function expects all of the array's - * fields to be set - * @access public - */ - function addCookie($cookie) - { - $hash = $this->_makeHash($cookie['name'], $cookie['domain'], $cookie['path']); - $this->_cookies[$hash] = $cookie; - } - - - /** - * Updates cookie list from HTTP server response - * - * @access public - * @param HTTP_Request Request object already containing the response - */ - function updateCookies(&$request) - { - if (false !== ($cookies = $request->getResponseCookies())) { - $url =& $request->_url; - foreach ($cookies as $cookie) { - // use the current domain by default - if (!isset($cookie['domain'])) { - $cookie['domain'] = $url->host; - } - // use the path to the current page by default - if (empty($cookie['path'])) { - $cookie['path'] = DIRECTORY_SEPARATOR == dirname($url->path)? '/': dirname($url->path); - } - // check if the domains match - if ($this->_domainMatch($url->host, $cookie['domain'])) { - $hash = $this->_makeHash($cookie['name'], $cookie['domain'], $cookie['path']); - // if value is empty or the time is in the past the cookie is deleted, else added - if (strlen($cookie['value']) - && (!isset($cookie['expires']) || (strtotime($cookie['expires']) > time()))) { - $this->_cookies[$hash] = $cookie; - } elseif (isset($this->_cookies[$hash])) { - unset($this->_cookies[$hash]); - } - } - } - } - } - - - /** - * Generates a key for the $_cookies array. - * - * The cookies is uniquely identified by its name, domain and path. - * Thus we cannot make f.e. an associative array with name as a key, we should - * generate a key from these 3 values. - * - * @access private - * @param string Cookie name - * @param string Cookie domain - * @param string Cookie path - * @return string a key - */ - function _makeHash($name, $domain, $path) - { - return md5($name . "\r\n" . $domain . "\r\n" . $path); - } - - - /** - * Checks whether a cookie domain matches a request host. - * - * Cookie domain can begin with a dot, it also must contain at least - * two dots. - * - * @access private - * @param string request host - * @param string cookie domain - * @return bool match success - */ - function _domainMatch($requestHost, $cookieDomain) - { - if ('.' != $cookieDomain{0}) { - return $requestHost == $cookieDomain; - } elseif (substr_count($cookieDomain, '.') < 2) { - return false; - } else { - return substr('.'. $requestHost, - strlen($cookieDomain)) == $cookieDomain; - } - } - - - /** - * Clears the $_cookies array - * - * @access public - */ - function reset() - { - $this->_cookies = array(); - } - - - /** - * Magic serialization function - * - * Removes session cookies if $_serializeSessionCookies is false (default) - */ - function __sleep() - { - if (!$this->_serializeSessionCookies) { - foreach ($this->_cookies as $hash => $cookie) { - if (empty($cookie['expires'])) { - unset($this->_cookies[$hash]); - } - } - } - return array('_cookies', '_serializeSessionCookies'); - } - - - /** - * Magic unserialization function, purges expired cookies - */ - function __wakeup() - { - foreach ($this->_cookies as $hash => $cookie) { - if (!empty($cookie['expires']) && strtotime($cookie['expires']) < time()) { - unset($this->_cookies[$hash]); - } - } - } -} -?> diff --git a/glmPEAR/Config.php b/glmPEAR/Config.php deleted file mode 100755 index 7c32b22..0000000 --- a/glmPEAR/Config.php +++ /dev/null @@ -1,231 +0,0 @@ - | -// +----------------------------------------------------------------------+ -// -// $Id: Config.php,v 1.1.1.1 2008/04/28 15:20:46 jamie Exp $ - -require_once('PEAR.php'); -require_once('Config/Container.php'); - -$GLOBALS['CONFIG_TYPES'] = - array( - 'apache' => array('Config/Container/Apache.php', 'Config_Container_Apache'), - 'genericconf' => array('Config/Container/GenericConf.php', 'Config_Container_GenericConf'), - 'inifile' => array('Config/Container/IniFile.php', 'Config_Container_IniFile'), - 'inicommented' => array('Config/Container/IniCommented.php', 'Config_Container_IniCommented'), - 'phparray' => array('Config/Container/PHPArray.php', 'Config_Container_PHPArray'), - 'phpconstants' => array('Config/Container/PHPConstants.php', 'Config_Container_PHPConstants'), - 'xml' => array('Config/Container/XML.php', 'Config_Container_XML') - ); - -/** -* Config -* -* This class allows for parsing and editing of configuration datasources. -* Do not use this class only to read datasources because of the overhead -* it creates to keep track of the configuration structure. -* -* @author Bertrand Mansion -* @package Config -*/ -class Config { - - /** - * Datasource - * Can be a file url, a dsn, an object... - * @var mixed - */ - var $datasrc; - - /** - * Type of datasource for config - * Ex: IniCommented, Apache... - * @var string - */ - var $configType = ''; - - /** - * Options for parser - * @var string - */ - var $parserOptions = array(); - - /** - * Container object - * @var object - */ - var $container; - - /** - * Constructor - * Creates a root container - * - * @access public - */ - function Config() - { - $this->container =& new Config_Container('section', 'root'); - } // end constructor - - /** - * Returns true if container is registered - * - * @param string $configType Type of config - * @access public - * @return bool - */ - function isConfigTypeRegistered($configType) - { - return isset($GLOBALS['CONFIG_TYPES'][strtolower($configType)]); - } // end func isConfigTypeRegistered - - /** - * Register a new container - * - * @param string $configType Type of config - * @param array|false $configInfo Array of format: - * array('path/to/Name.php', - * 'Config_Container_Class_Name'). - * - * If left false, defaults to: - * array('Config/Container/$configType.php', - * 'Config_Container_$configType') - * @access public - * @static - * @author Greg Beaver - * @return true|PEAR_Error true on success - */ - function registerConfigType($configType, $configInfo = false) - { - if (Config::isConfigTypeRegistered($configType)) { - $info = $GLOBALS['CONFIG_TYPES'][strtolower($configType)]; - if ($info[0] == $configInfo[0] && - $info[1] == $configInfo[1]) { - return true; - } else { - return PEAR::raiseError("Config::registerConfigType registration of existing $configType failed.", null, PEAR_ERROR_RETURN); - } - } - if (!is_array($configInfo)) { - // make the normal assumption, that this is a standard config container added in at runtime - $configInfo = array('Config/Container/' . $configType . '.php', - 'Config_Container_'. $configType); - } - $file_exists = @include_once($configInfo[0]); - if ($file_exists) { - if (!class_exists($configInfo[1])) { - return PEAR::raiseError("Config::registerConfigType class '$configInfo[1]' not found in $configInfo[0]", null, PEAR_ERROR_RETURN); - } - } else { - return PEAR::raiseError("Config::registerConfigType file $configInfo[0] not found", null, PEAR_ERROR_RETURN); - } - $GLOBALS['CONFIG_TYPES'][strtolower($configType)] = $configInfo; - return true; - } // end func registerConfigType - - /** - * Returns the root container for this config object - * - * @access public - * @return object reference to config's root container object - */ - function &getRoot() - { - return $this->container; - } // end func getRoot - - /** - * Sets the content of the root Config_container object. - * - * This method will replace the current child of the root - * Config_Container object by the given object. - * - * @param object $rootContainer container to be used as the first child to root - * @access public - * @return mixed true on success or PEAR_Error - */ - function setRoot(&$rootContainer) - { - if (is_object($rootContainer) && strtolower(get_class($rootContainer)) === 'config_container') { - if ($rootContainer->getName() === 'root' && $rootContainer->getType() === 'section') { - $this->container =& $rootContainer; - } else { - $this->container =& new Config_Container('section', 'root'); - $this->container->addItem($rootContainer); - } - return true; - } else { - return PEAR::raiseError("Config::setRoot only accepts object of Config_Container type.", null, PEAR_ERROR_RETURN); - } - } // end func setRoot - - /** - * Parses the datasource contents - * - * This method will parse the datasource given and fill the root - * Config_Container object with other Config_Container objects. - * - * @param mixed $datasrc Datasource to parse - * @param string $configType Type of configuration - * @param array $options Options for the parser - * @access public - * @return mixed PEAR_Error on error or Config_Container object - */ - function &parseConfig($datasrc, $configType, $options = array()) - { - $configType = strtolower($configType); - if (!$this->isConfigTypeRegistered($configType)) { - return PEAR::raiseError("Configuration type '$configType' is not registered in Config::parseConfig.", null, PEAR_ERROR_RETURN); - } - $includeFile = $GLOBALS['CONFIG_TYPES'][$configType][0]; - $className = $GLOBALS['CONFIG_TYPES'][$configType][1]; - include_once($includeFile); - - $parser = new $className($options); - $error = $parser->parseDatasrc($datasrc, $this); - if ($error !== true) { - return $error; - } - $this->parserOptions = $parser->options; - $this->datasrc = $datasrc; - $this->configType = $configType; - return $this->container; - } // end func &parseConfig - - /** - * Writes the container contents to the datasource. - * - * @param mixed $datasrc Datasource to write to - * @param string $configType Type of configuration - * @param array $options Options for config container - * @access public - * @return mixed PEAR_Error on error or true if ok - */ - function writeConfig($datasrc = null, $configType = null, $options = array()) - { - if (empty($datasrc)) { - $datasrc = $this->datasrc; - } - if (empty($configType)) { - $configType = $this->configType; - } - if (empty($options)) { - $options = $this->parserOptions; - } - return $this->container->writeDatasrc($datasrc, $configType, $options); - } // end func writeConfig -} // end class Config -?> diff --git a/glmPEAR/Config/Container.php b/glmPEAR/Config/Container.php deleted file mode 100755 index 6afb228..0000000 --- a/glmPEAR/Config/Container.php +++ /dev/null @@ -1,776 +0,0 @@ - | -// +---------------------------------------------------------------------+ -// -// $Id: Container.php,v 1.1.1.1 2008/04/28 15:20:47 jamie Exp $ - -require_once 'Config.php'; - -/** -* Interface for Config containers -* -* @author Bertrand Mansion -* @package Config -*/ -class Config_Container { - - /** - * Container object type - * Ex: section, directive, comment, blank - * @var string - */ - var $type; - - /** - * Container object name - * @var string - */ - var $name = ''; - - /** - * Container object content - * @var string - */ - var $content = ''; - - /** - * Container object children - * @var array - */ - var $children = array(); - - /** - * Reference to container object's parent - * @var object - */ - var $parent; - - /** - * Array of attributes for this item - * @var array - */ - var $attributes; - - /** - * Unique id to differenciate nodes - * - * This is used to compare nodes - * Will not be needed anymore when this class will use ZendEngine 2 - * - * @var int - */ - var $_id; - - /** - * Constructor - * - * @param string $type Type of container object - * @param string $name Name of container object - * @param string $content Content of container object - * @param array $attributes Array of attributes for container object - */ - function Config_Container($type = 'section', $name = '', $content = '', $attributes = null) - { - $this->type = $type; - $this->name = $name; - $this->content = $content; - $this->attributes = $attributes; - $this->parent = null; - if (version_compare(PHP_VERSION, '5.0.0', 'gt')) { - $this->_id = uniqid($name.$type, true); - } else { - $this->_id = uniqid(substr($name.$type, 0, 114), true); - } - } // end constructor - - /** - * Create a child for this item. - * @param string $type type of item: directive, section, comment, blank... - * @param mixed $item item name - * @param string $content item content - * @param array $attributes item attributes - * @param string $where choose a position 'bottom', 'top', 'after', 'before' - * @param object $target needed if you choose 'before' or 'after' for where - * @return object reference to new item or Pear_Error - */ - function &createItem($type, $name, $content, $attributes = null, $where = 'bottom', $target = null) - { - $item =& new Config_Container($type, $name, $content, $attributes); - $result =& $this->addItem($item, $where, $target); - return $result; - } // end func &createItem - - /** - * Adds an item to this item. - * @param object $item a container object - * @param string $where choose a position 'bottom', 'top', 'after', 'before' - * @param object $target needed if you choose 'before' or 'after' in $where - * @return mixed reference to added container on success, Pear_Error on error - */ - function &addItem(&$item, $where = 'bottom', $target = null) - { - if ($this->type != 'section') { - return PEAR::raiseError('Config_Container::addItem must be called on a section type object.', null, PEAR_ERROR_RETURN); - } - if (is_null($target)) { - $target =& $this; - } - if (strtolower(get_class($target)) != 'config_container') { - return PEAR::raiseError('Target must be a Config_Container object in Config_Container::addItem.', null, PEAR_ERROR_RETURN); - } - - switch ($where) { - case 'before': - $index = $target->getItemIndex(); - break; - case 'after': - $index = $target->getItemIndex()+1; - break; - case 'top': - $index = 0; - break; - case 'bottom': - $index = -1; - break; - default: - return PEAR::raiseError('Use only top, bottom, before or after in Config_Container::addItem.', null, PEAR_ERROR_RETURN); - } - if (isset($index) && $index >= 0) { - array_splice($this->children, $index, 0, 'tmp'); - } else { - $index = count($this->children); - } - $this->children[$index] =& $item; - $this->children[$index]->parent =& $this; - - return $item; - } // end func addItem - - /** - * Adds a comment to this item. - * This is a helper method that calls createItem - * - * @param string $content Object content - * @param string $where Position : 'top', 'bottom', 'before', 'after' - * @param object $target Needed when $where is 'before' or 'after' - * @return object reference to new item or Pear_Error - */ - function &createComment($content = '', $where = 'bottom', $target = null) - { - return $this->createItem('comment', null, $content, null, $where, $target); - } // end func &createComment - - /** - * Adds a blank line to this item. - * This is a helper method that calls createItem - * - * @return object reference to new item or Pear_Error - */ - function &createBlank($where = 'bottom', $target = null) - { - return $this->createItem('blank', null, null, null, $where, $target); - } // end func &createBlank - - /** - * Adds a directive to this item. - * This is a helper method that calls createItem - * - * @param string $name Name of new directive - * @param string $content Content of new directive - * @param mixed $attributes Directive attributes - * @param string $where Position : 'top', 'bottom', 'before', 'after' - * @param object $target Needed when $where is 'before' or 'after' - * @return object reference to new item or Pear_Error - */ - function &createDirective($name, $content, $attributes = null, $where = 'bottom', $target = null) - { - return $this->createItem('directive', $name, $content, $attributes, $where, $target); - } // end func &createDirective - - /** - * Adds a section to this item. - * - * This is a helper method that calls createItem - * If the section already exists, it won't create a new one. - * It will return reference to existing item. - * - * @param string $name Name of new section - * @param array $attributes Section attributes - * @param string $where Position : 'top', 'bottom', 'before', 'after' - * @param object $target Needed when $where is 'before' or 'after' - * @return object reference to new item or Pear_Error - */ - function &createSection($name, $attributes = null, $where = 'bottom', $target = null) - { - return $this->createItem('section', $name, null, $attributes, $where, $target); - } // end func &createSection - - /** - * Tries to find the specified item(s) and returns the objects. - * - * Examples: - * $directives =& $obj->getItem('directive'); - * $directive_bar_4 =& $obj->getItem('directive', 'bar', null, 4); - * $section_foo =& $obj->getItem('section', 'foo'); - * - * This method can only be called on an object of type 'section'. - * Note that root is a section. - * This method is not recursive and tries to keep the current structure. - * For a deeper search, use searchPath() - * - * @param string $type Type of item: directive, section, comment, blank... - * @param mixed $name Item name - * @param mixed $content Find item with this content - * @param array $attributes Find item with attribute set to the given value - * @param int $index Index of the item in the returned object list. If it is not set, will try to return the last item with this name. - * @return mixed reference to item found or false when not found - * @see &searchPath() - */ - function &getItem($type = null, $name = null, $content = null, $attributes = null, $index = -1) - { - if ($this->type != 'section') { - return PEAR::raiseError('Config_Container::getItem must be called on a section type object.', null, PEAR_ERROR_RETURN); - } - if (!is_null($type)) { - $testFields[] = 'type'; - } - if (!is_null($name)) { - $testFields[] = 'name'; - } - if (!is_null($content)) { - $testFields[] = 'content'; - } - if (!is_null($attributes) && is_array($attributes)) { - $testFields[] = 'attributes'; - } - - $itemsArr = array(); - $fieldsToMatch = count($testFields); - for ($i = 0, $count = count($this->children); $i < $count; $i++) { - $match = 0; - reset($testFields); - foreach ($testFields as $field) { - if ($field != 'attributes') { - if ($this->children[$i]->$field == ${$field}) { - $match++; - } - } else { - // Look for attributes in array - $attrToMatch = count($attributes); - $attrMatch = 0; - foreach ($attributes as $key => $value) { - if (isset($this->children[$i]->attributes[$key]) && - $this->children[$i]->attributes[$key] == $value) { - $attrMatch++; - } - } - if ($attrMatch == $attrToMatch) { - $match++; - } - } - } - if ($match == $fieldsToMatch) { - $itemsArr[] =& $this->children[$i]; - } - } - if ($index >= 0) { - if (isset($itemsArr[$index])) { - return $itemsArr[$index]; - } else { - $return = false; - return $return; - } - } else { - if ($count = count($itemsArr)) { - return $itemsArr[$count-1]; - } else { - $return = false; - return $return; - } - } - } // end func &getItem - - /** - * Finds a node using XPATH like format. - * - * The search format is an array: - * array(item1, item2, item3, ...) - * - * Each item can be defined as the following: - * item = 'string' : will match the container named 'string' - * item = array('string', array('name' => 'xyz')) - * will match the container name 'string' whose attribute name is equal to "xyz" - * For example : - * - * @param mixed Search path and attributes - * - * @return mixed Config_Container object, array of Config_Container objects or false on failure. - * @access public - */ - function &searchPath($args) - { - if ($this->type != 'section') { - return PEAR::raiseError('Config_Container::searchPath must be called on a section type object.', null, PEAR_ERROR_RETURN); - } - - $arg = array_shift($args); - - if (is_array($arg)) { - $name = $arg[0]; - $attributes = $arg[1]; - } else { - $name = $arg; - $attributes = null; - } - // find all the matches for first.. - $match =& $this->getItem(null, $name, null, $attributes); - - if (!$match) { - $return = false; - return $return; - } - if (!empty($args)) { - return $match->searchPath($args); - } - return $match; - } // end func &searchPath - - /** - * Return a child directive's content. - * - * This method can use two different search approach, depending on - * the parameter it is given. If the parameter is an array, it will use - * the {@link Config_Container::searchPath()} method. If it is a string, - * it will use the {@link Config_Container::getItem()} method. - * - * Example: - * - * require_once 'Config.php'; - * $ini = new Config(); - * $conf =& $ini->parseConfig('/path/to/config.ini', 'inicommented'); - * - * // Will return the value found at : - * // [Database] - * // host=localhost - * echo $conf->directiveContent(array('Database', 'host'))); - * - * // Will return the value found at : - * // date="dec-2004" - * echo $conf->directiveContent('date'); - * - * - * - * @param mixed Search path and attributes or a directive name - * @param int Index of the item in the returned directive list. - * Eventually used if args is a string. - * - * @return mixed Content of directive or false if not found. - * @access public - */ - function directiveContent($args, $index = -1) - { - if (is_array($args)) { - $item =& $this->searchPath($args); - } else { - $item =& $this->getItem('directive', $args, null, null, $index); - } - if ($item) { - return $item->getContent(); - } - return false; - } // end func getDirectiveContent - - /** - * Returns how many children this container has - * - * @param string $type type of children counted - * @param string $name name of children counted - * @return int number of children found - */ - function countChildren($type = null, $name = null) - { - if (is_null($type) && is_null($name)) { - return count($this->children); - } - $count = 0; - if (isset($name) && isset($type)) { - for ($i = 0, $children = count($this->children); $i < $children; $i++) { - if ($this->children[$i]->name === $name && - $this->children[$i]->type == $type) { - $count++; - } - } - return $count; - } - if (isset($type)) { - for ($i = 0, $children = count($this->children); $i < $children; $i++) { - if ($this->children[$i]->type == $type) { - $count++; - } - } - return $count; - } - if (isset($name)) { - // Some directives can have the same name - for ($i = 0, $children = count($this->children); $i < $children; $i++) { - if ($this->children[$i]->name === $name) { - $count++; - } - } - return $count; - } - } // end func &countChildren - - /** - * Deletes an item (section, directive, comment...) from the current object - * TODO: recursive remove in sub-sections - * @return mixed true if object was removed, false if not, or PEAR_Error if root - */ - function removeItem() - { - if ($this->isRoot()) { - return PEAR::raiseError('Cannot remove root item in Config_Container::removeItem.', null, PEAR_ERROR_RETURN); - } - $index = $this->getItemIndex(); - if (!is_null($index)) { - array_splice($this->parent->children, $index, 1); - return true; - } - return false; - } // end func removeItem - - /** - * Returns the item index in its parent children array. - * @return int returns int or null if root object - */ - function getItemIndex() - { - if (is_object($this->parent)) { - // This will be optimized with Zend Engine 2 - $pchildren =& $this->parent->children; - for ($i = 0, $count = count($pchildren); $i < $count; $i++) { - if ($pchildren[$i]->_id == $this->_id) { - return $i; - } - } - } - return; - } // end func getItemIndex - - /** - * Returns the item rank in its parent children array - * according to other items with same type and name. - * @param bool count items differently by type - * @return int returns int or null if root object - */ - function getItemPosition($byType = true) - { - if (is_object($this->parent)) { - $pchildren =& $this->parent->children; - for ($i = 0, $count = count($pchildren); $i < $count; $i++) { - if ($pchildren[$i]->name == $this->name) { - if ($byType == true) { - if ($pchildren[$i]->type == $this->type) { - $obj[] =& $pchildren[$i]; - } - } else { - $obj[] =& $pchildren[$i]; - } - } - } - for ($i = 0, $count = count($obj); $i < $count; $i++) { - if ($obj[$i]->_id == $this->_id) { - return $i; - } - } - } - return; - } // end func getItemPosition - - /** - * Returns the item parent object. - * @return object returns reference to parent object or null if root object - */ - function &getParent() - { - return $this->parent; - } // end func &getParent - - /** - * Returns the item parent object. - * @return mixed returns reference to child object or false if child does not exist - */ - function &getChild($index = 0) - { - if (!empty($this->children[$index])) { - return $this->children[$index]; - } else { - return false; - } - } // end func &getChild - - /** - * Set this item's name. - * @return void - */ - function setName($name) - { - $this->name = $name; - } // end func setName - - /** - * Get this item's name. - * @return string item's name - */ - function getName() - { - return $this->name; - } // end func getName - - /** - * Set this item's content. - * @return void - */ - function setContent($content) - { - $this->content = $content; - } // end func setContent - - /** - * Get this item's content. - * @return string item's content - */ - function getContent() - { - return $this->content; - } // end func getContent - - /** - * Set this item's type. - * @return void - */ - function setType($type) - { - $this->type = $type; - } // end func setType - - /** - * Get this item's type. - * @return string item's type - */ - function getType() - { - return $this->type; - } // end func getType - - /** - * Set this item's attributes. - * @param array $attributes Array of attributes - * @return void - */ - function setAttributes($attributes) - { - $this->attributes = $attributes; - } // end func setAttributes - - /** - * Set this item's attributes. - * @param array $attributes Array of attributes - * @return void - */ - function updateAttributes($attributes) - { - if (is_array($attributes)) { - foreach ($attributes as $key => $value) { - $this->attributes[$key] = $value; - } - } - } // end func updateAttributes - - /** - * Get this item's attributes. - * @return array item's attributes - */ - function getAttributes() - { - return $this->attributes; - } // end func getAttributes - - /** - * Get one attribute value of this item - * @param string $attribute Attribute key - * @return mixed item's attribute value - */ - function getAttribute($attribute) - { - if (isset($this->attributes[$attribute])) { - return $this->attributes[$attribute]; - } - return null; - } // end func getAttribute - - /** - * Set a children directive content. - * This is an helper method calling getItem and addItem or setContent for you. - * If the directive does not exist, it will be created at the bottom. - * - * @param string $name Name of the directive to look for - * @param mixed $content New content - * @param int $index Index of the directive to set, - * in case there are more than one directive - * with the same name - * @return object newly set directive - */ - function &setDirective($name, $content, $index = -1) - { - $item =& $this->getItem('directive', $name, null, null, $index); - if ($item === false || PEAR::isError($item)) { - // Directive does not exist, will create one - unset($item); - return $this->createDirective($name, $content, null); - } else { - // Change existing directive value - $item->setContent($content); - return $item; - } - } // end func setDirective - - /** - * Is this item root, in a config container object - * @return bool true if item is root - */ - function isRoot() - { - if (is_null($this->parent)) { - return true; - } - return false; - } // end func isRoot - - /** - * Call the toString methods in the container plugin - * @param string $configType Type of configuration used to generate the string - * @param array $options Specify special options used by the parser - * @return mixed true on success or PEAR_ERROR - */ - function toString($configType, $options = array()) - { - $configType = strtolower($configType); - if (!isset($GLOBALS['CONFIG_TYPES'][$configType])) { - return PEAR::raiseError("Configuration type '$configType' is not registered in Config_Container::toString.", null, PEAR_ERROR_RETURN); - } - $includeFile = $GLOBALS['CONFIG_TYPES'][$configType][0]; - $className = $GLOBALS['CONFIG_TYPES'][$configType][1]; - include_once($includeFile); - $renderer = new $className($options); - return $renderer->toString($this); - } // end func toString - - /** - * Returns a key/value pair array of the container and its children. - * - * Format : section[directive][index] = value - * If the container has attributes, it will use '@' and '#' - * index is here because multiple directives can have the same name. - * - * @param bool $useAttr Whether to return the attributes too - * @return array - */ - function toArray($useAttr = true) - { - $array[$this->name] = array(); - switch ($this->type) { - case 'directive': - if ($useAttr && count($this->attributes) > 0) { - $array[$this->name]['#'] = $this->content; - $array[$this->name]['@'] = $this->attributes; - } else { - $array[$this->name] = $this->content; - } - break; - case 'section': - if ($useAttr && count($this->attributes) > 0) { - $array[$this->name]['@'] = $this->attributes; - } - if ($count = count($this->children)) { - for ($i = 0; $i < $count; $i++) { - $newArr = $this->children[$i]->toArray($useAttr); - if (!is_null($newArr)) { - foreach ($newArr as $key => $value) { - if (isset($array[$this->name][$key])) { - // duplicate name/type - if (!is_array($array[$this->name][$key]) || - !isset($array[$this->name][$key][0])) { - $old = $array[$this->name][$key]; - unset($array[$this->name][$key]); - $array[$this->name][$key][0] = $old; - } - $array[$this->name][$key][] = $value; - } else { - $array[$this->name][$key] = $value; - } - } - } - } - } - break; - default: - return null; - } - return $array; - } // end func toArray - - /** - * Writes the configuration to a file - * - * @param mixed $datasrc Info on datasource such as path to the configuraton file or dsn... - * @param string $configType Type of configuration - * @param array $options Options for writer - * @access public - * @return mixed true on success or PEAR_ERROR - */ - function writeDatasrc($datasrc, $configType, $options = array()) - { - $configType = strtolower($configType); - if (!isset($GLOBALS['CONFIG_TYPES'][$configType])) { - return PEAR::raiseError("Configuration type '$configType' is not registered in Config_Container::writeDatasrc.", null, PEAR_ERROR_RETURN); - } - $includeFile = $GLOBALS['CONFIG_TYPES'][$configType][0]; - $className = $GLOBALS['CONFIG_TYPES'][$configType][1]; - include_once($includeFile); - - $writeMethodName = (version_compare(phpversion(), '5', '<')) ? 'writedatasrc' : 'writeDatasrc'; - if (in_array($writeMethodName, get_class_methods($className))) { - $writer = new $className($options); - return $writer->writeDatasrc($datasrc, $this); - } - - // Default behaviour - $fp = @fopen($datasrc, 'w'); - if ($fp) { - $string = $this->toString($configType, $options); - $len = strlen($string); - @flock($fp, LOCK_EX); - @fwrite($fp, $string, $len); - @flock($fp, LOCK_UN); - @fclose($fp); - return true; - } else { - return PEAR::raiseError('Cannot open datasource for writing.', 1, PEAR_ERROR_RETURN); - } - } // end func writeDatasrc -} // end class Config_Container -?> diff --git a/glmPEAR/Config/Container/Apache.php b/glmPEAR/Config/Container/Apache.php deleted file mode 100755 index 265a0a7..0000000 --- a/glmPEAR/Config/Container/Apache.php +++ /dev/null @@ -1,169 +0,0 @@ - | -// +----------------------------------------------------------------------+ -// -// $Id: Apache.php,v 1.1.1.1 2008/04/28 15:20:47 jamie Exp $ - -/** -* Simple config parser for apache httpd.conf files -* A more complex version could handle directives as -* associative arrays. -* -* @author Bertrand Mansion -* @package Config -*/ -class Config_Container_Apache { - - /** - * This class options - * Not used at the moment - * - * @var array - */ - var $options = array(); - - /** - * Constructor - * - * @access public - * @param string $options (optional)Options to be used by renderer - */ - function Config_Container_Apache($options = array()) - { - $this->options = $options; - } // end constructor - - /** - * Parses the data of the given configuration file - * - * @access public - * @param string $datasrc path to the configuration file - * @param object $obj reference to a config object - * @return mixed returns a PEAR_ERROR, if error occurs or true if ok - */ - function &parseDatasrc($datasrc, &$obj) - { - $return = true; - if (!is_readable($datasrc)) { - return PEAR::raiseError("Datasource file cannot be read.", null, PEAR_ERROR_RETURN); - } - $lines = file($datasrc); - $n = 0; - $lastline = ''; - $sections[0] =& $obj->container; - foreach ($lines as $line) { - $n++; - if (!preg_match('/^\s*#/', $line) && - preg_match('/^\s*(.*)\s+\\\$/', $line, $match)) { - // directive on more than one line - $lastline .= $match[1].' '; - continue; - } - if ($lastline != '') { - $line = $lastline.trim($line); - $lastline = ''; - } - if (preg_match('/^\s*#+\s*(.*?)\s*$/', $line, $match)) { - // a comment - $currentSection =& $sections[count($sections)-1]; - $currentSection->createComment($match[1]); - } elseif (trim($line) == '') { - // a blank line - $currentSection =& $sections[count($sections)-1]; - $currentSection->createBlank(); - } elseif (preg_match('/^\s*(\w+)(?:\s+(.*?)|)\s*$/', $line, $match)) { - // a directive - $currentSection =& $sections[count($sections)-1]; - $currentSection->createDirective($match[1], $match[2]); - } elseif (preg_match('/^\s*<(\w+)(?:\s+([^>]*)|\s*)>\s*$/', $line, $match)) { - // a section opening - if (!isset($match[2])) - $match[2] = ''; - $currentSection =& $sections[count($sections)-1]; - $attributes = explode(' ', $match[2]); - $sections[] =& $currentSection->createSection($match[1], $attributes); - } elseif (preg_match('/^\s*<\/(\w+)\s*>\s*$/', $line, $match)) { - // a section closing - $currentSection =& $sections[count($sections)-1]; - if ($currentSection->name != $match[1]) { - return PEAR::raiseError("Section not closed in '$datasrc' at line $n.", null, PEAR_ERROR_RETURN); - } - array_pop($sections); - } else { - return PEAR::raiseError("Syntax error in '$datasrc' at line $n.", null, PEAR_ERROR_RETURN); - } - } - return $return; - } // end func parseDatasrc - - /** - * Returns a formatted string of the object - * @param object $obj Container object to be output as string - * @access public - * @return string - */ - function toString(&$obj) - { - static $deep = -1; - $ident = ''; - if (!$obj->isRoot()) { - // no indent for root - $deep++; - $ident = str_repeat(' ', $deep); - } - if (!isset($string)) { - $string = ''; - } - switch ($obj->type) { - case 'blank': - $string = "\n"; - break; - case 'comment': - $string = $ident.'# '.$obj->content."\n"; - break; - case 'directive': - $string = $ident.$obj->name.' '.$obj->content."\n"; - break; - case 'section': - if (!$obj->isRoot()) { - $string = $ident.'<'.$obj->name; - if (is_array($obj->attributes) && count($obj->attributes) > 0) { - foreach ($obj->attributes as $attr => $val) { - $string .= ' '.$val; - } - } - $string .= ">\n"; - } - if (count($obj->children) > 0) { - for ($i = 0; $i < count($obj->children); $i++) { - $string .= $this->toString($obj->getChild($i)); - } - } - if (!$obj->isRoot()) { - // object is not root - $string .= $ident.'name.">\n"; - } - break; - default: - $string = ''; - } - if (!$obj->isRoot()) { - $deep--; - } - return $string; - } // end func toString -} // end class Config_Container_Apache -?> diff --git a/glmPEAR/Config/Container/GenericConf.php b/glmPEAR/Config/Container/GenericConf.php deleted file mode 100755 index 40c3e39..0000000 --- a/glmPEAR/Config/Container/GenericConf.php +++ /dev/null @@ -1,139 +0,0 @@ - | -// +----------------------------------------------------------------------+ -// -// $Id: GenericConf.php,v 1.1.1.1 2008/04/28 15:20:47 jamie Exp $ - -/** -* Config parser for generic .conf files like -* htdig.conf... -* -* @author Bertrand Mansion -* @package Config -*/ -class Config_Container_GenericConf { - - /** - * This class options: - * Ex: $options['comment'] = '#'; - * Ex: $options['equals'] = ':'; - * Ex: $options['newline'] = '\\'; - * - * @var array - */ - var $options = array(); - - /** - * Constructor - * - * @access public - * @param string $options (optional)Options to be used by renderer - */ - function Config_Container_GenericConf($options = array()) - { - if (empty($options['comment'])) { - $options['comment'] = '#'; - } - if (empty($options['equals'])) { - $options['equals'] = ':'; - } - if (empty($options['newline'])) { - $options['newline'] = '\\'; - } - $this->options = $options; - } // end constructor - - /** - * Parses the data of the given configuration file - * - * @access public - * @param string $datasrc path to the configuration file - * @param object $obj reference to a config object - * @return mixed returns a PEAR_ERROR, if error occurs or true if ok - */ - function &parseDatasrc($datasrc, &$obj) - { - $return = true; - if (!is_readable($datasrc)) { - return PEAR::raiseError("Datasource file cannot be read.", null, PEAR_ERROR_RETURN); - } - - $lines = file($datasrc); - $n = 0; - $lastline = ''; - $currentSection =& $obj->container; - foreach ($lines as $line) { - $n++; - if (!preg_match('/^\s*'.$this->options['comment'].'/', $line) && - preg_match('/^\s*(.*)\s+'.$this->options['newline'].'\s*$/', $line, $match)) { - // directive on more than one line - $lastline .= $match[1].' '; - continue; - } - if ($lastline != '') { - $line = $lastline.trim($line); - $lastline = ''; - } - if (preg_match('/^\s*'.$this->options['comment'].'+\s*(.*?)\s*$/', $line, $match)) { - // a comment - $currentSection->createComment($match[1]); - } elseif (preg_match('/^\s*$/', $line)) { - // a blank line - $currentSection->createBlank(); - } elseif (preg_match('/^\s*(\w+)'.$this->options['equals'].'\s*((.*?)|)\s*$/', $line, $match)) { - // a directive - $currentSection->createDirective($match[1], $match[2]); - } else { - return PEAR::raiseError("Syntax error in '$datasrc' at line $n.", null, PEAR_ERROR_RETURN); - } - } - return $return; - } // end func parseDatasrc - - /** - * Returns a formatted string of the object - * @param object $obj Container object to be output as string - * @access public - * @return string - */ - function toString(&$obj) - { - $string = ''; - switch ($obj->type) { - case 'blank': - $string = "\n"; - break; - case 'comment': - $string = $this->options['comment'].$obj->content."\n"; - break; - case 'directive': - $string = $obj->name.$this->options['equals'].$obj->content."\n"; - break; - case 'section': - // How to deal with sections ??? - if (count($obj->children) > 0) { - for ($i = 0; $i < count($obj->children); $i++) { - $string .= $this->toString($obj->getChild($i)); - } - } - break; - default: - $string = ''; - } - return $string; - } // end func toString -} // end class Config_Container_GenericConf -?> diff --git a/glmPEAR/Config/Container/IniCommented.php b/glmPEAR/Config/Container/IniCommented.php deleted file mode 100755 index c00ae44..0000000 --- a/glmPEAR/Config/Container/IniCommented.php +++ /dev/null @@ -1,327 +0,0 @@ - | -// +----------------------------------------------------------------------+ -// -// $Id: IniCommented.php,v 1.1.1.1 2008/04/28 15:20:47 jamie Exp $ - -/** -* Config parser for PHP .ini files with comments -* -* @author Bertrand Mansion -* @package Config -*/ -class Config_Container_IniCommented { - - /** - * This class options - * Not used at the moment - * - * @var array - */ - var $options = array(); - - /** - * Constructor - * - * @access public - * @param string $options (optional)Options to be used by renderer - */ - function Config_Container_IniCommented($options = array()) - { - $this->options = $options; - } // end constructor - - /** - * Parses the data of the given configuration file - * - * @access public - * @param string $datasrc path to the configuration file - * @param object $obj reference to a config object - * @return mixed returns a PEAR_ERROR, if error occurs or true if ok - */ - function &parseDatasrc($datasrc, &$obj) - { - $return = true; - if (!file_exists($datasrc)) { - return PEAR::raiseError("Datasource file does not exist.", null, PEAR_ERROR_RETURN); - } - $lines = file($datasrc); - $n = 0; - $lastline = ''; - $currentSection =& $obj->container; - foreach ($lines as $line) { - $n++; - if (preg_match('/^\s*;(.*?)\s*$/', $line, $match)) { - // a comment - $currentSection->createComment($match[1]); - } elseif (preg_match('/^\s*$/', $line)) { - // a blank line - $currentSection->createBlank(); - } elseif (preg_match('/^\s*([a-zA-Z0-9_\-\.\s:]*)\s*=\s*(.*)\s*$/', $line, $match)) { - // a directive - - $values = $this->_quoteAndCommaParser($match[2]); - if (PEAR::isError($values)) { - return PEAR::raiseError($values); - } - - if (count($values)) { - foreach($values as $value) { - if ($value[0] == 'normal') { - $currentSection->createDirective(trim($match[1]), $value[1]); - } - if ($value[0] == 'comment') { - $currentSection->createComment(substr($value[1], 1)); - } - } - } - } elseif (preg_match('/^\s*\[\s*(.*)\s*\]\s*$/', $line, $match)) { - // a section - $currentSection =& $obj->container->createSection($match[1]); - } else { - return PEAR::raiseError("Syntax error in '$datasrc' at line $n.", null, PEAR_ERROR_RETURN); - } - } - return $return; - } // end func parseDatasrc - - /** - * Quote and Comma Parser for INI files - * - * This function allows complex values such as: - * - * - * mydirective = "Item, number \"1\"", Item 2 ; "This" is really, really tricky - * - * @param string $text value of a directive to parse for quotes/multiple values - * @return array The array returned contains multiple values, if any (unquoted literals - * to be used as is), and a comment, if any. The format of the array is: - * - *
-     * array(array('normal', 'first value'),
-     *       array('normal', 'next value'),...
-     *       array('comment', '; comment with leading ;'))
-     * 
- * @author Greg Beaver - * @access private - */ - function _quoteAndCommaParser($text) - { - $text = trim($text); - if ($text == '') { - $emptyNode = array(); - $emptyNode[0][0] = 'normal'; - $emptyNode[0][1] = ''; - return $emptyNode; - } - - // tokens - $tokens['normal'] = array('"', ';', ','); - $tokens['quote'] = array('"', '\\'); - $tokens['escape'] = false; // cycle - $tokens['after_quote'] = array(',', ';'); - - // events - $events['normal'] = array('"' => 'quote', ';' => 'comment', ',' => 'normal'); - $events['quote'] = array('"' => 'after_quote', '\\' => 'escape'); - $events['after_quote'] = array(',' => 'normal', ';' => 'comment'); - - // state stack - $stack = array(); - - // return information - $return = array(); - $returnpos = 0; - $returntype = 'normal'; - - // initialize - array_push($stack, 'normal'); - $pos = 0; // position in $text - - do { - $char = $text{$pos}; - $state = $this->_getQACEvent($stack); - - if ($tokens[$state]) { - if (in_array($char, $tokens[$state])) { - switch($events[$state][$char]) { - case 'quote' : - if ($state == 'normal' && - isset($return[$returnpos]) && - !empty($return[$returnpos][1])) { - return PEAR::raiseError("invalid ini syntax, quotes cannot follow text '$text'", - null, PEAR_ERROR_RETURN); - } - if ($returnpos >= 0 && isset($return[$returnpos])) { - // trim any unnecessary whitespace in earlier entries - $return[$returnpos][1] = trim($return[$returnpos][1]); - } else { - $returnpos++; - } - $return[$returnpos] = array('normal', ''); - array_push($stack, 'quote'); - continue 2; - break; - case 'comment' : - // comments go to the end of the line, so we are done - $return[++$returnpos] = array('comment', substr($text, $pos)); - return $return; - break; - case 'after_quote' : - array_push($stack, 'after_quote'); - break; - case 'escape' : - // don't save the first slash - array_push($stack, 'escape'); - continue 2; - break; - case 'normal' : - // start a new segment - if ($state == 'normal') { - $returnpos++; - continue 2; - } else { - while ($state != 'normal') { - array_pop($stack); - $state = $this->_getQACEvent($stack); - } - $returnpos++; - } - break; - default : - PEAR::raiseError("::_quoteAndCommaParser oops, state missing", null, PEAR_ERROR_DIE); - break; - } - } else { - if ($state != 'after_quote') { - if (!isset($return[$returnpos])) { - $return[$returnpos] = array('normal', ''); - } - // add this character to the current ini segment if non-empty, or if in a quote - if ($state == 'quote') { - $return[$returnpos][1] .= $char; - } elseif (!empty($return[$returnpos][1]) || - (empty($return[$returnpos][1]) && trim($char) != '')) { - if (!isset($return[$returnpos])) { - $return[$returnpos] = array('normal', ''); - } - $return[$returnpos][1] .= $char; - if (strcasecmp('true', $return[$returnpos][1]) == 0) { - $return[$returnpos][1] = '1'; - } elseif (strcasecmp('false', $return[$returnpos][1]) == 0) { - $return[$returnpos][1] = ''; - } - } - } else { - if (trim($char) != '') { - return PEAR::raiseError("invalid ini syntax, text after a quote not allowed '$text'", - null, PEAR_ERROR_RETURN); - } - } - } - } else { - // no tokens, so add this one and cycle to previous state - $return[$returnpos][1] .= $char; - array_pop($stack); - } - } while (++$pos < strlen($text)); - return $return; - } // end func _quoteAndCommaParser - - /** - * Retrieve the state off of a state stack for the Quote and Comma Parser - * @param array $stack The parser state stack - * @author Greg Beaver - * @access private - */ - function _getQACEvent($stack) - { - return array_pop($stack); - } // end func _getQACEvent - - /** - * Returns a formatted string of the object - * @param object $obj Container object to be output as string - * @access public - * @return string - */ - function toString(&$obj) - { - static $childrenCount, $commaString; - - if (!isset($string)) { - $string = ''; - } - switch ($obj->type) { - case 'blank': - $string = "\n"; - break; - case 'comment': - $string = ';'.$obj->content."\n"; - break; - case 'directive': - $count = $obj->parent->countChildren('directive', $obj->name); - $content = $obj->content; - if ($content === false) { - $content = '0'; - } elseif ($content === true) { - $content = '1'; - } elseif (strlen(trim($content)) < strlen($content) || - strpos($content, ',') !== false || - strpos($content, ';') !== false || - strpos($content, '=') !== false || - strpos($content, '"') !== false || - strpos($content, '%') !== false || - strpos($content, '~') !== false) { - $content = '"'.addslashes($content).'"'; - } - if ($count > 1) { - // multiple values for a directive are separated by a comma - if (isset($childrenCount[$obj->name])) { - $childrenCount[$obj->name]++; - } else { - $childrenCount[$obj->name] = 0; - $commaString[$obj->name] = $obj->name.' = '; - } - if ($childrenCount[$obj->name] == $count-1) { - // Clean the static for future calls to toString - $string .= $commaString[$obj->name].$content."\n"; - unset($childrenCount[$obj->name]); - unset($commaString[$obj->name]); - } else { - $commaString[$obj->name] .= $content.', '; - } - } else { - $string = $obj->name.' = '.$content."\n"; - } - break; - case 'section': - if (!$obj->isRoot()) { - $string = '['.$obj->name."]\n"; - } - if (count($obj->children) > 0) { - for ($i = 0; $i < count($obj->children); $i++) { - $string .= $this->toString($obj->getChild($i)); - } - } - break; - default: - $string = ''; - } - return $string; - } // end func toString -} // end class Config_Container_IniCommented -?> diff --git a/glmPEAR/Config/Container/IniFile.php b/glmPEAR/Config/Container/IniFile.php deleted file mode 100755 index cd17099..0000000 --- a/glmPEAR/Config/Container/IniFile.php +++ /dev/null @@ -1,165 +0,0 @@ - | -// +----------------------------------------------------------------------+ -// -// $Id: IniFile.php,v 1.1.1.1 2008/04/28 15:20:47 jamie Exp $ - -/** -* Config parser for PHP .ini files -* Faster because it uses parse_ini_file() but get rid of comments, -* quotes, types and converts On, Off, True, False, Yes, No to 0 and 1. -* -* @author Bertrand Mansion -* @package Config -*/ -class Config_Container_IniFile { - - /** - * This class options - * Not used at the moment - * - * @var array - */ - var $options = array(); - - /** - * Constructor - * - * @access public - * @param string $options (optional)Options to be used by renderer - */ - function Config_Container_IniFile($options = array()) - { - $this->options = $options; - } // end constructor - - /** - * Parses the data of the given configuration file - * - * @access public - * @param string $datasrc path to the configuration file - * @param object $obj reference to a config object - * @return mixed returns a PEAR_ERROR, if error occurs or true if ok - */ - function &parseDatasrc($datasrc, &$obj) - { - $return = true; - if (!file_exists($datasrc)) { - return PEAR::raiseError("Datasource file does not exist.", null, PEAR_ERROR_RETURN); - } - $currentSection =& $obj->container; - $confArray = parse_ini_file($datasrc, true); - if (!$confArray) { - return PEAR::raiseError("File '$datasrc' does not contain configuration data.", null, PEAR_ERROR_RETURN); - } - foreach ($confArray as $key => $value) { - if (is_array($value)) { - $currentSection =& $obj->container->createSection($key); - foreach ($value as $directive => $content) { - // try to split the value if comma found - if (strpos($content, '"') === false) { - $values = preg_split('/\s*,\s+/', $content); - if (count($values) > 1) { - foreach ($values as $k => $v) { - $currentSection->createDirective($directive, $v); - } - } else { - $currentSection->createDirective($directive, $content); - } - } else { - $currentSection->createDirective($directive, $content); - } - } - } else { - $currentSection->createDirective($key, $value); - } - } - return $return; - } // end func parseDatasrc - - /** - * Returns a formatted string of the object - * @param object $obj Container object to be output as string - * @access public - * @return string - */ - function toString(&$obj) - { - static $childrenCount, $commaString; - - if (!isset($string)) { - $string = ''; - } - switch ($obj->type) { - case 'blank': - $string = "\n"; - break; - case 'comment': - $string = ';'.$obj->content."\n"; - break; - case 'directive': - $count = $obj->parent->countChildren('directive', $obj->name); - $content = $obj->content; - if ($content === false) { - $content = '0'; - } elseif ($content === true) { - $content = '1'; - } elseif (strlen(trim($content)) < strlen($content) || - strpos($content, ',') !== false || - strpos($content, ';') !== false || - strpos($content, '=') !== false || - strpos($content, '"') !== false || - strpos($content, '%') !== false || - strpos($content, '~') !== false) { - $content = '"'.addslashes($content).'"'; - } - if ($count > 1) { - // multiple values for a directive are separated by a comma - if (isset($childrenCount[$obj->name])) { - $childrenCount[$obj->name]++; - } else { - $childrenCount[$obj->name] = 0; - $commaString[$obj->name] = $obj->name.'='; - } - if ($childrenCount[$obj->name] == $count-1) { - // Clean the static for future calls to toString - $string .= $commaString[$obj->name].$content."\n"; - unset($childrenCount[$obj->name]); - unset($commaString[$obj->name]); - } else { - $commaString[$obj->name] .= $content.', '; - } - } else { - $string = $obj->name.'='.$content."\n"; - } - break; - case 'section': - if (!$obj->isRoot()) { - $string = '['.$obj->name."]\n"; - } - if (count($obj->children) > 0) { - for ($i = 0; $i < count($obj->children); $i++) { - $string .= $this->toString($obj->getChild($i)); - } - } - break; - default: - $string = ''; - } - return $string; - } // end func toString -} // end class Config_Container_IniFile -?> diff --git a/glmPEAR/Config/Container/PHPArray.php b/glmPEAR/Config/Container/PHPArray.php deleted file mode 100755 index aac6fa7..0000000 --- a/glmPEAR/Config/Container/PHPArray.php +++ /dev/null @@ -1,251 +0,0 @@ - | -// +----------------------------------------------------------------------+ -// -// $Id: PHPArray.php,v 1.1.1.1 2008/04/28 15:20:47 jamie Exp $ - -/** -* Config parser for common PHP configuration array -* such as found in the horde project. -* -* Options expected is: -* 'name' => 'conf' -* Name of the configuration array. -* Default is $conf[]. -* 'useAttr' => true -* Whether we render attributes -* -* @author Bertrand Mansion -* @package Config -*/ -class Config_Container_PHPArray { - - /** - * This class options: - * - name of the config array to parse/output - * Ex: $options['name'] = 'myconf'; - * - Whether to add attributes to the array - * Ex: $options['useAttr'] = false; - * - Whether to treat numbered arrays as duplicates of their parent directive - * or as individual directives - * Ex: $options['duplicateDirectives'] = false; - * - * @var array - */ - var $options = array('name' => 'conf', - 'useAttr' => true, - 'duplicateDirectives' => true); - - /** - * Constructor - * - * @access public - * @param string $options Options to be used by renderer - */ - function Config_Container_PHPArray($options = array()) - { - foreach ($options as $key => $value) { - $this->options[$key] = $value; - } - } // end constructor - - /** - * Parses the data of the given configuration file - * - * @access public - * @param string $datasrc path to the configuration file - * @param object $obj reference to a config object - * @return mixed returns a PEAR_ERROR, if error occurs or true if ok - */ - function &parseDatasrc($datasrc, &$obj) - { - $return = true; - if (empty($datasrc)) { - return PEAR::raiseError("Datasource file path is empty.", null, PEAR_ERROR_RETURN); - } - if (is_array($datasrc)) { - $this->_parseArray($datasrc, $obj->container); - } else { - if (!file_exists($datasrc)) { - return PEAR::raiseError("Datasource file does not exist.", null, PEAR_ERROR_RETURN); - } else { - include($datasrc); - if (!isset(${$this->options['name']}) || !is_array(${$this->options['name']})) { - return PEAR::raiseError("File '$datasrc' does not contain a required '".$this->options['name']."' array.", null, PEAR_ERROR_RETURN); - } - } - $this->_parseArray(${$this->options['name']}, $obj->container); - } - return $return; - } // end func parseDatasrc - - /** - * Parses the PHP array recursively - * @param array $array array values from the config file - * @param object $container reference to the container object - * @access private - * @return void - */ - function _parseArray($array, &$container) - { - foreach ($array as $key => $value) { - switch ((string)$key) { - case '@': - $container->setAttributes($value); - break; - case '#': - $container->setType('directive'); - $container->setContent($value); - break; - default: - if (is_array($value)) { - if ($this->options['duplicateDirectives'] == true && is_integer(key($value))) { - foreach ($value as $nestedValue) { - if (is_array($nestedValue)) { - $section =& $container->createSection($key); - $this->_parseArray($nestedValue, $section); - } else { - $container->createDirective($key, $nestedValue); - } - } - } else { - $section =& $container->createSection($key); - $this->_parseArray($value, $section); - } - } else { - $container->createDirective($key, $value); - } - } - } - } // end func _parseArray - - /** - * Returns a formatted string of the object - * @param object $obj Container object to be output as string - * @access public - * @return string - */ - function toString(&$obj) - { - if (!isset($string)) { - $string = ''; - } - switch ($obj->type) { - case 'blank': - $string .= "\n"; - break; - case 'comment': - $string .= '// '.$obj->content."\n"; - break; - case 'directive': - $attrString = ''; - $parentString = $this->_getParentString($obj); - $attributes = $obj->getAttributes(); - if ($this->options['useAttr'] && is_array($attributes) && count($attributes) > 0) { - // Directive with attributes '@' and value '#' - $string .= $parentString."['#']"; - foreach ($attributes as $attr => $val) { - $attrString .= $parentString."['@']" - ."['".$attr."'] = '".addcslashes($val, "\\'")."';\n"; - } - } else { - $string .= $parentString; - } - $string .= ' = '; - if (is_string($obj->content)) { - $string .= "'".addcslashes($obj->content, "\\'")."'"; - } elseif (is_int($obj->content) || is_float($obj->content)) { - $string .= $obj->content; - } elseif (is_bool($obj->content)) { - $string .= ($obj->content) ? 'true' : 'false'; - } - $string .= ";\n"; - $string .= $attrString; - break; - case 'section': - $attrString = ''; - $attributes = $obj->getAttributes(); - if ($this->options['useAttr'] && is_array($attributes) && count($attributes) > 0) { - $parentString = $this->_getParentString($obj); - foreach ($attributes as $attr => $val) { - $attrString .= $parentString."['@']" - ."['".$attr."'] = '".addcslashes($val, "\\'")."';\n"; - } - } - $string .= $attrString; - if ($count = count($obj->children)) { - for ($i = 0; $i < $count; $i++) { - $string .= $this->toString($obj->getChild($i)); - } - } - break; - default: - $string = ''; - } - return $string; - } // end func toString - - /** - * Returns a formatted string of the object parents - * @access private - * @return string - */ - function _getParentString(&$obj) - { - $string = ''; - if (!$obj->isRoot()) { - $string = is_int($obj->name) ? "[".$obj->name."]" : "['".$obj->name."']"; - $string = $this->_getParentString($obj->parent).$string; - $count = $obj->parent->countChildren(null, $obj->name); - if ($count > 1) { - $string .= '['.$obj->getItemPosition(false).']'; - } - } - else { - if (empty($this->options['name'])) { - $string .= '$'.$obj->name; - } else { - $string .= '$'.$this->options['name']; - } - } - return $string; - } // end func _getParentString - - /** - * Writes the configuration to a file - * - * @param mixed datasrc info on datasource such as path to the configuraton file - * @param string configType (optional)type of configuration - * @access public - * @return string - */ - function writeDatasrc($datasrc, &$obj) - { - $fp = @fopen($datasrc, 'w'); - if ($fp) { - $string = "toString($obj) ."?>"; // diff --git a/glmPEAR/Config/Container/PHPConstants.php b/glmPEAR/Config/Container/PHPConstants.php deleted file mode 100755 index a7c528d..0000000 --- a/glmPEAR/Config/Container/PHPConstants.php +++ /dev/null @@ -1,199 +0,0 @@ - | -// +----------------------------------------------------------------------+ -// -// $Id: PHPConstants.php,v 1.1.1.1 2008/04/28 15:20:47 jamie Exp $ - -/** -* Config parser for PHP constant files -* -* @author Phillip Oertel -* @package Config -* @version 0.1 (not submitted) -*/ - -require_once 'Config/Container.php'; - -class Config_Container_PHPConstants extends Config_Container { - - /** - * This class options - * Not used at the moment - * - * @var array - */ - var $options = array(); - - /** - * Constructor - * - * @access public - * @param string $options (optional)Options to be used by renderer - */ - function Config_Container_PHPConstants($options = array()) - { - $this->options = $options; - } // end constructor - - /** - * Parses the data of the given configuration file - * - * @access public - * @param string $datasrc path to the configuration file - * @param object $obj reference to a config object - * @return mixed returns a PEAR_ERROR, if error occurs or true if ok - */ - function &parseDatasrc($datasrc, &$obj) - { - $return = true; - - if (!file_exists($datasrc)) { - return PEAR::raiseError("Datasource file does not exist.", null, - PEAR_ERROR_RETURN); - } - - $fileContent = file_get_contents($datasrc, true); - - if (!$fileContent) { - return PEAR::raiseError("File '$datasrc' could not be read.", null, - PEAR_ERROR_RETURN); - } - - $rows = explode("\n", $fileContent); - for ($i=0, $max=count($rows); $i<$max; $i++) { - $line = $rows[$i]; - - //blanks? - - // sections - if (preg_match("/^\/\/\s*$/", $line)) { - preg_match("/^\/\/\s*(.+)$/", $rows[$i+1], $matches); - $obj->container->createSection(trim($matches[1])); - $i += 2; - continue; - } - - // comments - if (preg_match("/^\/\/\s*(.+)$/", $line, $matches) || - preg_match("/^#\s*(.+)$/", $line, $matches)) { - $obj->container->createComment(trim($matches[1])); - continue; - } - - // directives - $regex = "/^\s*define\s*\('([A-Z1-9_]+)',\s*'*(.[^\']*)'*\)/"; - preg_match($regex, $line, $matches); - if (!empty($matches)) { - $obj->container->createDirective(trim($matches[1]), - trim($matches[2])); - } - } - - return $return; - - } // end func parseDatasrc - - /** - * Returns a formatted string of the object - * @param object $obj Container object to be output as string - * @access public - * @return string - */ - function toString(&$obj) - { - $string = ''; - - switch ($obj->type) - { - case 'blank': - $string = "\n"; - break; - - case 'comment': - $string = '// '.$obj->content."\n"; - break; - - case 'directive': - $content = $obj->content; - // don't quote numeric values, true/false and constants - if (!is_numeric($content) && !in_array($content, array('false', - 'true')) && !preg_match('/^[A-Z_]+$/', $content)) { - $content = "'".$content."'"; - } - $string = 'define(\''.$obj->name.'\', '.$content.');'.chr(10); - break; - - case 'section': - if (!$obj->isRoot()) { - $string = chr(10); - $string .= '//'.chr(10); - $string .= '// '.$obj->name.chr(10); - $string .= '//'.chr(10); - } - if (count($obj->children) > 0) { - for ($i = 0, $max = count($obj->children); $i < $max; $i++) { - $string .= $this->toString($obj->getChild($i)); - } - } - break; - default: - $string = ''; - } - return $string; - } // end func toString - - /** - * Writes the configuration to a file - * - * @param mixed datasrc info on datasource such as path to the file - * @param string configType (optional)type of configuration - * @access public - * @return string - */ - function writeDatasrc($datasrc, &$obj) - { - $fp = @fopen($datasrc, 'w'); - if ($fp) { - $string = "toString($obj); - $string .= "\n?>"; // diff --git a/glmPEAR/Config/Container/XML.php b/glmPEAR/Config/Container/XML.php deleted file mode 100755 index e57de1c..0000000 --- a/glmPEAR/Config/Container/XML.php +++ /dev/null @@ -1,249 +0,0 @@ - | -// +----------------------------------------------------------------------+ -// -// $Id: XML.php,v 1.1.1.1 2008/04/28 15:20:47 jamie Exp $ - -require_once('XML/Parser.php'); -require_once('XML/Util.php'); - -/** -* Config parser for XML Files -* -* @author Bertrand Mansion -* @package Config -*/ -class Config_Container_XML extends XML_Parser -{ - /** - * Deep level used for indentation - * - * @var int - * @access private - */ - var $_deep = -1; - - /** - * This class options: - * version (1.0) : XML version - * encoding (ISO-8859-1) : XML content encoding - * name : like in phparray, name of your config global entity - * indent : char used for indentation - * linebreak : char used for linebreak - * addDecl : whether to add the xml declaration at beginning or not - * useAttr : whether to use the attributes - * isFile : whether the given content is a file or an XML string - * useCData : whether to surround data with - * - * @var array - */ - var $options = array('version' => '1.0', - 'encoding' => 'ISO-8859-1', - 'name' => '', - 'indent' => ' ', - 'linebreak' => "\n", - 'addDecl' => true, - 'useAttr' => true, - 'isFile' => true, - 'useCData' => false); - - /** - * Container objects - * - * @var array - */ - var $containers = array(); - - /** - * Constructor - * - * @access public - * @param string $options Options to be used by renderer - * version : (1.0) XML version - * encoding : (ISO-8859-1) XML content encoding - * name : like in phparray, name of your config global entity - * indent : char used for indentation - * linebreak : char used for linebreak - * addDecl : whether to add the xml declaration at beginning or not - * useAttr : whether to use the attributes - * isFile : whether the given content is a file or an XML string - */ - function Config_Container_XML($options = array()) - { - foreach ($options as $key => $value) { - $this->options[$key] = $value; - } - } // end constructor - - /** - * Parses the data of the given configuration file - * - * @access public - * @param string $datasrc path to the configuration file - * @param object $obj reference to a config object - * @return mixed returns a PEAR_ERROR, if error occurs or true if ok - */ - function &parseDatasrc($datasrc, &$obj) - { - $err = true; - $this->folding = false; - $this->cdata = null; - $this->XML_Parser($this->options['encoding'], 'event'); - $this->containers[0] =& $obj->container; - if (is_string($datasrc)) { - if ($this->options['isFile']) { - $err = $this->setInputFile($datasrc); - if (PEAR::isError($err)) { - return $err; - } - $err = $this->parse(); - } else { - $err = $this->parseString($datasrc, true); - } - } else { - $this->setInput($datasrc); - $err = $this->parse(); - } - return $err; - } // end func parseDatasrc - - /** - * Handler for the xml-data - * - * @param mixed $xp ignored - * @param string $elem name of the element - * @param array $attribs attributes for the generated node - * - * @access private - */ - function startHandler($xp, $elem, &$attribs) - { - $container =& new Config_Container('section', $elem, null, $attribs); - $this->containers[] =& $container; - return null; - } // end func startHandler - - /** - * Handler for the xml-data - * - * @param mixed $xp ignored - * @param string $elem name of the element - * - * @access private - */ - function endHandler($xp, $elem) - { - $count = count($this->containers); - $container =& $this->containers[$count-1]; - $currentSection =& $this->containers[$count-2]; - if (count($container->children) == 0) { - $container->setType('directive'); - $container->setContent(trim($this->cdata)); - } - $currentSection->addItem($container); - array_pop($this->containers); - $this->cdata = null; - return null; - } // end func endHandler - - /* - * The xml character data handler - * - * @param mixed $xp ignored - * @param string $data PCDATA between tags - * - * @access private - */ - function cdataHandler($xp, $cdata) - { - $this->cdata .= $cdata; - } // end func cdataHandler - - /** - * Returns a formatted string of the object - * @param object $obj Container object to be output as string - * @access public - * @return string - */ - function toString(&$obj) - { - $indent = ''; - if (!$obj->isRoot()) { - // no indent for root - $this->_deep++; - $indent = str_repeat($this->options['indent'], $this->_deep); - } else { - // Initialize string with xml declaration - $string = ''; - if ($this->options['addDecl']) { - $string .= XML_Util::getXMLDeclaration($this->options['version'], $this->options['encoding']); - $string .= $this->options['linebreak']; - } - if (!empty($this->options['name'])) { - $string .= '<'.$this->options['name'].'>'.$this->options['linebreak']; - $this->_deep++; - $indent = str_repeat($this->options['indent'], $this->_deep); - } - } - if (!isset($string)) { - $string = ''; - } - switch ($obj->type) { - case 'directive': - $attributes = ($this->options['useAttr']) ? $obj->attributes : array(); - $string .= $indent.XML_Util::createTag($obj->name, $attributes, $obj->content, null, - ($this->options['useCData'] ? XML_UTIL_CDATA_SECTION : XML_UTIL_REPLACE_ENTITIES)); - $string .= $this->options['linebreak']; - break; - case 'comment': - $string .= $indent.''; - $string .= $this->options['linebreak']; - break; - case 'section': - if (!$obj->isRoot()) { - $string = $indent.'<'.$obj->name; - $string .= ($this->options['useAttr']) ? XML_Util::attributesToString($obj->attributes) : ''; - } - if ($children = count($obj->children)) { - if (!$obj->isRoot()) { - $string .= '>'.$this->options['linebreak']; - } - for ($i = 0; $i < $children; $i++) { - $string .= $this->toString($obj->getChild($i)); - } - } - if (!$obj->isRoot()) { - if ($children) { - $string .= $indent.'name.'>'.$this->options['linebreak']; - } else { - $string .= '/>'.$this->options['linebreak']; - } - } else { - if (!empty($this->options['name'])) { - $string .= 'options['name'].'>'.$this->options['linebreak']; - } - } - break; - default: - $string = ''; - } - if (!$obj->isRoot()) { - $this->_deep--; - } - return $string; - } // end func toString -} // end class Config_Container_XML -?> diff --git a/glmPEAR/Console/Getopt.php b/glmPEAR/Console/Getopt.php deleted file mode 100755 index e2ffe79..0000000 --- a/glmPEAR/Console/Getopt.php +++ /dev/null @@ -1,290 +0,0 @@ - | -// +----------------------------------------------------------------------+ -// -// $Id: Getopt.php,v 1.1.1.1 2008/04/28 15:20:47 jamie Exp $ - -require_once 'PEAR.php'; - -/** - * Command-line options parsing class. - * - * @author Andrei Zmievski - * - */ -class Console_Getopt { - /** - * Parses the command-line options. - * - * The first parameter to this function should be the list of command-line - * arguments without the leading reference to the running program. - * - * The second parameter is a string of allowed short options. Each of the - * option letters can be followed by a colon ':' to specify that the option - * requires an argument, or a double colon '::' to specify that the option - * takes an optional argument. - * - * The third argument is an optional array of allowed long options. The - * leading '--' should not be included in the option name. Options that - * require an argument should be followed by '=', and options that take an - * option argument should be followed by '=='. - * - * The return value is an array of two elements: the list of parsed - * options and the list of non-option command-line arguments. Each entry in - * the list of parsed options is a pair of elements - the first one - * specifies the option, and the second one specifies the option argument, - * if there was one. - * - * Long and short options can be mixed. - * - * Most of the semantics of this function are based on GNU getopt_long(). - * - * @param array $args an array of command-line arguments - * @param string $short_options specifies the list of allowed short options - * @param array $long_options specifies the list of allowed long options - * - * @return array two-element array containing the list of parsed options and - * the non-option arguments - * - * @access public - * - */ - function getopt2($args, $short_options, $long_options = null) - { - return Console_Getopt::doGetopt(2, $args, $short_options, $long_options); - } - - /** - * This function expects $args to start with the script name (POSIX-style). - * Preserved for backwards compatibility. - * @see getopt2() - */ - function getopt($args, $short_options, $long_options = null) - { - return Console_Getopt::doGetopt(1, $args, $short_options, $long_options); - } - - /** - * The actual implementation of the argument parsing code. - */ - function doGetopt($version, $args, $short_options, $long_options = null) - { - // in case you pass directly readPHPArgv() as the first arg - if (PEAR::isError($args)) { - return $args; - } - if (empty($args)) { - return array(array(), array()); - } - $opts = array(); - $non_opts = array(); - - settype($args, 'array'); - - if ($long_options) { - sort($long_options); - } - - /* - * Preserve backwards compatibility with callers that relied on - * erroneous POSIX fix. - */ - if ($version < 2) { - if (isset($args[0]{0}) && $args[0]{0} != '-') { - array_shift($args); - } - } - - reset($args); - while (list($i, $arg) = each($args)) { - - /* The special element '--' means explicit end of - options. Treat the rest of the arguments as non-options - and end the loop. */ - if ($arg == '--') { - $non_opts = array_merge($non_opts, array_slice($args, $i + 1)); - break; - } - - if ($arg{0} != '-' || (strlen($arg) > 1 && $arg{1} == '-' && !$long_options)) { - $non_opts = array_merge($non_opts, array_slice($args, $i)); - break; - } elseif (strlen($arg) > 1 && $arg{1} == '-') { - $error = Console_Getopt::_parseLongOption(substr($arg, 2), $long_options, $opts, $args); - if (PEAR::isError($error)) - return $error; - } elseif ($arg == '-') { - // - is stdin - $non_opts = array_merge($non_opts, array_slice($args, $i)); - break; - } else { - $error = Console_Getopt::_parseShortOption(substr($arg, 1), $short_options, $opts, $args); - if (PEAR::isError($error)) - return $error; - } - } - - return array($opts, $non_opts); - } - - /** - * @access private - * - */ - function _parseShortOption($arg, $short_options, &$opts, &$args) - { - for ($i = 0; $i < strlen($arg); $i++) { - $opt = $arg{$i}; - $opt_arg = null; - - /* Try to find the short option in the specifier string. */ - if (($spec = strstr($short_options, $opt)) === false || $arg{$i} == ':') - { - return PEAR::raiseError("Console_Getopt: unrecognized option -- $opt"); - } - - if (strlen($spec) > 1 && $spec{1} == ':') { - if (strlen($spec) > 2 && $spec{2} == ':') { - if ($i + 1 < strlen($arg)) { - /* Option takes an optional argument. Use the remainder of - the arg string if there is anything left. */ - $opts[] = array($opt, substr($arg, $i + 1)); - break; - } - } else { - /* Option requires an argument. Use the remainder of the arg - string if there is anything left. */ - if ($i + 1 < strlen($arg)) { - $opts[] = array($opt, substr($arg, $i + 1)); - break; - } else if (list(, $opt_arg) = each($args)) { - /* Else use the next argument. */; - if (Console_Getopt::_isShortOpt($opt_arg) || Console_Getopt::_isLongOpt($opt_arg)) { - return PEAR::raiseError("Console_Getopt: option requires an argument -- $opt"); - } - } else { - return PEAR::raiseError("Console_Getopt: option requires an argument -- $opt"); - } - } - } - - $opts[] = array($opt, $opt_arg); - } - } - - /** - * @access private - * - */ - function _isShortOpt($arg) - { - return strlen($arg) == 2 && $arg[0] == '-' && preg_match('/[a-zA-Z]/', $arg[1]); - } - - /** - * @access private - * - */ - function _isLongOpt($arg) - { - return strlen($arg) > 2 && $arg[0] == '-' && $arg[1] == '-' && - preg_match('/[a-zA-Z]+$/', substr($arg, 2)); - } - - /** - * @access private - * - */ - function _parseLongOption($arg, $long_options, &$opts, &$args) - { - @list($opt, $opt_arg) = explode('=', $arg, 2); - $opt_len = strlen($opt); - - for ($i = 0; $i < count($long_options); $i++) { - $long_opt = $long_options[$i]; - $opt_start = substr($long_opt, 0, $opt_len); - $long_opt_name = str_replace('=', '', $long_opt); - - /* Option doesn't match. Go on to the next one. */ - if ($long_opt_name != $opt) { - continue; - } - - $opt_rest = substr($long_opt, $opt_len); - - /* Check that the options uniquely matches one of the allowed - options. */ - if ($i + 1 < count($long_options)) { - $next_option_rest = substr($long_options[$i + 1], $opt_len); - } else { - $next_option_rest = ''; - } - if ($opt_rest != '' && $opt{0} != '=' && - $i + 1 < count($long_options) && - $opt == substr($long_options[$i+1], 0, $opt_len) && - $next_option_rest != '' && - $next_option_rest{0} != '=') { - return PEAR::raiseError("Console_Getopt: option --$opt is ambiguous"); - } - - if (substr($long_opt, -1) == '=') { - if (substr($long_opt, -2) != '==') { - /* Long option requires an argument. - Take the next argument if one wasn't specified. */; - if (!strlen($opt_arg) && !(list(, $opt_arg) = each($args))) { - return PEAR::raiseError("Console_Getopt: option --$opt requires an argument"); - } - if (Console_Getopt::_isShortOpt($opt_arg) || Console_Getopt::_isLongOpt($opt_arg)) { - return PEAR::raiseError("Console_Getopt: option requires an argument --$opt"); - } - } - } else if ($opt_arg) { - return PEAR::raiseError("Console_Getopt: option --$opt doesn't allow an argument"); - } - - $opts[] = array('--' . $opt, $opt_arg); - return; - } - - return PEAR::raiseError("Console_Getopt: unrecognized option --$opt"); - } - - /** - * Safely read the $argv PHP array across different PHP configurations. - * Will take care on register_globals and register_argc_argv ini directives - * - * @access public - * @return mixed the $argv PHP array or PEAR error if not registered - */ - function readPHPArgv() - { - global $argv; - if (!is_array($argv)) { - if (!@is_array($_SERVER['argv'])) { - if (!@is_array($GLOBALS['HTTP_SERVER_VARS']['argv'])) { - return PEAR::raiseError("Console_Getopt: Could not read cmd args (register_argc_argv=Off?)"); - } - return $GLOBALS['HTTP_SERVER_VARS']['argv']; - } - return $_SERVER['argv']; - } - return $argv; - } - -} - -?> diff --git a/glmPEAR/Container.php b/glmPEAR/Container.php deleted file mode 100755 index 7b5df70..0000000 --- a/glmPEAR/Container.php +++ /dev/null @@ -1,262 +0,0 @@ - - * @author Adam Ashley - * @copyright 2001-2006 The PHP Group - * @license http://www.php.net/license/3_01.txt PHP License 3.01 - * @version CVS: $Id: Container.php,v 1.1.1.1 2008/04/28 15:20:46 jamie Exp $ - * @link http://pear.php.net/package/Auth - */ - -/** - * Storage class for fetching login data - * - * @category Authentication - * @package Auth - * @author Martin Jansen - * @author Adam Ashley - * @copyright 2001-2006 The PHP Group - * @license http://www.php.net/license/3_01.txt PHP License 3.01 - * @version Release: 1.5.4 File: $Revision: 1.1.1.1 $ - * @link http://pear.php.net/package/Auth - */ -class Auth_Container -{ - - // {{{ properties - - /** - * User that is currently selected from the storage container. - * - * @access public - */ - var $activeUser = ""; - - /** - * The Auth object this container is attached to. - * - * @access public - */ - var $_auth_obj = null; - - // }}} - // {{{ Auth_Container() [constructor] - - /** - * Constructor - * - * Has to be overwritten by each storage class - * - * @access public - */ - function Auth_Container() - { - } - - // }}} - // {{{ fetchData() - - /** - * Fetch data from storage container - * - * Has to be overwritten by each storage class - * - * @access public - */ - function fetchData($username, $password, $isChallengeResponse=false) - { - $this->log('Auth_Container::fetchData() called.', AUTH_LOG_DEBUG); - } - - // }}} - // {{{ verifyPassword() - - /** - * Crypt and verfiy the entered password - * - * @param string Entered password - * @param string Password from the data container (usually this password - * is already encrypted. - * @param string Type of algorithm with which the password from - * the container has been crypted. (md5, crypt etc.) - * Defaults to "md5". - * @return bool True, if the passwords match - */ - function verifyPassword($password1, $password2, $cryptType = "md5") - { - $this->log('Auth_Container::verifyPassword() called.', AUTH_LOG_DEBUG); - switch ($cryptType) { - case "crypt" : - return ((string)crypt($password1, $password2) === (string)$password2); - break; - case "none" : - case "" : - return ((string)$password1 === (string)$password2); - break; - case "md5" : - return ((string)md5($password1) === (string)$password2); - break; - default : - if (function_exists($cryptType)) { - return ((string)$cryptType($password1) === (string)$password2); - } elseif (method_exists($this,$cryptType)) { - return ((string)$this->$cryptType($password1) === (string)$password2); - } else { - return false; - } - break; - } - } - - // }}} - // {{{ supportsChallengeResponse() - - /** - * Returns true if the container supports Challenge Response - * password authentication - */ - function supportsChallengeResponse() - { - return(false); - } - - // }}} - // {{{ getCryptType() - - /** - * Returns the crypt current crypt type of the container - * - * @return string - */ - function getCryptType() - { - return(''); - } - - // }}} - // {{{ listUsers() - - /** - * List all users that are available from the storage container - */ - function listUsers() - { - $this->log('Auth_Container::listUsers() called.', AUTH_LOG_DEBUG); - return AUTH_METHOD_NOT_SUPPORTED; - } - - // }}} - // {{{ getUser() - - /** - * Returns a user assoc array - * - * Containers which want should overide this - * - * @param string The username - */ - function getUser($username) - { - $this->log('Auth_Container::getUser() called.', AUTH_LOG_DEBUG); - $users = $this->listUsers(); - if ($users === AUTH_METHOD_NOT_SUPPORTED) { - return AUTH_METHOD_NOT_SUPPORTED; - } - for ($i=0; $c = count($users), $i<$c; $i++) { - if ($users[$i]['username'] == $username) { - return $users[$i]; - } - } - return false; - } - - // }}} - // {{{ addUser() - - /** - * Add a new user to the storage container - * - * @param string Username - * @param string Password - * @param array Additional information - * - * @return boolean - */ - function addUser($username, $password, $additional=null) - { - $this->log('Auth_Container::addUser() called.', AUTH_LOG_DEBUG); - return AUTH_METHOD_NOT_SUPPORTED; - } - - // }}} - // {{{ removeUser() - - /** - * Remove user from the storage container - * - * @param string Username - */ - function removeUser($username) - { - $this->log('Auth_Container::removeUser() called.', AUTH_LOG_DEBUG); - return AUTH_METHOD_NOT_SUPPORTED; - } - - // }}} - // {{{ changePassword() - - /** - * Change password for user in the storage container - * - * @param string Username - * @param string The new password - */ - function changePassword($username, $password) - { - $this->log('Auth_Container::changePassword() called.', AUTH_LOG_DEBUG); - return AUTH_METHOD_NOT_SUPPORTED; - } - - // }}} - // {{{ log() - - /** - * Log a message to the Auth log - * - * @param string The message - * @param int - * @return boolean - */ - function log($message, $level = AUTH_LOG_DEBUG) { - - if (is_null($this->_auth_obj)) { - - return false; - - } else { - - return $this->_auth_obj->log($message, $level); - - } - - } - - // }}} - -} - -?> diff --git a/glmPEAR/Container/Array.php b/glmPEAR/Container/Array.php deleted file mode 100755 index e2bf030..0000000 --- a/glmPEAR/Container/Array.php +++ /dev/null @@ -1,161 +0,0 @@ - - * @copyright 2001-2006 The PHP Group - * @license http://www.php.net/license/3_01.txt PHP License 3.01 - * @version CVS: $Id: Array.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ - * @since File available since Release 1.4.0 - */ - -/** - * Include Auth_Container base class - */ -require_once "Auth/Container.php"; -/** - * Include PEAR package for error handling - */ -require_once "PEAR.php"; - -/** - * Storage driver for fetching authentication data from a PHP Array - * - * This container takes two options when configuring: - * - * cryptType: The crypt used to store the password. Currently recognised - * are: none, md5 and crypt. default: none - * users: A named array of usernames and passwords. - * Ex: - * array( - * 'guest' => '084e0343a0486ff05530df6c705c8bb4', // password guest - * 'georg' => 'fc77dba827fcc88e0243404572c51325' // password georg - * ) - * - * Usage Example: - * array( - * 'guest' => '084e0343a0486ff05530df6c705c8bb4', // password guest - * 'georg' => 'fc77dba827fcc88e0243404572c51325' // password georg - * ), - * 'cryptType'=>'md5', - * ); - * - * $auth = new Auth("Array", $AuthOptions); - * ?> - * - * @category Authentication - * @package Auth - * @author georg_1 at have2 dot com - * @author Adam Ashley - * @copyright 2001-2006 The PHP Group - * @license http://www.php.net/license/3_01.txt PHP License 3.01 - * @version Release: 1.5.4 File: $Revision: 1.1.1.1 $ - * @since File available since Release 1.4.0 - */ - -class Auth_Container_Array extends Auth_Container { - - // {{{ properties - - /** - * The users and their password to authenticate against - * - * @var array $users - */ - var $users; - - /** - * The cryptType used on the passwords - * - * @var string $cryptType - */ - var $cryptType = 'none'; - - // }}} - // {{{ Auth_Container_Array() - - /** - * Constructor for Array Container - * - * @param array $data Options for the container - * @return void - */ - function Auth_Container_Array($data) - { - if (!is_array($data)) { - PEAR::raiseError('The options for Auth_Container_Array must be an array'); - } - if (isset($data['users']) && is_array($data['users'])) { - $this->users = $data['users']; - } else { - $this->users = array(); - PEAR::raiseError('Auth_Container_Array: no user data found in options array'); - } - if (isset($data['cryptType'])) { - $this->cryptType = $data['cryptType']; - } - } - - // }}} - // {{{ fetchData() - - /** - * Get user information from array - * - * This function uses the given username to fetch the corresponding - * login data from the array. If an account that matches the passed - * username and password is found, the function returns true. - * Otherwise it returns false. - * - * @param string Username - * @param string Password - * @return boolean|PEAR_Error Error object or boolean - */ - function fetchData($user, $pass) - { - $this->log('Auth_Container_Array::fetchData() called.', AUTH_LOG_DEBUG); - if ( isset($this->users[$user]) - && $this->verifyPassword($pass, $this->users[$user], $this->cryptType)) { - return true; - } - return false; - } - - // }}} - // {{{ listUsers() - - /** - * Returns a list of users available within the container - * - * @return array - */ - function listUsers() - { - $this->log('Auth_Container_Array::listUsers() called.', AUTH_LOG_DEBUG); - $ret = array(); - foreach ($this->users as $username => $password) { - $ret[]['username'] = $username; - } - return $ret; - } - - // }}} - -} - -?> diff --git a/glmPEAR/Container/DB.php b/glmPEAR/Container/DB.php deleted file mode 100755 index 818e7d5..0000000 --- a/glmPEAR/Container/DB.php +++ /dev/null @@ -1,632 +0,0 @@ - - * @author Adam Ashley - * @copyright 2001-2006 The PHP Group - * @license http://www.php.net/license/3_01.txt PHP License 3.01 - * @version CVS: $Id: DB.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ - * @link http://pear.php.net/package/Auth - */ - -/** - * Include Auth_Container base class - */ -require_once 'Auth/Container.php'; -/** - * Include PEAR DB - */ -require_once 'DB.php'; - -/** - * Storage driver for fetching login data from a database - * - * This storage driver can use all databases which are supported - * by the PEAR DB abstraction layer to fetch login data. - * - * @category Authentication - * @package Auth - * @author Martin Jansen - * @author Adam Ashley - * @copyright 2001-2006 The PHP Group - * @license http://www.php.net/license/3_01.txt PHP License 3.01 - * @version Release: 1.5.4 File: $Revision: 1.1.1.1 $ - * @link http://pear.php.net/package/Auth - */ -class Auth_Container_DB extends Auth_Container -{ - - // {{{ properties - - /** - * Additional options for the storage container - * @var array - */ - var $options = array(); - - /** - * DB object - * @var object - */ - var $db = null; - var $dsn = ''; - - /** - * User that is currently selected from the DB. - * @var string - */ - var $activeUser = ''; - - // }}} - // {{{ Auth_Container_DB [constructor] - - /** - * Constructor of the container class - * - * Save the initial options passed to the container. Initiation of the DB - * connection is no longer performed here and is only done when needed. - * - * @param string Connection data or DB object - * @return object Returns an error object if something went wrong - */ - function Auth_Container_DB($dsn) - { - $this->_setDefaults(); - - if (is_array($dsn)) { - $this->_parseOptions($dsn); - - if (empty($this->options['dsn'])) { - PEAR::raiseError('No connection parameters specified!'); - } - } else { - $this->options['dsn'] = $dsn; - } - } - - // }}} - // {{{ _connect() - - /** - * Connect to database by using the given DSN string - * - * @access private - * @param string DSN string - * @return mixed Object on error, otherwise bool - */ - function _connect($dsn) - { - $this->log('Auth_Container_DB::_connect() called.', AUTH_LOG_DEBUG); - - if (is_string($dsn) || is_array($dsn)) { - $this->db = DB::Connect($dsn, $this->options['db_options']); - } elseif (is_subclass_of($dsn, 'db_common')) { - $this->db = $dsn; - } elseif (DB::isError($dsn)) { - return PEAR::raiseError($dsn->getMessage(), $dsn->getCode()); - } else { - return PEAR::raiseError('The given dsn was not valid in file ' . __FILE__ . ' at line ' . __LINE__, - 41, - PEAR_ERROR_RETURN, - null, - null - ); - } - - if (DB::isError($this->db) || PEAR::isError($this->db)) { - return PEAR::raiseError($this->db->getMessage(), $this->db->getCode()); - } else { - return true; - } - } - - // }}} - // {{{ _prepare() - - /** - * Prepare database connection - * - * This function checks if we have already opened a connection to - * the database. If that's not the case, a new connection is opened. - * - * @access private - * @return mixed True or a DB error object. - */ - function _prepare() - { - if (!DB::isConnection($this->db)) { - $res = $this->_connect($this->options['dsn']); - if (DB::isError($res) || PEAR::isError($res)) { - return $res; - } - } - if ($this->options['auto_quote'] && $this->db->dsn['phptype'] != 'sqlite') { - $this->options['final_table'] = $this->db->quoteIdentifier($this->options['table']); - $this->options['final_usernamecol'] = $this->db->quoteIdentifier($this->options['usernamecol']); - $this->options['final_passwordcol'] = $this->db->quoteIdentifier($this->options['passwordcol']); - } else { - $this->options['final_table'] = $this->options['table']; - $this->options['final_usernamecol'] = $this->options['usernamecol']; - $this->options['final_passwordcol'] = $this->options['passwordcol']; - } - return true; - } - - // }}} - // {{{ query() - - /** - * Prepare query to the database - * - * This function checks if we have already opened a connection to - * the database. If that's not the case, a new connection is opened. - * After that the query is passed to the database. - * - * @access public - * @param string Query string - * @return mixed a DB_result object or DB_OK on success, a DB - * or PEAR error on failure - */ - function query($query) - { - $err = $this->_prepare(); - if ($err !== true) { - return $err; - } - return $this->db->query($query); - } - - // }}} - // {{{ _setDefaults() - - /** - * Set some default options - * - * @access private - * @return void - */ - function _setDefaults() - { - $this->options['table'] = 'auth'; - $this->options['usernamecol'] = 'username'; - $this->options['passwordcol'] = 'password'; - $this->options['dsn'] = ''; - $this->options['db_fields'] = ''; - $this->options['cryptType'] = 'md5'; - $this->options['db_options'] = array(); - $this->options['db_where'] = ''; - $this->options['auto_quote'] = true; - } - - // }}} - // {{{ _parseOptions() - - /** - * Parse options passed to the container class - * - * @access private - * @param array - */ - function _parseOptions($array) - { - foreach ($array as $key => $value) { - if (isset($this->options[$key])) { - $this->options[$key] = $value; - } - } - } - - // }}} - // {{{ _quoteDBFields() - - /** - * Quote the db_fields option to avoid the possibility of SQL injection. - * - * @access private - * @return string A properly quoted string that can be concatenated into a - * SELECT clause. - */ - function _quoteDBFields() - { - if (isset($this->options['db_fields'])) { - if (is_array($this->options['db_fields'])) { - if ($this->options['auto_quote']) { - $fields = array(); - foreach ($this->options['db_fields'] as $field) { - $fields[] = $this->db->quoteIdentifier($field); - } - return implode(', ', $fields); - } else { - return implode(', ', $this->options['db_fields']); - } - } else { - if (strlen($this->options['db_fields']) > 0) { - if ($this->options['auto_quote']) { - return $this->db->quoteIdentifier($this->options['db_fields']); - } else { - return $this->options['db_fields']; - } - } - } - } - - return ''; - } - - // }}} - // {{{ fetchData() - - /** - * Get user information from database - * - * This function uses the given username to fetch - * the corresponding login data from the database - * table. If an account that matches the passed username - * and password is found, the function returns true. - * Otherwise it returns false. - * - * @param string Username - * @param string Password - * @param boolean If true password is secured using a md5 hash - * the frontend and auth are responsible for making sure the container supports - * challenge response password authentication - * @return mixed Error object or boolean - */ - function fetchData($username, $password, $isChallengeResponse=false) - { - $this->log('Auth_Container_DB::fetchData() called.', AUTH_LOG_DEBUG); - // Prepare for a database query - $err = $this->_prepare(); - if ($err !== true) { - return PEAR::raiseError($err->getMessage(), $err->getCode()); - } - - // Find if db_fields contains a *, if so assume all columns are selected - if (is_string($this->options['db_fields']) - && strstr($this->options['db_fields'], '*')) { - $sql_from = "*"; - } else { - $sql_from = $this->options['final_usernamecol']. - ", ".$this->options['final_passwordcol']; - - if (strlen($fields = $this->_quoteDBFields()) > 0) { - $sql_from .= ', '.$fields; - } - } - - $query = "SELECT ".$sql_from. - " FROM ".$this->options['final_table']. - " WHERE ".$this->options['final_usernamecol']." = ".$this->db->quoteSmart($username); - - // check if there is an optional parameter db_where - if ($this->options['db_where'] != '') { - // there is one, so add it to the query - $query .= " AND ".$this->options['db_where']; - } - - $this->log('Running SQL against DB: '.$query, AUTH_LOG_DEBUG); - - $res = $this->db->getRow($query, null, DB_FETCHMODE_ASSOC); - - if (DB::isError($res)) { - return PEAR::raiseError($res->getMessage(), $res->getCode()); - } - - if (!is_array($res)) { - $this->activeUser = ''; - return false; - } - - // Perform trimming here before the hashihg - $password = trim($password, "\r\n"); - $res[$this->options['passwordcol']] = trim($res[$this->options['passwordcol']], "\r\n"); - - // If using Challenge Response md5 the pass with the secret - if ($isChallengeResponse) { - $res[$this->options['passwordcol']] = md5($res[$this->options['passwordcol']] - .$this->_auth_obj->session['loginchallenege']); - - // UGLY cannot avoid without modifying verifyPassword - if ($this->options['cryptType'] == 'md5') { - $res[$this->options['passwordcol']] = md5($res[$this->options['passwordcol']]); - } - - //print " Hashed Password [{$res[$this->options['passwordcol']]}]
\n"; - } - - if ($this->verifyPassword($password, - $res[$this->options['passwordcol']], - $this->options['cryptType'])) { - // Store additional field values in the session - foreach ($res as $key => $value) { - if ($key == $this->options['passwordcol'] || - $key == $this->options['usernamecol']) { - continue; - } - - $this->log('Storing additional field: '.$key, AUTH_LOG_DEBUG); - - // Use reference to the auth object if exists - // This is because the auth session variable can change so a - // static call to setAuthData does not make sence - $this->_auth_obj->setAuthData($key, $value); - } - return true; - } - $this->activeUser = $res[$this->options['usernamecol']]; - return false; - } - - // }}} - // {{{ listUsers() - - /** - * Returns a list of users from the container - * - * @return mixed - * @access public - */ - function listUsers() - { - $this->log('Auth_Container_DB::listUsers() called.', AUTH_LOG_DEBUG); - $err = $this->_prepare(); - if ($err !== true) { - return PEAR::raiseError($err->getMessage(), $err->getCode()); - } - - $retVal = array(); - - // Find if db_fields contains a *, if so assume all col are selected - if ( is_string($this->options['db_fields']) - && strstr($this->options['db_fields'], '*')) { - $sql_from = "*"; - } else { - $sql_from = $this->options['final_usernamecol']. - ", ".$this->options['final_passwordcol']; - - if (strlen($fields = $this->_quoteDBFields()) > 0) { - $sql_from .= ', '.$fields; - } - } - - $query = sprintf("SELECT %s FROM %s", - $sql_from, - $this->options['final_table'] - ); - - // check if there is an optional parameter db_where - if ($this->options['db_where'] != '') { - // there is one, so add it to the query - $query .= " WHERE ".$this->options['db_where']; - } - - $this->log('Running SQL against DB: '.$query, AUTH_LOG_DEBUG); - - $res = $this->db->getAll($query, null, DB_FETCHMODE_ASSOC); - - if (DB::isError($res)) { - return PEAR::raiseError($res->getMessage(), $res->getCode()); - } else { - foreach ($res as $user) { - $user['username'] = $user[$this->options['usernamecol']]; - $retVal[] = $user; - } - } - $this->log('Found '.count($retVal).' users.', AUTH_LOG_DEBUG); - return $retVal; - } - - // }}} - // {{{ addUser() - - /** - * Add user to the storage container - * - * @access public - * @param string Username - * @param string Password - * @param mixed Additional information that are stored in the DB - * - * @return mixed True on success, otherwise error object - */ - function addUser($username, $password, $additional = "") - { - $this->log('Auth_Container_DB::addUser() called.', AUTH_LOG_DEBUG); - $err = $this->_prepare(); - if ($err !== true) { - return PEAR::raiseError($err->getMessage(), $err->getCode()); - } - - if ( isset($this->options['cryptType']) - && $this->options['cryptType'] == 'none') { - $cryptFunction = 'strval'; - } elseif ( isset($this->options['cryptType']) - && function_exists($this->options['cryptType'])) { - $cryptFunction = $this->options['cryptType']; - } else { - $cryptFunction = 'md5'; - } - - $password = $cryptFunction($password); - - $additional_key = ''; - $additional_value = ''; - - if (is_array($additional)) { - foreach ($additional as $key => $value) { - if ($this->options['auto_quote']) { - $additional_key .= ', ' . $this->db->quoteIdentifier($key); - } else { - $additional_key .= ', ' . $key; - } - $additional_value .= ", " . $this->db->quoteSmart($value); - } - } - - $query = sprintf("INSERT INTO %s (%s, %s%s) VALUES (%s, %s%s)", - $this->options['final_table'], - $this->options['final_usernamecol'], - $this->options['final_passwordcol'], - $additional_key, - $this->db->quoteSmart($username), - $this->db->quoteSmart($password), - $additional_value - ); - - $this->log('Running SQL against DB: '.$query, AUTH_LOG_DEBUG); - - $res = $this->query($query); - - if (DB::isError($res)) { - return PEAR::raiseError($res->getMessage(), $res->getCode()); - } else { - return true; - } - } - - // }}} - // {{{ removeUser() - - /** - * Remove user from the storage container - * - * @access public - * @param string Username - * - * @return mixed True on success, otherwise error object - */ - function removeUser($username) - { - $this->log('Auth_Container_DB::removeUser() called.', AUTH_LOG_DEBUG); - - $err = $this->_prepare(); - if ($err !== true) { - return PEAR::raiseError($err->getMessage(), $err->getCode()); - } - - // check if there is an optional parameter db_where - if ($this->options['db_where'] != '') { - // there is one, so add it to the query - $where = " AND ".$this->options['db_where']; - } else { - $where = ''; - } - - $query = sprintf("DELETE FROM %s WHERE %s = %s %s", - $this->options['final_table'], - $this->options['final_usernamecol'], - $this->db->quoteSmart($username), - $where - ); - - $this->log('Running SQL against DB: '.$query, AUTH_LOG_DEBUG); - - $res = $this->query($query); - - if (DB::isError($res)) { - return PEAR::raiseError($res->getMessage(), $res->getCode()); - } else { - return true; - } - } - - // }}} - // {{{ changePassword() - - /** - * Change password for user in the storage container - * - * @param string Username - * @param string The new password (plain text) - */ - function changePassword($username, $password) - { - $this->log('Auth_Container_DB::changePassword() called.', AUTH_LOG_DEBUG); - $err = $this->_prepare(); - if ($err !== true) { - return PEAR::raiseError($err->getMessage(), $err->getCode()); - } - - if ( isset($this->options['cryptType']) - && $this->options['cryptType'] == 'none') { - $cryptFunction = 'strval'; - } elseif ( isset($this->options['cryptType']) - && function_exists($this->options['cryptType'])) { - $cryptFunction = $this->options['cryptType']; - } else { - $cryptFunction = 'md5'; - } - - $password = $cryptFunction($password); - - // check if there is an optional parameter db_where - if ($this->options['db_where'] != '') { - // there is one, so add it to the query - $where = " AND ".$this->options['db_where']; - } else { - $where = ''; - } - - $query = sprintf("UPDATE %s SET %s = %s WHERE %s = %s %s", - $this->options['final_table'], - $this->options['final_passwordcol'], - $this->db->quoteSmart($password), - $this->options['final_usernamecol'], - $this->db->quoteSmart($username), - $where - ); - - $this->log('Running SQL against DB: '.$query, AUTH_LOG_DEBUG); - - $res = $this->query($query); - - if (DB::isError($res)) { - return PEAR::raiseError($res->getMessage(), $res->getCode()); - } else { - return true; - } - } - - // }}} - // {{{ supportsChallengeResponse() - - /** - * Determine if this container supports - * password authentication with challenge response - * - * @return bool - * @access public - */ - function supportsChallengeResponse() - { - return in_array($this->options['cryptType'], array('md5', 'none', '')); - } - - // }}} - // {{{ getCryptType() - - /** - * Returns the selected crypt type for this container - */ - function getCryptType() - { - return($this->options['cryptType']); - } - - // }}} - -} -?> diff --git a/glmPEAR/Container/DBLite.php b/glmPEAR/Container/DBLite.php deleted file mode 100755 index 2715f8e..0000000 --- a/glmPEAR/Container/DBLite.php +++ /dev/null @@ -1,313 +0,0 @@ - - * @author Adam Ashley - * @copyright 2001-2006 The PHP Group - * @license http://www.php.net/license/3_01.txt PHP License 3.01 - * @version CVS: $Id: DBLite.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ - * @link http://pear.php.net/package/Auth - * @since File available since Release 1.3.0 - */ - -/** - * Include Auth_Container base class - */ -require_once 'Auth/Container.php'; -/** - * Include PEAR DB package - */ -require_once 'DB.php'; - -/** - * A lighter storage driver for fetching login data from a database - * - * This driver is derived from the DB storage container but - * with the user manipulation function removed for smaller file size - * by the PEAR DB abstraction layer to fetch login data. - * - * @category Authentication - * @package Auth - * @author Martin Jansen - * @author Adam Ashley - * @copyright 2001-2006 The PHP Group - * @license http://www.php.net/license/3_01.txt PHP License 3.01 - * @version Release: 1.5.4 File: $Revision: 1.1.1.1 $ - * @link http://pear.php.net/package/Auth - * @since Class available since Release 1.3.0 - */ -class Auth_Container_DBLite extends Auth_Container -{ - - // {{{ properties - - /** - * Additional options for the storage container - * @var array - */ - var $options = array(); - - /** - * DB object - * @var object - */ - var $db = null; - var $dsn = ''; - - /** - * User that is currently selected from the DB. - * @var string - */ - var $activeUser = ''; - - // }}} - // {{{ Auth_Container_DBLite() [constructor] - - /** - * Constructor of the container class - * - * Initate connection to the database via PEAR::DB - * - * @param string Connection data or DB object - * @return object Returns an error object if something went wrong - */ - function Auth_Container_DBLite($dsn) - { - $this->options['table'] = 'auth'; - $this->options['usernamecol'] = 'username'; - $this->options['passwordcol'] = 'password'; - $this->options['dsn'] = ''; - $this->options['db_fields'] = ''; - $this->options['cryptType'] = 'md5'; - $this->options['db_options'] = array(); - $this->options['db_where'] = ''; - $this->options['auto_quote'] = true; - - if (is_array($dsn)) { - $this->_parseOptions($dsn); - if (empty($this->options['dsn'])) { - PEAR::raiseError('No connection parameters specified!'); - } - } else { - $this->options['dsn'] = $dsn; - } - } - - // }}} - // {{{ _connect() - - /** - * Connect to database by using the given DSN string - * - * @access private - * @param string DSN string - * @return mixed Object on error, otherwise bool - */ - function _connect(&$dsn) - { - $this->log('Auth_Container_DBLite::_connect() called.', AUTH_LOG_DEBUG); - if (is_string($dsn) || is_array($dsn)) { - $this->db =& DB::connect($dsn, $this->options['db_options']); - } elseif (is_subclass_of($dsn, "db_common")) { - $this->db =& $dsn; - } else { - return PEAR::raiseError("Invalid dsn or db object given"); - } - - if (DB::isError($this->db) || PEAR::isError($this->db)) { - return PEAR::raiseError($this->db->getMessage(), $this->db->getCode()); - } else { - return true; - } - } - - // }}} - // {{{ _prepare() - - /** - * Prepare database connection - * - * This function checks if we have already opened a connection to - * the database. If that's not the case, a new connection is opened. - * - * @access private - * @return mixed True or a DB error object. - */ - function _prepare() - { - if (!DB::isConnection($this->db)) { - $res = $this->_connect($this->options['dsn']); - if (DB::isError($res) || PEAR::isError($res)) { - return $res; - } - } - if ($this->options['auto_quote'] && $this->db->dsn['phptype'] != 'sqlite') { - $this->options['final_table'] = $this->db->quoteIdentifier($this->options['table']); - $this->options['final_usernamecol'] = $this->db->quoteIdentifier($this->options['usernamecol']); - $this->options['final_passwordcol'] = $this->db->quoteIdentifier($this->options['passwordcol']); - } else { - $this->options['final_table'] = $this->options['table']; - $this->options['final_usernamecol'] = $this->options['usernamecol']; - $this->options['final_passwordcol'] = $this->options['passwordcol']; - } - return true; - } - - // }}} - // {{{ _parseOptions() - - /** - * Parse options passed to the container class - * - * @access private - * @param array - */ - function _parseOptions($array) - { - foreach ($array as $key => $value) { - if (isset($this->options[$key])) { - $this->options[$key] = $value; - } - } - } - - // }}} - // {{{ _quoteDBFields() - - /** - * Quote the db_fields option to avoid the possibility of SQL injection. - * - * @access private - * @return string A properly quoted string that can be concatenated into a - * SELECT clause. - */ - function _quoteDBFields() - { - if (isset($this->options['db_fields'])) { - if (is_array($this->options['db_fields'])) { - if ($this->options['auto_quote']) { - $fields = array(); - foreach ($this->options['db_fields'] as $field) { - $fields[] = $this->db->quoteIdentifier($field); - } - return implode(', ', $fields); - } else { - return implode(', ', $this->options['db_fields']); - } - } else { - if (strlen($this->options['db_fields']) > 0) { - if ($this->options['auto_quote']) { - return $this->db->quoteIdentifier($this->options['db_fields']); - } else { - $this->options['db_fields']; - } - } - } - } - - return ''; - } - - // }}} - // {{{ fetchData() - - /** - * Get user information from database - * - * This function uses the given username to fetch - * the corresponding login data from the database - * table. If an account that matches the passed username - * and password is found, the function returns true. - * Otherwise it returns false. - * - * @param string Username - * @param string Password - * @return mixed Error object or boolean - */ - function fetchData($username, $password) - { - $this->log('Auth_Container_DBLite::fetchData() called.', AUTH_LOG_DEBUG); - // Prepare for a database query - $err = $this->_prepare(); - if ($err !== true) { - return PEAR::raiseError($err->getMessage(), $err->getCode()); - } - - // Find if db_fields contains a *, if so assume all col are selected - if (is_string($this->options['db_fields']) - && strstr($this->options['db_fields'], '*')) { - $sql_from = "*"; - } else { - $sql_from = $this->options['final_usernamecol']. - ", ".$this->options['final_passwordcol']; - - if (strlen($fields = $this->_quoteDBFields()) > 0) { - $sql_from .= ', '.$fields; - } - } - - $query = "SELECT ".$sql_from. - " FROM ".$this->options['final_table']. - " WHERE ".$this->options['final_usernamecol']." = ".$this->db->quoteSmart($username); - - // check if there is an optional parameter db_where - if ($this->options['db_where'] != '') { - // there is one, so add it to the query - $query .= " AND ".$this->options['db_where']; - } - - $this->log('Running SQL against DB: '.$query, AUTH_LOG_DEBUG); - - $res = $this->db->getRow($query, null, DB_FETCHMODE_ASSOC); - - if (DB::isError($res)) { - return PEAR::raiseError($res->getMessage(), $res->getCode()); - } - if (!is_array($res)) { - $this->activeUser = ''; - return false; - } - if ($this->verifyPassword(trim($password, "\r\n"), - trim($res[$this->options['passwordcol']], "\r\n"), - $this->options['cryptType'])) { - // Store additional field values in the session - foreach ($res as $key => $value) { - if ($key == $this->options['passwordcol'] || - $key == $this->options['usernamecol']) { - continue; - } - - $this->log('Storing additional field: '.$key, AUTH_LOG_DEBUG); - - // Use reference to the auth object if exists - // This is because the auth session variable can change so a static call to setAuthData does not make sence - if (is_object($this->_auth_obj)) { - $this->_auth_obj->setAuthData($key, $value); - } else { - Auth::setAuthData($key, $value); - } - } - $this->activeUser = $res[$this->options['usernamecol']]; - return true; - } - $this->activeUser = $res[$this->options['usernamecol']]; - return false; - } - - // }}} - -} -?> diff --git a/glmPEAR/Container/File.php b/glmPEAR/Container/File.php deleted file mode 100755 index aca3423..0000000 --- a/glmPEAR/Container/File.php +++ /dev/null @@ -1,314 +0,0 @@ - - * @author Martin Jansen - * @author Mika Tuupola - * @author Michael Wallner - * @author Adam Ashley - * @copyright 2001-2006 The PHP Group - * @license http://www.php.net/license/3_01.txt PHP License 3.01 - * @version CVS: $Id: File.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ - * @link http://pear.php.net/package/Auth - */ - -/** - * Include PEAR File_Passwd package - */ -require_once "File/Passwd.php"; -/** - * Include Auth_Container base class - */ -require_once "Auth/Container.php"; -/** - * Include PEAR package for error handling - */ -require_once "PEAR.php"; - -/** - * Storage driver for fetching login data from an encrypted password file. - * - * This storage container can handle CVS pserver style passwd files. - * - * @category Authentication - * @package Auth - * @author Stefan Ekman - * @author Martin Jansen - * @author Mika Tuupola - * @author Michael Wallner - * @author Adam Ashley - * @copyright 2001-2006 The PHP Group - * @license http://www.php.net/license/3_01.txt PHP License 3.01 - * @version Release: 1.5.4 File: $Revision: 1.1.1.1 $ - * @link http://pear.php.net/package/Auth - */ -class Auth_Container_File extends Auth_Container -{ - - // {{{ properties - - /** - * Path to passwd file - * - * @var string - */ - var $pwfile = ''; - - /** - * Options for container - * - * @var array - */ - var $options = array(); - - // }}} - // {{{ Auth_Container_File() [constructor] - - /** - * Constructor of the container class - * - * @param string $filename path to passwd file - * @return object Auth_Container_File new Auth_Container_File object - */ - function Auth_Container_File($filename) { - $this->_setDefaults(); - - // Only file is a valid option here - if(is_array($filename)) { - $this->pwfile = $filename['file']; - $this->_parseOptions($filename); - } else { - $this->pwfile = $filename; - } - } - - // }}} - // {{{ fetchData() - - /** - * Authenticate an user - * - * @param string username - * @param string password - * @return mixed boolean|PEAR_Error - */ - function fetchData($user, $pass) - { - $this->log('Auth_Container_File::fetchData() called.', AUTH_LOG_DEBUG); - return File_Passwd::staticAuth($this->options['type'], $this->pwfile, $user, $pass); - } - - // }}} - // {{{ listUsers() - - /** - * List all available users - * - * @return array - */ - function listUsers() - { - $this->log('Auth_Container_File::listUsers() called.', AUTH_LOG_DEBUG); - - $pw_obj = &$this->_load(); - if (PEAR::isError($pw_obj)) { - return array(); - } - - $users = $pw_obj->listUser(); - if (!is_array($users)) { - return array(); - } - - foreach ($users as $key => $value) { - $retVal[] = array("username" => $key, - "password" => $value['passwd'], - "cvsuser" => $value['system']); - } - - $this->log('Found '.count($retVal).' users.', AUTH_LOG_DEBUG); - - return $retVal; - } - - // }}} - // {{{ addUser() - - /** - * Add a new user to the storage container - * - * @param string username - * @param string password - * @param mixed Additional parameters to File_Password_*::addUser() - * - * @return boolean - */ - function addUser($user, $pass, $additional='') - { - $this->log('Auth_Container_File::addUser() called.', AUTH_LOG_DEBUG); - $params = array($user, $pass); - if (is_array($additional)) { - foreach ($additional as $item) { - $params[] = $item; - } - } else { - $params[] = $additional; - } - - $pw_obj = &$this->_load(); - if (PEAR::isError($pw_obj)) { - return false; - } - - $res = call_user_func_array(array(&$pw_obj, 'addUser'), $params); - if (PEAR::isError($res)) { - return false; - } - - $res = $pw_obj->save(); - if (PEAR::isError($res)) { - return false; - } - - return true; - } - - // }}} - // {{{ removeUser() - - /** - * Remove user from the storage container - * - * @param string Username - * @return boolean - */ - function removeUser($user) - { - $this->log('Auth_Container_File::removeUser() called.', AUTH_LOG_DEBUG); - $pw_obj = &$this->_load(); - if (PEAR::isError($pw_obj)) { - return false; - } - - $res = $pw_obj->delUser($user); - if (PEAR::isError($res)) { - return false; - } - - $res = $pw_obj->save(); - if (PEAR::isError($res)) { - return false; - } - - return true; - } - - // }}} - // {{{ changePassword() - - /** - * Change password for user in the storage container - * - * @param string Username - * @param string The new password - */ - function changePassword($username, $password) - { - $this->log('Auth_Container_File::changePassword() called.', AUTH_LOG_DEBUG); - $pw_obj = &$this->_load(); - if (PEAR::isError($pw_obj)) { - return false; - } - - $res = $pw_obj->changePasswd($username, $password); - if (PEAR::isError($res)) { - return false; - } - - $res = $pw_obj->save(); - if (PEAR::isError($res)) { - return false; - } - - return true; - } - - // }}} - // {{{ _load() - - /** - * Load and initialize the File_Passwd object - * - * @return object File_Passwd_Cvs|PEAR_Error - */ - function &_load() - { - static $pw_obj; - - if (!isset($pw_obj)) { - $this->log('Instanciating File_Password object of type '.$this->options['type'], AUTH_LOG_DEBUG); - $pw_obj = File_Passwd::factory($this->options['type']); - if (PEAR::isError($pw_obj)) { - return $pw_obj; - } - - $pw_obj->setFile($this->pwfile); - - $res = $pw_obj->load(); - if (PEAR::isError($res)) { - return $res; - } - } - - return $pw_obj; - } - - // }}} - // {{{ _setDefaults() - - /** - * Set some default options - * - * @access private - * @return void - */ - function _setDefaults() - { - $this->options['type'] = 'Cvs'; - } - - // }}} - // {{{ _parseOptions() - - /** - * Parse options passed to the container class - * - * @access private - * @param array - */ - function _parseOptions($array) - { - foreach ($array as $key => $value) { - if (isset($this->options[$key])) { - $this->options[$key] = $value; - } - } - } - - // }}} - -} -?> diff --git a/glmPEAR/Container/IMAP.php b/glmPEAR/Container/IMAP.php deleted file mode 100755 index aebab67..0000000 --- a/glmPEAR/Container/IMAP.php +++ /dev/null @@ -1,210 +0,0 @@ - - * @author Adam Ashley - * @copyright 2001-2006 The PHP Group - * @license http://www.php.net/license/3_01.txt PHP License 3.01 - * @version CVS: $Id: IMAP.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ - * @link http://pear.php.net/package/Auth - * @since File available since Release 1.2.0 - */ - -/** - * Include Auth_Container base class - */ -require_once "Auth/Container.php"; - -/** - * Include PEAR class for error handling - */ -require_once "PEAR.php"; - -/** - * Storage driver for fetching login data from an IMAP server - * - * This class is based on LDAP containers, but it very simple. - * By default it connects to localhost:143 - * The constructor will first check if the host:port combination is - * actually reachable. This behaviour can be disabled. - * It then tries to create an IMAP stream (without opening a mailbox) - * If you wish to pass extended options to the connections, you may - * do so by specifying protocol options. - * - * To use this storage containers, you have to use the - * following syntax: - * - * 'mail.example.com', - * 'port' => 143, - * ); - * $myAuth = new Auth('IMAP', $params); - * ... - * - * By default we connect without any protocol options set. However, some - * servers require you to connect with the notls or norsh options set. - * To do this you need to add the following value to the params array: - * 'baseDSN' => '/imap/notls/norsh' - * - * To connect to an SSL IMAP server: - * 'baseDSN' => '/imap/ssl' - * - * To connect to an SSL IMAP server with a self-signed certificate: - * 'baseDSN' => '/imap/ssl/novalidate-cert' - * - * Further options may be available and can be found on the php site at - * http://www.php.net/manual/function.imap-open.php - * - * @category Authentication - * @package Auth - * @author Jeroen Houben - * @author Cipriano Groenendal - * @author Adam Ashley - * @copyright 2001-2006 The PHP Group - * @license http://www.php.net/license/3_01.txt PHP License 3.01 - * @version Release: 1.5.4 File: $Revision: 1.1.1.1 $ - * @link http://pear.php.net/package/Auth - * @since Class available since Release 1.2.0 - */ -class Auth_Container_IMAP extends Auth_Container -{ - - // {{{ properties - - /** - * Options for the class - * @var array - */ - var $options = array(); - - // }}} - // {{{ Auth_Container_IMAP() [constructor] - - /** - * Constructor of the container class - * - * @param $params associative array with host, port, baseDSN, checkServer - * and userattr key - * @return object Returns an error object if something went wrong - * @todo Use PEAR Net_IMAP if IMAP extension not loaded - */ - function Auth_Container_IMAP($params) - { - if (!extension_loaded('imap')) { - return PEAR::raiseError('Cannot use IMAP authentication, ' - .'IMAP extension not loaded!', 41, PEAR_ERROR_DIE); - } - $this->_setDefaults(); - - // set parameters (if any) - if (is_array($params)) { - $this->_parseOptions($params); - } - - if ($this->options['checkServer']) { - $this->_checkServer($this->options['timeout']); - } - return true; - } - - // }}} - // {{{ _setDefaults() - - /** - * Set some default options - * - * @access private - */ - function _setDefaults() - { - $this->options['host'] = 'localhost'; - $this->options['port'] = 143; - $this->options['baseDSN'] = ''; - $this->options['checkServer'] = true; - $this->options['timeout'] = 20; - } - - // }}} - // {{{ _checkServer() - - /** - * Check if the given server and port are reachable - * - * @access private - */ - function _checkServer() { - $this->log('Auth_Container_IMAP::_checkServer() called.', AUTH_LOG_DEBUG); - $fp = @fsockopen ($this->options['host'], $this->options['port'], - $errno, $errstr, $this->options['timeout']); - if (is_resource($fp)) { - @fclose($fp); - } else { - $message = "Error connecting to IMAP server " - . $this->options['host'] - . ":" . $this->options['port']; - return PEAR::raiseError($message, 41); - } - } - - // }}} - // {{{ _parseOptions() - - /** - * Parse options passed to the container class - * - * @access private - * @param array - */ - function _parseOptions($array) - { - foreach ($array as $key => $value) { - $this->options[$key] = $value; - } - } - - // }}} - // {{{ fetchData() - - /** - * Try to open a IMAP stream using $username / $password - * - * @param string Username - * @param string Password - * @return boolean - */ - function fetchData($username, $password) - { - $this->log('Auth_Container_IMAP::fetchData() called.', AUTH_LOG_DEBUG); - $dsn = '{'.$this->options['host'].':'.$this->options['port'].$this->options['baseDSN'].'}'; - $conn = @imap_open ($dsn, $username, $password, OP_HALFOPEN); - if (is_resource($conn)) { - $this->log('Successfully connected to IMAP server.', AUTH_LOG_DEBUG); - $this->activeUser = $username; - @imap_close($conn); - return true; - } else { - $this->log('Connection to IMAP server failed.', AUTH_LOG_DEBUG); - $this->activeUser = ''; - return false; - } - } - - // }}} - -} -?> diff --git a/glmPEAR/Container/KADM5.php b/glmPEAR/Container/KADM5.php deleted file mode 100755 index c101e62..0000000 --- a/glmPEAR/Container/KADM5.php +++ /dev/null @@ -1,171 +0,0 @@ - - * @author Adam Ashley - * @copyright 2001-2006 The PHP Group - * @license http://www.php.net/license/3_01.txt PHP License 3.01 - * @version CVS: $Id: KADM5.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ - * @link http://pear.php.net/package/Auth - * @since File available since Release 1.4.0 - */ - -/** - * Include Auth_Container base class - */ -require_once 'Auth/Container.php'; -/** - * Include PEAR for error handling - */ -require_once 'PEAR.php'; - -/** - * Storage driver for Authentication on a Kerberos V server. - * - * Available options: - * hostname: The hostname of the kerberos server - * realm: The Kerberos V realm - * timeout: The timeout for checking the server - * checkServer: Set to true to check if the server is running when - * constructing the object - * - * @category Authentication - * @package Auth - * @author Andrew Teixeira - * @author Adam Ashley - * @copyright 2001-2006 The PHP Group - * @license http://www.php.net/license/3_01.txt PHP License 3.01 - * @version Release: 1.5.4 File: $Revision: 1.1.1.1 $ - * @link http://pear.php.net/package/Auth - * @since Class available since Release 1.4.0 - */ -class Auth_Container_KADM5 extends Auth_Container { - - // {{{ properties - - /** - * Options for the class - * @var string - */ - var $options = array(); - - // }}} - // {{{ Auth_Container_KADM5() - - /** - * Constructor of the container class - * - * $options can have these keys: - * 'hostname' The hostname of the kerberos server - * 'realm' The Kerberos V realm - * 'timeout' The timeout for checking the server - * 'checkServer' Set to true to check if the server is running when - * constructing the object - * - * @param $options associative array - * @return object Returns an error object if something went wrong - */ - function Auth_Container_KADM5($options) { - if (!extension_loaded('kadm5')) { - return PEAR::raiseError("Cannot use Kerberos V authentication, KADM5 extension not loaded!", 41, PEAR_ERROR_DIE); - } - - $this->_setDefaults(); - - if (isset($options['hostname'])) { - $this->options['hostname'] = $options['hostname']; - } - if (isset($options['realm'])) { - $this->options['realm'] = $options['realm']; - } - if (isset($options['timeout'])) { - $this->options['timeout'] = $options['timeout']; - } - if (isset($options['checkServer'])) { - $this->options['checkServer'] = $options['checkServer']; - } - - if ($this->options['checkServer']) { - $this->_checkServer(); - } - } - - // }}} - // {{{ fetchData() - - /** - * Try to login to the KADM5 server - * - * @param string Username - * @param string Password - * @return boolean - */ - function fetchData($username, $password) { - $this->log('Auth_Container_KADM5::fetchData() called.', AUTH_LOG_DEBUG); - if ( ($username == NULL) || ($password == NULL) ) { - return false; - } - - $server = $this->options['hostname']; - $realm = $this->options['realm']; - $check = @kadm5_init_with_password($server, $realm, $username, $password); - - if ($check == false) { - return false; - } else { - return true; - } - } - - // }}} - // {{{ _setDefaults() - - /** - * Set some default options - * - * @access private - */ - function _setDefaults() { - $this->options['hostname'] = 'localhost'; - $this->options['realm'] = NULL; - $this->options['timeout'] = 10; - $this->options['checkServer'] = false; - } - - // }}} - // {{{ _checkServer() - - /** - * Check if the given server and port are reachable - * - * @access private - */ - function _checkServer() { - $fp = @fsockopen ($this->options['hostname'], 88, $errno, $errstr, $this->options['timeout']); - if (is_resource($fp)) { - @fclose($fp); - } else { - $message = "Error connecting to Kerberos V server " - .$this->options['hostname'].":".$this->options['port']; - return PEAR::raiseError($message, 41, PEAR_ERROR_DIE); - } - } - - // }}} - -} - -?> diff --git a/glmPEAR/Container/LDAP.php b/glmPEAR/Container/LDAP.php deleted file mode 100755 index 00b2eab..0000000 --- a/glmPEAR/Container/LDAP.php +++ /dev/null @@ -1,766 +0,0 @@ - - * @author Adam Ashley - * @author Hugues Peeters - * @copyright 2001-2006 The PHP Group - * @license http://www.php.net/license/3_01.txt PHP License 3.01 - * @version CVS: $Id: LDAP.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ - * @link http://pear.php.net/package/Auth - */ - -/** - * Include Auth_Container base class - */ -require_once "Auth/Container.php"; -/** - * Include PEAR package for error handling - */ -require_once "PEAR.php"; - -/** - * Storage driver for fetching login data from LDAP - * - * This class is heavily based on the DB and File containers. By default it - * connects to localhost:389 and searches for uid=$username with the scope - * "sub". If no search base is specified, it will try to determine it via - * the namingContexts attribute. It takes its parameters in a hash, connects - * to the ldap server, binds anonymously, searches for the user, and tries - * to bind as the user with the supplied password. When a group was set, it - * will look for group membership of the authenticated user. If all goes - * well the authentication was successful. - * - * Parameters: - * - * host: localhost (default), ldap.netsols.de or 127.0.0.1 - * port: 389 (default) or 636 or whereever your server runs - * url: ldap://localhost:389/ - * useful for ldaps://, works only with openldap2 ? - * it will be preferred over host and port - * version: LDAP version to use, ususally 2 (default) or 3, - * must be an integer! - * referrals: If set, determines whether the LDAP library automatically - * follows referrals returned by LDAP servers or not. Possible - * values are true (default) or false. - * binddn: If set, searching for user will be done after binding - * as this user, if not set the bind will be anonymous. - * This is reported to make the container work with MS - * Active Directory, but should work with any server that - * is configured this way. - * This has to be a complete dn for now (basedn and - * userdn will not be appended). - * bindpw: The password to use for binding with binddn - * basedn: the base dn of your server - * userdn: gets prepended to basedn when searching for user - * userscope: Scope for user searching: one, sub (default), or base - * userattr: the user attribute to search for (default: uid) - * userfilter: filter that will be added to the search filter - * this way: (&(userattr=username)(userfilter)) - * default: (objectClass=posixAccount) - * attributes: array of additional attributes to fetch from entry. - * these will added to auth data and can be retrieved via - * Auth::getAuthData(). An empty array will fetch all attributes, - * array('') will fetch no attributes at all (default) - * If you add 'dn' as a value to this array, the users DN that was - * used for binding will be added to auth data as well. - * attrformat: The returned format of the additional data defined in the - * 'attributes' option. Two formats are available. - * LDAP returns data formatted in a - * multidimensional array where each array starts with a - * 'count' element providing the number of attributes in the - * entry, or the number of values for attributes. When set - * to this format, the only way to retrieve data from the - * Auth object is by calling getAuthData('attributes'). - * AUTH returns data formatted in a - * structure more compliant with other Auth Containers, - * where each attribute element can be directly called by - * getAuthData() method from Auth. - * For compatibily with previous LDAP container versions, - * the default format is LDAP. - * groupdn: gets prepended to basedn when searching for group - * groupattr: the group attribute to search for (default: cn) - * groupfilter: filter that will be added to the search filter when - * searching for a group: - * (&(groupattr=group)(memberattr=username)(groupfilter)) - * default: (objectClass=groupOfUniqueNames) - * memberattr : the attribute of the group object where the user dn - * may be found (default: uniqueMember) - * memberisdn: whether the memberattr is the dn of the user (default) - * or the value of userattr (usually uid) - * group: the name of group to search for - * groupscope: Scope for group searching: one, sub (default), or base - * start_tls: enable/disable the use of START_TLS encrypted connection - * (default: false) - * debug: Enable/Disable debugging output (default: false) - * try_all: Whether to try all user accounts returned from the search - * or just the first one. (default: false) - * - * To use this storage container, you have to use the following syntax: - * - * 'localhost', - * 'port' => '389', - * 'version' => 3, - * 'basedn' => 'o=netsols,c=de', - * 'userattr' => 'uid' - * 'binddn' => 'cn=admin,o=netsols,c=de', - * 'bindpw' => 'password')); - * - * $a2 = new Auth('LDAP', array( - * 'url' => 'ldaps://ldap.netsols.de', - * 'basedn' => 'o=netsols,c=de', - * 'userscope' => 'one', - * 'userdn' => 'ou=People', - * 'groupdn' => 'ou=Groups', - * 'groupfilter' => '(objectClass=posixGroup)', - * 'memberattr' => 'memberUid', - * 'memberisdn' => false, - * 'group' => 'admin' - * )); - * - * $a3 = new Auth('LDAP', array( - * 'host' => 'ldap.netsols.de', - * 'port' => 389, - * 'version' => 3, - * 'referrals' => false, - * 'basedn' => 'dc=netsols,dc=de', - * 'binddn' => 'cn=Jan Wagner,cn=Users,dc=netsols,dc=de', - * 'bindpw' => 'password', - * 'userattr' => 'samAccountName', - * 'userfilter' => '(objectClass=user)', - * 'attributes' => array(''), - * 'group' => 'testing', - * 'groupattr' => 'samAccountName', - * 'groupfilter' => '(objectClass=group)', - * 'memberattr' => 'member', - * 'memberisdn' => true, - * 'groupdn' => 'cn=Users', - * 'groupscope' => 'one', - * 'debug' => true); - * - * The parameter values have to correspond - * to the ones for your LDAP server of course. - * - * When talking to a Microsoft ActiveDirectory server you have to - * use 'samaccountname' as the 'userattr' and follow special rules - * to translate the ActiveDirectory directory names into 'basedn'. - * The 'basedn' for the default 'Users' folder on an ActiveDirectory - * server for the ActiveDirectory Domain (which is not related to - * its DNS name) "win2000.example.org" would be: - * "CN=Users, DC=win2000, DC=example, DC=org' - * where every component of the domain name becomes a DC attribute - * of its own. If you want to use a custom users folder you have to - * replace "CN=Users" with a sequence of "OU" attributes that specify - * the path to your custom folder in reverse order. - * So the ActiveDirectory folder - * "win2000.example.org\Custom\Accounts" - * would become - * "OU=Accounts, OU=Custom, DC=win2000, DC=example, DC=org' - * - * It seems that binding anonymously to an Active Directory - * is not allowed, so you have to set binddn and bindpw for - * user searching. - * - * LDAP Referrals need to be set to false for AD to work sometimes. - * - * Example a3 shows a full blown and tested example for connection to - * Windows 2000 Active Directory with group mebership checking - * - * Note also that if you want an encrypted connection to an MS LDAP - * server, then, on your webserver, you must specify - * TLS_REQCERT never - * in /etc/ldap/ldap.conf or in the webserver user's ~/.ldaprc (which - * may or may not be read depending on your configuration). - * - * - * @category Authentication - * @package Auth - * @author Jan Wagner - * @author Adam Ashley - * @author Hugues Peeters - * @copyright 2001-2006 The PHP Group - * @license http://www.php.net/license/3_01.txt PHP License 3.01 - * @version Release: 1.5.4 File: $Revision: 1.1.1.1 $ - * @link http://pear.php.net/package/Auth - */ -class Auth_Container_LDAP extends Auth_Container -{ - - // {{{ properties - - /** - * Options for the class - * @var array - */ - var $options = array(); - - /** - * Connection ID of LDAP Link - * @var string - */ - var $conn_id = false; - - // }}} - - // {{{ Auth_Container_LDAP() [constructor] - - /** - * Constructor of the container class - * - * @param $params, associative hash with host,port,basedn and userattr key - * @return object Returns an error object if something went wrong - */ - function Auth_Container_LDAP($params) - { - if (false === extension_loaded('ldap')) { - return PEAR::raiseError('Auth_Container_LDAP: LDAP Extension not loaded', - 41, PEAR_ERROR_DIE); - } - - $this->_setDefaults(); - - if (is_array($params)) { - $this->_parseOptions($params); - } - } - - // }}} - // {{{ _prepare() - - /** - * Prepare LDAP connection - * - * This function checks if we have already opened a connection to - * the LDAP server. If that's not the case, a new connection is opened. - * - * @access private - * @return mixed True or a PEAR error object. - */ - function _prepare() - { - if (!$this->_isValidLink()) { - $res = $this->_connect(); - if (PEAR::isError($res)) { - return $res; - } - } - return true; - } - - // }}} - // {{{ _connect() - - /** - * Connect to the LDAP server using the global options - * - * @access private - * @return object Returns a PEAR error object if an error occurs. - */ - function _connect() - { - $this->log('Auth_Container_LDAP::_connect() called.', AUTH_LOG_DEBUG); - // connect - if (isset($this->options['url']) && $this->options['url'] != '') { - $this->log('Connecting with URL', AUTH_LOG_DEBUG); - $conn_params = array($this->options['url']); - } else { - $this->log('Connecting with host:port', AUTH_LOG_DEBUG); - $conn_params = array($this->options['host'], $this->options['port']); - } - - if (($this->conn_id = @call_user_func_array('ldap_connect', $conn_params)) === false) { - $this->log('Connection to server failed.', AUTH_LOG_DEBUG); - $this->log('LDAP ERROR: '.ldap_errno($this->conn_id).': '.ldap_error($this->conn_id), AUTH_LOG_DEBUG); - return PEAR::raiseError('Auth_Container_LDAP: Could not connect to server.', 41); - } - $this->log('Successfully connected to server', AUTH_LOG_DEBUG); - - // switch LDAP version - if (is_numeric($this->options['version']) && $this->options['version'] > 2) { - $this->log("Switching to LDAP version {$this->options['version']}", AUTH_LOG_DEBUG); - @ldap_set_option($this->conn_id, LDAP_OPT_PROTOCOL_VERSION, $this->options['version']); - - // start TLS if available - if (isset($this->options['start_tls']) && $this->options['start_tls']) { - $this->log("Starting TLS session", AUTH_LOG_DEBUG); - if (@ldap_start_tls($this->conn_id) === false) { - $this->log('Could not start TLS session', AUTH_LOG_DEBUG); - $this->log('LDAP ERROR: '.ldap_errno($this->conn_id).': '.ldap_error($this->conn_id), AUTH_LOG_DEBUG); - return PEAR::raiseError('Auth_Container_LDAP: Could not start tls.', 41); - } - } - } - - // switch LDAP referrals - if (is_bool($this->options['referrals'])) { - $this->log("Switching LDAP referrals to " . (($this->options['referrals']) ? 'true' : 'false'), AUTH_LOG_DEBUG); - if (@ldap_set_option($this->conn_id, LDAP_OPT_REFERRALS, $this->options['referrals']) === false) { - $this->log('Could not change LDAP referrals options', AUTH_LOG_DEBUG); - $this->log('LDAP ERROR: '.ldap_errno($this->conn_id).': '.ldap_error($this->conn_id), AUTH_LOG_DEBUG); - } - } - - // bind with credentials or anonymously - if (strlen($this->options['binddn']) && strlen($this->options['bindpw'])) { - $this->log('Binding with credentials', AUTH_LOG_DEBUG); - $bind_params = array($this->conn_id, $this->options['binddn'], $this->options['bindpw']); - } else { - $this->log('Binding anonymously', AUTH_LOG_DEBUG); - $bind_params = array($this->conn_id); - } - - // bind for searching - if ((@call_user_func_array('ldap_bind', $bind_params)) === false) { - $this->log('Bind failed', AUTH_LOG_DEBUG); - $this->log('LDAP ERROR: '.ldap_errno($this->conn_id).': '.ldap_error($this->conn_id), AUTH_LOG_DEBUG); - $this->_disconnect(); - return PEAR::raiseError("Auth_Container_LDAP: Could not bind to LDAP server.", 41); - } - $this->log('Binding was successful', AUTH_LOG_DEBUG); - - return true; - } - - // }}} - // {{{ _disconnect() - - /** - * Disconnects (unbinds) from ldap server - * - * @access private - */ - function _disconnect() - { - $this->log('Auth_Container_LDAP::_disconnect() called.', AUTH_LOG_DEBUG); - if ($this->_isValidLink()) { - $this->log('disconnecting from server'); - @ldap_unbind($this->conn_id); - } - } - - // }}} - // {{{ _getBaseDN() - - /** - * Tries to find Basedn via namingContext Attribute - * - * @access private - */ - function _getBaseDN() - { - $this->log('Auth_Container_LDAP::_getBaseDN() called.', AUTH_LOG_DEBUG); - $err = $this->_prepare(); - if ($err !== true) { - return PEAR::raiseError($err->getMessage(), $err->getCode()); - } - - if ($this->options['basedn'] == "" && $this->_isValidLink()) { - $this->log("basedn not set, searching via namingContexts.", AUTH_LOG_DEBUG); - - $result_id = @ldap_read($this->conn_id, "", "(objectclass=*)", array("namingContexts")); - - if (@ldap_count_entries($this->conn_id, $result_id) == 1) { - - $this->log("got result for namingContexts", AUTH_LOG_DEBUG); - - $entry_id = @ldap_first_entry($this->conn_id, $result_id); - $attrs = @ldap_get_attributes($this->conn_id, $entry_id); - $basedn = $attrs['namingContexts'][0]; - - if ($basedn != "") { - $this->log("result for namingContexts was $basedn", AUTH_LOG_DEBUG); - $this->options['basedn'] = $basedn; - } - } - @ldap_free_result($result_id); - } - - // if base ist still not set, raise error - if ($this->options['basedn'] == "") { - return PEAR::raiseError("Auth_Container_LDAP: LDAP search base not specified!", 41); - } - return true; - } - - // }}} - // {{{ _isValidLink() - - /** - * determines whether there is a valid ldap conenction or not - * - * @accessd private - * @return boolean - */ - function _isValidLink() - { - if (is_resource($this->conn_id)) { - if (get_resource_type($this->conn_id) == 'ldap link') { - return true; - } - } - return false; - } - - // }}} - // {{{ _setDefaults() - - /** - * Set some default options - * - * @access private - */ - function _setDefaults() - { - $this->options['url'] = ''; - $this->options['host'] = 'localhost'; - $this->options['port'] = '389'; - $this->options['version'] = 2; - $this->options['referrals'] = true; - $this->options['binddn'] = ''; - $this->options['bindpw'] = ''; - $this->options['basedn'] = ''; - $this->options['userdn'] = ''; - $this->options['userscope'] = 'sub'; - $this->options['userattr'] = 'uid'; - $this->options['userfilter'] = '(objectClass=posixAccount)'; - $this->options['attributes'] = array(''); // no attributes - $this->options['attrformat'] = 'AUTH'; // returns attribute like other Auth containers - $this->options['group'] = ''; - $this->options['groupdn'] = ''; - $this->options['groupscope'] = 'sub'; - $this->options['groupattr'] = 'cn'; - $this->options['groupfilter'] = '(objectClass=groupOfUniqueNames)'; - $this->options['memberattr'] = 'uniqueMember'; - $this->options['memberisdn'] = true; - $this->options['start_tls'] = false; - $this->options['debug'] = false; - $this->options['try_all'] = false; // Try all user ids returned not just the first one - } - - // }}} - // {{{ _parseOptions() - - /** - * Parse options passed to the container class - * - * @access private - * @param array - */ - function _parseOptions($array) - { - $array = $this->_setV12OptionsToV13($array); - - foreach ($array as $key => $value) { - if (array_key_exists($key, $this->options)) { - if ($key == 'attributes') { - if (is_array($value)) { - $this->options[$key] = $value; - } else { - $this->options[$key] = explode(',', $value); - } - } else { - $this->options[$key] = $value; - } - } - } - } - - // }}} - // {{{ _setV12OptionsToV13() - - /** - * Adapt deprecated options from Auth 1.2 LDAP to Auth 1.3 LDAP - * - * @author Hugues Peeters - * @access private - * @param array - * @return array - */ - function _setV12OptionsToV13($array) - { - if (isset($array['useroc'])) - $array['userfilter'] = "(objectClass=".$array['useroc'].")"; - if (isset($array['groupoc'])) - $array['groupfilter'] = "(objectClass=".$array['groupoc'].")"; - if (isset($array['scope'])) - $array['userscope'] = $array['scope']; - - return $array; - } - - // }}} - // {{{ _scope2function() - - /** - * Get search function for scope - * - * @param string scope - * @return string ldap search function - */ - function _scope2function($scope) - { - switch($scope) { - case 'one': - $function = 'ldap_list'; - break; - case 'base': - $function = 'ldap_read'; - break; - default: - $function = 'ldap_search'; - break; - } - return $function; - } - - // }}} - // {{{ fetchData() - - /** - * Fetch data from LDAP server - * - * Searches the LDAP server for the given username/password - * combination. Escapes all LDAP meta characters in username - * before performing the query. - * - * @param string Username - * @param string Password - * @return boolean - */ - function fetchData($username, $password) - { - $this->log('Auth_Container_LDAP::fetchData() called.', AUTH_LOG_DEBUG); - $err = $this->_prepare(); - if ($err !== true) { - return PEAR::raiseError($err->getMessage(), $err->getCode()); - } - - $err = $this->_getBaseDN(); - if ($err !== true) { - return PEAR::raiseError($err->getMessage(), $err->getCode()); - } - - // UTF8 Encode username for LDAPv3 - if (@ldap_get_option($this->conn_id, LDAP_OPT_PROTOCOL_VERSION, $ver) && $ver == 3) { - $this->log('UTF8 encoding username for LDAPv3', AUTH_LOG_DEBUG); - $username = utf8_encode($username); - } - - // make search filter - $filter = sprintf('(&(%s=%s)%s)', - $this->options['userattr'], - $this->_quoteFilterString($username), - $this->options['userfilter']); - - // make search base dn - $search_basedn = $this->options['userdn']; - if ($search_basedn != '' && substr($search_basedn, -1) != ',') { - $search_basedn .= ','; - } - $search_basedn .= $this->options['basedn']; - - // attributes - $searchAttributes = $this->options['attributes']; - - // make functions params array - $func_params = array($this->conn_id, $search_basedn, $filter, $searchAttributes); - - // search function to use - $func_name = $this->_scope2function($this->options['userscope']); - - $this->log("Searching with $func_name and filter $filter in $search_basedn", AUTH_LOG_DEBUG); - - // search - if (($result_id = @call_user_func_array($func_name, $func_params)) === false) { - $this->log('User not found', AUTH_LOG_DEBUG); - } elseif (@ldap_count_entries($this->conn_id, $result_id) >= 1) { // did we get some possible results? - - $this->log('User(s) found', AUTH_LOG_DEBUG); - - $first = true; - $entry_id = null; - - do { - - // then get the user dn - if ($first) { - $entry_id = @ldap_first_entry($this->conn_id, $result_id); - $first = false; - } else { - $entry_id = @ldap_next_entry($this->conn_id, $entry_id); - if ($entry_id === false) - break; - } - $user_dn = @ldap_get_dn($this->conn_id, $entry_id); - - // as the dn is not fetched as an attribute, we save it anyway - if (is_array($searchAttributes) && in_array('dn', $searchAttributes)) { - $this->log('Saving DN to AuthData', AUTH_LOG_DEBUG); - $this->_auth_obj->setAuthData('dn', $user_dn); - } - - // fetch attributes - if ($attributes = @ldap_get_attributes($this->conn_id, $entry_id)) { - - if (is_array($attributes) && isset($attributes['count']) && - $attributes['count'] > 0) { - - // ldap_get_attributes() returns a specific multi dimensional array - // format containing all the attributes and where each array starts - // with a 'count' element providing the number of attributes in the - // entry, or the number of values for attribute. For compatibility - // reasons, it remains the default format returned by LDAP container - // setAuthData(). - // The code below optionally returns attributes in another format, - // more compliant with other Auth containers, where each attribute - // element are directly set in the 'authData' list. This option is - // enabled by setting 'attrformat' to - // 'AUTH' in the 'options' array. - // eg. $this->options['attrformat'] = 'AUTH' - - if ( strtoupper($this->options['attrformat']) == 'AUTH' ) { - $this->log('Saving attributes to Auth data in AUTH format', AUTH_LOG_DEBUG); - unset ($attributes['count']); - foreach ($attributes as $attributeName => $attributeValue ) { - if (is_int($attributeName)) continue; - if (is_array($attributeValue) && isset($attributeValue['count'])) { - unset ($attributeValue['count']); - } - if (count($attributeValue)<=1) $attributeValue = $attributeValue[0]; - $this->log('Storing additional field: '.$attributeName, AUTH_LOG_DEBUG); - $this->_auth_obj->setAuthData($attributeName, $attributeValue); - } - } - else - { - $this->log('Saving attributes to Auth data in LDAP format', AUTH_LOG_DEBUG); - $this->_auth_obj->setAuthData('attributes', $attributes); - } - } - } - @ldap_free_result($result_id); - - // need to catch an empty password as openldap seems to return TRUE - // if anonymous binding is allowed - if ($password != "") { - $this->log("Bind as $user_dn", AUTH_LOG_DEBUG); - - // try binding as this user with the supplied password - if (@ldap_bind($this->conn_id, $user_dn, $password)) { - $this->log('Bind successful', AUTH_LOG_DEBUG); - - // check group if appropiate - if (strlen($this->options['group'])) { - // decide whether memberattr value is a dn or the username - $this->log('Checking group membership', AUTH_LOG_DEBUG); - $return = $this->checkGroup(($this->options['memberisdn']) ? $user_dn : $username); - $this->_disconnect(); - return $return; - } else { - $this->log('Authenticated', AUTH_LOG_DEBUG); - $this->_disconnect(); - return true; // user authenticated - } // checkGroup - } // bind - } // non-empty password - } while ($this->options['try_all'] == true); // interate through entries - } // get results - // default - $this->log('NOT authenticated!', AUTH_LOG_DEBUG); - $this->_disconnect(); - return false; - } - - // }}} - // {{{ checkGroup() - - /** - * Validate group membership - * - * Searches the LDAP server for group membership of the - * supplied username. Quotes all LDAP filter meta characters in - * the user name before querying the LDAP server. - * - * @param string Distinguished Name of the authenticated User - * @return boolean - */ - function checkGroup($user) - { - $this->log('Auth_Container_LDAP::checkGroup() called.', AUTH_LOG_DEBUG); - $err = $this->_prepare(); - if ($err !== true) { - return PEAR::raiseError($err->getMessage(), $err->getCode()); - } - - // make filter - $filter = sprintf('(&(%s=%s)(%s=%s)%s)', - $this->options['groupattr'], - $this->options['group'], - $this->options['memberattr'], - $this->_quoteFilterString($user), - $this->options['groupfilter']); - - // make search base dn - $search_basedn = $this->options['groupdn']; - if ($search_basedn != '' && substr($search_basedn, -1) != ',') { - $search_basedn .= ','; - } - $search_basedn .= $this->options['basedn']; - - $func_params = array($this->conn_id, $search_basedn, $filter, - array($this->options['memberattr'])); - $func_name = $this->_scope2function($this->options['groupscope']); - - $this->log("Searching with $func_name and filter $filter in $search_basedn", AUTH_LOG_DEBUG); - - // search - if (($result_id = @call_user_func_array($func_name, $func_params)) != false) { - if (@ldap_count_entries($this->conn_id, $result_id) == 1) { - @ldap_free_result($result_id); - $this->log('User is member of group', AUTH_LOG_DEBUG); - return true; - } - } - // default - $this->log('User is NOT member of group', AUTH_LOG_DEBUG); - return false; - } - - // }}} - // {{{ _quoteFilterString() - - /** - * Escapes LDAP filter special characters as defined in RFC 2254. - * - * @access private - * @param string Filter String - */ - function _quoteFilterString($filter_str) - { - $metas = array( '\\', '*', '(', ')', "\x00"); - $quoted_metas = array('\\\\', '\*', '\(', '\)', "\\\x00"); - return str_replace($metas, $quoted_metas, $filter_str); - } - - // }}} - -} - -?> diff --git a/glmPEAR/Container/MDB.php b/glmPEAR/Container/MDB.php deleted file mode 100755 index 4f15ddb..0000000 --- a/glmPEAR/Container/MDB.php +++ /dev/null @@ -1,618 +0,0 @@ - - * @author Adam Ashley - * @copyright 2001-2006 The PHP Group - * @license http://www.php.net/license/3_01.txt PHP License 3.01 - * @version CVS: $Id: MDB.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ - * @link http://pear.php.net/package/Auth - * @since File available since Release 1.2.3 - */ - -/** - * Include Auth_Container base class - */ -require_once 'Auth/Container.php'; -/** - * Include PEAR MDB package - */ -require_once 'MDB.php'; - -/** - * Storage driver for fetching login data from a database - * - * This storage driver can use all databases which are supported - * by the PEAR MDB abstraction layer to fetch login data. - * - * @category Authentication - * @package Auth - * @author Lorenzo Alberton - * @author Adam Ashley - * @copyright 2001-2006 The PHP Group - * @license http://www.php.net/license/3_01.txt PHP License 3.01 - * @version Release: 1.5.4 File: $Revision: 1.1.1.1 $ - * @link http://pear.php.net/package/Auth - * @since Class available since Release 1.2.3 - */ -class Auth_Container_MDB extends Auth_Container -{ - - // {{{ properties - - /** - * Additional options for the storage container - * @var array - */ - var $options = array(); - - /** - * MDB object - * @var object - */ - var $db = null; - var $dsn = ''; - - /** - * User that is currently selected from the DB. - * @var string - */ - var $activeUser = ''; - - // }}} - // {{{ Auth_Container_MDB() [constructor] - - /** - * Constructor of the container class - * - * Initate connection to the database via PEAR::MDB - * - * @param string Connection data or MDB object - * @return object Returns an error object if something went wrong - */ - function Auth_Container_MDB($dsn) - { - $this->_setDefaults(); - - if (is_array($dsn)) { - $this->_parseOptions($dsn); - if (empty($this->options['dsn'])) { - PEAR::raiseError('No connection parameters specified!'); - } - } else { - $this->options['dsn'] = $dsn; - } - } - - // }}} - // {{{ _connect() - - /** - * Connect to database by using the given DSN string - * - * @access private - * @param mixed DSN string | array | mdb object - * @return mixed Object on error, otherwise bool - */ - function _connect($dsn) - { - $this->log('Auth_Container_MDB::_connect() called.', AUTH_LOG_DEBUG); - if (is_string($dsn) || is_array($dsn)) { - $this->db =& MDB::connect($dsn, $this->options['db_options']); - } elseif (is_subclass_of($dsn, 'mdb_common')) { - $this->db = $dsn; - } elseif (is_object($dsn) && MDB::isError($dsn)) { - return PEAR::raiseError($dsn->getMessage(), $dsn->code); - } else { - return PEAR::raiseError('The given dsn was not valid in file ' . __FILE__ . ' at line ' . __LINE__, - 41, - PEAR_ERROR_RETURN, - null, - null - ); - - } - - if (MDB::isError($this->db) || PEAR::isError($this->db)) { - return PEAR::raiseError($this->db->getMessage(), $this->db->code); - } - - if ($this->options['auto_quote']) { - $this->options['final_table'] = $this->db->quoteIdentifier($this->options['table']); - $this->options['final_usernamecol'] = $this->db->quoteIdentifier($this->options['usernamecol']); - $this->options['final_passwordcol'] = $this->db->quoteIdentifier($this->options['passwordcol']); - } else { - $this->options['final_table'] = $this->options['table']; - $this->options['final_usernamecol'] = $this->options['usernamecol']; - $this->options['final_passwordcol'] = $this->options['passwordcol']; - } - - return true; - } - - // }}} - // {{{ _prepare() - - /** - * Prepare database connection - * - * This function checks if we have already opened a connection to - * the database. If that's not the case, a new connection is opened. - * - * @access private - * @return mixed True or a MDB error object. - */ - function _prepare() - { - if (is_subclass_of($this->db, 'mdb_common')) { - return true; - } - return $this->_connect($this->options['dsn']); - } - - // }}} - // {{{ query() - - /** - * Prepare query to the database - * - * This function checks if we have already opened a connection to - * the database. If that's not the case, a new connection is opened. - * After that the query is passed to the database. - * - * @access public - * @param string Query string - * @return mixed a MDB_result object or MDB_OK on success, a MDB - * or PEAR error on failure - */ - function query($query) - { - $this->log('Auth_Container_MDB::query() called.', AUTH_LOG_DEBUG); - $err = $this->_prepare(); - if ($err !== true) { - return $err; - } - return $this->db->query($query); - } - - // }}} - // {{{ _setDefaults() - - /** - * Set some default options - * - * @access private - * @return void - */ - function _setDefaults() - { - $this->options['table'] = 'auth'; - $this->options['usernamecol'] = 'username'; - $this->options['passwordcol'] = 'password'; - $this->options['dsn'] = ''; - $this->options['db_fields'] = ''; - $this->options['cryptType'] = 'md5'; - $this->options['db_options'] = array(); - $this->options['db_where'] = ''; - $this->options['auto_quote'] = true; - } - - // }}} - // {{{ _parseOptions() - - /** - * Parse options passed to the container class - * - * @access private - * @param array - */ - function _parseOptions($array) - { - foreach ($array as $key => $value) { - if (isset($this->options[$key])) { - $this->options[$key] = $value; - } - } - } - - // }}} - // {{{ _quoteDBFields() - - /** - * Quote the db_fields option to avoid the possibility of SQL injection. - * - * @access private - * @return string A properly quoted string that can be concatenated into a - * SELECT clause. - */ - function _quoteDBFields() - { - if (isset($this->options['db_fields'])) { - if (is_array($this->options['db_fields'])) { - if ($this->options['auto_quote']) { - $fields = array(); - foreach ($this->options['db_fields'] as $field) { - $fields[] = $this->db->quoteIdentifier($field); - } - return implode(', ', $fields); - } else { - return implode(', ', $this->options['db_fields']); - } - } else { - if (strlen($this->options['db_fields']) > 0) { - if ($this->options['auto_quote']) { - return $this->db->quoteIdentifier($this->options['db_fields']); - } else { - return $this->options['db_fields']; - } - } - } - } - - return ''; - } - - // }}} - // {{{ fetchData() - - /** - * Get user information from database - * - * This function uses the given username to fetch - * the corresponding login data from the database - * table. If an account that matches the passed username - * and password is found, the function returns true. - * Otherwise it returns false. - * - * @param string Username - * @param string Password - * @param boolean If true password is secured using a md5 hash - * the frontend and auth are responsible for making sure the container supports - * challenge response password authentication - * @return mixed Error object or boolean - */ - function fetchData($username, $password, $isChallengeResponse=false) - { - $this->log('Auth_Container_MDB::fetchData() called.', AUTH_LOG_DEBUG); - // Prepare for a database query - $err = $this->_prepare(); - if ($err !== true) { - return PEAR::raiseError($err->getMessage(), $err->getCode()); - } - - //Check if db_fields contains a *, if so assume all columns are selected - if (is_string($this->options['db_fields']) - && strstr($this->options['db_fields'], '*')) { - $sql_from = '*'; - } else { - $sql_from = $this->options['final_usernamecol']. - ", ".$this->options['final_passwordcol']; - - if (strlen($fields = $this->_quoteDBFields()) > 0) { - $sql_from .= ', '.$fields; - } - } - - $query = sprintf("SELECT %s FROM %s WHERE %s = %s", - $sql_from, - $this->options['final_table'], - $this->options['final_usernamecol'], - $this->db->getTextValue($username) - ); - - // check if there is an optional parameter db_where - if ($this->options['db_where'] != '') { - // there is one, so add it to the query - $query .= " AND ".$this->options['db_where']; - } - - $this->log('Running SQL against MDB: '.$query, AUTH_LOG_DEBUG); - - $res = $this->db->getRow($query, null, null, null, MDB_FETCHMODE_ASSOC); - - if (MDB::isError($res) || PEAR::isError($res)) { - return PEAR::raiseError($res->getMessage(), $res->getCode()); - } - if (!is_array($res)) { - $this->activeUser = ''; - return false; - } - - // Perform trimming here before the hashing - $password = trim($password, "\r\n"); - $res[$this->options['passwordcol']] = trim($res[$this->options['passwordcol']], "\r\n"); - - // If using Challenge Response md5 the pass with the secret - if ($isChallengeResponse) { - $res[$this->options['passwordcol']] = - md5($res[$this->options['passwordcol']].$this->_auth_obj->session['loginchallenege']); - // UGLY cannot avoid without modifying verifyPassword - if ($this->options['cryptType'] == 'md5') { - $res[$this->options['passwordcol']] = md5($res[$this->options['passwordcol']]); - } - } - - if ($this->verifyPassword($password, - $res[$this->options['passwordcol']], - $this->options['cryptType'])) { - // Store additional field values in the session - foreach ($res as $key => $value) { - if ($key == $this->options['passwordcol'] || - $key == $this->options['usernamecol']) { - continue; - } - - $this->log('Storing additional field: '.$key, AUTH_LOG_DEBUG); - // Use reference to the auth object if exists - // This is because the auth session variable can change so a static - // call to setAuthData does not make sense - $this->_auth_obj->setAuthData($key, $value); - } - return true; - } - - $this->activeUser = $res[$this->options['usernamecol']]; - return false; - } - - // }}} - // {{{ listUsers() - - /** - * Returns a list of users from the container - * - * @return mixed array|PEAR_Error - * @access public - */ - function listUsers() - { - $this->log('Auth_Container_MDB::listUsers() called.', AUTH_LOG_DEBUG); - $err = $this->_prepare(); - if ($err !== true) { - return PEAR::raiseError($err->getMessage(), $err->getCode()); - } - - $retVal = array(); - - //Check if db_fields contains a *, if so assume all columns are selected - if ( is_string($this->options['db_fields']) - && strstr($this->options['db_fields'], '*')) { - $sql_from = '*'; - } else { - $sql_from = $this->options['final_usernamecol'] - .', '.$this->options['final_passwordcol']; - - if (strlen($fields = $this->_quoteDBFields()) > 0) { - $sql_from .= ', '.$fields; - } - } - - $query = sprintf('SELECT %s FROM %s', - $sql_from, - $this->options['final_table'] - ); - - // check if there is an optional parameter db_where - if ($this->options['db_where'] != '') { - // there is one, so add it to the query - $query .= " WHERE ".$this->options['db_where']; - } - - $this->log('Running SQL against MDB: '.$query, AUTH_LOG_DEBUG); - - $res = $this->db->getAll($query, null, null, null, MDB_FETCHMODE_ASSOC); - - if (MDB::isError($res)) { - return PEAR::raiseError($res->getMessage(), $res->getCode()); - } else { - foreach ($res as $user) { - $user['username'] = $user[$this->options['usernamecol']]; - $retVal[] = $user; - } - } - $this->log('Found '.count($retVal).' users.', AUTH_LOG_DEBUG); - return $retVal; - } - - // }}} - // {{{ addUser() - - /** - * Add user to the storage container - * - * @access public - * @param string Username - * @param string Password - * @param mixed Additional information that are stored in the DB - * - * @return mixed True on success, otherwise error object - */ - function addUser($username, $password, $additional = "") - { - $this->log('Auth_Container_MDB::addUser() called.', AUTH_LOG_DEBUG); - $err = $this->_prepare(); - if ($err !== true) { - return PEAR::raiseError($err->getMessage(), $err->getCode()); - } - - if (isset($this->options['cryptType']) && $this->options['cryptType'] == 'none') { - $cryptFunction = 'strval'; - } elseif (isset($this->options['cryptType']) && function_exists($this->options['cryptType'])) { - $cryptFunction = $this->options['cryptType']; - } else { - $cryptFunction = 'md5'; - } - - $password = $cryptFunction($password); - - $additional_key = ''; - $additional_value = ''; - - if (is_array($additional)) { - foreach ($additional as $key => $value) { - if ($this->options['auto_quote']) { - $additional_key .= ', ' . $this->db->quoteIdentifier($key); - } else { - $additional_key .= ', ' . $key; - } - $additional_value .= ', ' . $this->db->getTextValue($value); - } - } - - $query = sprintf("INSERT INTO %s (%s, %s%s) VALUES (%s, %s%s)", - $this->options['final_table'], - $this->options['final_usernamecol'], - $this->options['final_passwordcol'], - $additional_key, - $this->db->getTextValue($username), - $this->db->getTextValue($password), - $additional_value - ); - - $this->log('Running SQL against MDB: '.$query, AUTH_LOG_DEBUG); - - $res = $this->query($query); - - if (MDB::isError($res)) { - return PEAR::raiseError($res->getMessage(), $res->code); - } - return true; - } - - // }}} - // {{{ removeUser() - - /** - * Remove user from the storage container - * - * @access public - * @param string Username - * - * @return mixed True on success, otherwise error object - */ - function removeUser($username) - { - $this->log('Auth_Container_MDB::removeUser() called.', AUTH_LOG_DEBUG); - $err = $this->_prepare(); - if ($err !== true) { - return PEAR::raiseError($err->getMessage(), $err->getCode()); - } - - $query = sprintf("DELETE FROM %s WHERE %s = %s", - $this->options['final_table'], - $this->options['final_usernamecol'], - $this->db->getTextValue($username) - ); - - // check if there is an optional parameter db_where - if ($this->options['db_where'] != '') { - // there is one, so add it to the query - $query .= " AND ".$this->options['db_where']; - } - - $this->log('Running SQL against MDB: '.$query, AUTH_LOG_DEBUG); - - $res = $this->query($query); - - if (MDB::isError($res)) { - return PEAR::raiseError($res->getMessage(), $res->code); - } - return true; - } - - // }}} - // {{{ changePassword() - - /** - * Change password for user in the storage container - * - * @param string Username - * @param string The new password (plain text) - */ - function changePassword($username, $password) - { - $this->log('Auth_Container_MDB::changePassword() called.', AUTH_LOG_DEBUG); - $err = $this->_prepare(); - if ($err !== true) { - return PEAR::raiseError($err->getMessage(), $err->getCode()); - } - - if (isset($this->options['cryptType']) && $this->options['cryptType'] == 'none') { - $cryptFunction = 'strval'; - } elseif (isset($this->options['cryptType']) && function_exists($this->options['cryptType'])) { - $cryptFunction = $this->options['cryptType']; - } else { - $cryptFunction = 'md5'; - } - - $password = $cryptFunction($password); - - $query = sprintf("UPDATE %s SET %s = %s WHERE %s = %s", - $this->options['final_table'], - $this->options['final_passwordcol'], - $this->db->getTextValue($password), - $this->options['final_usernamecol'], - $this->db->getTextValue($username) - ); - - // check if there is an optional parameter db_where - if ($this->options['db_where'] != '') { - // there is one, so add it to the query - $query .= " AND ".$this->options['db_where']; - } - - $this->log('Running SQL against MDB: '.$query, AUTH_LOG_DEBUG); - - $res = $this->query($query); - - if (MDB::isError($res)) { - return PEAR::raiseError($res->getMessage(), $res->code); - } - return true; - } - - // }}} - // {{{ supportsChallengeResponse() - - /** - * Determine if this container supports - * password authentication with challenge response - * - * @return bool - * @access public - */ - function supportsChallengeResponse() - { - return in_array($this->options['cryptType'], array('md5', 'none', '')); - } - - // }}} - // {{{ getCryptType() - - /** - * Returns the selected crypt type for this container - * - * @return string Function used to crypt the password - */ - function getCryptType() - { - return $this->options['cryptType']; - } - - // }}} - -} -?> diff --git a/glmPEAR/Container/MDB2.php b/glmPEAR/Container/MDB2.php deleted file mode 100755 index 833b3d5..0000000 --- a/glmPEAR/Container/MDB2.php +++ /dev/null @@ -1,617 +0,0 @@ - - * @author Adam Ashley - * @copyright 2001-2006 The PHP Group - * @license http://www.php.net/license/3_01.txt PHP License 3.01 - * @version CVS: $Id: MDB2.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ - * @link http://pear.php.net/package/Auth - * @since File available since Release 1.3.0 - */ - -/** - * Include Auth_Container base class - */ -require_once 'Auth/Container.php'; -/** - * Include PEAR MDB2 package - */ -require_once 'MDB2.php'; - -/** - * Storage driver for fetching login data from a database - * - * This storage driver can use all databases which are supported - * by the PEAR MDB2 abstraction layer to fetch login data. - * - * @category Authentication - * @package Auth - * @author Lorenzo Alberton - * @author Adam Ashley - * @copyright 2001-2006 The PHP Group - * @license http://www.php.net/license/3_01.txt PHP License 3.01 - * @version Release: 1.5.4 File: $Revision: 1.1.1.1 $ - * @link http://pear.php.net/package/Auth - * @since Class available since Release 1.3.0 - */ -class Auth_Container_MDB2 extends Auth_Container -{ - - // {{{ properties - - /** - * Additional options for the storage container - * @var array - */ - var $options = array(); - - /** - * MDB object - * @var object - */ - var $db = null; - var $dsn = ''; - - /** - * User that is currently selected from the DB. - * @var string - */ - var $activeUser = ''; - - // }}} - // {{{ Auth_Container_MDB2() [constructor] - - /** - * Constructor of the container class - * - * Initate connection to the database via PEAR::MDB2 - * - * @param string Connection data or MDB2 object - * @return object Returns an error object if something went wrong - */ - function Auth_Container_MDB2($dsn) - { - $this->_setDefaults(); - - if (is_array($dsn)) { - $this->_parseOptions($dsn); - if (empty($this->options['dsn'])) { - PEAR::raiseError('No connection parameters specified!'); - } - } else { - $this->options['dsn'] = $dsn; - } - } - - // }}} - // {{{ _connect() - - /** - * Connect to database by using the given DSN string - * - * @access private - * @param mixed DSN string | array | mdb object - * @return mixed Object on error, otherwise bool - */ - function _connect($dsn) - { - $this->log('Auth_Container_MDB2::_connect() called.', AUTH_LOG_DEBUG); - if (is_string($dsn) || is_array($dsn)) { - $this->db =& MDB2::connect($dsn, $this->options['db_options']); - } elseif (is_subclass_of($dsn, 'MDB2_Driver_Common')) { - $this->db = $dsn; - } elseif (is_object($dsn) && MDB2::isError($dsn)) { - return PEAR::raiseError($dsn->getMessage(), $dsn->code); - } else { - return PEAR::raiseError('The given dsn was not valid in file ' . __FILE__ . ' at line ' . __LINE__, - 41, - PEAR_ERROR_RETURN, - null, - null - ); - - } - - if (MDB2::isError($this->db) || PEAR::isError($this->db)) { - return PEAR::raiseError($this->db->getMessage(), $this->db->code); - } - - if ($this->options['auto_quote']) { - $this->options['final_table'] = $this->db->quoteIdentifier($this->options['table'], true); - $this->options['final_usernamecol'] = $this->db->quoteIdentifier($this->options['usernamecol'], true); - $this->options['final_passwordcol'] = $this->db->quoteIdentifier($this->options['passwordcol'], true); - } else { - $this->options['final_table'] = $this->options['table']; - $this->options['final_usernamecol'] = $this->options['usernamecol']; - $this->options['final_passwordcol'] = $this->options['passwordcol']; - } - - return true; - } - - // }}} - // {{{ _prepare() - - /** - * Prepare database connection - * - * This function checks if we have already opened a connection to - * the database. If that's not the case, a new connection is opened. - * - * @access private - * @return mixed True or a MDB error object. - */ - function _prepare() - { - if (is_subclass_of($this->db, 'MDB2_Driver_Common')) { - return true; - } - return $this->_connect($this->options['dsn']); - } - - // }}} - // {{{ query() - - /** - * Prepare query to the database - * - * This function checks if we have already opened a connection to - * the database. If that's not the case, a new connection is opened. - * After that the query is passed to the database. - * - * @access public - * @param string Query string - * @return mixed a MDB_result object or MDB_OK on success, a MDB - * or PEAR error on failure - */ - function query($query) - { - $this->log('Auth_Container_MDB2::query() called.', AUTH_LOG_DEBUG); - $err = $this->_prepare(); - if ($err !== true) { - return $err; - } - return $this->db->exec($query); - } - - // }}} - // {{{ _setDefaults() - - /** - * Set some default options - * - * @access private - * @return void - */ - function _setDefaults() - { - $this->options['table'] = 'auth'; - $this->options['usernamecol'] = 'username'; - $this->options['passwordcol'] = 'password'; - $this->options['dsn'] = ''; - $this->options['db_fields'] = ''; - $this->options['cryptType'] = 'md5'; - $this->options['db_options'] = array(); - $this->options['db_where'] = ''; - $this->options['auto_quote'] = true; - } - - // }}} - // {{{ _parseOptions() - - /** - * Parse options passed to the container class - * - * @access private - * @param array - */ - function _parseOptions($array) - { - foreach ($array as $key => $value) { - if (isset($this->options[$key])) { - $this->options[$key] = $value; - } - } - } - - // }}} - // {{{ _quoteDBFields() - - /** - * Quote the db_fields option to avoid the possibility of SQL injection. - * - * @access private - * @return string A properly quoted string that can be concatenated into a - * SELECT clause. - */ - function _quoteDBFields() - { - if (isset($this->options['db_fields'])) { - if (is_array($this->options['db_fields'])) { - if ($this->options['auto_quote']) { - $fields = array(); - foreach ($this->options['db_fields'] as $field) { - $fields[] = $this->db->quoteIdentifier($field, true); - } - return implode(', ', $fields); - } else { - return implode(', ', $this->options['db_fields']); - } - } else { - if (strlen($this->options['db_fields']) > 0) { - if ($this->options['auto_quote']) { - return $this->db->quoteIdentifier($this->options['db_fields'], true); - } else { - return $this->options['db_fields']; - } - } - } - } - - return ''; - } - - // }}} - // {{{ fetchData() - - /** - * Get user information from database - * - * This function uses the given username to fetch - * the corresponding login data from the database - * table. If an account that matches the passed username - * and password is found, the function returns true. - * Otherwise it returns false. - * - * @param string Username - * @param string Password - * @param boolean If true password is secured using a md5 hash - * the frontend and auth are responsible for making sure the container supports - * challenge response password authentication - * @return mixed Error object or boolean - */ - function fetchData($username, $password, $isChallengeResponse=false) - { - $this->log('Auth_Container_MDB2::fetchData() called.', AUTH_LOG_DEBUG); - // Prepare for a database query - $err = $this->_prepare(); - if ($err !== true) { - return PEAR::raiseError($err->getMessage(), $err->getCode()); - } - - //Check if db_fields contains a *, if so assume all columns are selected - if (is_string($this->options['db_fields']) - && strstr($this->options['db_fields'], '*')) { - $sql_from = '*'; - } else { - $sql_from = $this->options['final_usernamecol']. - ", ".$this->options['final_passwordcol']; - - if (strlen($fields = $this->_quoteDBFields()) > 0) { - $sql_from .= ', '.$fields; - } - } - $query = sprintf("SELECT %s FROM %s WHERE %s = %s", - $sql_from, - $this->options['final_table'], - $this->options['final_usernamecol'], - $this->db->quote($username, 'text') - ); - - // check if there is an optional parameter db_where - if ($this->options['db_where'] != '') { - // there is one, so add it to the query - $query .= " AND ".$this->options['db_where']; - } - - $this->log('Running SQL against MDB2: '.$query, AUTH_LOG_DEBUG); - - $res = $this->db->queryRow($query, null, MDB2_FETCHMODE_ASSOC); - if (MDB2::isError($res) || PEAR::isError($res)) { - return PEAR::raiseError($res->getMessage(), $res->getCode()); - } - if (!is_array($res)) { - $this->activeUser = ''; - return false; - } - - // Perform trimming here before the hashing - $password = trim($password, "\r\n"); - $res[$this->options['passwordcol']] = trim($res[$this->options['passwordcol']], "\r\n"); - // If using Challenge Response md5 the pass with the secret - if ($isChallengeResponse) { - $res[$this->options['passwordcol']] = - md5($res[$this->options['passwordcol']].$this->_auth_obj->session['loginchallenege']); - // UGLY cannot avoid without modifying verifyPassword - if ($this->options['cryptType'] == 'md5') { - $res[$this->options['passwordcol']] = md5($res[$this->options['passwordcol']]); - } - } - if ($this->verifyPassword($password, - $res[$this->options['passwordcol']], - $this->options['cryptType'])) { - // Store additional field values in the session - foreach ($res as $key => $value) { - if ($key == $this->options['passwordcol'] || - $key == $this->options['usernamecol']) { - continue; - } - - $this->log('Storing additional field: '.$key, AUTH_LOG_DEBUG); - - // Use reference to the auth object if exists - // This is because the auth session variable can change so a static call to setAuthData does not make sense - $this->_auth_obj->setAuthData($key, $value); - } - return true; - } - - $this->activeUser = $res[$this->options['usernamecol']]; - return false; - } - - // }}} - // {{{ listUsers() - - /** - * Returns a list of users from the container - * - * @return mixed array|PEAR_Error - * @access public - */ - function listUsers() - { - $this->log('Auth_Container_MDB2::listUsers() called.', AUTH_LOG_DEBUG); - $err = $this->_prepare(); - if ($err !== true) { - return PEAR::raiseError($err->getMessage(), $err->getCode()); - } - - $retVal = array(); - - //Check if db_fields contains a *, if so assume all columns are selected - if ( is_string($this->options['db_fields']) - && strstr($this->options['db_fields'], '*')) { - $sql_from = '*'; - } else { - $sql_from = $this->options['final_usernamecol']. - ", ".$this->options['final_passwordcol']; - - if (strlen($fields = $this->_quoteDBFields()) > 0) { - $sql_from .= ', '.$fields; - } - } - - $query = sprintf('SELECT %s FROM %s', - $sql_from, - $this->options['final_table'] - ); - - // check if there is an optional parameter db_where - if ($this->options['db_where'] != '') { - // there is one, so add it to the query - $query .= " WHERE ".$this->options['db_where']; - } - - $this->log('Running SQL against MDB2: '.$query, AUTH_LOG_DEBUG); - - $res = $this->db->queryAll($query, null, MDB2_FETCHMODE_ASSOC); - if (MDB2::isError($res)) { - return PEAR::raiseError($res->getMessage(), $res->getCode()); - } else { - foreach ($res as $user) { - $user['username'] = $user[$this->options['usernamecol']]; - $retVal[] = $user; - } - } - $this->log('Found '.count($retVal).' users.', AUTH_LOG_DEBUG); - return $retVal; - } - - // }}} - // {{{ addUser() - - /** - * Add user to the storage container - * - * @access public - * @param string Username - * @param string Password - * @param mixed Additional information that are stored in the DB - * - * @return mixed True on success, otherwise error object - */ - function addUser($username, $password, $additional = "") - { - $this->log('Auth_Container_MDB2::addUser() called.', AUTH_LOG_DEBUG); - - // Prepare for a database query - $err = $this->_prepare(); - if ($err !== true) { - return PEAR::raiseError($err->getMessage(), $err->getCode()); - } - - if (isset($this->options['cryptType']) && $this->options['cryptType'] == 'none') { - $cryptFunction = 'strval'; - } elseif (isset($this->options['cryptType']) && function_exists($this->options['cryptType'])) { - $cryptFunction = $this->options['cryptType']; - } else { - $cryptFunction = 'md5'; - } - - $password = $cryptFunction($password); - - $additional_key = ''; - $additional_value = ''; - - if (is_array($additional)) { - foreach ($additional as $key => $value) { - if ($this->options['auto_quote']) { - $additional_key .= ', ' . $this->db->quoteIdentifier($key, true); - } else { - $additional_key .= ', ' . $key; - } - $additional_value .= ', ' . $this->db->quote($value, 'text'); - } - } - - $query = sprintf("INSERT INTO %s (%s, %s%s) VALUES (%s, %s%s)", - $this->options['final_table'], - $this->options['final_usernamecol'], - $this->options['final_passwordcol'], - $additional_key, - $this->db->quote($username, 'text'), - $this->db->quote($password, 'text'), - $additional_value - ); - - $this->log('Running SQL against MDB2: '.$query, AUTH_LOG_DEBUG); - - $res = $this->query($query); - - if (MDB2::isError($res)) { - return PEAR::raiseError($res->getMessage(), $res->code); - } - return true; - } - - // }}} - // {{{ removeUser() - - /** - * Remove user from the storage container - * - * @access public - * @param string Username - * - * @return mixed True on success, otherwise error object - */ - function removeUser($username) - { - $this->log('Auth_Container_MDB2::removeUser() called.', AUTH_LOG_DEBUG); - // Prepare for a database query - $err = $this->_prepare(); - if ($err !== true) { - return PEAR::raiseError($err->getMessage(), $err->getCode()); - } - - $query = sprintf("DELETE FROM %s WHERE %s = %s", - $this->options['final_table'], - $this->options['final_usernamecol'], - $this->db->quote($username, 'text') - ); - - // check if there is an optional parameter db_where - if ($this->options['db_where'] != '') { - // there is one, so add it to the query - $query .= " AND ".$this->options['db_where']; - } - - $this->log('Running SQL against MDB2: '.$query, AUTH_LOG_DEBUG); - - $res = $this->query($query); - - if (MDB2::isError($res)) { - return PEAR::raiseError($res->getMessage(), $res->code); - } - return true; - } - - // }}} - // {{{ changePassword() - - /** - * Change password for user in the storage container - * - * @param string Username - * @param string The new password (plain text) - */ - function changePassword($username, $password) - { - $this->log('Auth_Container_MDB2::changePassword() called.', AUTH_LOG_DEBUG); - // Prepare for a database query - $err = $this->_prepare(); - if ($err !== true) { - return PEAR::raiseError($err->getMessage(), $err->getCode()); - } - - if (isset($this->options['cryptType']) && $this->options['cryptType'] == 'none') { - $cryptFunction = 'strval'; - } elseif (isset($this->options['cryptType']) && function_exists($this->options['cryptType'])) { - $cryptFunction = $this->options['cryptType']; - } else { - $cryptFunction = 'md5'; - } - - $password = $cryptFunction($password); - - $query = sprintf("UPDATE %s SET %s = %s WHERE %s = %s", - $this->options['final_table'], - $this->options['final_passwordcol'], - $this->db->quote($password, 'text'), - $this->options['final_usernamecol'], - $this->db->quote($username, 'text') - ); - - // check if there is an optional parameter db_where - if ($this->options['db_where'] != '') { - // there is one, so add it to the query - $query .= " AND ".$this->options['db_where']; - } - - $this->log('Running SQL against MDB2: '.$query, AUTH_LOG_DEBUG); - - $res = $this->query($query); - - if (MDB2::isError($res)) { - return PEAR::raiseError($res->getMessage(), $res->code); - } - return true; - } - - // }}} - // {{{ supportsChallengeResponse() - - /** - * Determine if this container supports - * password authentication with challenge response - * - * @return bool - * @access public - */ - function supportsChallengeResponse() - { - return in_array($this->options['cryptType'], array('md5', 'none', '')); - } - - // }}} - // {{{ getCryptType() - - /** - * Returns the selected crypt type for this container - * - * @return string Function used to crypt the password - */ - function getCryptType() - { - return $this->options['cryptType']; - } - - // }}} - -} -?> diff --git a/glmPEAR/Container/Multiple.php b/glmPEAR/Container/Multiple.php deleted file mode 100755 index 87e261e..0000000 --- a/glmPEAR/Container/Multiple.php +++ /dev/null @@ -1,188 +0,0 @@ - - * @copyright 2001-2006 The PHP Group - * @license http://www.php.net/license/3_01.txt PHP License 3.01 - * @version CVS: $Id: Multiple.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ - * @since File available since Release 1.5.0 - */ - -/** - * Include Auth_Container base class - */ -require_once "Auth/Container.php"; -/** - * Include PEAR package for error handling - */ -require_once "PEAR.php"; - -/** - * Storage driver for using multiple storage drivers in a fall through fashion - * - * This storage driver provides a mechanism for working through multiple - * storage drivers until either one allows successful login or the list is - * exhausted. - * - * This container takes an array of options of the following form: - * - * array( - * array( - * 'type' => , - * 'options' => , - * ), - * ); - * - * Full example: - * - * $options = array( - * array( - * 'type' => 'DB', - * 'options' => array( - * 'dsn' => "mysql://user:password@localhost/database", - * ), - * ), - * array( - * 'type' => 'Array', - * 'options' => array( - * 'cryptType' => 'md5', - * 'users' => array( - * 'admin' => md5('password'), - * ), - * ), - * ), - * ); - * - * $auth = new Auth('Multiple', $options); - * - * @category Authentication - * @package Auth - * @author Adam Ashley - * @copyright 2001-2006 The PHP Group - * @license http://www.php.net/license/3_01.txt PHP License 3.01 - * @version Release: 1.5.4 File: $Revision: 1.1.1.1 $ - * @since File available since Release 1.5.0 - */ - -class Auth_Container_Multiple extends Auth_Container { - - // {{{ properties - - /** - * The options for each container - * - * @var array $options - */ - var $options = array(); - - /** - * The instanciated containers - * - * @var array $containers - */ - var $containers = array(); - - // }}} - // {{{ Auth_Container_Multiple() - - /** - * Constructor for Array Container - * - * @param array $data Options for the container - * @return void - */ - function Auth_Container_Multiple($options) - { - if (!is_array($options)) { - PEAR::raiseError('The options for Auth_Container_Multiple must be an array'); - } - if (count($options) < 1) { - PEAR::raiseError('You must define at least one sub container to use in Auth_Container_Multiple'); - } - foreach ($options as $option) { - if (!isset($option['type'])) { - PEAR::raiseError('No type defined for sub container'); - } - } - $this->options = $options; - } - - // }}} - // {{{ fetchData() - - /** - * Get user information from array - * - * This function uses the given username to fetch the corresponding - * login data from the array. If an account that matches the passed - * username and password is found, the function returns true. - * Otherwise it returns false. - * - * @param string Username - * @param string Password - * @return boolean|PEAR_Error Error object or boolean - */ - function fetchData($user, $pass) - { - $this->log('Auth_Container_Multiple::fetchData() called.', AUTH_LOG_DEBUG); - - foreach ($this->options as $key => $options) { - - $this->log('Using Container '.$key.' of type '.$options['type'].'.', AUTH_LOG_DEBUG); - - if (isset($this->containers[$key]) && is_a($this->containers[$key], 'Auth_Container')) { - - $container = &$this->containers[$key]; - - } else { - - $this->containers[$key] = &$this->_auth_obj->_factory($options['type'], $options['options']); - $this->containers[$key]->_auth_obj = &$this->_auth_obj; - $container = &$this->containers[$key]; - - } - - $result = $container->fetchData($user, $pass); - - if (PEAR::isError($result)) { - - $this->log('Container '.$key.': '.$result->getMessage(), AUTH_LOG_ERR); - return $result; - - } elseif ($result == true) { - - $this->log('Container '.$key.': Authentication successful.', AUTH_LOG_DEBUG); - return true; - - } else { - - $this->log('Container '.$key.': Authentication failed.', AUTH_LOG_DEBUG); - - } - - } - - $this->log('Auth_Container_Multiple: All containers rejected user credentials.', AUTH_LOG_DEBUG); - - return false; - - } - - // }}} - -} - -?> diff --git a/glmPEAR/Container/PEAR.php b/glmPEAR/Container/PEAR.php deleted file mode 100755 index bc01aad..0000000 --- a/glmPEAR/Container/PEAR.php +++ /dev/null @@ -1,115 +0,0 @@ - - * @author Adam Ashley - * @copyright 2001-2006 The PHP Group - * @license http://www.php.net/license/3_01.txt PHP License 3.01 - * @version CVS: $Id: PEAR.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ - * @link http://pear.php.net/package/Auth - * @since File available since Release 1.3.0 - */ - -/** - * Include PEAR HTTP_Client. - */ -require_once 'HTTP/Client.php'; -/** - * Include Auth_Container base class - */ -require_once 'Auth/Container.php'; - -/** - * Storage driver for authenticating against PEAR website - * - * This driver provides a method for authenticating against the pear.php.net - * authentication system. - * - * @category Authentication - * @package Auth - * @author Yavor Shahpasov - * @author Adam Ashley - * @author Adam Harvey - * @copyright 2001-2007 The PHP Group - * @license http://www.php.net/license/3_01.txt PHP License 3.01 - * @version Release: 1.5.4 File: $Revision: 1.1.1.1 $ - * @link http://pear.php.net/package/Auth - * @since Class available since Release 1.3.0 - */ -class Auth_Container_Pear extends Auth_Container -{ - - // {{{ Auth_Container_Pear() [constructor] - - /** - * Constructor - * - * Currently does nothing - * - * @return void - */ - function Auth_Container_Pear() - { - - } - - // }}} - // {{{ fetchData() - - /** - * Get user information from pear.php.net - * - * This function uses the given username and password to authenticate - * against the pear.php.net website - * - * @param string Username - * @param string Password - * @return mixed Error object or boolean - */ - function fetchData($username, $password) - { - $this->log('Auth_Container_PEAR::fetchData() called.', AUTH_LOG_DEBUG); - - $client = new HTTP_Client; - - $this->log('Auth_Container_PEAR::fetchData() getting salt.', AUTH_LOG_DEBUG); - $code = $client->get('https://pear.php.net/rest-login.php/getsalt'); - if ($code != 200) { - return PEAR::raiseError('Bad response to salt request.', $code); - } - $resp = $client->currentResponse(); - $salt = $resp['body']; - - $this->log('Auth_Container_PEAR::fetchData() calling validate.', AUTH_LOG_DEBUG); - $code = $client->post('https://pear.php.net/rest-login.php/validate', - array('username' => $username, - 'password' => md5($salt.md5($password)))); - if ($code != 200) { - return PEAR::raiseError('Bad response to validate request.', $code); - } - $resp = $client->currentResponse(); - - list($code, $message) = explode(' ', $resp['body'], 1); - if ($code != 8) { - return PEAR::raiseError($message, $code); - } - return true; - } - - // }}} - -} -?> diff --git a/glmPEAR/Container/POP3.php b/glmPEAR/Container/POP3.php deleted file mode 100755 index fc139a5..0000000 --- a/glmPEAR/Container/POP3.php +++ /dev/null @@ -1,145 +0,0 @@ - - * @author Martin Jansen - * @author Mika Tuupola - * @author Adam Ashley - * @copyright 2001-2006 The PHP Group - * @license http://www.php.net/license/3_01.txt PHP License 3.01 - * @version CVS: $Id: POP3.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ - * @link http://pear.php.net/package/Auth - * @since File available since Release 1.2.0 - */ - -/** - * Include Auth_Container base class - */ -require_once 'Auth/Container.php'; -/** - * Include PEAR package for error handling - */ -require_once 'PEAR.php'; -/** - * Include PEAR Net_POP3 package - */ -require_once 'Net/POP3.php'; - -/** - * Storage driver for Authentication on a POP3 server. - * - * @category Authentication - * @package Auth - * @author Martin Jansen - * @author Mika Tuupola - * @author Adam Ashley - * @copyright 2001-2006 The PHP Group - * @license http://www.php.net/license/3_01.txt PHP License 3.01 - * @version Release: 1.5.4 File: $Revision: 1.1.1.1 $ - * @link http://pear.php.net/package/Auth - * @since Class available since Release 1.2.0 - */ -class Auth_Container_POP3 extends Auth_Container -{ - - // {{{ properties - - /** - * POP3 Server - * @var string - */ - var $server='localhost'; - - /** - * POP3 Server port - * @var string - */ - var $port='110'; - - /** - * POP3 Authentication method - * - * Prefered POP3 authentication method. Acceptable values: - * Boolean TRUE - Use Net_POP3's autodetection - * String 'DIGEST-MD5','CRAM-MD5','LOGIN','PLAIN','APOP','USER' - * - Attempt this authentication style first - * then fallback to autodetection. - * @var mixed - */ - var $method=true; - - // }}} - // {{{ Auth_Container_POP3() [constructor] - - /** - * Constructor of the container class - * - * @param $server string server or server:port combination - * @return object Returns an error object if something went wrong - */ - function Auth_Container_POP3($server=null) - { - if (isset($server) && !is_null($server)) { - if (is_array($server)) { - if (isset($server['host'])) { - $this->server = $server['host']; - } - if (isset($server['port'])) { - $this->port = $server['port']; - } - if (isset($server['method'])) { - $this->method = $server['method']; - } - } else { - if (strstr($server, ':')) { - $serverparts = explode(':', trim($server)); - $this->server = $serverparts[0]; - $this->port = $serverparts[1]; - } else { - $this->server = $server; - } - } - } - } - - // }}} - // {{{ fetchData() - - /** - * Try to login to the POP3 server - * - * @param string Username - * @param string Password - * @return boolean - */ - function fetchData($username, $password) - { - $this->log('Auth_Container_POP3::fetchData() called.', AUTH_LOG_DEBUG); - $pop3 =& new Net_POP3(); - $res = $pop3->connect($this->server, $this->port, $this->method); - if (!$res) { - $this->log('Connection to POP3 server failed.', AUTH_LOG_DEBUG); - return $res; - } - $result = $pop3->login($username, $password); - $pop3->disconnect(); - return $result; - } - - // }}} - -} -?> diff --git a/glmPEAR/Container/RADIUS.php b/glmPEAR/Container/RADIUS.php deleted file mode 100755 index b3bb8e2..0000000 --- a/glmPEAR/Container/RADIUS.php +++ /dev/null @@ -1,182 +0,0 @@ - - * @author Adam Ashley - * @copyright 2001-2006 The PHP Group - * @license http://www.php.net/license/3_01.txt PHP License 3.01 - * @version CVS: $Id: RADIUS.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ - * @link http://pear.php.net/package/Auth - * @since File available since Release 1.2.0 - */ - -/** - * Include Auth_Container base class - */ -require_once "Auth/Container.php"; -/** - * Include PEAR Auth_RADIUS package - */ -require_once "Auth/RADIUS.php"; - -/** - * Storage driver for authenticating users against RADIUS servers. - * - * @category Authentication - * @package Auth - * @author Michael Bretterklieber - * @author Adam Ashley - * @copyright 2001-2006 The PHP Group - * @license http://www.php.net/license/3_01.txt PHP License 3.01 - * @version Release: 1.5.4 File: $Revision: 1.1.1.1 $ - * @link http://pear.php.net/package/Auth - * @since Class available since Release 1.2.0 - */ -class Auth_Container_RADIUS extends Auth_Container -{ - - // {{{ properties - - /** - * Contains a RADIUS object - * @var object - */ - var $radius; - - /** - * Contains the authentication type - * @var string - */ - var $authtype; - - // }}} - // {{{ Auth_Container_RADIUS() [constructor] - - /** - * Constructor of the container class. - * - * $options can have these keys: - * 'servers' an array containing an array: servername, port, - * sharedsecret, timeout, maxtries - * 'configfile' The filename of the configuration file - * 'authtype' The type of authentication, one of: PAP, CHAP_MD5, - * MSCHAPv1, MSCHAPv2, default is PAP - * - * @param $options associative array - * @return object Returns an error object if something went wrong - */ - function Auth_Container_RADIUS($options) - { - $this->authtype = 'PAP'; - if (isset($options['authtype'])) { - $this->authtype = $options['authtype']; - } - $classname = 'Auth_RADIUS_' . $this->authtype; - if (!class_exists($classname)) { - PEAR::raiseError("Unknown Authtype, please use one of: " - ."PAP, CHAP_MD5, MSCHAPv1, MSCHAPv2!", 41, PEAR_ERROR_DIE); - } - - $this->radius = new $classname; - - if (isset($options['configfile'])) { - $this->radius->setConfigfile($options['configfile']); - } - - $servers = $options['servers']; - if (is_array($servers)) { - foreach ($servers as $server) { - $servername = $server[0]; - $port = isset($server[1]) ? $server[1] : 0; - $sharedsecret = isset($server[2]) ? $server[2] : 'testing123'; - $timeout = isset($server[3]) ? $server[3] : 3; - $maxtries = isset($server[4]) ? $server[4] : 3; - $this->radius->addServer($servername, $port, $sharedsecret, $timeout, $maxtries); - } - } - - if (!$this->radius->start()) { - PEAR::raiseError($this->radius->getError(), 41, PEAR_ERROR_DIE); - } - } - - // }}} - // {{{ fetchData() - - /** - * Authenticate - * - * @param string Username - * @param string Password - * @return bool true on success, false on reject - */ - function fetchData($username, $password, $challenge = null) - { - $this->log('Auth_Container_RADIUS::fetchData() called.', AUTH_LOG_DEBUG); - - switch($this->authtype) { - case 'CHAP_MD5': - case 'MSCHAPv1': - if (isset($challenge)) { - $this->radius->challenge = $challenge; - $this->radius->chapid = 1; - $this->radius->response = pack('H*', $password); - } else { - require_once 'Crypt/CHAP.php'; - $classname = 'Crypt_' . $this->authtype; - $crpt = new $classname; - $crpt->password = $password; - $this->radius->challenge = $crpt->challenge; - $this->radius->chapid = $crpt->chapid; - $this->radius->response = $crpt->challengeResponse(); - } - break; - - case 'MSCHAPv2': - require_once 'Crypt/CHAP.php'; - $crpt = new Crypt_MSCHAPv2; - $crpt->username = $username; - $crpt->password = $password; - $this->radius->challenge = $crpt->authChallenge; - $this->radius->peerChallenge = $crpt->peerChallenge; - $this->radius->chapid = $crpt->chapid; - $this->radius->response = $crpt->challengeResponse(); - break; - - default: - $this->radius->password = $password; - break; - } - - $this->radius->username = $username; - - $this->radius->putAuthAttributes(); - $result = $this->radius->send(); - if (PEAR::isError($result)) { - return false; - } - - $this->radius->getAttributes(); -// just for debugging -// $this->radius->dumpAttributes(); - - return $result; - } - - // }}} - -} -?> diff --git a/glmPEAR/Container/SAP.php b/glmPEAR/Container/SAP.php deleted file mode 100755 index 50f0997..0000000 --- a/glmPEAR/Container/SAP.php +++ /dev/null @@ -1,179 +0,0 @@ - - * @author Adam Ashley - * @copyright 2001-2006 The PHP Group - * @license http://www.php.net/license/3_01.txt PHP License 3.01 - * @version CVS: $Id: SAP.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ - * @link http://pear.php.net/package/Auth - * @since File available since Release 1.4.0 - */ - -/** - * Include Auth_Container base class - */ -require_once 'Auth/Container.php'; -/** - * Include PEAR for error handling - */ -require_once 'PEAR.php'; - -/** - * Performs authentication against a SAP system using the SAPRFC PHP extension. - * - * When the option GETSSO2 is TRUE (default) - * the Single Sign-On (SSO) ticket is retrieved - * and stored as an Auth attribute called 'sap' - * in order to be reused for consecutive connections. - * - * @category Authentication - * @package Auth - * @author Stoyan Stefanov - * @author Adam Ashley - * @copyright 2001-2006 The PHP Group - * @license http://www.php.net/license/3_01.txt PHP License 3.01 - * @version Release: 1.5.4 File: $Revision: 1.1.1.1 $ - * @since Class available since Release 1.4.0 - */ -class Auth_Container_SAP extends Auth_Container { - - // {{{ properties - - /** - * @var array Default options - */ - var $options = array( - 'CLIENT' => '000', - 'LANG' => 'EN', - 'GETSSO2' => true, - ); - - // }}} - // {{{ Auth_Container_SAP() - - /** - * Class constructor. Checks that required options - * are present and that the SAPRFC extension is loaded - * - * Options that can be passed and their defaults: - *
-     * array(
-     *   'ASHOST' => "",
-     *   'SYSNR'  => "",
-     *   'CLIENT' => "000",
-     *   'GWHOST' =>"",
-     *   'GWSERV' =>"",
-     *   'MSHOST' =>"",
-     *   'R3NAME' =>"",
-     *   'GROUP'  =>"",
-     *   'LANG'   =>"EN",
-     *   'TRACE'  =>"",
-     *   'GETSSO2'=> true
-     * )
-     * 
- * - * @param array array of options. - * @return void - */ - function Auth_Container_SAP($options) - { - $saprfc_loaded = PEAR::loadExtension('saprfc'); - if (!$saprfc_loaded) { - return PEAR::raiseError('Cannot use SAP authentication, ' - .'SAPRFC extension not loaded!'); - } - if (empty($options['R3NAME']) && empty($options['ASHOST'])) { - return PEAR::raiseError('R3NAME or ASHOST required for authentication'); - } - $this->options = array_merge($this->options, $options); - } - - // }}} - // {{{ fetchData() - - /** - * Performs username and password check - * - * @param string Username - * @param string Password - * @return boolean TRUE on success (valid user), FALSE otherwise - */ - function fetchData($username, $password) - { - $this->log('Auth_Container_SAP::fetchData() called.', AUTH_LOG_DEBUG); - $connection_options = $this->options; - $connection_options['USER'] = $username; - $connection_options['PASSWD'] = $password; - $rfc = saprfc_open($connection_options); - if (!$rfc) { - $message = "Couldn't connect to the SAP system."; - $error = $this->getError(); - if ($error['message']) { - $message .= ': ' . $error['message']; - } - PEAR::raiseError($message, null, null, null, @$erorr['all']); - return false; - } else { - if (!empty($this->options['GETSSO2'])) { - $this->log('Attempting to retrieve SSO2 ticket.', AUTH_LOG_DEBUG); - if ($ticket = @saprfc_get_ticket($rfc)) { - $this->options['MYSAPSSO2'] = $ticket; - unset($this->options['GETSSO2']); - $this->_auth_obj->setAuthData('sap', $this->options); - } else { - PEAR::raiseError("SSO ticket retrieval failed"); - } - } - @saprfc_close($rfc); - return true; - } - - } - - // }}} - // {{{ getError() - - /** - * Retrieves the last error from the SAP connection - * and returns it as an array. - * - * @return array Array of error information - */ - function getError() - { - - $error = array(); - $sap_error = saprfc_error(); - if (empty($err)) { - return $error; - } - $err = explode("n", $sap_error); - foreach ($err AS $line) { - $item = split(':', $line); - $error[strtolower(trim($item[0]))] = trim($item[1]); - } - $error['all'] = $sap_error; - return $error; - } - - // }}} - -} - -?> diff --git a/glmPEAR/Container/SMBPasswd.php b/glmPEAR/Container/SMBPasswd.php deleted file mode 100755 index 883a70f..0000000 --- a/glmPEAR/Container/SMBPasswd.php +++ /dev/null @@ -1,182 +0,0 @@ - - * @author Adam Ashley - * @copyright 2001-2006 The PHP Group - * @license http://www.php.net/license/3_01.txt PHP License 3.01 - * @version CVS: $Id: SMBPasswd.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ - * @link http://pear.php.net/package/Auth - * @since File available since Release 1.2.3 - */ - -/** - * Include PEAR File_SMBPasswd - */ -require_once "File/SMBPasswd.php"; -/** - * Include Auth_Container Base file - */ -require_once "Auth/Container.php"; -/** - * Include PEAR class for error handling - */ -require_once "PEAR.php"; - -/** - * Storage driver for fetching login data from an SAMBA smbpasswd file. - * - * This storage container can handle SAMBA smbpasswd files. - * - * Example: - * $a = new Auth("SMBPasswd", '/usr/local/private/smbpasswd'); - * $a->start(); - * if ($a->getAuth()) { - * printf ("AUTH OK
\n"); - * $a->logout(); - * } - * - * @category Authentication - * @package Auth - * @author Michael Bretterklieber - * @author Adam Ashley - * @package Auth - * @copyright 2001-2006 The PHP Group - * @license http://www.php.net/license/3_01.txt PHP License 3.01 - * @version Release: 1.5.4 File: $Revision: 1.1.1.1 $ - * @link http://pear.php.net/package/Auth - * @since Class available since Release 1.2.3 - */ -class Auth_Container_SMBPasswd extends Auth_Container -{ - - // {{{ properties - - /** - * File_SMBPasswd object - * @var object - */ - var $pwfile; - - // }}} - - // {{{ Auth_Container_SMBPasswd() [constructor] - - /** - * Constructor of the container class - * - * @param $filename string filename for a passwd type file - * @return object Returns an error object if something went wrong - */ - function Auth_Container_SMBPasswd($filename) - { - $this->pwfile = new File_SMBPasswd($filename,0); - - if (!$this->pwfile->load()) { - PEAR::raiseError("Error while reading file contents.", 41, PEAR_ERROR_DIE); - return; - } - - } - - // }}} - // {{{ fetchData() - - /** - * Get user information from pwfile - * - * @param string Username - * @param string Password - * @return boolean - */ - function fetchData($username, $password) - { - $this->log('Auth_Container_SMBPasswd::fetchData() called.', AUTH_LOG_DEBUG); - return $this->pwfile->verifyAccount($username, $password); - } - - // }}} - // {{{ listUsers() - - function listUsers() - { - $this->log('Auth_Container_SMBPasswd::fetchData() called.', AUTH_LOG_DEBUG); - return $this->pwfile->getAccounts(); - } - - // }}} - // {{{ addUser() - - /** - * Add a new user to the storage container - * - * @param string Username - * @param string Password - * @param array Additional information - * - * @return boolean - */ - function addUser($username, $password, $additional = '') - { - $this->log('Auth_Container_SMBPasswd::addUser() called.', AUTH_LOG_DEBUG); - $res = $this->pwfile->addUser($user, $additional['userid'], $pass); - if ($res === true) { - return $this->pwfile->save(); - } - return $res; - } - - // }}} - // {{{ removeUser() - - /** - * Remove user from the storage container - * - * @param string Username - */ - function removeUser($username) - { - $this->log('Auth_Container_SMBPasswd::removeUser() called.', AUTH_LOG_DEBUG); - $res = $this->pwfile->delUser($username); - if ($res === true) { - return $this->pwfile->save(); - } - return $res; - } - - // }}} - // {{{ changePassword() - - /** - * Change password for user in the storage container - * - * @param string Username - * @param string The new password - */ - function changePassword($username, $password) - { - $this->log('Auth_Container_SMBPasswd::changePassword() called.', AUTH_LOG_DEBUG); - $res = $this->pwfile->modUser($username, '', $password); - if ($res === true) { - return $this->pwfile->save(); - } - return $res; - } - - // }}} - -} -?> diff --git a/glmPEAR/Container/SOAP.php b/glmPEAR/Container/SOAP.php deleted file mode 100755 index 3ecf30a..0000000 --- a/glmPEAR/Container/SOAP.php +++ /dev/null @@ -1,229 +0,0 @@ - - * @author Adam Ashley - * @copyright 2001-2006 The PHP Group - * @license http://www.php.net/license/3_01.txt PHP License 3.01 - * @version CVS: $Id: SOAP.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ - * @link http://pear.php.net/package/Auth - * @since File available since Release 1.2.0 - */ - -/** - * Include Auth_Container base class - */ -require_once "Auth/Container.php"; -/** - * Include PEAR package for error handling - */ -require_once "PEAR.php"; -/** - * Include PEAR SOAP_Client - */ -require_once 'SOAP/Client.php'; - -/** - * Storage driver for fetching login data from SOAP - * - * This class takes one parameter (options), where - * you specify the following fields: endpoint, namespace, - * method, encoding, usernamefield and passwordfield. - * - * You can use specify features of your SOAP service - * by providing its parameters in an associative manner by - * using the '_features' array through the options parameter. - * - * The 'matchpassword' option should be set to false if your - * webservice doesn't return (username,password) pairs, but - * instead returns error when the login is invalid. - * - * Example usage: - * - * 'http://your.soap.service/endpoint', - * 'namespace' => 'urn:/Your/Namespace', - * 'method' => 'get', - * 'encoding' => 'UTF-8', - * 'usernamefield' => 'login', - * 'passwordfield' => 'password', - * 'matchpasswords' => false, - * '_features' => array ( - * 'example_feature' => 'example_value', - * 'another_example' => '' - * ) - * ); - * $auth = new Auth('SOAP', $options, 'loginFunction'); - * $auth->start(); - * - * ... - * - * ?> - * - * @category Authentication - * @package Auth - * @author Bruno Pedro - * @author Adam Ashley - * @copyright 2001-2006 The PHP Group - * @license http://www.php.net/license/3_01.txt PHP License 3.01 - * @version Release: 1.5.4 File: $Revision: 1.1.1.1 $ - * @link http://pear.php.net/package/Auth - * @since Class available since Release 1.2.0 - */ -class Auth_Container_SOAP extends Auth_Container -{ - - // {{{ properties - - /** - * Required options for the class - * @var array - * @access private - */ - var $_requiredOptions = array( - 'endpoint', - 'namespace', - 'method', - 'encoding', - 'usernamefield', - 'passwordfield', - ); - - /** - * Options for the class - * @var array - * @access private - */ - var $_options = array(); - - /** - * Optional SOAP features - * @var array - * @access private - */ - var $_features = array(); - - /** - * The SOAP response - * @var array - * @access public - */ - var $soapResponse = array(); - - /** - * The SOAP client - * @var mixed - * @access public - */ - var $soapClient = null; - - // }}} - // {{{ Auth_Container_SOAP() [constructor] - - /** - * Constructor of the container class - * - * @param $options, associative array with endpoint, namespace, method, - * usernamefield, passwordfield and optional features - */ - function Auth_Container_SOAP($options) - { - $this->_options = $options; - if (!isset($this->_options['matchpasswords'])) { - $this->_options['matchpasswords'] = true; - } - if (!empty($this->_options['_features'])) { - $this->_features = $this->_options['_features']; - unset($this->_options['_features']); - } - } - - // }}} - // {{{ fetchData() - - /** - * Fetch data from SOAP service - * - * Requests the SOAP service for the given username/password - * combination. - * - * @param string Username - * @param string Password - * @return mixed Returns the SOAP response or false if something went wrong - */ - function fetchData($username, $password) - { - $this->log('Auth_Container_SOAP::fetchData() called.', AUTH_LOG_DEBUG); - // check if all required options are set - if (array_intersect($this->_requiredOptions, array_keys($this->_options)) != $this->_requiredOptions) { - return false; - } else { - // create a SOAP client and set encoding - $this->soapClient = new SOAP_Client($this->_options['endpoint']); - $this->soapClient->setEncoding($this->_options['encoding']); - } - - // set the trace option if requested - if (isset($this->_options['trace'])) { - $this->soapClient->__options['trace'] = true; - } - - // set the timeout option if requested - if (isset($this->_options['timeout'])) { - $this->soapClient->__options['timeout'] = $this->_options['timeout']; - } - - // assign username and password fields - $usernameField = new SOAP_Value($this->_options['usernamefield'],'string', $username); - $passwordField = new SOAP_Value($this->_options['passwordfield'],'string', $password); - $SOAPParams = array($usernameField, $passwordField); - - // assign optional features - foreach ($this->_features as $fieldName => $fieldValue) { - $SOAPParams[] = new SOAP_Value($fieldName, 'string', $fieldValue); - } - - // make SOAP call - $this->soapResponse = $this->soapClient->call( - $this->_options['method'], - $SOAPParams, - array('namespace' => $this->_options['namespace']) - ); - - if (!PEAR::isError($this->soapResponse)) { - if ($this->_options['matchpasswords']) { - // check if passwords match - if ($password == $this->soapResponse->{$this->_options['passwordfield']}) { - return true; - } else { - return false; - } - } else { - return true; - } - } else { - return false; - } - } - - // }}} - -} -?> diff --git a/glmPEAR/Container/SOAP5.php b/glmPEAR/Container/SOAP5.php deleted file mode 100755 index afaf581..0000000 --- a/glmPEAR/Container/SOAP5.php +++ /dev/null @@ -1,268 +0,0 @@ - - * @author Marcel Oelke - * @author Adam Ashley - * @copyright 2001-2006 The PHP Group - * @license http://www.php.net/license/3_01.txt PHP License 3.01 - * @version CVS: $Id: SOAP5.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ - * @since File available since Release 1.4.0 - */ - -/** - * Include Auth_Container base class - */ -require_once "Auth/Container.php"; -/** - * Include PEAR package for error handling - */ -require_once "PEAR.php"; - -/** - * Storage driver for fetching login data from SOAP using the PHP5 Builtin SOAP - * functions. This is a modification of the SOAP Storage driver from Bruno Pedro - * thats using the PEAR SOAP Package. - * - * This class takes one parameter (options), where - * you specify the following fields: - * * location and uri, or wsdl file - * * method to call on the SOAP service - * * usernamefield, the name of the parameter where the username is supplied - * * passwordfield, the name of the parameter where the password is supplied - * * matchpassword, whether to look for the password in the response from - * the function call or assume that no errors means user - * authenticated. - * - * See http://www.php.net/manual/en/ref.soap.php for further details - * on options for the PHP5 SoapClient which are passed through. - * - * Example usage without WSDL: - * - * NULL, - * 'location' => 'http://your.soap.service/endpoint', - * 'uri' => 'urn:/Your/Namespace', - * 'method' => 'checkAuth', - * 'usernamefield' => 'username', - * 'passwordfield' => 'password', - * 'matchpasswords' => false, - * '_features' => array ( - * 'extra_parameter' => 'example_value', - * 'another_parameter' => 'foobar' - * ) - * ); - * - * $auth = new Auth('SOAP5', $options); - * $auth->start(); - * - * ?> - * - * Example usage with WSDL: - * - * 'http://your.soap.service/wsdl', - * 'method' => 'checkAuth', - * 'usernamefield' => 'username', - * 'passwordfield' => 'password', - * 'matchpasswords' => false, - * '_features' => array ( - * 'extra_parameter' => 'example_value', - * 'another_parameter' => 'foobar' - * ) - * ); - * - * $auth = new Auth('SOAP5', $options); - * $auth->start(); - * - * ?> - * - * @category Authentication - * @package Auth - * @author Based upon Auth_Container_SOAP by Bruno Pedro - * @author Marcel Oelke - * @author Adam Ashley - * @copyright 2001-2006 The PHP Group - * @license http://www.php.net/license/3_01.txt PHP License 3.01 - * @version Release: 1.5.4 File: $Revision: 1.1.1.1 $ - * @since Class available since Release 1.4.0 - */ -class Auth_Container_SOAP5 extends Auth_Container -{ - - // {{{ properties - - /** - * Required options for the class - * @var array - * @access private - */ - var $_requiredOptions = array( - 'location', - 'uri', - 'method', - 'usernamefield', - 'passwordfield', - 'wsdl', - ); - - /** - * Options for the class - * @var array - * @access private - */ - var $_options = array(); - - /** - * Optional SOAP features - * @var array - * @access private - */ - var $_features = array(); - - /** - * The SOAP response - * @var array - * @access public - */ - var $soapResponse = array(); - - // }}} - // {{{ Auth_Container_SOAP5() - - /** - * Constructor of the container class - * - * @param $options, associative array with endpoint, namespace, method, - * usernamefield, passwordfield and optional features - */ - function Auth_Container_SOAP5($options) - { - $this->_setDefaults(); - - foreach ($options as $name => $value) { - $this->_options[$name] = $value; - } - - if (!empty($this->_options['_features'])) { - $this->_features = $this->_options['_features']; - unset($this->_options['_features']); - } - } - - // }}} - // {{{ fetchData() - - /** - * Fetch data from SOAP service - * - * Requests the SOAP service for the given username/password - * combination. - * - * @param string Username - * @param string Password - * @return mixed Returns the SOAP response or false if something went wrong - */ - function fetchData($username, $password) - { - $this->log('Auth_Container_SOAP5::fetchData() called.', AUTH_LOG_DEBUG); - $result = $this->_validateOptions(); - if (PEAR::isError($result)) - return $result; - - // create a SOAP client - $soapClient = new SoapClient($this->_options["wsdl"], $this->_options); - - $params = array(); - // first, assign the optional features - foreach ($this->_features as $fieldName => $fieldValue) { - $params[$fieldName] = $fieldValue; - } - // assign username and password ... - $params[$this->_options['usernamefield']] = $username; - $params[$this->_options['passwordfield']] = $password; - - try { - $this->soapResponse = $soapClient->__soapCall($this->_options['method'], $params); - - if ($this->_options['matchpasswords']) { - // check if passwords match - if ($password == $this->soapResponse[$this->_options['passwordfield']]) { - return true; - } else { - return false; - } - } else { - return true; - } - } catch (SoapFault $e) { - return PEAR::raiseError("Error retrieving authentication data. Received SOAP Fault: ".$e->faultstring, $e->faultcode); - } - } - - // }}} - // {{{ _validateOptions() - - /** - * Validate that the options passed to the container class are enough for us to proceed - * - * @access private - * @param array - */ - function _validateOptions() - { - if ( ( is_null($this->_options['wsdl']) - && is_null($this->_options['location']) - && is_null($this->_options['uri'])) - || ( is_null($this->_options['wsdl']) - && ( is_null($this->_options['location']) - || is_null($this->_options['uri'])))) { - return PEAR::raiseError('Either a WSDL file or a location/uri pair must be specified.'); - } - if (is_null($this->_options['method'])) { - return PEAR::raiseError('A method to call on the soap service must be specified.'); - } - return true; - } - - // }}} - // {{{ _setDefaults() - - /** - * Set some default options - * - * @access private - * @return void - */ - function _setDefaults() - { - $this->_options['wsdl'] = null; - $this->_options['location'] = null; - $this->_options['uri'] = null; - $this->_options['method'] = null; - $this->_options['usernamefield'] = 'username'; - $this->_options['passwordfield'] = 'password'; - $this->_options['matchpasswords'] = true; - } - - // }}} - -} -?> diff --git a/glmPEAR/Container/vpopmail.php b/glmPEAR/Container/vpopmail.php deleted file mode 100755 index 9ec7bea..0000000 --- a/glmPEAR/Container/vpopmail.php +++ /dev/null @@ -1,88 +0,0 @@ - - * @author Adam Ashley - * @copyright 2001-2006 The PHP Group - * @license http://www.php.net/license/3_01.txt PHP License 3.01 - * @version CVS: $Id: vpopmail.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ - * @link http://pear.php.net/package/Auth - * @since File available since Release 1.2.0 - */ - -/** - * Include Auth_Container base class - */ -require_once "Auth/Container.php"; -/** - * Include PEAR package for error handling - */ -require_once "PEAR.php"; - -/** - * Storage driver for fetching login data from vpopmail - * - * @category Authentication - * @package Auth - * @author Stanislav Grozev - * @author Adam Ashley - * @copyright 2001-2006 The PHP Group - * @license http://www.php.net/license/3_01.txt PHP License 3.01 - * @version Release: 1.5.4 File: $Revision: 1.1.1.1 $ - * @link http://pear.php.net/package/Auth - * @since Class available since Release 1.2.0 - */ -class Auth_Container_vpopmail extends Auth_Container { - - // {{{ Constructor - - /** - * Constructor of the container class - * - * @return void - */ - function Auth_Container_vpopmail() - { - if (!extension_loaded('vpopmail')) { - return PEAR::raiseError('Cannot use VPOPMail authentication, ' - .'VPOPMail extension not loaded!', 41, PEAR_ERROR_DIE); - } - } - - // }}} - // {{{ fetchData() - - /** - * Get user information from vpopmail - * - * @param string Username - has to be valid email address - * @param string Password - * @return boolean - */ - function fetchData($username, $password) - { - $this->log('Auth_Container_vpopmail::fetchData() called.', AUTH_LOG_DEBUG); - $userdata = array(); - $userdata = preg_split("/@/", $username, 2); - $result = @vpopmail_auth_user($userdata[0], $userdata[1], $password); - - return $result; - } - - // }}} - -} -?> diff --git a/glmPEAR/DB.php b/glmPEAR/DB.php deleted file mode 100755 index 922f67a..0000000 --- a/glmPEAR/DB.php +++ /dev/null @@ -1,1114 +0,0 @@ - | -// | Tomas V.V.Cox | -// | Maintainer: Daniel Convissor | -// +----------------------------------------------------------------------+ -// -// $Id: DB.php,v 1.1.1.1 2008/04/28 15:20:46 jamie Exp $ -// -// Database independent query interface. - - -require_once 'PEAR.php'; - -// {{{ constants -// {{{ error codes - -/* - * The method mapErrorCode in each DB_dbtype implementation maps - * native error codes to one of these. - * - * If you add an error code here, make sure you also add a textual - * version of it in DB::errorMessage(). - */ -define('DB_OK', 1); -define('DB_ERROR', -1); -define('DB_ERROR_SYNTAX', -2); -define('DB_ERROR_CONSTRAINT', -3); -define('DB_ERROR_NOT_FOUND', -4); -define('DB_ERROR_ALREADY_EXISTS', -5); -define('DB_ERROR_UNSUPPORTED', -6); -define('DB_ERROR_MISMATCH', -7); -define('DB_ERROR_INVALID', -8); -define('DB_ERROR_NOT_CAPABLE', -9); -define('DB_ERROR_TRUNCATED', -10); -define('DB_ERROR_INVALID_NUMBER', -11); -define('DB_ERROR_INVALID_DATE', -12); -define('DB_ERROR_DIVZERO', -13); -define('DB_ERROR_NODBSELECTED', -14); -define('DB_ERROR_CANNOT_CREATE', -15); -define('DB_ERROR_CANNOT_DELETE', -16); -define('DB_ERROR_CANNOT_DROP', -17); -define('DB_ERROR_NOSUCHTABLE', -18); -define('DB_ERROR_NOSUCHFIELD', -19); -define('DB_ERROR_NEED_MORE_DATA', -20); -define('DB_ERROR_NOT_LOCKED', -21); -define('DB_ERROR_VALUE_COUNT_ON_ROW', -22); -define('DB_ERROR_INVALID_DSN', -23); -define('DB_ERROR_CONNECT_FAILED', -24); -define('DB_ERROR_EXTENSION_NOT_FOUND',-25); -define('DB_ERROR_ACCESS_VIOLATION', -26); -define('DB_ERROR_NOSUCHDB', -27); -define('DB_ERROR_CONSTRAINT_NOT_NULL',-29); - - -// }}} -// {{{ prepared statement-related - - -/* - * These constants are used when storing information about prepared - * statements (using the "prepare" method in DB_dbtype). - * - * The prepare/execute model in DB is mostly borrowed from the ODBC - * extension, in a query the "?" character means a scalar parameter. - * There are two extensions though, a "&" character means an opaque - * parameter. An opaque parameter is simply a file name, the real - * data are in that file (useful for putting uploaded files into your - * database and such). The "!" char means a parameter that must be - * left as it is. - * They modify the quote behavoir: - * DB_PARAM_SCALAR (?) => 'original string quoted' - * DB_PARAM_OPAQUE (&) => 'string from file quoted' - * DB_PARAM_MISC (!) => original string - */ -define('DB_PARAM_SCALAR', 1); -define('DB_PARAM_OPAQUE', 2); -define('DB_PARAM_MISC', 3); - - -// }}} -// {{{ binary data-related - - -/* - * These constants define different ways of returning binary data - * from queries. Again, this model has been borrowed from the ODBC - * extension. - * - * DB_BINMODE_PASSTHRU sends the data directly through to the browser - * when data is fetched from the database. - * DB_BINMODE_RETURN lets you return data as usual. - * DB_BINMODE_CONVERT returns data as well, only it is converted to - * hex format, for example the string "123" would become "313233". - */ -define('DB_BINMODE_PASSTHRU', 1); -define('DB_BINMODE_RETURN', 2); -define('DB_BINMODE_CONVERT', 3); - - -// }}} -// {{{ fetch modes - - -/** - * This is a special constant that tells DB the user hasn't specified - * any particular get mode, so the default should be used. - */ -define('DB_FETCHMODE_DEFAULT', 0); - -/** - * Column data indexed by numbers, ordered from 0 and up - */ -define('DB_FETCHMODE_ORDERED', 1); - -/** - * Column data indexed by column names - */ -define('DB_FETCHMODE_ASSOC', 2); - -/** - * Column data as object properties - */ -define('DB_FETCHMODE_OBJECT', 3); - -/** - * For multi-dimensional results: normally the first level of arrays - * is the row number, and the second level indexed by column number or name. - * DB_FETCHMODE_FLIPPED switches this order, so the first level of arrays - * is the column name, and the second level the row number. - */ -define('DB_FETCHMODE_FLIPPED', 4); - -/* for compatibility */ -define('DB_GETMODE_ORDERED', DB_FETCHMODE_ORDERED); -define('DB_GETMODE_ASSOC', DB_FETCHMODE_ASSOC); -define('DB_GETMODE_FLIPPED', DB_FETCHMODE_FLIPPED); - - -// }}} -// {{{ tableInfo() && autoPrepare()-related - - -/** - * these are constants for the tableInfo-function - * they are bitwised or'ed. so if there are more constants to be defined - * in the future, adjust DB_TABLEINFO_FULL accordingly - */ -define('DB_TABLEINFO_ORDER', 1); -define('DB_TABLEINFO_ORDERTABLE', 2); -define('DB_TABLEINFO_FULL', 3); - -/* - * Used by autoPrepare() - */ -define('DB_AUTOQUERY_INSERT', 1); -define('DB_AUTOQUERY_UPDATE', 2); - - -// }}} -// {{{ portability modes - - -/** - * Portability: turn off all portability features. - * @see DB_common::setOption() - */ -define('DB_PORTABILITY_NONE', 0); - -/** - * Portability: convert names of tables and fields to lower case - * when using the get*(), fetch*() and tableInfo() methods. - * @see DB_common::setOption() - */ -define('DB_PORTABILITY_LOWERCASE', 1); - -/** - * Portability: right trim the data output by get*() and fetch*(). - * @see DB_common::setOption() - */ -define('DB_PORTABILITY_RTRIM', 2); - -/** - * Portability: force reporting the number of rows deleted. - * @see DB_common::setOption() - */ -define('DB_PORTABILITY_DELETE_COUNT', 4); - -/** - * Portability: enable hack that makes numRows() work in Oracle. - * @see DB_common::setOption() - */ -define('DB_PORTABILITY_NUMROWS', 8); - -/** - * Portability: makes certain error messages in certain drivers compatible - * with those from other DBMS's. - * - * + mysql, mysqli: change unique/primary key constraints - * DB_ERROR_ALREADY_EXISTS -> DB_ERROR_CONSTRAINT - * - * + odbc(access): MS's ODBC driver reports 'no such field' as code - * 07001, which means 'too few parameters.' When this option is on - * that code gets mapped to DB_ERROR_NOSUCHFIELD. - * - * @see DB_common::setOption() - */ -define('DB_PORTABILITY_ERRORS', 16); - -/** - * Portability: convert null values to empty strings in data output by - * get*() and fetch*(). - * @see DB_common::setOption() - */ -define('DB_PORTABILITY_NULL_TO_EMPTY', 32); - -/** - * Portability: turn on all portability features. - * @see DB_common::setOption() - */ -define('DB_PORTABILITY_ALL', 63); - -// }}} - - -// }}} -// {{{ class DB - -/** - * The main "DB" class is simply a container class with some static - * methods for creating DB objects as well as some utility functions - * common to all parts of DB. - * - * The object model of DB is as follows (indentation means inheritance): - * - * DB The main DB class. This is simply a utility class - * with some "static" methods for creating DB objects as - * well as common utility functions for other DB classes. - * - * DB_common The base for each DB implementation. Provides default - * | implementations (in OO lingo virtual methods) for - * | the actual DB implementations as well as a bunch of - * | query utility functions. - * | - * +-DB_mysql The DB implementation for MySQL. Inherits DB_common. - * When calling DB::factory or DB::connect for MySQL - * connections, the object returned is an instance of this - * class. - * - * @package DB - * @author Stig Bakken - * @author Tomas V.V.Cox - * @since PHP 4.0 - * @version $Id: DB.php,v 1.1.1.1 2008/04/28 15:20:46 jamie Exp $ - * @category Database - */ -class DB -{ - // {{{ &factory() - - /** - * Create a new DB object for the specified database type. - * - * Allows creation of a DB_ object from which the object's - * methods can be utilized without actually connecting to a database. - * - * @param string $type database type, for example "mysql" - * @param array $options associative array of option names and values - * - * @return object a new DB object. On error, an error object. - * - * @see DB_common::setOption() - * @access public - */ - function &factory($type, $options = false) - { - if (!is_array($options)) { - $options = array('persistent' => $options); - } - - if (isset($options['debug']) && $options['debug'] >= 2) { - // expose php errors with sufficient debug level - include_once "DB/{$type}.php"; - } else { - @include_once "DB/{$type}.php"; - } - - $classname = "DB_${type}"; - - if (!class_exists($classname)) { - $tmp = PEAR::raiseError(null, DB_ERROR_NOT_FOUND, null, null, - "Unable to include the DB/{$type}.php file", - 'DB_Error', true); - return $tmp; - } - - @$obj =& new $classname; - - foreach ($options as $option => $value) { - $test = $obj->setOption($option, $value); - if (DB::isError($test)) { - return $test; - } - } - - return $obj; - } - - // }}} - // {{{ &connect() - - /** - * Create a new DB object and connect to the specified database. - * - * Example 1. - * 2, - * 'portability' => DB_PORTABILITY_ALL, - * ); - * - * $dbh =& DB::connect($dsn, $options); - * if (DB::isError($dbh)) { - * die($dbh->getMessage()); - * } - * ?> - * - * @param mixed $dsn string "data source name" or an array in the - * format returned by DB::parseDSN() - * - * @param array $options an associative array of option names and - * their values - * - * @return object a newly created DB connection object, or a DB - * error object on error - * - * @see DB::parseDSN(), DB_common::setOption(), DB::isError() - * @access public - */ - function &connect($dsn, $options = array()) - { - $dsninfo = DB::parseDSN($dsn); - $type = $dsninfo['phptype']; - - if (!is_array($options)) { - /* - * For backwards compatibility. $options used to be boolean, - * indicating whether the connection should be persistent. - */ - $options = array('persistent' => $options); - } - - if (isset($options['debug']) && $options['debug'] >= 2) { - // expose php errors with sufficient debug level - include_once "DB/${type}.php"; - } else { - @include_once "DB/${type}.php"; - } - - $classname = "DB_${type}"; - if (!class_exists($classname)) { - $tmp = PEAR::raiseError(null, DB_ERROR_NOT_FOUND, null, null, - "Unable to include the DB/{$type}.php file for `$dsn'", - 'DB_Error', true); - return $tmp; - } - - @$obj =& new $classname; - - foreach ($options as $option => $value) { - $test = $obj->setOption($option, $value); - if (DB::isError($test)) { - return $test; - } - } - - $err = $obj->connect($dsninfo, $obj->getOption('persistent')); - if (DB::isError($err)) { - $err->addUserInfo($dsn); - return $err; - } - - return $obj; - } - - // }}} - // {{{ apiVersion() - - /** - * Return the DB API version - * - * @return int the DB API version number - * - * @access public - */ - function apiVersion() - { - return 2; - } - - // }}} - // {{{ isError() - - /** - * Tell whether a result code from a DB method is an error - * - * @param int $value result code - * - * @return bool whether $value is an error - * - * @access public - */ - function isError($value) - { - return is_a($value, 'DB_Error'); - } - - // }}} - // {{{ isConnection() - - /** - * Tell whether a value is a DB connection - * - * @param mixed $value value to test - * - * @return bool whether $value is a DB connection - * - * @access public - */ - 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 query (insert, - * update or delete) or a data definition query (create, drop, - * alter, grant, revoke). - * - * @access public - * - * @param string $query the query - * - * @return boolean whether $query is a data manipulation query - */ - function isManip($query) - { - $manips = 'INSERT|UPDATE|DELETE|LOAD DATA|'.'REPLACE|CREATE|DROP|'. - '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 error code - * - * @return string error message, or false if the error code was - * not recognized - */ - function errorMessage($value) - { - static $errorMessages; - if (!isset($errorMessages)) { - $errorMessages = array( - DB_ERROR => 'unknown error', - DB_ERROR_ALREADY_EXISTS => 'already exists', - DB_ERROR_CANNOT_CREATE => 'can not create', - DB_ERROR_CANNOT_DELETE => 'can not delete', - DB_ERROR_CANNOT_DROP => 'can not drop', - DB_ERROR_CONSTRAINT => 'constraint violation', - DB_ERROR_CONSTRAINT_NOT_NULL=> 'null value violates not-null constraint', - DB_ERROR_DIVZERO => 'division by zero', - DB_ERROR_INVALID => 'invalid', - DB_ERROR_INVALID_DATE => 'invalid date or time', - DB_ERROR_INVALID_NUMBER => 'invalid number', - DB_ERROR_MISMATCH => 'mismatch', - DB_ERROR_NODBSELECTED => 'no database selected', - 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_VALUE_COUNT_ON_ROW => 'value count on row', - DB_ERROR_INVALID_DSN => 'invalid DSN', - DB_ERROR_CONNECT_FAILED => 'connect failed', - DB_OK => 'no error', - DB_ERROR_NEED_MORE_DATA => 'insufficient data supplied', - DB_ERROR_EXTENSION_NOT_FOUND=> 'extension not found', - DB_ERROR_NOSUCHDB => 'no such database', - DB_ERROR_ACCESS_VIOLATION => 'insufficient permissions', - DB_ERROR_TRUNCATED => 'truncated' - ); - } - - if (DB::isError($value)) { - $value = $value->getCode(); - } - - return isset($errorMessages[$value]) ? $errorMessages[$value] : $errorMessages[DB_ERROR]; - } - - // }}} - // {{{ parseDSN() - - /** - * Parse a data source name. - * - * Additional keys can be added by appending a URI query string to the - * end of the DSN. - * - * The format of the supplied DSN is in its fullest form: - * - * phptype(dbsyntax)://username:password@protocol+hostspec/database?option=8&another=true - * - * - * Most variations are allowed: - * - * phptype://username:password@protocol+hostspec:110//usr/db_file.db?mode=0644 - * phptype://username:password@hostspec/database_name - * phptype://username:password@hostspec - * phptype://username@hostspec - * phptype://hostspec/database - * phptype://hostspec - * phptype(dbsyntax) - * phptype - * - * - * @param string $dsn Data Source Name to be parsed - * - * @return array an associative array with the following keys: - * + phptype: Database backend used in PHP (mysql, odbc etc.) - * + dbsyntax: Database used with regards to SQL syntax etc. - * + protocol: Communication protocol to use (tcp, unix etc.) - * + hostspec: Host specification (hostname[:port]) - * + database: Database to use on the DBMS server - * + username: User name for login - * + password: Password for login - * - * @author Tomas V.V.Cox - */ - function parseDSN($dsn) - { - $parsed = array( - 'phptype' => false, - 'dbsyntax' => false, - 'username' => false, - 'password' => false, - 'protocol' => false, - 'hostspec' => false, - 'port' => false, - 'socket' => false, - 'database' => false, - ); - - if (is_array($dsn)) { - $dsn = array_merge($parsed, $dsn); - if (!$dsn['dbsyntax']) { - $dsn['dbsyntax'] = $dsn['phptype']; - } - return $dsn; - } - - // Find phptype and dbsyntax - if (($pos = strpos($dsn, '://')) !== false) { - $str = substr($dsn, 0, $pos); - $dsn = substr($dsn, $pos + 3); - } else { - $str = $dsn; - $dsn = null; - } - - // Get phptype and dbsyntax - // $str => phptype(dbsyntax) - if (preg_match('|^(.+?)\((.*?)\)$|', $str, $arr)) { - $parsed['phptype'] = $arr[1]; - $parsed['dbsyntax'] = !$arr[2] ? $arr[1] : $arr[2]; - } else { - $parsed['phptype'] = $str; - $parsed['dbsyntax'] = $str; - } - - if (!count($dsn)) { - return $parsed; - } - - // Get (if found): username and password - // $dsn => username:password@protocol+hostspec/database - if (($at = strrpos($dsn,'@')) !== false) { - $str = substr($dsn, 0, $at); - $dsn = substr($dsn, $at + 1); - if (($pos = strpos($str, ':')) !== false) { - $parsed['username'] = rawurldecode(substr($str, 0, $pos)); - $parsed['password'] = rawurldecode(substr($str, $pos + 1)); - } else { - $parsed['username'] = rawurldecode($str); - } - } - - // Find protocol and hostspec - - // $dsn => proto(proto_opts)/database - if (preg_match('|^([^(]+)\((.*?)\)/?(.*?)$|', $dsn, $match)) { - $proto = $match[1]; - $proto_opts = $match[2] ? $match[2] : false; - $dsn = $match[3]; - - // $dsn => protocol+hostspec/database (old format) - } else { - if (strpos($dsn, '+') !== false) { - list($proto, $dsn) = explode('+', $dsn, 2); - } - if (strpos($dsn, '/') !== false) { - list($proto_opts, $dsn) = explode('/', $dsn, 2); - } else { - $proto_opts = $dsn; - $dsn = null; - } - } - - // process the different protocol options - $parsed['protocol'] = (!empty($proto)) ? $proto : 'tcp'; - $proto_opts = rawurldecode($proto_opts); - if ($parsed['protocol'] == 'tcp') { - if (strpos($proto_opts, ':') !== false) { - list($parsed['hostspec'], $parsed['port']) = explode(':', $proto_opts); - } else { - $parsed['hostspec'] = $proto_opts; - } - } elseif ($parsed['protocol'] == 'unix') { - $parsed['socket'] = $proto_opts; - } - - // Get dabase if any - // $dsn => database - if ($dsn) { - // /database - if (($pos = strpos($dsn, '?')) === false) { - $parsed['database'] = $dsn; - // /database?param1=value1¶m2=value2 - } else { - $parsed['database'] = substr($dsn, 0, $pos); - $dsn = substr($dsn, $pos + 1); - if (strpos($dsn, '&') !== false) { - $opts = explode('&', $dsn); - } else { // database?param1=value1 - $opts = array($dsn); - } - foreach ($opts as $opt) { - list($key, $value) = explode('=', $opt); - if (!isset($parsed[$key])) { - // don't allow params overwrite - $parsed[$key] = rawurldecode($value); - } - } - } - } - - return $parsed; - } - - // }}} - // {{{ assertExtension() - - /** - * Load a PHP database extension if it is not loaded already. - * - * @access public - * - * @param string $name the base name of the extension (without the .so or - * .dll suffix) - * - * @return boolean true if the extension was already or successfully - * loaded, false if it could not be loaded - */ - function assertExtension($name) - { - if (!extension_loaded($name)) { - $dlext = OS_WINDOWS ? '.dll' : '.so'; - $dlprefix = OS_WINDOWS ? 'php_' : ''; - @dl($dlprefix . $name . $dlext); - return extension_loaded($name); - } - return true; - } - // }}} -} - -// }}} -// {{{ class DB_Error - -/** - * DB_Error implements a class for reporting portable database error - * messages. - * - * @package DB - * @author Stig Bakken - */ -class DB_Error extends PEAR_Error -{ - // {{{ constructor - - /** - * DB_Error constructor. - * - * @param mixed $code DB error code, or string with error message. - * @param integer $mode what "error mode" to operate in - * @param integer $level what error level to use for $mode & PEAR_ERROR_TRIGGER - * @param mixed $debuginfo additional debug info, such as the last query - * - * @access public - * - * @see PEAR_Error - */ - function DB_Error($code = DB_ERROR, $mode = PEAR_ERROR_RETURN, - $level = E_USER_NOTICE, $debuginfo = null) - { - if (is_int($code)) { - $this->PEAR_Error('DB Error: ' . DB::errorMessage($code), $code, $mode, $level, $debuginfo); - } else { - $this->PEAR_Error("DB Error: $code", DB_ERROR, $mode, $level, $debuginfo); - } - } - // }}} -} - -// }}} -// {{{ class DB_result - -/** - * This class implements a wrapper for a DB result set. - * A new instance of this class will be returned by the DB implementation - * after processing a query that returns data. - * - * @package DB - * @author Stig Bakken - */ -class DB_result -{ - // {{{ properties - - var $dbh; - var $result; - var $row_counter = null; - - /** - * for limit queries, the row to start fetching - * @var integer - */ - var $limit_from = null; - - /** - * for limit queries, the number of rows to fetch - * @var integer - */ - var $limit_count = null; - - // }}} - // {{{ constructor - - /** - * DB_result constructor. - * @param resource &$dbh DB object reference - * @param resource $result result resource id - * @param array $options assoc array with optional result options - */ - function DB_result(&$dbh, $result, $options = array()) - { - $this->dbh = &$dbh; - $this->result = $result; - foreach ($options as $key => $value) { - $this->setOption($key, $value); - } - $this->limit_type = $dbh->features['limit']; - $this->autofree = $dbh->options['autofree']; - $this->fetchmode = $dbh->fetchmode; - $this->fetchmode_object_class = $dbh->fetchmode_object_class; - } - - function setOption($key, $value = null) - { - switch ($key) { - case 'limit_from': - $this->limit_from = $value; break; - case 'limit_count': - $this->limit_count = $value; break; - } - } - - // }}} - // {{{ fetchRow() - - /** - * Fetch a row of data and return it by reference into an array. - * - * The type of array returned can be controlled either by setting this - * method's $fetchmode parameter or by changing the default - * fetch mode setFetchMode() before calling this method. - * - * There are two options for standardizing the information returned - * from databases, ensuring their values are consistent when changing - * DBMS's. These portability options can be turned on when creating a - * new DB object or by using setOption(). - * - * + DB_PORTABILITY_LOWERCASE - * convert names of fields to lower case - * - * + DB_PORTABILITY_RTRIM - * right trim the data - * - * @param int $fetchmode how the resulting array should be indexed - * @param int $rownum the row number to fetch - * - * @return array a row of data, null on no more rows or PEAR_Error - * object on error - * - * @see DB_common::setOption(), DB_common::setFetchMode() - * @access public - */ - function &fetchRow($fetchmode = DB_FETCHMODE_DEFAULT, $rownum=null) - { - if ($fetchmode === DB_FETCHMODE_DEFAULT) { - $fetchmode = $this->fetchmode; - } - if ($fetchmode === DB_FETCHMODE_OBJECT) { - $fetchmode = DB_FETCHMODE_ASSOC; - $object_class = $this->fetchmode_object_class; - } - if ($this->limit_from !== null) { - if ($this->row_counter === null) { - $this->row_counter = $this->limit_from; - // Skip rows - if ($this->limit_type == false) { - $i = 0; - while ($i++ < $this->limit_from) { - $this->dbh->fetchInto($this->result, $arr, $fetchmode); - } - } - } - if ($this->row_counter >= ( - $this->limit_from + $this->limit_count)) - { - if ($this->autofree) { - $this->free(); - } - $tmp = null; - return $tmp; - } - if ($this->limit_type == 'emulate') { - $rownum = $this->row_counter; - } - $this->row_counter++; - } - $res = $this->dbh->fetchInto($this->result, $arr, $fetchmode, $rownum); - if ($res === DB_OK) { - if (isset($object_class)) { - // default mode specified in DB_common::fetchmode_object_class property - if ($object_class == 'stdClass') { - $arr = (object) $arr; - } else { - $arr = &new $object_class($arr); - } - } - return $arr; - } - if ($res == null && $this->autofree) { - $this->free(); - } - return $res; - } - - // }}} - // {{{ fetchInto() - - /** - * Fetch a row of data into an array which is passed by reference. - * - * The type of array returned can be controlled either by setting this - * method's $fetchmode parameter or by changing the default - * fetch mode setFetchMode() before calling this method. - * - * There are two options for standardizing the information returned - * from databases, ensuring their values are consistent when changing - * DBMS's. These portability options can be turned on when creating a - * new DB object or by using setOption(). - * - * + DB_PORTABILITY_LOWERCASE - * convert names of fields to lower case - * - * + DB_PORTABILITY_RTRIM - * right trim the data - * - * @param array &$arr (reference) array where data from the row - * should be placed - * @param int $fetchmode how the resulting array should be indexed - * @param int $rownum the row number to fetch - * - * @return mixed DB_OK on success, null on no more rows or - * a DB_Error object on error - * - * @see DB_common::setOption(), DB_common::setFetchMode() - * @access public - */ - function fetchInto(&$arr, $fetchmode = DB_FETCHMODE_DEFAULT, $rownum=null) - { - if ($fetchmode === DB_FETCHMODE_DEFAULT) { - $fetchmode = $this->fetchmode; - } - if ($fetchmode === DB_FETCHMODE_OBJECT) { - $fetchmode = DB_FETCHMODE_ASSOC; - $object_class = $this->fetchmode_object_class; - } - if ($this->limit_from !== null) { - if ($this->row_counter === null) { - $this->row_counter = $this->limit_from; - // Skip rows - if ($this->limit_type == false) { - $i = 0; - while ($i++ < $this->limit_from) { - $this->dbh->fetchInto($this->result, $arr, $fetchmode); - } - } - } - if ($this->row_counter >= ( - $this->limit_from + $this->limit_count)) - { - if ($this->autofree) { - $this->free(); - } - return null; - } - if ($this->limit_type == 'emulate') { - $rownum = $this->row_counter; - } - - $this->row_counter++; - } - $res = $this->dbh->fetchInto($this->result, $arr, $fetchmode, $rownum); - if ($res === DB_OK) { - if (isset($object_class)) { - // default mode specified in DB_common::fetchmode_object_class property - if ($object_class == 'stdClass') { - $arr = (object) $arr; - } else { - $arr = new $object_class($arr); - } - } - return DB_OK; - } - if ($res == null && $this->autofree) { - $this->free(); - } - return $res; - } - - // }}} - // {{{ numCols() - - /** - * Get the the number of columns in a result set. - * - * @return int the number of columns, or a DB error - * - * @access public - */ - function numCols() - { - return $this->dbh->numCols($this->result); - } - - // }}} - // {{{ numRows() - - /** - * Get the number of rows in a result set. - * - * @return int the number of rows, or a DB error - * - * @access public - */ - function numRows() - { - return $this->dbh->numRows($this->result); - } - - // }}} - // {{{ nextResult() - - /** - * Get the next result if a batch of queries was executed. - * - * @return bool true if a new result is available or false if not. - * - * @access public - */ - function nextResult() - { - return $this->dbh->nextResult($this->result); - } - - // }}} - // {{{ free() - - /** - * Frees the resources allocated for this result set. - * @return int error code - * - * @access public - */ - function free() - { - $err = $this->dbh->freeResult($this->result); - if (DB::isError($err)) { - return $err; - } - $this->result = false; - return true; - } - - // }}} - // {{{ tableInfo() - - /** - * @deprecated - * @internal - * @see DB_common::tableInfo() - */ - function tableInfo($mode = null) - { - if (is_string($mode)) { - return $this->dbh->raiseError(DB_ERROR_NEED_MORE_DATA); - } - return $this->dbh->tableInfo($this, $mode); - } - - // }}} - // {{{ getRowCounter() - - /** - * returns the actual row number - * @return integer - */ - function getRowCounter() - { - return $this->row_counter; - } - // }}} -} - -// }}} -// {{{ class DB_row - -/** - * Pear DB Row Object - * @see DB_common::setFetchMode() - */ -class DB_row -{ - // {{{ constructor - - /** - * constructor - * - * @param resource row data as array - */ - function DB_row(&$arr) - { - foreach ($arr as $key => $value) { - $this->$key = &$arr[$key]; - } - } - - // }}} -} - -// }}} - -/* - * Local variables: - * tab-width: 4 - * c-basic-offset: 4 - * End: - */ - -?> diff --git a/glmPEAR/DB/DataObject.php b/glmPEAR/DB/DataObject.php deleted file mode 100755 index d782516..0000000 --- a/glmPEAR/DB/DataObject.php +++ /dev/null @@ -1,3543 +0,0 @@ - -// +----------------------------------------------------------------------+ -/** - * Object Based Database Query Builder and data store - * - * @package DB_DataObject - * @category DB - * - * $Id: DataObject.php,v 1.1.1.1 2008/04/28 15:20:47 jamie Exp $ - */ - -/* =========================================================================== -* -* !!!!!!!!!!!!! W A R N I N G !!!!!!!!!!! -* -* THIS MAY SEGFAULT PHP IF YOU ARE USING THE ZEND OPTIMIZER (to fix it, -* just add "define('DB_DATAOBJECT_NO_OVERLOAD',true);" before you include -* this file. reducing the optimization level may also solve the segfault. -* =========================================================================== -*/ - -/** - * The main "DB_DataObject" class is really a base class for your own tables classes - * - * // Set up the class by creating an ini file (refer to the manual for more details - * [DB_DataObject] - * database = mysql:/username:password@host/database - * schema_location = /home/myapplication/database - * class_location = /home/myapplication/DBTables/ - * clase_prefix = DBTables_ - * - * - * //Start and initialize...................... - dont forget the & - * $config = parse_ini_file('example.ini',true); - * $options = &PEAR::getStaticProperty('DB_DataObject','options'); - * $options = $config['DB_DataObject']; - * - * // example of a class (that does not use the 'auto generated tables data') - * class mytable extends DB_DataObject { - * // mandatory - set the table - * var $_database_dsn = "mysql://username:password@localhost/database"; - * var $__table = "mytable"; - * function table() { - * return array( - * 'id' => 1, // integer or number - * 'name' => 2, // string - * ); - * } - * function keys() { - * return array('id'); - * } - * } - * - * // use in the application - * - * - * Simple get one row - * - * $instance = new mytable; - * $instance->get("id",12); - * echo $instance->somedata; - * - * - * Get multiple rows - * - * $instance = new mytable; - * $instance->whereAdd("ID > 12"); - * $instance->whereAdd("ID < 14"); - * $instance->find(); - * while ($instance->fetch()) { - * echo $instance->somedata; - * } - - -/** - * Needed classes - * - we use getStaticProperty from PEAR pretty extensively (cant remove it ATM) - */ - -require_once 'PEAR.php'; - -/** - * these are constants for the get_table array - * user to determine what type of escaping is required around the object vars. - */ -define('DB_DATAOBJECT_INT', 1); // does not require '' -define('DB_DATAOBJECT_STR', 2); // requires '' - -define('DB_DATAOBJECT_DATE', 4); // is date #TODO -define('DB_DATAOBJECT_TIME', 8); // is time #TODO -define('DB_DATAOBJECT_BOOL', 16); // is boolean #TODO -define('DB_DATAOBJECT_TXT', 32); // is long text #TODO -define('DB_DATAOBJECT_BLOB', 64); // is blob type - - -define('DB_DATAOBJECT_NOTNULL', 128); // not null col. -define('DB_DATAOBJECT_MYSQLTIMESTAMP' , 256); // mysql timestamps (ignored by update/insert) -/* - * Define this before you include DataObjects.php to disable overload - if it segfaults due to Zend optimizer.. - */ -//define('DB_DATAOBJECT_NO_OVERLOAD',true) - - -/** - * Theses are the standard error codes, most methods will fail silently - and return false - * to access the error message either use $table->_lastError - * or $last_error = PEAR::getStaticProperty('DB_DataObject','lastError'); - * the code is $last_error->code, and the message is $last_error->message (a standard PEAR error) - */ - -define('DB_DATAOBJECT_ERROR_INVALIDARGS', -1); // wrong args to function -define('DB_DATAOBJECT_ERROR_NODATA', -2); // no data available -define('DB_DATAOBJECT_ERROR_INVALIDCONFIG', -3); // something wrong with the config -define('DB_DATAOBJECT_ERROR_NOCLASS', -4); // no class exists -define('DB_DATAOBJECT_ERROR_NOTSUPPORTED' ,-6); // limit queries on unsuppored databases -define('DB_DATAOBJECT_ERROR_INVALID_CALL' ,-7); // overlad getter/setter failure - -/** - * Used in methods like delete() and count() to specify that the method should - * build the condition only out of the whereAdd's and not the object parameters. - */ -define('DB_DATAOBJECT_WHEREADD_ONLY', true); - -/** - * - * storage for connection and result objects, - * it is done this way so that print_r()'ing the is smaller, and - * it reduces the memory size of the object. - * -- future versions may use $this->_connection = & PEAR object.. - * although will need speed tests to see how this affects it. - * - includes sub arrays - * - connections = md5 sum mapp to pear db object - * - results = [id] => map to pear db object - * - resultseq = sequence id for results & results field - * - resultfields = [id] => list of fields return from query (for use with toArray()) - * - ini = mapping of database to ini file results - * - links = mapping of database to links file - * - lasterror = pear error objects for last error event. - * - config = aliased view of PEAR::getStaticPropery('DB_DataObject','options') * done for performance. - * - array of loaded classes by autoload method - to stop it doing file access request over and over again! - */ -$GLOBALS['_DB_DATAOBJECT']['RESULTS'] = array(); -$GLOBALS['_DB_DATAOBJECT']['RESULTSEQ'] = 1; -$GLOBALS['_DB_DATAOBJECT']['RESULTFIELDS'] = array(); -$GLOBALS['_DB_DATAOBJECT']['CONNECTIONS'] = array(); -$GLOBALS['_DB_DATAOBJECT']['INI'] = array(); -$GLOBALS['_DB_DATAOBJECT']['LINKS'] = array(); -$GLOBALS['_DB_DATAOBJECT']['SEQUENCE'] = array(); -$GLOBALS['_DB_DATAOBJECT']['LASTERROR'] = null; -$GLOBALS['_DB_DATAOBJECT']['CONFIG'] = array(); -$GLOBALS['_DB_DATAOBJECT']['CACHE'] = array(); -$GLOBALS['_DB_DATAOBJECT']['OVERLOADED'] = false; -$GLOBALS['_DB_DATAOBJECT']['QUERYENDTIME'] = 0; - - - -// this will be horrifically slow!!!! -// NOTE: Overload SEGFAULTS ON PHP4 + Zend Optimizer (see define before..) -// these two are BC/FC handlers for call in PHP4/5 - -if ( substr(phpversion(),0,1) == 5) { - class DB_DataObject_Overload { - function __call($method,$args) { - $return = null; - $this->_call($method,$args,$return); - return $return; - } - } -} else { - if (!function_exists('clone')) { - eval('function clone($t) { return $t; }'); - } - eval(' - class DB_DataObject_Overload { - function __call($method,$args,&$return) { - return $this->_call($method,$args,$return); - } - } - '); -} - - - - - - - /* - * - * @package DB_DataObject - * @author Alan Knowles - * @since PHP 4.0 - */ - -class DB_DataObject extends DB_DataObject_Overload -{ - /** - * The Version - use this to check feature changes - * - * @access private - * @var string - */ - var $_DB_DataObject_version = "1.7.2"; - - /** - * The Database table (used by table extends) - * - * @access private - * @var string - */ - var $__table = ''; // database table - - /** - * The Number of rows returned from a query - * - * @access public - * @var int - */ - var $N = 0; // Number of rows returned from a query - - - /* ============================================================= */ - /* Major Public Methods */ - /* (designed to be optionally then called with parent::method()) */ - /* ============================================================= */ - - - /** - * Get a result using key, value. - * - * for example - * $object->get("ID",1234); - * Returns Number of rows located (usually 1) for success, - * and puts all the table columns into this classes variables - * - * see the fetch example on how to extend this. - * - * if no value is entered, it is assumed that $key is a value - * and get will then use the first key in keys() - * to obtain the key. - * - * @param string $k column - * @param string $v value - * @access public - * @return int No. of rows - */ - function get($k = null, $v = null) - { - global $_DB_DATAOBJECT; - if (empty($_DB_DATAOBJECT['CONFIG'])) { - DB_DataObject::_loadConfig(); - } - $keys = array(); - - if ($v === null) { - $v = $k; - $keys = $this->keys(); - if (!$keys) { - $this->raiseError("No Keys available for {$this->__table}", DB_DATAOBJECT_ERROR_INVALIDCONFIG); - return false; - } - $k = $keys[0]; - } - if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) { - $this->debug("$k $v " .print_r($keys,true), "GET"); - } - - if ($v === null) { - $this->raiseError("No Value specified for get", DB_DATAOBJECT_ERROR_INVALIDARGS); - return false; - } - $this->$k = $v; - return $this->find(1); - } - - /** - * An autoloading, caching static get method using key, value (based on get) - * - * Usage: - * $object = DB_DataObject::staticGet("DbTable_mytable",12); - * or - * $object = DB_DataObject::staticGet("DbTable_mytable","name","fred"); - * - * or write it into your extended class: - * function &staticGet($k,$v=NULL) { return DB_DataObject::staticGet("This_Class",$k,$v); } - * - * @param string $class class name - * @param string $k column (or value if using keys) - * @param string $v value (optional) - * @access public - * @return object - */ - function &staticGet($class, $k, $v = null) - { - $lclass = strtolower($class); - global $_DB_DATAOBJECT; - if (empty($_DB_DATAOBJECT['CONFIG'])) { - DB_DataObject::_loadConfig(); - } - - - - $key = "$k:$v"; - if ($v === null) { - $key = $k; - } - if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) { - DB_DataObject::debug("$class $key","STATIC GET - TRY CACHE"); - } - if (!empty($_DB_DATAOBJECT['CACHE'][$lclass][$key])) { - return $_DB_DATAOBJECT['CACHE'][$lclass][$key]; - } - if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) { - DB_DataObject::debug("$class $key","STATIC GET - NOT IN CACHE"); - } - - $obj = DB_DataObject::factory(substr($class,strlen($_DB_DATAOBJECT['CONFIG']['class_prefix']))); - if (PEAR::isError($obj)) { - DB_DataObject::raiseError("could not autoload $class", DB_DATAOBJECT_ERROR_NOCLASS); - return false; - } - - if (!isset($_DB_DATAOBJECT['CACHE'][$lclass])) { - $_DB_DATAOBJECT['CACHE'][$lclass] = array(); - } - if (!$obj->get($k,$v)) { - DB_DataObject::raiseError("No Data return from get $k $v", DB_DATAOBJECT_ERROR_NODATA); - return false; - } - $_DB_DATAOBJECT['CACHE'][$lclass][$key] = $obj; - return $_DB_DATAOBJECT['CACHE'][$lclass][$key]; - } - - /** - * find results, either normal or crosstable - * - * for example - * - * $object = new mytable(); - * $object->ID = 1; - * $object->find(); - * - * - * will set $object->N to number of rows, and expects next command to fetch rows - * will return $object->N - * - * @param boolean $n Fetch first result - * @access public - * @return int - */ - function find($n = false) - { - global $_DB_DATAOBJECT; - if (!isset($this->_query)) { - $this->raiseError( - "You cannot do two queries on the same object (copy it before finding)", - DB_DATAOBJECT_ERROR_INVALIDARGS); - return false; - } - - if (empty($_DB_DATAOBJECT['CONFIG'])) { - DB_DataObject::_loadConfig(); - } - - if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) { - $this->debug($n, "__find",1); - } - if (!$this->__table) { - echo "NO \$__table SPECIFIED in class definition"; - exit; - } - $this->N = 0; - $query_before = $this->_query; - $this->_build_condition($this->table()) ; - - $quoteIdentifiers = !empty($_DB_DATAOBJECT['CONFIG']['quote_identifiers']); - $this->_connect(); - $DB = &$_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5]; - - - $this->_query('SELECT ' . - $this->_query['data_select'] . - ' FROM ' . ($quoteIdentifiers ? $DB->quoteIdentifier($this->__table) : $this->__table) . " " . - $this->_join . - $this->_query['condition'] . ' '. - $this->_query['group_by'] . ' '. - $this->_query['having'] . ' '. - $this->_query['order_by'] . ' '. - - $this->_query['limit']); // is select - - if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) { - $this->debug("CHECK autofetchd $n", "__find", 1); - } - // unset the - - - if ($n && $this->N > 0 ) { - if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) { - $this->debug("ABOUT TO AUTOFETCH", "__find", 1); - } - $this->fetch() ; - } - if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) { - $this->debug("DONE", "__find", 1); - } - $this->_query = $query_before; - return $this->N; - } - - /** - * fetches next row into this objects var's - * - * returns 1 on success 0 on failure - * - * - * - * Example - * $object = new mytable(); - * $object->name = "fred"; - * $object->find(); - * $store = array(); - * while ($object->fetch()) { - * echo $this->ID; - * $store[] = $object; // builds an array of object lines. - * } - * - * to add features to a fetch - * function fetch () { - * $ret = parent::fetch(); - * $this->date_formated = date('dmY',$this->date); - * return $ret; - * } - * - * @access public - * @return boolean on success - */ - function fetch() - { - - global $_DB_DATAOBJECT; - if (empty($_DB_DATAOBJECT['CONFIG'])) { - DB_DataObject::_loadConfig(); - } - if (empty($this->N)) { - if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) { - $this->debug("No data returned from FIND (eg. N is 0)","FETCH", 3); - } - return false; - } - - if (empty($_DB_DATAOBJECT['RESULTS'][$this->_DB_resultid]) || - !is_object($result = &$_DB_DATAOBJECT['RESULTS'][$this->_DB_resultid])) - { - if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) { - $this->debug('fetched on object after fetch completed (no results found)'); - } - return false; - } - - - $array = $result->fetchRow(DB_FETCHMODE_ASSOC); - if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) { - $this->debug(serialize($array),"FETCH"); - } - - if ($array === null) { - if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) { - $t= explode(' ',microtime()); - - $this->debug("Last Data Fetch'ed after " . - ($t[0]+$t[1]- $_DB_DATAOBJECT['QUERYENDTIME'] ) . - " seconds", - "FETCH", 1); - } - // reduce the memory usage a bit... (but leave the id in, so count() works ok on it) - unset($_DB_DATAOBJECT['RESULTS'][$this->_DB_resultid]); - - // this is probably end of data!! - //DB_DataObject::raiseError("fetch: no data returned", DB_DATAOBJECT_ERROR_NODATA); - return false; - } - - if (!isset($_DB_DATAOBJECT['RESULTFIELDS'][$this->_DB_resultid])) { - // note: we dont declare this to keep the print_r size down. - $_DB_DATAOBJECT['RESULTFIELDS'][$this->_DB_resultid]= array_flip(array_keys($array)); - } - - foreach($array as $k=>$v) { - $kk = str_replace(".", "_", $k); - $kk = str_replace(" ", "_", $kk); - if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) { - $this->debug("$kk = ". $array[$k], "fetchrow LINE", 3); - } - $this->$kk = $array[$k]; - } - - // set link flag - $this->_link_loaded=false; - if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) { - $this->debug("{$this->__table} DONE", "fetchrow",2); - } - if (isset($this->_query) && empty($_DB_DATAOBJECT['CONFIG']['keep_query_after_fetch'])) { - unset($this->_query); - } - return true; - } - - /** - * Adds a condition to the WHERE statement, defaults to AND - * - * $object->whereAdd(); //reset or cleaer ewhwer - * $object->whereAdd("ID > 20"); - * $object->whereAdd("age > 20","OR"); - * - * @param string $cond condition - * @param string $logic optional logic "OR" (defaults to "AND") - * @access public - * @return string|PEAR::Error - previous condition or Error when invalid args found - */ - function whereAdd($cond = false, $logic = 'AND') - { - if (!isset($this->_query)) { - return $this->raiseError( - "You cannot do two queries on the same object (clone it before finding)", - DB_DATAOBJECT_ERROR_INVALIDARGS); - } - - if ($cond === false) { - $r = $this->_query['condition']; - $this->_query['condition'] = ''; - return $r; - } - // check input...= 0 or ' ' == error! - if (!trim($cond)) { - return $this->raiseError("WhereAdd: No Valid Arguments", DB_DATAOBJECT_ERROR_INVALIDARGS); - } - $r = $this->_query['condition']; - if ($this->_query['condition']) { - $this->_query['condition'] .= " {$logic} {$cond}"; - return $r; - } - $this->_query['condition'] = " WHERE {$cond}"; - return $r; - } - - /** - * Adds a order by condition - * - * $object->orderBy(); //clears order by - * $object->orderBy("ID"); - * $object->orderBy("ID,age"); - * - * @param string $order Order - * @access public - * @return none|PEAR::Error - invalid args only - */ - function orderBy($order = false) - { - if (!isset($this->_query)) { - $this->raiseError( - "You cannot do two queries on the same object (copy it before finding)", - DB_DATAOBJECT_ERROR_INVALIDARGS); - return false; - } - if ($order === false) { - $this->_query['order_by'] = ''; - return; - } - // check input...= 0 or ' ' == error! - if (!trim($order)) { - return $this->raiseError("orderBy: No Valid Arguments", DB_DATAOBJECT_ERROR_INVALIDARGS); - } - - if (!$this->_query['order_by']) { - $this->_query['order_by'] = " ORDER BY {$order} "; - return; - } - $this->_query['order_by'] .= " , {$order}"; - } - - /** - * Adds a group by condition - * - * $object->groupBy(); //reset the grouping - * $object->groupBy("ID DESC"); - * $object->groupBy("ID,age"); - * - * @param string $group Grouping - * @access public - * @return none|PEAR::Error - invalid args only - */ - function groupBy($group = false) - { - if (!isset($this->_query)) { - $this->raiseError( - "You cannot do two queries on the same object (copy it before finding)", - DB_DATAOBJECT_ERROR_INVALIDARGS); - return false; - } - if ($group === false) { - $this->_query['group_by'] = ''; - return; - } - // check input...= 0 or ' ' == error! - if (!trim($group)) { - return $this->raiseError("groupBy: No Valid Arguments", DB_DATAOBJECT_ERROR_INVALIDARGS); - } - - - if (!$this->_query['group_by']) { - $this->_query['group_by'] = " GROUP BY {$group} "; - return; - } - $this->_query['group_by'] .= " , {$group}"; - } - - /** - * Adds a having clause - * - * $object->having(); //reset the grouping - * $object->having("sum(value) > 0 "); - * - * @param string $having condition - * @access public - * @return none|PEAR::Error - invalid args only - */ - function having($having = false) - { - if (!isset($this->_query)) { - $this->raiseError( - "You cannot do two queries on the same object (copy it before finding)", - DB_DATAOBJECT_ERROR_INVALIDARGS); - return false; - } - if ($having === false) { - $this->_query['having'] = ''; - return; - } - // check input...= 0 or ' ' == error! - if (!trim($having)) { - return $this->raiseError("Having: No Valid Arguments", DB_DATAOBJECT_ERROR_INVALIDARGS); - } - - - if (!$this->_query['having']) { - $this->_query['having'] = " HAVING {$having} "; - return; - } - $this->_query['having'] .= " , {$having}"; - } - - /** - * Sets the Limit - * - * $boject->limit(); // clear limit - * $object->limit(12); - * $object->limit(12,10); - * - * Note this will emit an error on databases other than mysql/postgress - * as there is no 'clean way' to implement it. - you should consider refering to - * your database manual to decide how you want to implement it. - * - * @param string $a limit start (or number), or blank to reset - * @param string $b number - * @access public - * @return none|PEAR::Error - invalid args only - */ - function limit($a = null, $b = null) - { - if (!isset($this->_query)) { - $this->raiseError( - "You cannot do two queries on the same object (copy it before finding)", - DB_DATAOBJECT_ERROR_INVALIDARGS); - return false; - } - - if ($a === null) { - $this->_query['limit'] = ''; - return; - } - // check input...= 0 or ' ' == error! - if ((!is_int($a) && ((string)((int)$a) !== (string)$a)) - || (($b !== null) && (!is_int($b) && ((string)((int)$b) !== (string)$b)))) { - return $this->raiseError("limit: No Valid Arguments", DB_DATAOBJECT_ERROR_INVALIDARGS); - } - global $_DB_DATAOBJECT; - $this->_connect(); - $DB = &$_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5]; - - if (($DB->features['limit'] == 'alter') && ($DB->phptype != 'oci8')) { - if ($b === null) { - $this->_query['limit'] = " LIMIT $a"; - return; - } - - $this->_query['limit'] = $DB->modifyLimitQuery('',$a,$b); - - } else { - $this->raiseError( - "DB_DataObjects only supports limit queries on some databases,\n". - "Check with pear bugs for the package, or the dataobjects manual.\n", - "or Refer to your Database manual to find out how to do limit queries manually.\n", - DB_DATAOBJECT_ERROR_NOTSUPPORTED, PEAR_ERROR_DIE); - } - } - - /** - * Adds a select columns - * - * $object->selectAdd(); // resets select to nothing! - * $object->selectAdd("*"); // default select - * $object->selectAdd("unixtime(DATE) as udate"); - * $object->selectAdd("DATE"); - * - * to prepend distict: - * $object->selectAdd('distinct ' . $object->selectAdd()); - * - * @param string $k - * @access public - * @return mixed null or old string if you reset it. - */ - function selectAdd($k = null) - { - if (!isset($this->_query)) { - $this->raiseError( - "You cannot do two queries on the same object (copy it before finding)", - DB_DATAOBJECT_ERROR_INVALIDARGS); - return false; - } - if ($k === null) { - $old = $this->_query['data_select']; - $this->_query['data_select'] = ''; - return $old; - } - - // check input...= 0 or ' ' == error! - if (!trim($k)) { - return $this->raiseError("selectAdd: No Valid Arguments", DB_DATAOBJECT_ERROR_INVALIDARGS); - } - - if ($this->_query['data_select']) { - $this->_query['data_select'] .= ', '; - } - $this->_query['data_select'] .= " $k "; - } - /** - * Adds multiple Columns or objects to select with formating. - * - * $object->selectAs(null); // adds "table.colnameA as colnameA,table.colnameB as colnameB,......" - * // note with null it will also clear the '*' default select - * $object->selectAs(array('a','b'),'%s_x'); // adds "a as a_x, b as b_x" - * $object->selectAs(array('a','b'),'ddd_%s','ccc'); // adds "ccc.a as ddd_a, ccc.b as ddd_b" - * $object->selectAdd($object,'prefix_%s'); // calls $object->get_table and adds it all as - * objectTableName.colnameA as prefix_colnameA - * - * @param array|object|null the array or object to take column names from. - * @param string format in sprintf format (use %s for the colname) - * @param string table name eg. if you have joinAdd'd or send $from as an array. - * @access public - * @return void - */ - function selectAs($from = null,$format = '%s',$tableName=false) - { - global $_DB_DATAOBJECT; - - if (!isset($this->_query)) { - $this->raiseError( - "You cannot do two queries on the same object (copy it before finding)", - DB_DATAOBJECT_ERROR_INVALIDARGS); - return false; - } - - if ($from === null) { - // blank the '*' - $this->selectAdd(); - $from = $this; - } - - - $table = $this->__table; - if (is_object($from)) { - $table = $from->__table; - $from = array_keys($from->table()); - } - - if ($tableName !== false) { - $table = $tableName; - } - $s = '%s'; - if (!empty($_DB_DATAOBJECT['CONFIG']['quote_identifiers'])) { - $this->_connect(); - $DB = &$_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5]; - $s = $DB->quoteIdentifier($s); - } - foreach ($from as $k) { - $this->selectAdd(sprintf("{$s}.{$s} as {$format}",$table,$k,$k)); - } - $this->_query['data_select'] .= "\n"; - } - /** - * Insert the current objects variables into the database - * - * Returns the ID of the inserted element - mysql specific = fixme? - * - * for example - * - * Designed to be extended - * - * $object = new mytable(); - * $object->name = "fred"; - * echo $object->insert(); - * - * @access public - * @return mixed True on success, false on failure, 0 on no data affected - */ - function insert() - { - global $_DB_DATAOBJECT; - - // we need to write to the connection (For nextid) - so us the real - // one not, a copyied on (as ret-by-ref fails with overload!) - - if (!isset($_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5])) { - $this->_connect(); - } - - $quoteIdentifiers = !empty($_DB_DATAOBJECT['CONFIG']['quote_identifiers']); - - $DB = &$_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5]; - - $items = isset($_DB_DATAOBJECT['INI'][$this->_database][$this->__table]) ? - $_DB_DATAOBJECT['INI'][$this->_database][$this->__table] : $this->table(); - - if (!$items) { - $this->raiseError("insert:No table definition for {$this->__table}", DB_DATAOBJECT_ERROR_INVALIDCONFIG); - return false; - } - $options= &$_DB_DATAOBJECT['CONFIG']; - - - $datasaved = 1; - $leftq = ''; - $rightq = ''; - - $seqKeys = isset($_DB_DATAOBJECT['SEQUENCE'][$this->_database][$this->__table]) ? - $_DB_DATAOBJECT['SEQUENCE'][$this->_database][$this->__table] : - $this->sequenceKey(); - - $key = isset($seqKeys[0]) ? $seqKeys[0] : false; - $useNative = isset($seqKeys[1]) ? $seqKeys[1] : false; - $seq = isset($seqKeys[2]) ? $seqKeys[2] : false; - - $dbtype = $_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5]->dsn["phptype"]; - - - // nativeSequences or Sequences.. - - // big check for using sequences - - if (($key !== false) && !$useNative) { - - if (!$seq) { - $this->$key = $DB->nextId($this->__table); - } else { - $f = $DB->getOption('seqname_format'); - $DB->setOption('seqname_format','%s'); - $this->$key = $DB->nextId($seq); - $DB->setOption('seqname_format',$f); - } - } - - - - foreach($items as $k => $v) { - - // if we are using autoincrement - skip the column... - if ($key && ($k == $key) && $useNative) { - continue; - } - - - if (!isset($this->$k)) { - continue; - } - // dont insert data into mysql timestamps - // use query() if you really want to do this!!!! - if ($v & DB_DATAOBJECT_MYSQLTIMESTAMP) { - continue; - } - - if ($leftq) { - $leftq .= ', '; - $rightq .= ', '; - } - - $leftq .= ($quoteIdentifiers ? ($DB->quoteIdentifier($k) . ' ') : "$k "); - - if (is_a($this->$k,'db_dataobject_cast')) { - $value = $this->$k->toString($v,$dbtype); - if (PEAR::isError($value)) { - $this->raiseError($value->getMessage() ,DB_DATAOBJECT_ERROR_INVALIDARG); - return false; - } - $rightq .= $value; - continue; - } - - - if ((strtolower($this->$k) === 'null') && !($v & DB_DATAOBJECT_NOTNULL)) { - $rightq .= " NULL "; - continue; - } - // DATE is empty... on a col. that can be null.. - // note: this may be usefull for time as well.. - if (!$this->$k && - (($v & DB_DATAOBJECT_DATE) || ($v & DB_DATAOBJECT_TIME)) && - !($v & DB_DATAOBJECT_NOTNULL)) { - - $rightq .= " NULL "; - continue; - } - - if ($v & DB_DATAOBJECT_STR) { - $rightq .= $DB->quote($this->$k) . " "; - continue; - } - if (is_numeric($this->$k)) { - $rightq .=" {$this->$k} "; - continue; - } - // at present we only cast to integers - // - V2 may store additional data about float/int - $rightq .= ' ' . intval($this->$k) . ' '; - - } - - - if ($leftq || $useNative) { - $table = ($quoteIdentifiers ? $DB->quoteIdentifier($this->__table) : $this->__table); - - $r = $this->_query("INSERT INTO {$table} ($leftq) VALUES ($rightq) "); - - - - if (PEAR::isError($r)) { - $this->raiseError($r); - return false; - } - - if ($r < 1) { - return 0; - } - - - // now do we have an integer key! - - if ($key && $useNative) { - switch ($dbtype) { - case 'mysql': - $this->$key = mysql_insert_id( - $_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5]->connection - ); - break; - case 'mssql': - // note this is not really thread safe - you should wrapp it with - // transactions = eg. - // $db->query('BEGIN'); - // $db->insert(); - // $db->query('COMMIT'); - - $mssql_key = $DB->getOne("SELECT @@IDENTITY"); - if (PEAR::isError($mssql_key)) { - $this->raiseError($r); - return false; - } - $this->$key = $mssql_key; - break; - - case 'pgsql': - if (!$seq) { - $seq = $DB->getSequenceName($this->__table ); - } - $pgsql_key = $DB->getOne("SELECT last_value FROM ".$seq); - if (PEAR::isError($pgsql_key)) { - $this->raiseError($r); - return false; - } - $this->$key = $pgsql_key; - break; - } - - } - - if (isset($_DB_DATAOBJECT['CACHE'][strtolower(get_class($this))])) { - $this->_clear_cache(); - } - if ($key) { - return $this->$key; - } - return true; - } - $this->raiseError("insert: No Data specifed for query", DB_DATAOBJECT_ERROR_NODATA); - return false; - } - - /** - * Updates current objects variables into the database - * uses the keys() to decide how to update - * Returns the true on success - * - * for example - * - * $object = new mytable(); - * $object->get("ID",234); - * $object->email="testing@test.com"; - * if(!$object->update()) - * echo "UPDATE FAILED"; - * - * to only update changed items : - * $dataobject->get(132); - * $original = $dataobject; // clone/copy it.. - * $dataobject->setFrom($_POST); - * if ($dataobject->validate()) { - * $dataobject->update($original); - * } // otherwise an error... - * - * - * @param object dataobject (optional) - used to only update changed items. - * @access public - * @return int rows affected or false on failure - */ - function update($dataObject = false) - { - global $_DB_DATAOBJECT; - // connect will load the config! - $this->_connect(); - - - $original_query = isset($this->_query) ? $this->_query : null; - - $items = isset($_DB_DATAOBJECT['INI'][$this->_database][$this->__table]) ? - $_DB_DATAOBJECT['INI'][$this->_database][$this->__table] : $this->table(); - - - $keys = $this->keys(); - - - if (!$items) { - $this->raiseError("update:No table definition for {$this->__table}", DB_DATAOBJECT_ERROR_INVALIDCONFIG); - return false; - } - $datasaved = 1; - $settings = ''; - $this->_connect(); - - $DB = &$_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5]; - $dbtype = $DB->dsn["phptype"]; - $quoteIdentifiers = !empty($_DB_DATAOBJECT['CONFIG']['quote_identifiers']); - - foreach($items as $k => $v) { - if (!isset($this->$k)) { - continue; - } - // ignore stuff thats - - // dont write things that havent changed.. - if (($dataObject !== false) && isset($dataObject->$k) && ($dataObject->$k == $this->$k)) { - continue; - } - - // beta testing.. - dont write keys to left.!!! - if (in_array($k,$keys)) { - continue; - } - - // dont insert data into mysql timestamps - // use query() if you really want to do this!!!! - if ($v & DB_DATAOBJECT_MYSQLTIMESTAMP) { - continue; - } - - - if ($settings) { - $settings .= ', '; - } - - $kSql = ($quoteIdentifiers ? $DB->quoteIdentifier($k) : $k); - - if (is_a($this->$k,'db_dataobject_cast')) { - $value = $this->$k->toString($v,$dbtype); - if (PEAR::isError($value)) { - $this->raiseError($value->getMessage() ,DB_DATAOBJECT_ERROR_INVALIDARG); - return false; - } - $settings .= "$kSql = $value "; - continue; - } - - // special values ... at least null is handled... - if ((strtolower($this->$k) === 'null') && !($v & DB_DATAOBJECT_NOTNULL)) { - $settings .= "$kSql = NULL "; - continue; - } - // DATE is empty... on a col. that can be null.. - // note: this may be usefull for time as well.. - if (!$this->$k && - (($v & DB_DATAOBJECT_DATE) || ($v & DB_DATAOBJECT_TIME)) && - !($v & DB_DATAOBJECT_NOTNULL)) { - - $settings .= "$kSql = NULL "; - continue; - } - - - if ($v & DB_DATAOBJECT_STR) { - $settings .= "$kSql = ". $DB->quote($this->$k) . ' '; - continue; - } - if (is_numeric($this->$k)) { - $settings .= "$kSql = {$this->$k} "; - continue; - } - // at present we only cast to integers - // - V2 may store additional data about float/int - $settings .= "$kSql = " . intval($this->$k) . ' '; - } - - - if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) { - $this->debug("got keys as ".serialize($keys),3); - } - - $this->_build_condition($items,$keys); - - // echo " $settings, $this->condition "; - if ($settings && isset($this->_query) && $this->_query['condition']) { - - $table = ($quoteIdentifiers ? $DB->quoteIdentifier($this->__table) : $this->__table); - - $r = $this->_query("UPDATE {$table} SET {$settings} {$this->_query['condition']} "); - - // restore original query conditions. - $this->_query = $original_query; - - if (PEAR::isError($r)) { - $this->raiseError($r); - return false; - } - if ($r < 1) { - return 0; - } - - $this->_clear_cache(); - return $r; - } - // restore original query conditions. - $this->_query = $original_query; - - // if you manually specified a dataobject, and there where no changes - then it's ok.. - if ($dataObject !== false) { - return false; - } - - $this->raiseError( - "update: No Data specifed for query $settings , {$this->_query['condition']}", - DB_DATAOBJECT_ERROR_NODATA); - return false; - } - - /** - * Deletes items from table which match current objects variables - * - * Returns the true on success - * - * for example - * - * Designed to be extended - * - * $object = new mytable(); - * $object->ID=123; - * echo $object->delete(); // builds a conditon - * - * $object = new mytable(); - * $object->whereAdd('age > 12'); - * $object->limit(1); - * $object->orderBy('age DESC'); - * $object->delete(true); // dont use object vars, use the conditions, limit and order. - * - * @param bool $useWhere (optional) If DB_DATAOBJECT_WHEREADD_ONLY is passed in then - * we will build the condition only using the whereAdd's. Default is to - * build the condition only using the object parameters. - * - * @access public - * @return mixed True on success, false on failure, 0 on no data affected - */ - function delete($useWhere = false) - { - global $_DB_DATAOBJECT; - // connect will load the config! - $this->_connect(); - $DB = &$_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5]; - $quoteIdentifiers = !empty($_DB_DATAOBJECT['CONFIG']['quote_identifiers']); - - $extra_cond = ' ' . (isset($this->_query['order_by']) ? $this->_query['order_by'] : '') . - ' ' . (isset($this->_query['limit']) ? $this->_query['limit'] : ''); - - if (!$useWhere) { - - $keys = $this->keys(); - $this->_query = array(); // as it's probably unset! - $this->_query['condition'] = ''; // default behaviour not to use where condition - $this->_build_condition($this->table(),$keys); - // if primary keys are not set then use data from rest of object. - if (!$this->_query['condition']) { - $this->_build_condition($this->table(),array(),$keys); - } - $extra_cond = ''; - } - - - // don't delete without a condition - if (isset($this->_query) && $this->_query['condition']) { - - $table = ($quoteIdentifiers ? $DB->quoteIdentifier($this->__table) : $this->__table); - - $r = $this->_query("DELETE FROM {$table} {$this->_query['condition']}{$extra_cond}"); - - - if (PEAR::isError($r)) { - $this->raiseError($r); - return false; - } - if ($r < 1) { - return 0; - } - $this->_clear_cache(); - return $r; - } else { - $this->raiseError("delete: No condition specifed for query", DB_DATAOBJECT_ERROR_NODATA); - return false; - } - } - - /** - * fetches a specific row into this object variables - * - * Not recommended - better to use fetch() - * - * Returens true on success - * - * @param int $row row - * @access public - * @return boolean true on success - */ - function fetchRow($row = null) - { - global $_DB_DATAOBJECT; - if (empty($_DB_DATAOBJECT['CONFIG'])) { - $this->_loadConfig(); - } - if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) { - $this->debug("{$this->__table} $row of {$this->N}", "fetchrow",3); - } - if (!$this->__table) { - $this->raiseError("fetchrow: No table", DB_DATAOBJECT_ERROR_INVALIDCONFIG); - return false; - } - if ($row === null) { - $this->raiseError("fetchrow: No row specified", DB_DATAOBJECT_ERROR_INVALIDARGS); - return false; - } - if (!$this->N) { - $this->raiseError("fetchrow: No results avaiable", DB_DATAOBJECT_ERROR_NODATA); - return false; - } - if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) { - $this->debug("{$this->__table} $row of {$this->N}", "fetchrow",3); - } - - - $result = &$_DB_DATAOBJECT['RESULTS'][$this->_DB_resultid]; - $array = $result->fetchrow(DB_FETCHMODE_ASSOC,$row); - if (!is_array($array)) { - $this->raiseError("fetchrow: No results available", DB_DATAOBJECT_ERROR_NODATA); - return false; - } - - foreach($array as $k => $v) { - $kk = str_replace(".", "_", $k); - if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) { - $this->debug("$kk = ". $array[$k], "fetchrow LINE", 3); - } - $this->$kk = $array[$k]; - } - - if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) { - $this->debug("{$this->__table} DONE", "fetchrow", 3); - } - return true; - } - - /** - * Find the number of results from a simple query - * - * for example - * - * $object = new mytable(); - * $object->name = "fred"; - * echo $object->count(); - * echo $object->count(true); // dont use object vars. - * echo $object->count('distinct mycol'); - * echo $object->count('distinct mycol',true); // dont use object vars. - * - * - * @param bool|string (optional) - * (true|false = see below not on whereAddonly) - * (string) - * $countWhat (optional) normally it counts primary keys - you can use - * this to do things like $do->count('distinct mycol'); - * @param bool $whereAddOnly (optional) If DB_DATAOBJECT_WHEREADD_ONLY is passed in then - * we will build the condition only using the whereAdd's. Default is to - * build the condition using the object parameters as well. - * - * @access public - * @return int - */ - function count($countWhat = false,$whereAddOnly = false) - { - global $_DB_DATAOBJECT; - - if (is_bool($countWhat)) { - $whereAddOnly = $countWhat; - } - - $t = clone($this); - - $quoteIdentifiers = !empty($_DB_DATAOBJECT['CONFIG']['quote_identifiers']); - - $items = $t->table(); - if (!isset($t->_query)) { - $this->raiseError( - "You cannot do run count after you have run fetch()", - DB_DATAOBJECT_ERROR_INVALIDARGS); - return false; - } - $this->_connect(); - $DB = &$_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5]; - - - if (!$whereAddOnly && $items) { - $t->_build_condition($items); - } - $keys = $this->keys(); - - if (!$keys[0] && !is_string($countWhat)) { - $this->raiseError( - "You cannot do run count without keys - use \$do->keys('id');", - DB_DATAOBJECT_ERROR_INVALIDARGS,PEAR_ERROR_DIE); - return false; - - } - $table = ($quoteIdentifiers ? $DB->quoteIdentifier($this->__table) : $this->__table); - if (!is_string($countWhat)) { - $key_col = ($quoteIdentifiers ? $DB->quoteIdentifier($keys[0]) : $keys[0]); - } - - $as = ($quoteIdentifiers ? $DB->quoteIdentifier('DATAOBJECT_NUM') : 'DATAOBJECT_NUM'); - - $countWhat = is_string($countWhat) ? $countWhat : "{$table}.{$key_col}"; - - $r = $t->_query( - "SELECT count({$countWhat}) as $as - FROM $table {$t->_join} {$t->_query['condition']}"); - if (PEAR::isError($r)) { - return false; - } - - $result = &$_DB_DATAOBJECT['RESULTS'][$t->_DB_resultid]; - $l = $result->fetchRow(); - return $l[0]; - } - - /** - * sends raw query to database - * - * Since _query has to be a private 'non overwriteable method', this is a relay - * - * @param string $string SQL Query - * @access public - * @return void or DB_Error - */ - function query($string) - { - return $this->_query($string); - } - - - /** - * an escape wrapper around DB->escapeSimple() - * can be used when adding manual queries or clauses - * eg. - * $object->query("select * from xyz where abc like '". $object->escape($_GET['name']) . "'"); - * - * @param string $string value to be escaped - * @access public - * @return string - */ - function escape($string) - { - global $_DB_DATAOBJECT; - $this->_connect(); - $DB = &$_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5]; - return $DB->escapeSimple($string); - } - - /* ==================================================== */ - /* Major Private Vars */ - /* ==================================================== */ - - /** - * The Database connection dsn (as described in the PEAR DB) - * only used really if you are writing a very simple application/test.. - * try not to use this - it is better stored in configuration files.. - * - * @access private - * @var string - */ - var $_database_dsn = ''; - - /** - * The Database connection id (md5 sum of databasedsn) - * - * @access private - * @var string - */ - var $_database_dsn_md5 = ''; - - /** - * The Database name - * created in __connection - * - * @access private - * @var string - */ - var $_database = ''; - - - - /** - * The QUERY rules - * This replaces alot of the private variables - * used to build a query, it is unset after find() is run. - * - * - * - * @access private - * @var array - */ - var $_query = array( - 'condition' => '', // the WHERE condition - 'group_by' => '', // the GROUP BY condition - 'order_by' => '', // the ORDER BY condition - 'having' => '', // the HAVING condition - 'limit' => '', // the LIMIT condition - 'data_select' => '*', // the columns to be SELECTed - ); - - - - - /** - * Database result id (references global $_DB_DataObject[results] - * - * @access private - * @var integer - */ - var $_DB_resultid; // database result object - - - /* ============================================================== */ - /* Table definition layer (started of very private but 'came out'*/ - /* ============================================================== */ - - /** - * Autoload or manually load the table definitions - * - * - * usage : - * DB_DataObject::databaseStructure( 'databasename', - * parse_ini_file('mydb.ini',true), - * parse_ini_file('mydb.link.ini',true)); - * - * obviously you dont have to use ini files.. (just return array similar to ini files..) - * - * It should append to the table structure array - * - * - * @param optional string name of database to assign / read - * @param optional array structure of database, and keys - * @param optional array table links - * - * @access public - * @return true or PEAR:error on wrong paramenters.. or false if no file exists.. - * or the array(tablename => array(column_name=>type)) if called with 1 argument.. (databasename) - */ - function databaseStructure() - { - - global $_DB_DATAOBJECT; - - // Assignment code - - if ($args = func_get_args()) { - - if (count($args) == 1) { - - // this returns all the tables and their structure.. - - $x = new DB_DataObject; - $x->_database = $args[0]; - $this->_connect(); - $DB = &$_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5]; - - $tables = $DB->getListOf('tables'); - require_once 'DB/DataObject/Generator.php'; - foreach($tables as $table) { - $y = new DB_DataObject_Generator; - $y->fillTableSchema($x->_database,$table); - } - return $_DB_DATAOBJECT['INI'][$x->_database]; - } else { - - $_DB_DATAOBJECT['INI'][$args[0]] = isset($_DB_DATAOBJECT['INI'][$args[0]]) ? - $_DB_DATAOBJECT['INI'][$args[0]] + $args[1] : $args[1]; - - if (isset($args[1])) { - $_DB_DATAOBJECT['LINKS'][$args[0]] = isset($_DB_DATAOBJECT['LINKS'][$args[0]]) ? - $_DB_DATAOBJECT['LINKS'][$args[0]] + $args[2] : $args[2]; - } - return true; - } - - } - - - - if (!$this->_database) { - $this->_connect(); - } - - // loaded already? - if (!empty($_DB_DATAOBJECT['INI'][$this->_database])) { - // database loaded - but this is table is not available.. - if (empty($_DB_DATAOBJECT['INI'][$this->_database][$this->__table])) { - require_once 'DB/DataObject/Generator.php'; - $x = new DB_DataObject_Generator; - $x->fillTableSchema($this->_database,$this->__table); - } - return true; - } - - - if (empty($_DB_DATAOBJECT['CONFIG'])) { - DB_DataObject::_loadConfig(); - } - - // if you supply this with arguments, then it will take those - // as the database and links array... - - $schemas = isset($_DB_DATAOBJECT['CONFIG']['schema_location']) ? - array("{$_DB_DATAOBJECT['CONFIG']['schema_location']}/{$this->_database}.ini") : - array() ; - - if (isset($_DB_DATAOBJECT['CONFIG']["ini_{$this->_database}"])) { - $schemas = is_array($_DB_DATAOBJECT['CONFIG']["ini_{$this->_database}"]) ? - $_DB_DATAOBJECT['CONFIG']["ini_{$this->_database}"] : - explode(PATH_SEPARATOR,$_DB_DATAOBJECT['CONFIG']["ini_{$this->_database}"]); - } - - - - foreach ($schemas as $ini) { - $links = - isset($_DB_DATAOBJECT['CONFIG']["links_{$this->_database}"]) ? - $_DB_DATAOBJECT['CONFIG']["links_{$this->_database}"] : - str_replace('.ini','.links.ini',$ini); - - if (file_exists($ini)) { - $_DB_DATAOBJECT['INI'][$this->_database] = parse_ini_file($ini, true); - } - if (empty($_DB_DATAOBJECT['LINKS'][$this->_database]) && file_exists($links)) { - /* not sure why $links = ... here - TODO check if that works */ - $_DB_DATAOBJECT['LINKS'][$this->_database] = parse_ini_file($links, true); - } - } - // now have we loaded the structure.. - if not try building it.. - - if (empty($_DB_DATAOBJECT['INI'][$this->_database][$this->__table])) { - require_once 'DB/DataObject/Generator.php'; - $x = new DB_DataObject_Generator; - $x->fillTableSchema($this->_database,$this->__table); - } - - - return true; - } - - - - - /** - * Return or assign the name of the current table - * - * - * @param string optinal table name to set - * @access public - * @return string The name of the current table - */ - function tableName() - { - $args = func_get_args(); - if (count($args)) { - $this->__table = $args[0]; - } - return $this->__table; - } - - /** - * Return or assign the name of the current database - * - * @param string optional database name to set - * @access public - * @return string The name of the current database - */ - function database() - { - $args = func_get_args(); - if (count($args)) { - $this->_database = $args[0]; - } - return $this->_database; - } - - /** - * get/set an associative array of table columns - * - * @access public - * @param array key=>type array - * @return array (associative) - */ - function table() - { - - // for temporary storage of database fields.. - // note this is not declared as we dont want to bloat the print_r output - $args = func_get_args(); - if (count($args)) { - $this->_database_fields = $args[0]; - } - if (isset($this->_database_fields)) { - return $this->_database_fields; - } - - - global $_DB_DATAOBJECT; - if (!isset($_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5])) { - $this->_connect(); - } - - if (isset($_DB_DATAOBJECT['INI'][$this->_database][$this->__table])) { - return $_DB_DATAOBJECT['INI'][$this->_database][$this->__table]; - } - - $this->databaseStructure(); - - - $ret = array(); - if (isset($_DB_DATAOBJECT['INI'][$this->_database][$this->__table])) { - $ret = $_DB_DATAOBJECT['INI'][$this->_database][$this->__table]; - } - - return $ret; - } - - /** - * get/set an array of table primary keys - * - * set usage: $do->keys('id','code'); - * - * This is defined in the table definition if it gets it wrong, - * or you do not want to use ini tables, you can override this. - * @param string optional set the key - * @param * optional set more keys - * @access private - * @return array - */ - function keys() - { - // for temporary storage of database fields.. - // note this is not declared as we dont want to bloat the print_r output - $args = func_get_args(); - if (count($args)) { - $this->_database_keys = $args; - } - if (isset($this->_database_keys)) { - return $this->_database_keys; - } - - global $_DB_DATAOBJECT; - if (!isset($_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5])) { - $this->_connect(); - } - if (isset($_DB_DATAOBJECT['INI'][$this->_database][$this->__table."__keys"])) { - return array_keys($_DB_DATAOBJECT['INI'][$this->_database][$this->__table."__keys"]); - } - $this->databaseStructure(); - - if (isset($_DB_DATAOBJECT['INI'][$this->_database][$this->__table."__keys"])) { - return array_keys($_DB_DATAOBJECT['INI'][$this->_database][$this->__table."__keys"]); - } - return array(); - } - /** - * get/set an sequence key - * - * by default it returns the first key from keys() - * set usage: $do->sequenceKey('id',true); - * - * override this to return array(false,false) if table has no real sequence key. - * - * @param string optional the key sequence/autoinc. key - * @param boolean optional use native increment. default false - * @param false|string optional native sequence name - * @access private - * @return array (column,use_native,sequence_name) - */ - function sequenceKey() - { - global $_DB_DATAOBJECT; - - // call setting - if (!$this->_database) { - $this->_connect(); - } - - if (!isset($_DB_DATAOBJECT['SEQUENCE'][$this->_database])) { - $_DB_DATAOBJECT['SEQUENCE'][$this->_database] = array(); - } - - - $args = func_get_args(); - if (count($args)) { - $args[1] = isset($args[1]) ? $args[1] : false; - $args[2] = isset($args[2]) ? $args[2] : false; - $_DB_DATAOBJECT['SEQUENCE'][$this->_database][$this->__table] = $args; - } - if (isset($_DB_DATAOBJECT['SEQUENCE'][$this->_database][$this->__table])) { - return $_DB_DATAOBJECT['SEQUENCE'][$this->_database][$this->__table]; - } - // end call setting (eg. $do->sequenceKeys(a,b,c); ) - - - - - $keys = $this->keys(); - if (!$keys) { - return $_DB_DATAOBJECT['SEQUENCE'][$this->_database][$this->__table] - = array(false,false,false);; - } - - - $table = isset($_DB_DATAOBJECT['INI'][$this->_database][$this->__table]) ? - $_DB_DATAOBJECT['INI'][$this->_database][$this->__table] : $this->table(); - - $dbtype = $_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5]->dsn['phptype']; - - $usekey = $keys[0]; - - - - $seqname = false; - - if (!empty($_DB_DATAOBJECT['CONFIG']['sequence_'.$this->__table])) { - $usekey = $_DB_DATAOBJECT['CONFIG']['sequence_'.$this->__table]; - if (strpos($usekey,':') !== false) { - list($usekey,$seqname) = explode(':',$usekey); - } - } - - - // if the key is not an integer - then it's not a sequence or native - if (!($table[$usekey] & DB_DATAOBJECT_INT)) { - return $_DB_DATAOBJECT['SEQUENCE'][$this->_database][$this->__table] = array(false,false,false); - } - - - if (!empty($_DB_DATAOBJECT['CONFIG']['ignore_sequence_keys'])) { - $ignore = $_DB_DATAOBJECT['CONFIG']['ignore_sequence_keys']; - if (is_string($ignore) && (strtoupper($ignore) == 'ALL')) { - return $_DB_DATAOBJECT['SEQUENCE'][$this->_database][$this->__table] = array(false,false,$seqname); - } - if (is_string($ignore)) { - $ignore = $_DB_DATAOBJECT['CONFIG']['ignore_sequence_keys'] = explode(',',$ignore); - } - if (in_array($this->__table,$ignore)) { - return $_DB_DATAOBJECT['SEQUENCE'][$this->_database][$this->__table] = array(false,false,$seqname); - } - } - - - $realkeys = $_DB_DATAOBJECT['INI'][$this->_database][$this->__table."__keys"]; - - // if you are using an old ini file - go back to old behaviour... - if (is_numeric($realkeys[$usekey])) { - $realkeys[$usekey] = 'N'; - } - - // multiple unique primary keys without a native sequence... - if (($realkeys[$usekey] == 'K') && (count($keys) > 1)) { - return $_DB_DATAOBJECT['SEQUENCE'][$this->_database][$this->__table] = array(false,false,$seqname); - } - // use native sequence keys... - // technically postgres native here... - // we need to get the new improved tabledata sorted out first. - - if ( in_array($dbtype , array( 'mysql', 'mssql')) && - ($table[$usekey] & DB_DATAOBJECT_INT) && - isset($realkeys[$usekey]) && ($realkeys[$usekey] == 'N') - ) { - return $_DB_DATAOBJECT['SEQUENCE'][$this->_database][$this->__table] = array($usekey,true,$seqname); - } - // if not a native autoinc, and we have not assumed all primary keys are sequence - if (($realkeys[$usekey] != 'N') && - !empty($_DB_DATAOBJECT['CONFIG']['dont_use_pear_sequences'])) { - return array(false,false,false); - } - // I assume it's going to try and be a nextval DB sequence.. (not native) - return $_DB_DATAOBJECT['SEQUENCE'][$this->_database][$this->__table] = array($usekey,false,$seqname); - } - - - - /* =========================================================== */ - /* Major Private Methods - the core part! */ - /* =========================================================== */ - - - - /** - * clear the cache values for this class - normally done on insert/update etc. - * - * @access private - * @return void - */ - function _clear_cache() - { - global $_DB_DATAOBJECT; - - $class = get_class($this); - - if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) { - $this->debug("Clearing Cache for ".$class,1); - } - - if (!empty($_DB_DATAOBJECT['CACHE'][$class])) { - unset($_DB_DATAOBJECT['CACHE'][$class]); - } - } - - /** - * connects to the database - * - * - * TODO: tidy this up - This has grown to support a number of connection options like - * a) dynamic changing of ini file to change which database to connect to - * b) multi data via the table_{$table} = dsn ini option - * c) session based storage. - * - * @access private - * @return true | PEAR::error - */ - function _connect() - { - global $_DB_DATAOBJECT; - if (empty($_DB_DATAOBJECT['CONFIG'])) { - $this->_loadConfig(); - } - - // is it already connected ? - - if ($this->_database_dsn_md5 && !empty($_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5])) { - if (PEAR::isError($_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5])) { - return $this->raiseError( - $_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5]->message, - $_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5]->code, PEAR_ERROR_DIE - ); - - } - - if (!$this->_database) { - $this->_database = $_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5]->dsn['database']; - } - - } - - // it's not currently connected! - // try and work out what to use for the dsn ! - - $options= &$_DB_DATAOBJECT['CONFIG']; - $dsn = isset($this->_database_dsn) ? $this->_database_dsn : null; - - if (!$dsn) { - if (!$this->_database) { - $this->_database = isset($options["table_{$this->__table}"]) ?$options["table_{$this->__table}"] : null; - } - if ($this->_database && !empty($options["database_{$this->_database}"])) { - $dsn = $options["database_{$this->_database}"]; - } else if (!empty($options['database'])) { - $dsn = $options['database']; - } - } - - // if still no database... - if (!$dsn) { - return $this->raiseError( - "No database name / dsn found anywhere", - DB_DATAOBJECT_ERROR_INVALIDCONFIG, PEAR_ERROR_DIE - ); - - } - - - - $this->_database_dsn_md5 = md5($dsn); - - if (!empty($_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5])) { - if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) { - $this->debug("USING CACHED CONNECTION", "CONNECT",3); - } - if (!$this->_database) { - $this->_database = $_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5]->dsn["database"]; - } - return true; - } - if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) { - $this->debug("NEW CONNECTION", "CONNECT",3); - /* actualy make a connection */ - $this->debug("{$dsn} {$this->_database_dsn_md5}", "CONNECT",3); - } - $db_options = PEAR::getStaticProperty('DB','options'); - require_once 'DB.php'; - if ($db_options) { - - $_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5] = DB::connect($dsn,$db_options); - } else { - $_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5] = DB::connect($dsn); - } - - if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) { - $this->debug(serialize($_DB_DATAOBJECT['CONNECTIONS']), "CONNECT",5); - } - if (PEAR::isError($_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5])) { - return $this->raiseError( - $_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5]->message, - $_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5]->code, PEAR_ERROR_DIE - ); - - } - - if (!$this->_database) { - $this->_database = $_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5]->dsn["database"]; - } - - // Oracle need to optimize for portibility - not sure exactly what this does though :) - $c = &$_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5]; - - - - - - - - return true; - } - - /** - * sends query to database - this is the private one that must work - * - internal functions use this rather than $this->query() - * - * @param string $string - * @access private - * @return mixed none or PEAR_Error - */ - function _query($string) - { - global $_DB_DATAOBJECT; - $this->_connect(); - - - $DB = &$_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5]; - - $options = &$_DB_DATAOBJECT['CONFIG']; - - if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) { - $this->debug($string,$log="QUERY"); - - } - - if (strtoupper($string) == 'BEGIN') { - $DB->autoCommit(false); - // db backend adds begin anyway from now on.. - return true; - } - if (strtoupper($string) == 'COMMIT') { - $DB->commit(); - $DB->autoCommit(true); - return true; - } - - if (strtoupper($string) == 'ROLLBACK') { - $DB->rollback(); - $DB->autoCommit(true); - return true; - } - - - if (!empty($options['debug_ignore_updates']) && - (strtolower(substr(trim($string), 0, 6)) != 'select') && - (strtolower(substr(trim($string), 0, 4)) != 'show') && - (strtolower(substr(trim($string), 0, 8)) != 'describe')) { - - $this->debug('Disabling Update as you are in debug mode'); - return $this->raiseError("Disabling Update as you are in debug mode", null) ; - - } - //if (@$_DB_DATAOBJECT['CONFIG']['debug'] > 1) { - // this will only work when PEAR:DB supports it. - //$this->debug($DB->getAll('explain ' .$string,DB_FETCHMODE_ASSOC), $log="sql",2); - //} - - // some sim - $t= explode(' ',microtime()); - $_DB_DATAOBJECT['QUERYENDTIME'] = $time = $t[0]+$t[1]; - - $result = $DB->query($string); - - - - - if (is_a($result,'DB_Error')) { - if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) { - $this->debug($result->toString(), "Query Error",1 ); - } - return $result; - } - if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) { - $t= explode(' ',microtime()); - $_DB_DATAOBJECT['QUERYENDTIME'] = $t[0]+$t[1]; - $this->debug('QUERY DONE IN '.($t[0]+$t[1]-$time)." seconds", 'query',1); - } - switch (strtolower(substr(trim($string),0,6))) { - case 'insert': - case 'update': - case 'delete': - return $DB->affectedRows();; - } - if (is_object($result)) { - // lets hope that copying the result object is OK! - - $_DB_resultid = $GLOBALS['_DB_DATAOBJECT']['RESULTSEQ']++; - $_DB_DATAOBJECT['RESULTS'][$_DB_resultid] = $result; - $this->_DB_resultid = $_DB_resultid; - } - $this->N = 0; - if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) { - $this->debug(serialize($result), 'RESULT',5); - } - if (method_exists($result, 'numrows')) { - $DB->expectError(DB_ERROR_UNSUPPORTED); - $this->N = $result->numrows(); - if (is_a($this->N,'DB_Error')) { - $this->N = 1; - } - $DB->popExpect(); - } - } - - /** - * Builds the WHERE based on the values of of this object - * - * @param mixed $keys - * @param array $filter (used by update to only uses keys in this filter list). - * @param array $negative_filter (used by delete to prevent deleting using the keys mentioned..) - * @access private - * @return string - */ - function _build_condition($keys, $filter = array(),$negative_filter=array()) - { - global $_DB_DATAOBJECT; - $this->_connect(); - $DB = &$_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5]; - - $quoteIdentifiers = !empty($_DB_DATAOBJECT['CONFIG']['quote_identifiers']); - // if we dont have query vars.. - reset them. - if (!isset($this->_query)) { - $x = new DB_DataObject; - $this->_query= $x->_query; - } - - foreach($keys as $k => $v) { - // index keys is an indexed array - /* these filter checks are a bit suspicious.. - - need to check that update really wants to work this way */ - - if ($filter) { - if (!in_array($k, $filter)) { - continue; - } - } - if ($negative_filter) { - if (in_array($k, $negative_filter)) { - continue; - } - } - if (!isset($this->$k)) { - continue; - } - - $kSql = $quoteIdentifiers - ? ( $DB->quoteIdentifier($this->__table) . '.' . $DB->quoteIdentifier($k) ) - : "{$this->__table}.{$k}"; - - - - if (is_a($this->$k,'db_dataobject_cast')) { - $dbtype = $DB->dsn["phptype"]; - $value = $this->$k->toString($v,$dbtype); - if (PEAR::isError($value)) { - $this->raiseError($value->getMessage() ,DB_DATAOBJECT_ERROR_INVALIDARG); - return false; - } - if ($value == 'NULL') { - $value = 'IS NULL'; - } - $this->whereAdd(" $kSql = $value"); - continue; - } - - if ((strtolower($this->$k) === 'null') && !($v & DB_DATAOBJECT_NOTNULL)) { - $this->whereAdd(" $kSql IS NULL"); - continue; - } - - - if ($v & DB_DATAOBJECT_STR) { - $this->whereAdd(" $kSql = " . $DB->quote($this->$k) ); - continue; - } - if (is_numeric($this->$k)) { - $this->whereAdd(" $kSql = {$this->$k}"); - continue; - } - /* this is probably an error condition! */ - $this->whereAdd(" $kSql = 0"); - } - } - - /** - * autoload Class relating to a table - * (depreciated - use ::factory) - * - * @param string $table table - * @access private - * @return string classname on Success - */ - function staticAutoloadTable($table) - { - global $_DB_DATAOBJECT; - if (empty($_DB_DATAOBJECT['CONFIG'])) { - DB_DataObject::_loadConfig(); - } - $p = isset($_DB_DATAOBJECT['CONFIG']['class_prefix']) ? - $_DB_DATAOBJECT['CONFIG']['class_prefix'] : ''; - $class = $p . preg_replace('/[^A-Z0-9]/i','_',ucfirst($table)); - $class = (class_exists($class)) ? $class : DB_DataObject::_autoloadClass($class); - return $class; - } - - - /** - * classic factory method for loading a table class - * usage: $do = DB_DataObject::factory('person') - * WARNING - this may emit a include error if the file does not exist.. - * use @ to silence it (if you are sure it is acceptable) - * eg. $do = @DB_DataObject::factory('person') - * - * table name will eventually be databasename/table - * - and allow modular dataobjects to be written.. - * (this also helps proxy creation) - * - * - * @param string $table tablename (use blank to create a new instance of the same class.) - * @access private - * @return DataObject|PEAR_Error - */ - - - - function factory($table = '') { - global $_DB_DATAOBJECT; - if (empty($_DB_DATAOBJECT['CONFIG'])) { - DB_DataObject::_loadConfig(); - } - - if ($table === '') { - if (is_a($this,'DB_DataObject') && strlen($this->__table)) { - $table = $this->__table; - } else { - return DB_DataObject::raiseError( - "factory did not recieve a table name", - DB_DATAOBJECT_ERROR_INVALIDARGS); - } - } - - - $p = isset($_DB_DATAOBJECT['CONFIG']['class_prefix']) ? - $_DB_DATAOBJECT['CONFIG']['class_prefix'] : ''; - $class = $p . preg_replace('/[^A-Z0-9]/i','_',ucfirst($table)); - - $class = (class_exists($class)) ? $class : DB_DataObject::_autoloadClass($class); - - // proxy = full|light - if (!$class && isset($_DB_DATAOBJECT['CONFIG']['proxy'])) { - $proxyMethod = 'getProxy'.$_DB_DATAOBJECT['CONFIG']['proxy']; - - require_once 'DB/DataObject/Generator.php'; - $d = new DB_DataObject; - - $d->__table = $table; - $d->_connect(); - - $x = new DB_DataObject_Generator; - return $x->$proxyMethod( $d->_database, $table); - } - - if (!$class) { - return DB_DataObject::raiseError( - "factory could not find class $class from $table", - DB_DATAOBJECT_ERROR_INVALIDCONFIG); - } - - return new $class; - } - /** - * autoload Class - * - * @param string $class Class - * @access private - * @return string classname on Success - */ - function _autoloadClass($class) - { - global $_DB_DATAOBJECT; - - if (empty($_DB_DATAOBJECT['CONFIG'])) { - DB_DataObject::_loadConfig(); - } - $table = substr($class,strlen($_DB_DATAOBJECT['CONFIG']['class_prefix'])); - - // only include the file if it exists - and barf badly if it has parse errors :) - if (!empty($_DB_DATAOBJECT['CONFIG']['proxy']) && empty($_DB_DATAOBJECT['CONFIG']['class_location'])) { - return false; - } - - $file = $_DB_DATAOBJECT['CONFIG']['class_location'].'/'.preg_replace('/[^A-Z0-9]/i','_',ucfirst($table)).".php"; - - if (!file_exists($file)) { - $found = false; - foreach(explode(PATH_SEPARATOR, ini_get('include_path')) as $p) { - if (file_exists("$p/$file")) { - $file = "$p/$file"; - $found = true; - break; - } - } - if (!$found) { - DB_DataObject::raiseError( - "autoload:Could not find class {$class} using class_location value", - DB_DATAOBJECT_ERROR_INVALIDCONFIG); - return false; - } - } - - include_once $file; - - - - - if (!class_exists($class)) { - DB_DataObject::raiseError( - "autoload:Could not autoload {$class}", - DB_DATAOBJECT_ERROR_INVALIDCONFIG); - return false; - } - return $class; - } - - - - /** - * Have the links been loaded? - * if they have it contains a array of those variables. - * - * @access private - * @var boolean | array - */ - var $_link_loaded = false; - - /** - * Get the links associate array as defined by the links.ini file. - * - * - * Experimental... - - * Should look a bit like - * [local_col_name] => "related_tablename:related_col_name" - * - * - * @return array|null - * array = if there are links defined for this table. - * empty array - if there is a links.ini file, but no links on this table - * null - if no links.ini exists for this database (hence try auto_links). - * @access public - * @see DB_DataObject::getLinks(), DB_DataObject::getLink() - */ - - function links() - { - global $_DB_DATAOBJECT; - if (empty($_DB_DATAOBJECT['CONFIG'])) { - $this->_loadConfig(); - } - - - if (isset($_DB_DATAOBJECT['LINKS'][$this->_database][$this->__table])) { - return $_DB_DATAOBJECT['LINKS'][$this->_database][$this->__table]; - } - $this->databaseStructure(); - // if there is no link data at all on the file! - // we return null. - if (!isset($_DB_DATAOBJECT['LINKS'][$this->_database])) { - return null; - } - - if (isset($_DB_DATAOBJECT['LINKS'][$this->_database][$this->__table])) { - return $_DB_DATAOBJECT['LINKS'][$this->_database][$this->__table]; - } - - return array(); - } - /** - * load related objects - * - * There are two ways to use this, one is to set up a .links.ini file - * into a static property named .links and specifies the table joins, - * the other highly dependent on naming columns 'correctly' :) - * using colname = xxxxx_yyyyyy - * xxxxxx = related table; (yyyyy = user defined..) - * looks up table xxxxx, for value id=$this->xxxxx - * stores it in $this->_xxxxx_yyyyy - * you can change what object vars the links are stored in by - * changeing the format parameter - * - * - * @param string format (default _%s) where %s is the table name. - * @author Tim White - * @access public - * @return boolean , true on success - */ - function getLinks($format = '_%s') - { - - // get table will load the options. - if ($this->_link_loaded) { - return true; - } - $this->_link_loaded = false; - $cols = $this->table(); - $links = $this->links(); - - $loaded = array(); - - if ($links) { - foreach($links as $key => $match) { - list($table,$link) = explode(':', $match); - $k = sprintf($format, str_replace('.', '_', $key)); - // makes sure that '.' is the end of the key; - if ($p = strpos($key,'.')) { - $key = substr($key, 0, $p); - } - - $this->$k = $this->getLink($key, $table, $link); - if (is_object($this->$k)) { - $loaded[] = $k; - } - } - $this->_link_loaded = $loaded; - return true; - } - // this is the autonaming stuff.. - // it sends the column name down to getLink and lets that sort it out.. - // if there is a links file then it is not used! - // IT IS DEPRECIATED!!!! - USE - if (!is_null($links)) { - return false; - } - - - foreach (array_keys($cols) as $key) { - if (!($p = strpos($key, '_'))) { - continue; - } - // does the table exist. - $k =sprintf($format, $key); - $this->$k = $this->getLink($key); - if (is_object($this->$k)) { - $loaded[] = $k; - } - } - $this->_link_loaded = $loaded; - return true; - } - - /** - * return name from related object - * - * There are two ways to use this, one is to set up a .links.ini file - * into a static property named .links and specifies the table joins, - * the other is highly dependant on naming columns 'correctly' :) - * - * NOTE: the naming convention is depreciated!!! - use links.ini - * - * using colname = xxxxx_yyyyyy - * xxxxxx = related table; (yyyyy = user defined..) - * looks up table xxxxx, for value id=$this->xxxxx - * stores it in $this->_xxxxx_yyyyy - * - * you can also use $this->getLink('thisColumnName','otherTable','otherTableColumnName') - * - * - * @param string $row either row or row.xxxxx - * @param string $table name of table to look up value in - * @param string $link name of column in other table to match - * @author Tim White - * @access public - * @return mixed object on success - */ - function &getLink($row, $table = null, $link = false) - { - - - // GUESS THE LINKED TABLE.. (if found - recursevly call self) - - if ($table === null) { - $links = $this->links(); - - if (is_array($links)) { - - if ($links[$row]) { - list($table,$link) = explode(':', $links[$row]); - if ($p = strpos($row,".")) { - $row = substr($row,0,$p); - } - return $r = &$this->getLink($row,$table,$link); - } - - $this->raiseError( - "getLink: $row is not defined as a link (normally this is ok)", - DB_DATAOBJECT_ERROR_NODATA); - - return false; // technically a possible error condition? - - } - // use the old _ method - this shouldnt happen if called via getLinks() - if (!($p = strpos($row, '_'))) { - return null; - } - $table = substr($row, 0, $p); - return $r = &$this->getLink($row, $table); - - } - - - - if (!isset($this->$row)) { - $this->raiseError("getLink: row not set $row", DB_DATAOBJECT_ERROR_NODATA); - return false; - } - - // check to see if we know anything about this table.. - - $obj = $this->factory($table); - - if (!is_a($obj,'DB_DataObject')) { - $this->raiseError( - "getLink:Could not find class for row $row, table $table", - DB_DATAOBJECT_ERROR_INVALIDCONFIG); - return false; - } - if ($link) { - if ($obj->get($link, $this->$row)) { - return $obj; - } - return false; - } - - if ($obj->get($this->$row)) { - return $obj; - } - return false; - } - - /** - * IS THIS SUPPORTED/USED ANYMORE???? - *return a list of options for a linked table - * - * This is highly dependant on naming columns 'correctly' :) - * using colname = xxxxx_yyyyyy - * xxxxxx = related table; (yyyyy = user defined..) - * looks up table xxxxx, for value id=$this->xxxxx - * stores it in $this->_xxxxx_yyyyy - * - * @access public - * @return array of results (empty array on failure) - */ - function &getLinkArray($row, $table = null) - { - - $ret = array(); - if (!$table) { - $links = $this->links(); - - if (is_array($links)) { - if (!isset($links[$row])) { - // failed.. - return $ret; - } - list($table,$link) = explode(':',$links[$row]); - } else { - if (!($p = strpos($row,'_'))) { - return $ret; - } - $table = substr($row,0,$p); - } - } - - $c = $this->factory($table); - - if (!is_a($obj,'DB_DataObject')) { - $this->raiseError( - "getLinkArray:Could not find class for row $row, table $table", - DB_DATAOBJECT_ERROR_INVALIDCONFIG - ); - return $ret; - } - - // if the user defined method list exists - use it... - if (method_exists($c, 'listFind')) { - $c->listFind($this->id); - } else { - $c->find(); - } - while ($c->fetch()) { - $ret[] = $c; - } - return $ret; - } - - /** - * The JOIN condition - * - * @access private - * @var string - */ - var $_join = ''; - - /** - * joinAdd - adds another dataobject to this, building a joined query. - * - * example (requires links.ini to be set up correctly) - * // get all the images for product 24 - * $i = new DataObject_Image(); - * $pi = new DataObjects_Product_image(); - * $pi->product_id = 24; // set the product id to 24 - * $i->joinAdd($pi); // add the product_image connectoin - * $i->find(); - * while ($i->fetch()) { - * // do stuff - * } - * // an example with 2 joins - * // get all the images linked with products or productgroups - * $i = new DataObject_Image(); - * $pi = new DataObject_Product_image(); - * $pgi = new DataObject_Productgroup_image(); - * $i->joinAdd($pi); - * $i->joinAdd($pgi); - * $i->find(); - * while ($i->fetch()) { - * // do stuff - * } - * - * - * @param optional $obj object |array the joining object (no value resets the join) - * If you use an array here it should be in the format: - * array('local_column','remotetable:remote_column'); - * if remotetable does not have a definition, you should - * use @ to hide the include error message.. - * - * - * @param optional $joinType string 'LEFT'|'INNER'|'RIGHT'|'' Inner is default, '' indicates - * just select ... from a,b,c with no join and - * links are added as where items. - * - * @param optional $joinAs string if you want to select the table as anther name - * useful when you want to select multiple columsn - * from a secondary table. - - * @param optional $joinCol string The column on This objects table to match (needed - * if this table links to the child object in - * multiple places eg. - * user->friend (is a link to another user) - * user->mother (is a link to another user..) - * - * @return none - * @access public - * @author Stijn de Reede - */ - function joinAdd($obj = false, $joinType='INNER', $joinAs=false, $joinCol=false) - { - global $_DB_DATAOBJECT; - if ($obj === false) { - $this->_join = ''; - return; - } - - // support for array as first argument - // this assumes that you dont have a links.ini for the specified table. - // and it doesnt exist as am extended dataobject!! - experimental. - - $ofield = false; // object field - $tfield = false; // this field - $toTable = false; - if (is_array($obj)) { - $tfield = $obj[0]; - list($toTable,$ofield) = explode(':',$obj[1]); - $obj = DB_DataObject::factory($toTable); - if (!$obj) { - $obj = new DB_DataObject; - $obj->__table = $toTable; - } - // set the table items to nothing.. - eg. do not try and match - // things in the child table...??? - $items = array(); - } - - if (!is_object($obj)) { - $this->raiseError("joinAdd: called without an object", DB_DATAOBJECT_ERROR_NODATA,PEAR_ERROR_DIE); - } - /* make sure $this->_database is set. */ - $this->_connect(); - $DB = &$_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5]; - - - - - /* look up the links for obj table */ - - if (!$ofield && ($olinks = $obj->links())) { - foreach ($olinks as $k => $v) { - /* link contains {this column} = {linked table}:{linked column} */ - $ar = explode(':', $v); - if ($ar[0] == $this->__table) { - - // you have explictly specified the column - // and the col is listed here.. - // not sure if 1:1 table could cause probs here.. - - if ($joinCol !== false) { - $this->raiseError( - "joinAdd: You cannot target a join column in the " . - "'link from' table ({$obj->__table}). " . - "Either remove the fourth argument to joinAdd() ". - "({$joinCol}), or alter your links.ini file.", - DB_DATAOBJECT_ERROR_NODATA); - return false; - } - - $ofield = $k; - $tfield = $ar[1]; - break; - } - } - } - - /* otherwise see if there are any links from this table to the obj. */ - - if (($ofield === false) && ($links = $this->links())) { - foreach ($links as $k => $v) { - /* link contains {this column} = {linked table}:{linked column} */ - $ar = explode(':', $v); - if ($ar[0] == $obj->__table) { - if ($joinCol !== false) { - if ($k == $joinCol) { - $tfield = $k; - $ofield = $ar[1]; - break; - } else { - continue; - } - } else { - $tfield = $k; - $ofield = $ar[1]; - break; - } - } - } - } - - /* did I find a conneciton between them? */ - - if ($ofield === false) { - $this->raiseError( - "joinAdd: {$obj->__table} has no link with {$this->__table}", - DB_DATAOBJECT_ERROR_NODATA); - return false; - } - $joinType = strtoupper($joinType); - if ($joinAs === false) { - $joinAs = $obj->__table; - } - - $quoteIdentifiers = !empty($_DB_DATAOBJECT['CONFIG']['quote_identifiers']); - - $objTable = $quoteIdentifiers ? $DB->quoteIdentifier($obj->__table) : $obj->__table ; - - - // nested (join of joined objects..) - $appendJoin = ''; - if ($obj->_join) { - // postgres allows nested queries, with ()'s - // not sure what the results are with other databases.. - // may be unpredictable.. - if (in_array($DB->dsn["phptype"],array('pgsql'))) { - $objTable = "($objTable {$obj->_join})"; - } else { - $appendJoin = $obj->_join; - } - } - - - $table = $this->__table; - - if ($quoteIdentifiers) { - $joinAs = $DB->quoteIdentifier($joinAs); - $table = $DB->quoteIdentifier($table); - $ofield = $DB->quoteIdentifier($ofield); - $tfield = $DB->quoteIdentifier($tfield); - } - - $fullJoinAs = ''; - if ($DB->quoteIdentifier($obj->__table) != $joinAs) { - $fullJoinAs = "AS {$joinAs}"; - } - - switch ($joinType) { - case 'INNER': - case 'LEFT': - case 'RIGHT': // others??? .. cross, left outer, right outer, natural..? - $this->_join .= "\n {$joinType} JOIN {$objTable} {$fullJoinAs}". - " ON {$joinAs}.{$ofield}={$table}.{$tfield} {$appendJoin} "; - break; - case '': // this is just a standard multitable select.. - $this->_join .= "\n , {$objTable} {$fullJoinAs} {$appendJoin}"; - $this->whereAdd("{$joinAs}.{$ofield}={$table}.{$tfield}"); - } - - // if obj only a dataobject - eg. no extended class has been defined.. - // it obvioulsy cant work out what child elements might exist... - // untill we get on the fly querying of tables.. - if ( strtolower(get_class($obj)) == 'db_dataobject') { - return true; - } - - /* now add where conditions for anything that is set in the object */ - - - - $items = $obj->table(); - // will return an array if no items.. - - // only fail if we where expecting it to work (eg. not joined on a array) - - - - if (!$items) { - $this->raiseError( - "joinAdd: No table definition for {$obj->__table}", - DB_DATAOBJECT_ERROR_INVALIDCONFIG); - return false; - } - - foreach($items as $k => $v) { - if (!isset($obj->$k)) { - continue; - } - - $kSql = ($quoteIdentifiers ? $DB->quoteIdentifier($k) : $k); - - - if ($v & DB_DATAOBJECT_STR) { - $this->whereAdd("{$joinAs}.{$kSql} = " . $DB->quote($obj->$k)); - continue; - } - if (is_numeric($obj->$k)) { - $this->whereAdd("{$joinAs}.{$kSql} = {$obj->$k}"); - continue; - } - /* this is probably an error condition! */ - $this->whereAdd("{$joinAs}.{$kSql} = 0"); - } - - // and finally merge the whereAdd from the child.. - if (!$obj->_query['condition']) { - return true; - } - $cond = preg_replace('/^\sWHERE/i','',$obj->_query['condition']); - - $this->whereAdd("($cond)"); - return true; - - } - - /** - * Copies items that are in the table definitions from an - * array or object into the current object - * will not override key values. - * - * - * @param array | object $from - * @param string $format eg. map xxxx_name to $object->name using 'xxxx_%s' (defaults to %s - eg. name -> $object->name - * @access public - * @return true on success or array of key=>setValue error message - */ - function setFrom(&$from, $format = '%s') - { - global $_DB_DATAOBJECT; - $keys = $this->keys(); - $items = $this->table(); - if (!$items) { - $this->raiseError( - "setFrom:Could not find table definition for {$this->__table}", - DB_DATAOBJECT_ERROR_INVALIDCONFIG); - return; - } - $overload_return = array(); - foreach (array_keys($items) as $k) { - if (in_array($k,$keys)) { - continue; // dont overwrite keys - } - if (!$k) { - continue; // ignore empty keys!!! what - } - if (is_object($from) && isset($from->{sprintf($format,$k)})) { - $kk = (strtolower($k) == 'from') ? '_from' : $k; - if (method_exists($this,'set'.$kk)) { - $ret = $this->{'set'.$kk}($from->{sprintf($format,$k)}); - if (is_string($ret)) { - $overload_return[$k] = $ret; - } - continue; - } - $this->$k = $from->{sprintf($format,$k)}; - continue; - } - - if (is_object($from)) { - continue; - } - - if (!isset($from[sprintf($format,$k)])) { - continue; - } - if (is_object($from[sprintf($format,$k)])) { - continue; - } - if (is_array($from[sprintf($format,$k)])) { - continue; - } - $kk = (strtolower($k) == 'from') ? '_from' : $k; - if (method_exists($this,'set'. $kk)) { - $ret = $this->{'set'.$kk}($from[sprintf($format,$k)]); - if (is_string($ret)) { - $overload_return[$k] = $ret; - } - continue; - } - $ret = $this->fromValue($k,$from[sprintf($format,$k)]); - if ($ret !== true) { - $overload_return[$k] = 'Not A Valid Value'; - } - //$this->$k = $from[sprintf($format,$k)]; - } - if ($overload_return) { - return $overload_return; - } - return true; - } - - /** - * Returns an associative array from the current data - * (kind of oblivates the idea behind DataObjects, but - * is usefull if you use it with things like QuickForms. - * - * you can use the format to return things like user[key] - * by sending it $object->toArray('user[%s]') - * - * will also return links converted to arrays. - * - * @param string sprintf format for array - * @access public - * @return array of key => value for row - */ - - function toArray($format = '%s') - { - global $_DB_DATAOBJECT; - $ret = array(); - $ar = isset($_DB_DATAOBJECT['RESULTFIELDS'][$this->_DB_resultid]) ? - array_merge($_DB_DATAOBJECT['RESULTFIELDS'][$this->_DB_resultid],$this->table()) : - $this->table(); - - foreach($ar as $k=>$v) { - - if (!isset($this->$k)) { - $ret[sprintf($format,$k)] = ''; - continue; - } - // call the overloaded getXXXX() method. - if (method_exists($this,'get'.$k)) { - $ret[sprintf($format,$k)] = $this->{'get'.$k}(); - continue; - } - // should this call toValue() ??? - $ret[sprintf($format,$k)] = $this->$k; - } - if (!$this->_link_loaded) { - return $ret; - } - foreach($this->_link_loaded as $k) { - $ret[sprintf($format,$k)] = $this->$k->toArray(); - - } - - return $ret; - } - - /** - * validate - override this to set up your validation rules - * - * validate the current objects values either just testing strings/numbers or - * using the user defined validate{Row name}() methods. - * will attempt to call $this->validate{column_name}() - expects true = ok false = ERROR - * you can the use the validate Class from your own methods. - * - * @access public - * @return array of validation results or true - */ - function validate() - { - require_once 'Validate.php'; - $table = $this->table(); - $ret = array(); - - foreach($table as $key => $val) { - - - // call user defined validation always... - $method = "Validate" . ucfirst($key); - if (method_exists($this, $method)) { - $ret[$key] = $this->$method(); - continue; - } - - // if not null - and it's not set....... - - if (!isset($this->$key) && ($val & DB_DATAOBJECT_NOTNULL)) { - $ret[$key] = false; - continue; - } - - if (is_string($this->$key) && (strtolower($this->$key) == 'null') && ($val & DB_DATAOBJECT_NOTNULL)) { - $ret[$key] = false; - continue; - } - // ignore things that are not set. ? - - if (!isset($this->$key)) { - continue; - } - - // if the string is empty.. assume it is ok.. - if (!is_object($this->$key) && !is_array($this->$key) && !strlen((string) $this->$key)) { - continue; - } - - switch (true) { - // todo: date time..... - - - case ($val & DB_DATAOBJECT_STR): - $ret[$key] = Validate::string($this->$key, VALIDATE_PUNCTUATION . VALIDATE_NAME); - continue; - case ($val & DB_DATAOBJECT_INT): - $ret[$key] = Validate::number($this->$key, array('decimal'=>'.')); - continue; - } - } - - foreach ($ret as $key => $val) { - if ($val === false) { - return $ret; - } - } - return true; // everything is OK. - } - - /** - * Gets the DB object related to an object - so you can use funky peardb stuf with it :) - * - * @access public - * @return object The DB connection - */ - function &getDatabaseConnection() - { - global $_DB_DATAOBJECT; - - if (($e = $this->_connect()) !== true) { - return $e; - } - if (!isset($_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5])) { - return false; - } - return $_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5]; - } - - - /** - * Gets the DB result object related to the objects active query - * - so you can use funky pear stuff with it - like pager for example.. :) - * - * @access public - * @return object The DB result object - */ - - function &getDatabaseResult() - { - global $_DB_DATAOBJECT; - $this->_connect(); - if (!isset($_DB_DATAOBJECT['RESULTS'][$this->_DB_resultid])) { - return false; - } - return $_DB_DATAOBJECT['RESULTS'][$this->_DB_resultid]; - } - - /** - * Overload Extension support - * - enables setCOLNAME/getCOLNAME - * if you define a set/get method for the item it will be called. - * otherwise it will just return/set the value. - * NOTE this currently means that a few Names are NO-NO's - * eg. links,link,linksarray, from, Databaseconnection,databaseresult - * - * note - * - set is automatically called by setFrom. - * - get is automatically called by toArray() - * - * setters return true on success. = strings on failure - * getters return the value! - * - * this fires off trigger_error - if any problems.. pear_error, - * has problems with 4.3.2RC2 here - * - * @access public - * @return true? - * @see overload - */ - - - function _call($method,$params,&$return) { - - //$this->debug("ATTEMPTING OVERLOAD? $method"); - // ignore constructors : - mm - if (strtolower($method) == strtolower(get_class($this))) { - return true; - } - $type = strtolower(substr($method,0,3)); - $class = get_class($this); - if (($type != 'set') && ($type != 'get')) { - return false; - } - - - - // deal with naming conflick of setFrom = this is messy ATM! - - if (strtolower($method) == 'set_from') { - $return = $this->toValue('from',isset($params[0]) ? $params[0] : null); - return true; - } - - $element = substr($method,3); - if ($element{0} == '_') { - return false; - } - - - // dont you just love php's case insensitivity!!!! - - $array = array_keys(get_class_vars($class)); - - if (!in_array($element,$array)) { - // munge case - foreach($array as $k) { - $case[strtolower($k)] = $k; - } - if ((substr(phpversion(),0,1) == 5) && isset($case[strtolower($element)])) { - trigger_error("PHP5 set/get calls should match the case of the variable",E_USER_WARNING); - $element = strtolower($element); - } - - // does it really exist? - if (!isset($case[$element])) { - return false; - } - // use the mundged case - $element = $case[$element]; // real case ! - } - - - if ($type == 'get') { - $return = $this->toValue($element,isset($params[0]) ? $params[0] : null); - return true; - } - - - $return = $this->fromValue($element, $params[0]); - - return true; - - - } - - - /** - * standard set* implementation. - * - * takes data and uses it to set dates/strings etc. - * normally called from __call.. - * - * Current supports - * date = using (standard time format, or unixtimestamp).... so you could create a method : - * function setLastread($string) { $this->fromValue('lastread',strtotime($string)); } - * - * time = using strtotime - * datetime = using same as date - accepts iso standard or unixtimestamp. - * string = typecast only.. - * - * TODO: add formater:: eg. d/m/Y for date! ??? - * - * @param string column of database - * @param mixed value to assign - * - * @return true| false (False on error) - * @access public - * @see DB_DataObject::_call - */ - - - function fromValue($col,$value) - { - $cols = $this->table(); - // dont know anything about this col.. - if (!isset($cols[$col])) { - $this->$col = $value; - return true; - } - //echo "FROM VALUE $col, {$cols[$col]}, $value\n"; - switch (true) { - // set to null and column is can be null... - case ((strtolower($value) == 'null') && (!($cols[$col] & DB_DATAOBJECT_NOTNULL))): - case (is_object($value) && is_a($value,'DB_DataObject_Cast')): - $this->$col = $value; - return true; - - // fail on setting null on a not null field.. - case ((strtolower($value) == 'null') && ($cols[$col] & DB_DATAOBJECT_NOTNULL)): - return false; - - case (($cols[$col] & DB_DATAOBJECT_DATE) && ($cols[$col] & DB_DATAOBJECT_TIME)): - // empty values get set to '' (which is inserted/updated as NULl - if (!$value) { - $this->$col = ''; - } - - if (is_numeric($value)) { - $this->$col = date('Y-m-d H:i:s', $value); - return true; - } - - // eak... - no way to validate date time otherwise... - $this->$col = (string) $value; - return true; - - case ($cols[$col] & DB_DATAOBJECT_DATE): - // empty values get set to '' (which is inserted/updated as NULl - - if (!$value) { - $this->$col = ''; - } - - if (is_numeric($value)) { - echo "it's numberic?"; - $this->$col = date('Y-m-d',$value); - return true; - } - - // try date!!!! - require_once 'Date.php'; - $x = new Date($value); - $this->$col = $x->format("%Y-%m-%d"); - return true; - - case ($cols[$col] & DB_DATAOBJECT_TIME): - // empty values get set to '' (which is inserted/updated as NULl - if (!$value) { - $this->$col = ''; - } - - $guess = strtotime($value); - if ($guess != -1) { - $this->$col = date('H:i:s', $guess); - return $return = true; - } - // otherwise an error in type... - return false; - - case ($cols[$col] & DB_DATAOBJECT_STR): - - $this->$col = (string) $value; - return true; - - // todo : floats numerics and ints... - default: - $this->$col = $value; - return true; - } - - - - } - /** - * standard get* implementation. - * - * with formaters.. - * supported formaters: - * date/time : %d/%m/%Y (eg. php strftime) or pear::Date - * numbers : %02d (eg. sprintf) - * NOTE you will get unexpected results with times like 0000-00-00 !!! - * - * - * - * @param string column of database - * @param format foramt - * - * @return true Description - * @access public - * @see DB_DataObject::_call(),strftime(),Date::format() - */ - function toValue($col,$format = null) - { - if (is_null($format)) { - return $this->$col; - } - $cols = $this->table(); - switch (true) { - case (($cols[$col] & DB_DATAOBJECT_DATE) && ($cols[$col] & DB_DATAOBJECT_TIME)): - if (!$this->$col) { - return ''; - } - $guess = strtotime($this->$col); - if ($guess != -1) { - return strftime($format, $guess); - } - // eak... - no way to validate date time otherwise... - return $this->$col; - case ($cols[$col] & DB_DATAOBJECT_DATE): - if (!$this->$col) { - return ''; - } - $guess = strtotime($this->$col); - if ($guess != -1) { - return strftime($format,$guess); - } - // try date!!!! - require_once 'Date.php'; - $x = new Date($this->$col); - return $x->format($format); - - case ($cols[$col] & DB_DATAOBJECT_TIME): - if (!$this->$col) { - return ''; - } - $guess = strtotime($this->$col); - if ($guess > -1) { - return strftime($format, $guess); - } - // otherwise an error in type... - return $this->$col; - - case ($cols[$col] & DB_DATAOBJECT_MYSQLTIMESTAMP): - if (!$this->$col) { - return ''; - } - require_once 'Date.php'; - - $x = new Date($this->$col); - - return $x->format($format); - - - default: - return sprintf($format,$this->col); - } - - - } - - - /* ----------------------- Debugger ------------------ */ - - /** - * Debugger. - use this in your extended classes to output debugging information. - * - * Uses DB_DataObject::DebugLevel(x) to turn it on - * - * @param string $message - message to output - * @param string $logtype - bold at start - * @param string $level - output level - * @access public - * @return none - */ - function debug($message, $logtype = 0, $level = 1) - { - global $_DB_DATAOBJECT; - - if (empty($_DB_DATAOBJECT['CONFIG']['debug']) || - (is_int($_DB_DATAOBJECT['CONFIG']['debug']) && $_DB_DATAOBJECT['CONFIG']['debug'] < $level)) { - return; - } - // this is a bit flaky due to php's wonderfull class passing around crap.. - // but it's about as good as it gets.. - $class = (isset($this) && is_a($this,'DB_DataObject')) ? get_class($this) : 'DB_DataObject'; - - if (!is_string($message)) { - $message = print_r($message,true); - } - if (!is_int( $_DB_DATAOBJECT['CONFIG']['debug']) && is_callable( $_DB_DATAOBJECT['CONFIG']['debug'])) { - return call_user_func($_DB_DATAOBJECT['CONFIG']['debug'], $class, $message, $logtype, $level); - } - - if (!ini_get('html_errors')) { - echo "$class : $logtype : $message\n"; - flush(); - return; - } - if (!is_string($message)) { - $message = print_r($message,true); - } - echo "$class: $logtype: $message
\n"; - flush(); - } - - /** - * sets and returns debug level - * eg. DB_DataObject::debugLevel(4); - * - * @param int $v level - * @access public - * @return none - */ - function debugLevel($v = null) - { - global $_DB_DATAOBJECT; - if (empty($_DB_DATAOBJECT['CONFIG'])) { - DB_DataObject::_loadConfig(); - } - if ($v !== null) { - $r = isset($_DB_DATAOBJECT['CONFIG']['debug']) ? $_DB_DATAOBJECT['CONFIG']['debug'] : 0; - $_DB_DATAOBJECT['CONFIG']['debug'] = $v; - return $r; - } - return isset($_DB_DATAOBJECT['CONFIG']['debug']) ? $_DB_DATAOBJECT['CONFIG']['debug'] : 0; - } - - /** - * Last Error that has occured - * - use $this->_lastError or - * $last_error = &PEAR::getStaticProperty('DB_DataObject','lastError'); - * - * @access public - * @var object PEAR_Error (or false) - */ - var $_lastError = false; - - /** - * Default error handling is to create a pear error, but never return it. - * if you need to handle errors you should look at setting the PEAR_Error callback - * this is due to the fact it would wreck havoc on the internal methods! - * - * @param int $message message - * @param int $type type - * @param int $behaviour behaviour (die or continue!); - * @access public - * @return error object - */ - function raiseError($message, $type = null, $behaviour = null) - { - global $_DB_DATAOBJECT; - - if ($behaviour == PEAR_ERROR_DIE && !empty($_DB_DATAOBJECT['CONFIG']['dont_die'])) { - $behaviour = null; - } - - if (PEAR::isError($message)) { - $error = $message; - } else { - require_once 'DB/DataObject/Error.php'; - $error = PEAR::raiseError($message, $type, $behaviour, - $opts=null, $userinfo=null, 'DB_DataObject_Error' - ); - } - // this will never work totally with PHP's object model. - // as this is passed on static calls (like staticGet in our case) - - if (@is_object($this) && is_subclass_of($this,'db_dataobject')) { - $this->_lastError = $error; - } - - $_DB_DATAOBJECT['LASTERROR'] = $error; - - // no checks for production here?....... - DB_DataObject::debug($message,"ERROR",1); - return $error; - } - - /** - * Define the global $_DB_DATAOBJECT['CONFIG'] as an alias to PEAR::getStaticProperty('DB_DataObject','options'); - * - * After Profiling DB_DataObject, I discoved that the debug calls where taking - * considerable time (well 0.1 ms), so this should stop those calls happening. as - * all calls to debug are wrapped with direct variable queries rather than actually calling the funciton - * THIS STILL NEEDS FURTHER INVESTIGATION - * - * @access public - * @return object an error object - */ - function _loadConfig() - { - global $_DB_DATAOBJECT; - - $_DB_DATAOBJECT['CONFIG'] = &PEAR::getStaticProperty('DB_DataObject','options'); - - - } - /** - * Free global arrays associated with this object. - * - * Note: as we now store resultfields in a global, it is never freed, if you do alot of calls to find(), - * memory will grow gradually. - * - * - * @access public - * @return none - */ - function free() - { - global $_DB_DATAOBJECT; - - if (isset($_DB_DATAOBJECT['RESULTFIELDS'][$this->_DB_resultid])) { - unset($_DB_DATAOBJECT['RESULTFIELDS'][$this->_DB_resultid]); - } - if (isset($_DB_DATAOBJECT['RESULTS'][$this->_DB_resultid])) { - unset($_DB_DATAOBJECT['RESULTS'][$this->_DB_resultid]); - } - // this is a huge bug in DB! - $_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5]->num_rows = array(); - - } - - - /* ---- LEGACY BC METHODS - NOT DOCUMENTED - See Documentation on New Methods. ---*/ - - function _get_table() { return $this->table(); } - function _get_keys() { return $this->keys(); } - - - - -} -// technially 4.3.2RC1 was broken!! -// looks like 4.3.3 may have problems too.... -if (!defined('DB_DATAOBJECT_NO_OVERLOAD')) { - - if ((phpversion() != '4.3.2-RC1') && (version_compare( phpversion(), "4.3.1") > 0)) { - if (version_compare( phpversion(), "5") < 0) { - overload('DB_DataObject'); - } - $GLOBALS['_DB_DATAOBJECT']['OVERLOADED'] = true; - } -} diff --git a/glmPEAR/DB/DataObject/Cast.php b/glmPEAR/DB/DataObject/Cast.php deleted file mode 100755 index 0399455..0000000 --- a/glmPEAR/DB/DataObject/Cast.php +++ /dev/null @@ -1,340 +0,0 @@ - | -// +----------------------------------------------------------------------+ -// -// $Id: Cast.php,v 1.1.1.1 2008/04/28 15:20:47 jamie Exp $ -// -// Prototype Castable Object.. for DataObject queries -// - -/** -* -* @abstract Storage for Data that may be cast into a variety of formats. -* -* Common usages: -* // blobs -* $data = DB_DataObject_Cast::blob($somefile); -* $data = DB_DataObject_Cast::string($somefile); -* $dataObject->someblobfield = $data -* -* // dates? -* $d1 = new DB_DataObject_Cast::date('12/12/2000'); -* $d2 = new DB_DataObject_Cast::date(2000,12,30); -* $d3 = new DB_DataObject_Cast::date($d1->year, $d1->month+30, $d1->day+30); -* -* // time, datetime.. ????????? -* -* // raw sql???? -* $data = DB_DataObject_Cast::sql('cast("123123",datetime)'); -* $data = DB_DataObject_Cast::sql('NULL'); -* -* // int's/string etc. are proably pretty pointless..!!!! -* -* -* inside DB_DataObject, -* if (is_a($v,'db_dataobject_class')) { -* $value .= $v->toString(DB_DATAOBJECT_INT,'mysql'); -* } -* -* -* -* -* @version $Id: Cast.php,v 1.1.1.1 2008/04/28 15:20:47 jamie Exp $ -*/ -class DB_DataObject_Cast { - - /** - * Type of data Stored in the object.. - * - * @var string (date|blob|.....?) - * @access public - */ - var $type; - - /** - * Data For date representation - * - * @var int day/month/year - * @access public - */ - var $day; - var $month; - var $year; - - - /** - * Generic Data.. - * - * @var string - * @access public - */ - - var $value; - - - - /** - * Blob consructor - * - * create a Cast object from some raw data.. (binary) - * - * - * @param string (with binary data!) - * - * @return object DB_DataObject_Cast - * @access public - */ - - function blob($value) { - $r = new DB_DataObject_Cast; - $r->type = 'blob'; - $r->value = $value; - return $r; - } - - - /** - * String consructor (actually use if for ints and everything else!!! - * - * create a Cast object from some string (not binary) - * - * - * @param string (with binary data!) - * - * @return object DB_DataObject_Cast - * @access public - */ - - function string($value) { - $r = new DB_DataObject_Cast; - $r->type = 'string'; - $r->value = $value; - return $r; - } - - /** - * SQL constructor (for raw SQL insert) - * - * create a Cast object from some sql - * - * @param string (with binary data!) - * - * @return object DB_DataObject_Cast - * @access public - */ - - function sql($value) { - $r = new DB_DataObject_Cast; - $r->type = 'sql'; - $r->value = $value; - return $r; - } - - - /** - * Date Constructor - * - * create a Cast object from some string (not binary) - * - * - * @param vargs... accepts - * dd/mm - * dd/mm/yyyy - * yyyy-mm - * yyyy-mm-dd - * array(yyyy,dd) - * array(yyyy,dd,mm) - * - * - * - * @return object DB_DataObject_Cast - * @access public - */ - - function date() { - $args = func_get_args(); - switch(count($args)) { - case 0: // no args = today! - $bits = explode('-',date('Y-m-d')); - break; - case 1: // one arg = a string - - if (strpos($args[0],'/') !== false) { - $bits = array_reverse(explode('/',$args[0])); - } else { - $bits = explode('-',$args[0]); - } - default: // 2 or more.. - $bits = $args; - } - if (count($bits) == 1) { // if YYYY set day = 1st.. - $bits[] = 1; - } - - if (count($bits) == 2) { // if YYYY-DD set day = 1st.. - $bits[] = 1; - } - - // if year < 1970 we cant use system tools to check it... - // so we make a few best gueses.... - // basically do date calculations for the year 2000!!! - // fix me if anyone has more time... - if (($bits[0] < 1975) || ($bits[0] > 2030)) { - $oldyear = $bits[0]; - $bits = explode('-',date('Y-m-d',mktime(1,1,1,$bits[1],$bits[2],2000))); - $bits[0] = ($bits[0] - 2000) + $oldyear; - } else { - // now mktime - $bits = explode('-',date('Y-m-d',mktime(1,1,1,$bits[1],$bits[2],$bits[0]))); - } - $r = new DB_DataObject_Cast; - $r->type = 'date'; - list($r->year,$r->month,$r->day) = $bits; - return $r; - } - - /** - * get the string to use in the SQL statement for this... - * - * - * @param int $to Type (DB_DATAOBJECT_* - * @param string $db (eg. mysql|mssql.....) - * - * - * @return string - * @access public - */ - - function toString($to=false,$db='mysql') { - // if $this->type is not set, we are in serious trouble!!!! - // values for to: - $method = 'toStringFrom'.$this->type; - return $this->$method($to,$db); - } - - /** - * get the string to use in the SQL statement from a blob of binary data - * ** Suppots only blob->postgres::bytea - * - * @param int $to Type (DB_DATAOBJECT_* - * @param string $db (eg. mysql|mssql.....) - * - * - * @return string - * @access public - */ - function toStringFromBlob($to,$db) { - // first weed out invalid casts.. - // in blobs can only be cast to blobs.! - - // perhaps we should support TEXT fields??? - - if (!($to & DB_DATAOBJECT_BLOB)) { - return PEAR::raiseError('Invalid Cast from a DB_DataObject_Cast::blob to something other than a blob!'); - } - - switch ($db) { - case 'pgsql': - return "'".pg_escape_bytea($this->value)."'::bytea"; - - default: - return PEAR::raiseError("DB_DataObject_Cast cant handle blobs for Database:$db Yet"); - } - - } - - /** - * get the string to use in the SQL statement for a blob from a string! - * ** Suppots only string->postgres::bytea - * - * - * @param int $to Type (DB_DATAOBJECT_* - * @param string $db (eg. mysql|mssql.....) - * - * - * @return string - * @access public - */ - function toStringFromString($to,$db) { - // first weed out invalid casts.. - // in blobs can only be cast to blobs.! - - // perhaps we should support TEXT fields??? - // - - if (!($to & DB_DATAOBJECT_BLOB)) { - return PEAR::raiseError('Invalid Cast from a DB_DataObject_Cast::string to something other than a blob!'. - ' (why not just use native features)'); - } - - switch ($db) { - case 'pgsql': - return "'".pg_escape_string($this->value)."'::bytea"; - - default: - return PEAR::raiseError("DB_DataObject_Cast cant handle blobs for Database:$db Yet"); - } - - } - - - /** - * get the string to use in the SQL statement for a date - * - * - * - * @param int $to Type (DB_DATAOBJECT_* - * @param string $db (eg. mysql|mssql.....) - * - * - * @return string - * @access public - */ - function toStringFromDate($to,$db) { - // first weed out invalid casts.. - // in blobs can only be cast to blobs.! - // perhaps we should support TEXT fields??? - // - - if (($to !== false) && !($to & DB_DATAOBJECT_DATE)) { - return PEAR::raiseError('Invalid Cast from a DB_DataObject_Cast::string to something other than a date!'. - ' (why not just use native features)'); - } - return "'{$this->year}-{$this->month}-{$this->day}'"; - } - - - - /** - * get the string to use in the SQL statement for a raw sql statement. - * - * @param int $to Type (DB_DATAOBJECT_* - * @param string $db (eg. mysql|mssql.....) - * - * - * @return string - * @access public - */ - function toStringFromSql($to,$db) { - return $this->value; - } - - - - -} - diff --git a/glmPEAR/DB/DataObject/Error.php b/glmPEAR/DB/DataObject/Error.php deleted file mode 100755 index 5713210..0000000 --- a/glmPEAR/DB/DataObject/Error.php +++ /dev/null @@ -1,59 +0,0 @@ - | -// +----------------------------------------------------------------------+ -// -// $Id: Error.php,v 1.1.1.1 2008/04/28 15:20:47 jamie Exp $ -// -// DataObjects error handler, loaded on demand... -// - -/** - * DB_DataObject_Error is a quick wrapper around pear error, so you can distinguish the - * error code source. - * messages. - * - * @package DB_DataObject - * @author Alan Knowles - */ -class DB_DataObject_Error extends PEAR_Error -{ - - /** - * DB_DataObject_Error constructor. - * - * @param mixed $code DB error code, or string with error message. - * @param integer $mode what "error mode" to operate in - * @param integer $level what error level to use for $mode & PEAR_ERROR_TRIGGER - * @param mixed $debuginfo additional debug info, such as the last query - * - * @access public - * - * @see PEAR_Error - */ - function DB_DataObject_Error($message = '', $code = DB_ERROR, $mode = PEAR_ERROR_RETURN, - $level = E_USER_NOTICE) - { - $this->PEAR_Error('DB_DataObject Error: ' . $message, $code, $mode, $level); - - } - - - // todo : - support code -> message handling, and translated error messages... - - - -} diff --git a/glmPEAR/DB/DataObject/FormBuilder.php b/glmPEAR/DB/DataObject/FormBuilder.php deleted file mode 100755 index 8ed9714..0000000 --- a/glmPEAR/DB/DataObject/FormBuilder.php +++ /dev/null @@ -1,2574 +0,0 @@ - | -// +----------------------------------------------------------------------+ - -/** - * This class adds some nice utility methods to the DataObject class - * to speed up prototyping new applications - like auto-generating fully - * functional forms using HTML_QuickForm. - * - * All the settings for FormBuilder must be in a section [DB_DataObject_FormBuilder] - * within the DataObject.ini file (or however you've named it). - * If you stuck to the DB_DataObject example in the doc, you'll read in your - * config like this: - * - * $config = parse_ini_file('DataObject.ini', true); - * foreach ($config as $class => $values) { - * $options = &PEAR::getStaticProperty($class, 'options'); - * $options = $values; - * } - * - * Unfortunately, DataObject will overwrite FormBuilder's settings when first instantiated, - * so you'll have to add another line after that: - * - * $_DB_DATAOBJECT_FORMBUILDER['CONFIG'] = $config['DB_DataObject_FormBuilder']; - * - * Now you're ready to go! - * - * You can also set any option through your DB_DataObject derived classes by - * appending 'fb_' to the option name. Ex: 'fb_fieldLabels'. This is the - * preferred way of setting DataObject-specific options. - * - * You may also set all options manually by setting them in the DO ir FB objects. - * - * You may also set the options in an FB derived class, but this isn't as well - * supported. - * - * In addition, there are special methods you can define in your DataObject classes for even more control. - *
    - *
  • preGenerateForm(&$formBuilder): - * This method will be called before the form is generated. Use this to change - * property values or options in your DataObject. This is the normal plave to - * set up fb_preDefElements. Note: the $formBuilder object passed in has not - * yet copied the options from the DataObject into it. If you plan to use the - * functions in FB in this method, call populateOptions() on it first. - *
  • - *
  • postGenerateForm(&$form): - * This method will be called after the form is generated. The form is passed in by reference so you can - * alter it. Use this method to add, remove, or alter elements in the form or the form itself. - *
  • - *
  • preProcessForm(&$values): - * This method is called just before FormBuilder processes the submitted form data. The values are sent - * by reference in the first parameter as an associative array. The key is the element name and the value - * the submitted value. You can alter the values as you see fit (md5 on passwords, for example). - *
  • - *
  • postProcessForm(&$values): - * This method is called just after FormBuilder processed the submitted form data. The values are again - * sent by reference. This method could be used to inform the user of changes, alter the DataObject, etc. - *
  • - *
  • getForm(): - * If this function exists, it will be used instead of FormBuilder's internal form generation routines - * Use this only if you want to create the entire form on your own. - *
  • - *
- * - * Note for PHP5-users: These properties have to be public! In general, you can - * override all settings from the .ini file by setting similarly-named properties - * in your DataObject classes. - * - * Most basic usage: - * - * $do =& new MyDataObject(); - * // Insert "$do->get($some_id);" here to edit an existing object instead of making a new one - * $fg =& DB_DataObject_FormBuilder::create($do); - * $form =& $fg->getForm(); - * if ($form->validate()) { - * $form->process(array(&$fg,'processForm'), false); - * $form->freeze(); - * } - * $form->display(); - * - * - * For more information on how to use the DB_DataObject or HTML_QuickForm packages - * themselves, please see the excellent documentation on http://pear.php.net/. - * - * @package DB_DataObject_FormBuilder - * @author Markus Wolff - * @version $Id: FormBuilder.php,v 1.1.1.1 2008/04/28 15:20:47 jamie Exp $ - */ - -// Import requirements -require_once ('DB/DataObject.php'); - -// Constants used for forceQueryType() -define ('DB_DATAOBJECT_FORMBUILDER_QUERY_AUTODETECT', 0); -define ('DB_DATAOBJECT_FORMBUILDER_QUERY_FORCEINSERT', 1); -define ('DB_DATAOBJECT_FORMBUILDER_QUERY_FORCEUPDATE', 2); -define ('DB_DATAOBJECT_FORMBUILDER_QUERY_FORCENOACTION', 3); - -// Constants used for cross/triple links -define ('DB_DATAOBJECT_FORMBUILDER_CROSSLINK', 1048576); -define ('DB_DATAOBJECT_FORMBUILDER_TRIPLELINK', 2097152); -define ('DB_DATAOBJECT_FORMBUILDER_ENUM', 4194304); -define ('DB_DATAOBJECT_FORMBUILDER_REVERSELINK',8388608); - -// Error code constants -define ('DB_DATAOBJECT_FORMBUILDER_ERROR_UNKNOWNDRIVER', 4711); -define ('DB_DATAOBJECT_FORMBUILDER_ERROR_NODATAOBJECT', 4712); - -class DB_DataObject_FormBuilder -{ - //PROTECTED vars - /** - * If you want to use the generator on an existing form object, pass it - * to the factory method within the options array, element name: 'form' - * (who would have guessed?) - * - * @access protected - * @see DB_DataObject_Formbuilder() - */ - var $_form = false; - - /** - * Contains the last validation errors, if validation checking is enabled. - * - * @access protected - */ - var $_validationErrors = false; - - /** - * Used to determine which action to perform with the submitted data in processForm() - * - * @access protected - */ - var $_queryType = DB_DATAOBJECT_FORMBUILDER_QUERY_AUTODETECT; - - /** - * If false, FormBuilder will use the form object from $_form as a basis for the new - * form: It will just add elements to the existing form object, not generate a new one. - * If true, FormBuilder will generate a new form object, create all elements as needed for - * the given DataObject, then strip the elements from the exiting form object in $_form - * and add it to the newly generated form object. - * - * @access protected - */ - var $_appendForm = false; - - - - //PUBLIC vars - /** - * Add a header to the form - if set to true, the form will - * have a header element as the first element in the form. - * - * @access public - * @see formHeaderText - */ - var $addFormHeader = true; - - /** - * Text for the form header. If not set, the name of the database - * table this form represents will be used. - * - * @access public - * @see addFormHeader - */ - var $formHeaderText = null; - - /** - * Text that is displayed as an error message if a validation rule - * is violated by the user's input. Use %s to insert the field name. - * - * @access public - * @see requiredRuleMessage - */ - var $ruleViolationMessage = '%s: The value you have entered is not valid.'; - - /** - * Text that is displayed as an error message if a required field is - * left empty. Use %s to insert the field name. - * - * @access public - * @see ruleViolationMessage - */ - var $requiredRuleMessage = 'The field %s is required.'; - - /** - * If set to TRUE, the current DataObject's validate method is being called - * before the form data is processed. If errors occur, no insert/update operation - * will be made on the database. Use getValidationErrors() to retrieve the reasons - * for a failure. - * Defaults to FALSE. - * - * @access public - */ - var $validateOnProcess = false; - - /** - * The language used in date fields. See documentation of HTML_Quickform's - * date element for more information. - * - * @see HTML_QuickForm_date - */ - var $dateFieldLanguage = 'en'; - - /** - * Callback method to convert a date from the format it is stored - * in the database to the format used by the QuickForm element that - * handles date values. Must have a format usable with call_user_func(). - */ - var $dateFromDatabaseCallback = array('DB_DataObject_FormBuilder','_date2array'); - - /** - * Callback method to convert a date from the format used by the QuickForm - * element that handles date values to the format the database can store it in. - * Must have a format usable with call_user_func(). - */ - var $dateToDatabaseCallback = array('DB_DataObject_FormBuilder','_array2date'); - - /** - * A format string that represents the display settings for QuickForm date elements. - * Example: "d-m-Y". See QuickForm documentation for details on format strings. - * Legal letters to use in the format string that work with FormBuilder are: - * d,m,Y,H,i,s - */ - var $dateElementFormat = 'd-m-Y'; - - /** - * A format string that represents the display settings for QuickForm time elements. - * Example: "H:i:s". See QuickForm documentation for details on format strings. - * Legal letters to use in the format string that work with FormBuilder are: - * d,m,Y,H,i,s - */ - var $timeElementFormat = 'H:i:s'; - - /** - * A format string that represents the display settings for QuickForm datetime elements. - * Example: "d-m-Y H:i:s". See QuickForm documentation for details on format strings. - * Legal letters to use in the format string that work with FormBuilder are: - * d,m,Y,H,i,s - */ - var $dateTimeElementFormat = 'd-m-Y H:i:s'; - - /** - * This is for the future support of string date formats other than ISO, but - * currently, that's the only supported one. Set to 1 for ISO, other values - * may be available later on. - */ - var $dbDateFormat = 1; - - /** - * These fields will be used when displaying a link record. The fields - * listed will be seperated by ", ". If you specify a link field as a - * display field and linkDisplayLevel is not 0, the link will be followed - * and the display fields of the record linked to displayed within parenthesis. - * - * For example, say we have these tables: - * - * [person] - * - * name = 130 - * gender_id = 129 - * - * [gender] - * id = 129 - * name = 130 - * - * - * this link: - * - * [person] - * gender_id = gender:id - * - * - * and this data: - * Person: - * name: "Justin Patrin" - * gender_id: 1 - * Gender: - * id: 1 - * name: "male" - * - * If person's display fields are: - * - * - * and gender's display fields are: - * - * - * and we set linkDisplayLevel to 0, the person record will be displayed as: - * "Justin Patrin, 1" - * - * If we set linkDisplayLevel to 1, the person record will be displayed as: - * "Justin Patrin, (male)" - */ - var $linkDisplayFields = array(); - - /** - * The fields to be used for sorting the options of an auto-generated link - * element. You can specify ASC and DESC in these options as well: - * - * - * You may also want to escape the field names if they are reserved words in - * the database you're using: - * getDatabaseConnection(); - * $this->fb_linkOrderFields = array($db->quoteIdentifier('config'), - * $db->quoteIdentifier('select').' DESC'); - * } - * } - * ?> - */ - var $linkOrderFields = array(); - - /** - * The caption of the submit button, if created. - */ - var $submitText = 'Submit'; - - /** - * If set to false, no submit button will be created for your forms. Useful when - * used together with QuickForm_Controller when you already have submit buttons - * for next/previous page. By default, a button is being generated. - */ - var $createSubmit = true; - - /** - * Array of field labels. The key of the element is the field name. Use this if - * you want to keep the auto-generated elements, but still define your - * own labels for them. - */ - var $fieldLabels = array(); - - /** - * Array of fields to render elements for. If a field is not given, it will not - * be rendered. If empty, all fields will be rendered (except, normally, the - * primary key). - */ - var $fieldsToRender = array(); - - /** - * Array of fields which the user can edit. If a field is rendered but not - * specified in this array, it will be frozen. Ignored if not given. - */ - var $userEditableFields = array(); - - /** - * Array of groups to put certain elements in. The key is an element name, the - * value is the group to put the element in. - */ - var $preDefGroups = array(); - - /** - * Indexed array of element names. If defined, this will determine the order - * in which the form elements are being created. This is useful if you're - * using QuickForm's default renderer or dynamic templates and the order of - * the fields in the database doesn't match your needs. - */ - var $preDefOrder = array(); - - /** - * Array of user-defined QuickForm elements that will be used for the field - * matching the array key. If no match is found, the element for that field - * will be auto-generated. Make your element objects either in the - * preGenerateForm() method or in the getForm() method. Use - * HTML_QuickForm::createElement() to do this. - * - * If you wish to put in a group of elements in place of a single element, - * you can put an array in preDefElements instead of a single element. The - * name of the group will be the name of the replaced element. - */ - var $preDefElements = array(); - - /** - * An array of the link or date fields which should have an empty option added to the - * select box. This is only a valid option for fields which link to another - * table or date fields. - */ - var $selectAddEmpty = array(); - - /** - * An string to put in the "empty option" added to select fields - */ - var $selectAddEmptyLabel = ''; - - /** - * By default, hidden fields are generated for the primary key of a - * DataObject. This behaviour can be deactivated by setting this option to - * false. - */ - var $hidePrimaryKey = true; - - /** - * A simple array of field names indicating which of the fields in a particular - * table/class are actually to be treated as textareas. This is an unfortunate - * workaround that is neccessary because the DataObject generator script does - * not make a difference between any other datatypes than string and integer. - * When it does, this can be dropped. - */ - var $textFields = array(); - - /** - * A simple array of field names indicating which of the fields in a particular - * table/class are actually to be treated date fields. This is an unfortunate - * workaround that is neccessary because the DataObject generator script does - * not make a difference between any other datatypes than string and integer. - * When it does, this can be dropped. - */ - var $dateFields = array(); - - /** - * A simple array of field names indicating which of the fields in a particular - * table/class are actually to be treated time fields. This is an unfortunate - * workaround that is neccessary because the DataObject generator script does - * not make a difference between any other datatypes than string and integer. - * When it does, this can be dropped. - */ - var $timeFields = array(); - - /** - * Array to configure the type of the link elements. By default, a select box - * will be used. The key is the name of the link element. The value is 'radio' - * or 'select'. If you choose 'radio', radio buttons will be made instead of - * a select box. - */ - var $linkElementTypes = array(); - - /** - * A simple array of fields names which should be treated as ENUMs. A select - * box will be created with the enum options. If you add this field to the - * linkElementTypes array and give it a 'radio' type, you will get radio buttons - * instead. - * - * The default handler for enums is only tested in mysql. If you are using a - * different DB backend, use enumOptionsCallback or enumOptions. - */ - var $enumFields = array(); - - /** - * A valid callback which will return the options in a simple array of strings - * for an enum field given the table and field names. - */ - var $enumOptionsCallback = array(); - - /** - * An array which holds enum options for specific fields. Each key should be a - * field in the current table and each value holds a an array of strings which - * are the possible values for the enum. This will only be used if the field is - * listed in enumFields. - */ - var $enumOptions = array(); - - /** - * An array which holds the field names of those fields which are booleans. - * They will be displayed as checkboxes. - */ - var $booleanFields = array(); - - /** - * The text to put between crosslink elements. - */ - var $crossLinkSeparator = '
'; - - /** - * If this is set to 1 or above, links will be followed in the display fields - * and the display fields of the record linked to will be used for display. - * If this is set to 2, links will be followed in the linked record as well. - * This can be set to any number of links you wish but could easily slow down - * your application if set to more than 1 or 2 (but only if you have links in - * your display fields that go that far ;-)). For a more in-depth example, see - * the docs for linkDisplayFields. - */ - var $linkDisplayLevel = 0; - - /** - * The crossLinks array holds data pertaining to many-many links. If you - * have a table which links two tables together, you can use this to - * automatically create a set of checkboxes or a multi-select on your form. - * The simplest way of using this is: - * - * 'crossLinkTable')); - * } - * ?> - * - * Where crossLinkTable is the name of the linking table. You can have as - * many cross-link entries as you want. Try it with just the table ewntry - * first. If it doesn't work, you can specify the fields to use as well. - * - * 'fromField' => 'linkFieldToCurrentTable' //This is the field which links to the current (from) table - * 'toField' => 'linkFieldToLinkedTable' //This is the field which links to the "other" (to) table - * - * To get a multi-select add a 'type' key which it set to 'select'. - * - * 'crossLinkTable', 'type' => 'select')); - * } - * ?> - * - * An example: I have a user table and a group table, each with a primary - * key called id. There is a table called user_group which has fields user_id - * and group_id which are set up as links to user and group. Here's the - * configuration array that could go in both the user DO and the group DO: - * - * 'user_group')); - * ?> - * - * Here is the full configuration for the user DO: - * - * 'user_group', - * 'fromField' => 'user_id', - * 'toField' => 'group_id')); - * ?> - * - * And the full configuration for the group DO: - * - * 'user_group', - * 'fromField' => 'group_id', - * 'toField' => 'user_id')); - * ?> - * - * - * You can also specify the seperator between the elements with crossLinkSeperator. - */ - var $crossLinks = array(); - - /** - * You can also specify extra fields to edit in the a crossLink table with - * this option. For example, if the user_group table mentioned above had - * another field called 'role' which was a text field, you could specify it - * like this in the user_group DataObject class: - * - * - * - * - * This would cause a text box to show up next to each checkbox in the - * user_group section of the form for the field 'role'. - * - * You can specify as many fields as you want in the 'extraFields' array. - * - * Note: If you specify a linked field in 'extraFields' you'll get a select - * box just like when you do a normal link field in a FormBuilder form. :-) - */ - var $crossLinkExtraFields = array(); - - /** - * Holds triple link data. - * The tripleLinks array can be used to display checkboxes for "triple-links". A triple link is set - * up with a table which links to three different tables. These will show up as a table of checkboxes - * The initial setting (table) is the same as for crossLinks. The field configuration keys (if you - * need them) are: - * - * 'fromField' - * 'toField1' - * 'toField2' - * - */ - var $tripleLinks = array(); - - /** - * Holds reverseLink configuration. - * A reverseLink is a table which links back to the current table. For - * example, let say we have a "gender" table which has Male and Female in it - * and a "person" table which has the fields "name", which holds the person's - * name and "genre_id" which links to the genre. If you set up a form for the - * gender table, the person table can be a reverseLink. The setup in the - * gender table would look like this: - * - * 'person')); - * } - * ?> - * - * Now a list of people will be shown in the gender form with a checkbox next - * to it which is checked if the record currently links to the one you're - * editing. In addition, some special text will be added to the end of the - * label for the person record if it's linked to another gender. - * - * Say we have a person record with the name "Justin Patrin" which is linked - * to the gender "Male". If you view the form for the gender "Male", the - * checkbox next to "Justin Patrin" will be checked. If you choose the - * "Female" gender the checkbox will be unchecked and it will say: - * Justin Patrin - currently linked to - Male - * - * If the link field is set as NOT NULL then FormBuilder will not process - * and unchecked checkbox unless you specify a default value to set the link - * to. If null is allowed, the link will be set to NULL. To specify a default - * value: - * - * 'person', - * 'defaultLinkValue' => 5)); - * } - * ?> - * - * Now if a checkbox is unchecked the link field will be set to 5...whatever - * that means. Be careful here as you need to make sure you enter the correct - * value here (probably the value of the primary key of the record you want - * to link to by default). - * - * You may also set the text which is displayed between the record and the - * currently linked to record. - * - * 'person', - * 'linkText' => ' is currently listed as a ')); - * } - * ?> - * - * If you select "Female" the Justin Patrin entry would now say: - * Justin Patrin__ is currently listed as a Male__ - */ - var $reverseLinks = array(); - - /** - * If set to true, validation rules will also be client side. - */ - var $clientRules = false; - - /** - * A string to prepend to element names. Together with elementNamePostfix, this option allows you to - * alter the form element names that FormBuilder uses to create and process elements. The main use for - * this is to combine multiple forms into one. For example, if you wanted to use multiple FB forms for - * the same table within one actual HTML form you could do something like this: - * elementNamePrefix = 'formOne'; - * $form = $fb->getForm(); - * - * $do2 = DB_DataObject::factory('table'); - * $fb2 = DB_DataObject_FormBuilder::create($do2); - * $fb->elementNamePrefix = 'formTwo'; - * $fb->useForm($form); - * $form = $fb->getForm(); - * - * //normal processing here - * ?> - * - * If you assume that "table: has one field, "name", then the resultant form will have two elements: - * "formOnename" and "formTwoname". - * - * Please note: You *cannot* use '[' or ']' anywhere in the prefix or postfix. Doing so - * will cause FormBuilder to not be able to process the form. - */ - var $elementNamePrefix = ''; - - /** - * A postfix to put after element names in the form - * @see DB_DataObject_FormBuilder::elementNamePrefix - */ - var $elementNamePostfix = ''; - - /** - * Whether or not to use call-time-pass-by-reference when calling DataObject callbacks - */ - var $useCallTimePassByReference = false; - - /** - * DB_DataObject_FormBuilder::create() - * - * Factory method. As this is meant as an abstract class, it is the only supported - * method to make a new object instance. Pass the DataObject-derived class you want to - * build a form from as the first parameter. Use the second to pass additional options. - * - * Options can be: - * - 'ruleViolationMessage' : See description of similarly-named class property - * - 'requiredRuleMessage' : See description of similarly-named class property - * - 'addFormHeader' : See description of similarly-named class property - * - 'formHeaderText' : See description of similarly-named class property - * - * The third parameter is the name of a driver class. A driver class will take care of - * the actual form generation. This way it's possible to have FormBuilder build different - * forms for different types of output media from the same set of DataObjects. - * - * Currently available driver classes: - * - QuickForm (stable) - * - XUL (experimental!) - * - * @param object $do The DB_DataObject-derived object for which a form shall be built - * @param array $options An optional associative array of options. - * @param string $driver Optional: Name of the driver class for constructing the form object. Default: QuickForm. - * @access public - * @returns object DB_DataObject_FormBuilder or PEAR_Error object - */ - function &create(&$do, $options = false, $driver = 'QuickForm') - { - if (!is_a($do, 'db_dataobject')) { - $err =& PEAR::raiseError('DB_DataObject_FormBuilder::create(): Object does not extend DB_DataObject.', - DB_DATAOBJECT_FORMBUILDER_ERROR_NODATAOBJECT); - return $err; - } - - @include_once('DB/DataObject/FormBuilder/'.$driver.'.php'); - $className = 'db_dataobject_formbuilder_'.strtolower($driver); - if (class_exists($className)) { - $obj = &new $className($do, $options); - return $obj; - } - $err =& PEAR::raiseError('DB_DataObject_FormBuilder::create(): Driver class "'.$className.'" not found.', - DB_DATAOBJECT_FORMBUILDER_ERROR_UNKNOWNDRIVER); - return $err; - } - - - /** - * DB_DataObject_FormBuilder::DB_DataObject_FormBuilder() - * - * The class constructor. - * - * @param object $do The DB_DataObject-derived object for which a form shall be built - * @param array $options An optional associative array of options. - * @access public - */ - function DB_DataObject_FormBuilder(&$do, $options = false) - { - // Set default callbacks first! - $this->dateToDatabaseCallback = array(&$this, '_array2date'); - $this->dateFromDatabaseCallback = array(&$this, '_date2array'); - $this->enumOptionsCallback = array(&$this, '_getEnumOptions'); - - // Read in config - $vars = get_object_vars($this); - if (isset($GLOBALS['_DB_DATAOBJECT_FORMBUILDER']['CONFIG'])) { - //read all config options into member vars - foreach ($GLOBALS['_DB_DATAOBJECT_FORMBUILDER']['CONFIG'] as $key => $value) { - if (in_array($key, $vars) && $key[0] != '_') { - $this->$key = $value; - } - } - } - if (is_array($options)) { - reset($options); - while (list($key, $value) = each($options)) { - if (in_array($key, $vars) && $key[0] != '_') { - $this->$key = $value; - } - } - } - - $defVars = get_class_vars(get_class($this)); - foreach ($defVars as $member => $value) { - if (is_array($value) && isset($this->$member) && is_string($this->$member)) { - $this->$member = $this->_explodeArrString($this->$member); - } - } - $this->_do = &$do; - } - - /** - * Gets the primary key field name for a DataObject - * Looks for $do->_primary_key, $do->sequenceKey(), then $do->keys() - * - * @param DB_DataObject the DataObject to get the primary key of - * @return string the name of the primary key or false if none is found - */ - function _getPrimaryKey(&$do) { - if (isset($do->_primary_key)) { - return $do->_primary_key; - } elseif (($seq = $do->sequenceKey()) && isset($seq[0])) { - return $seq[0]; - } else { - if (($keys = $do->keys()) && isset($keys[0])) { - return $keys[0]; - } - } - return false; - } - - /** - * DB_DataObject_FormBuilder::_getEnumOptions() - * Gets the possible values for an enum field from the DB. This is only tested in - * mysql and will likely break on all other DB backends. - * - * @param string Table to query on - * @param string Field to get enum options for - * @return array array of strings, each being a possible value for th eenum field - */ - function _getEnumOptions($table, $field) { - $db = $this->_do->getDatabaseConnection(); - if (isset($GLOBALS['_DB_DATAOBJECT']['CONFIG']['quote_identifiers']) && $GLOBALS['_DB_DATAOBJECT']['CONFIG']['quote_identifiers']) { - $table = $db->quoteIdentifier($table); - } - $option = $db->getRow('SHOW COLUMNS FROM '.$table.' LIKE '.$db->quoteSmart($field), DB_FETCHMODE_ASSOC); - if (PEAR::isError($option)) { - return PEAR::raiseError('There was an error querying for the enum options for field "'.$field.'". You likely need to use enumOptionsCallback.'); - } - $option = substr($option['Type'], strpos($option['Type'], '(') + 1); - $option = substr($option, 0, strrpos($option, ')') - strlen($option)); - $split = explode(',', $option); - $options = array(); - $option = ''; - for ($i = 0; $i < sizeof($split); ++$i) { - $option .= $split[$i]; - if (substr_count($option, "'") % 2 == 0) { - $option = trim(trim($option), "'"); - $options[$option] = $option; - $option = ''; - } - } - return $options; - } - - /** - * DB_DataObject_FormBuilder::_generateForm() - * - * Builds a simple HTML form for the current DataObject. Internal function, called by - * the public getForm() method. You can override this in child classes if needed, but - * it's also possible to leave this as it is and just override the getForm() method - * to simply fine-tune the auto-generated form object (i.e. add/remove elements, alter - * options, add/remove rules etc.). - * If a key with the same name as the current field is found in the fb_preDefElements - * property, the QuickForm element object contained in that array will be used instead - * of auto-generating a new one. This allows for complete step-by-step customizing of - * your forms. - * - * Note for date fields: HTML_QuickForm allows passing of an options array to the - * HTML_QuickForm_date element. You can define your own options array for date elements - * in your DataObject-derived classes by defining a method "dateOptions($fieldName)". - * FormBuilder will call that method whenever it encounters a date field and expects to - * get back a valid options array. - * - * @param string $action The form action. Optional. If set to false (default), PHP_SELF is used. - * @param string $target The window target of the form. Optional. Defaults to '_self'. - * @param string $formName The name of the form, will be used in "id" and "name" attributes. If set to false (default), the class name is used - * @param string $method The submit method. Defaults to 'post'. - * @return object - * @access protected - * @author Markus Wolff - * @author Fabien Franzen - */ - function &_generateForm($action = false, $target = '_self', $formName = false, $method = 'post') - { - if ($formName === false) { - $formName = strtolower(get_class($this->_do)); - } - if ($action === false) { - $action = $_SERVER['PHP_SELF']; - } - - // Retrieve the form object to use (may depend on the current renderer) - $form =& $this->_createFormObject($formName, $method, $action, $target); - - // Initialize array with default values - //$formValues = $this->_do->toArray(); - - // Add a header to the form - set addFormHeader property to false to prevent this - $this->_addFormHeader($form); - - // Go through all table fields and create appropriate form elements - $keys = $this->_do->keys(); - - // Reorder elements if requested - $elements = $this->_reorderElements(); - if ($elements == false) { //no sorting necessary - $elements = $this->_getFieldsToRender(); - } - //get elements to freeze - $user_editable_fields = $this->_getUserEditableFields(); - if (is_array($user_editable_fields)) { - $elements_to_freeze = array_diff(array_keys($elements), $user_editable_fields); - } else { - $elements_to_freeze = array(); - } - - $links = $this->_do->links(); - $pk = $this->_getPrimaryKey($this->_do); - $rules = array(); - foreach ($elements as $key => $type) { - // Check if current field is primary key. And primary key hiding is on. If so, make hidden field - if (in_array($key, $keys) && $this->hidePrimaryKey == true) { - $formValues[$key] = $this->_do->$key; - $element =& $this->_createHiddenField($key); - } else { - unset($element); - // Try to determine field types depending on object properties - $notNull = $type & DB_DATAOBJECT_NOTNULL; - if (in_array($key, $this->dateFields)) { - $type = DB_DATAOBJECT_DATE; - } elseif (in_array($key, $this->timeFields)) { - $type = DB_DATAOBJECT_TIME; - } elseif (in_array($key, $this->textFields)) { - $type = DB_DATAOBJECT_TXT; - } elseif (in_array($key, $this->enumFields)) { - $type = DB_DATAOBJECT_FORMBUILDER_ENUM; - } elseif (in_array($key, $this->booleanFields)) { - $type = DB_DATAOBJECT_BOOL; - } - if (isset($this->preDefElements[$key]) - && (is_object($this->preDefElements[$key]) || is_array($this->preDefElements[$key]))) { - // Use predefined form field, IMPORTANT: This may depend on the used renderer!! - $element =& $this->preDefElements[$key]; - } elseif (is_array($links) && isset($links[$key])) { - // If this field links to another table, display selectbox or radiobuttons - $opt = $this->getSelectOptions($key, false, !$notNull); - if (isset($this->linkElementTypes[$key]) && $this->linkElementTypes[$key] == 'radio') { - $element =& $this->_createRadioButtons($key, $opt); - } else { - $element =& $this->_createSelectBox($key, $opt); - } - unset($opt); - } - - // No predefined object available, auto-generate new one - $elValidator = false; - $elValidRule = false; - - // Auto-detect field types depending on field's database type - switch (true) { - case ($type & DB_DATAOBJECT_BOOL): - $formValues[$key] = $this->_do->$key; - if (!isset($element)) { - $element =& $this->_createCheckbox($key, null, null, $this->getFieldLabel($key)); - } - break; - case ($type & DB_DATAOBJECT_INT): - $formValues[$key] = $this->_do->$key; - if (!isset($element)) { - $element =& $this->_createIntegerField($key); - $elValidator = 'numeric'; - } - break; - case (($type & DB_DATAOBJECT_DATE) && ($type & DB_DATAOBJECT_TIME)): - $this->debug('DATE & TIME CONVERSION using callback for element '.$key.' ('.$this->_do->$key.')!', 'FormBuilder'); - $formValues[$key] = call_user_func($this->dateFromDatabaseCallback, $this->_do->$key); - if (!isset($element)) { - $element =& $this->_createDateTimeElement($key); - } - break; - case ($type & DB_DATAOBJECT_DATE): - $this->debug('DATE CONVERSION using callback for element '.$key.' ('.$this->_do->$key.')!', 'FormBuilder'); - $formValues[$key] = call_user_func($this->dateFromDatabaseCallback, $this->_do->$key); - if (!isset($element)) { - $element =& $this->_createDateElement($key); - } - break; - case ($type & DB_DATAOBJECT_TIME): - $this->debug('TIME CONVERSION using callback for element '.$key.' ('.$this->_do->$key.')!', 'FormBuilder'); - $formValues[$key] = call_user_func($this->dateFromDatabaseCallback, $this->_do->$key); - if (!isset($element)) { - $element =& $this->_createTimeElement($key); - } - break; - case ($type & DB_DATAOBJECT_TXT): - $formValues[$key] = $this->_do->$key; - if (!isset($element)) { - $element =& $this->_createTextArea($key); - } - break; - case ($type & DB_DATAOBJECT_STR): - $formValues[$key] = $this->_do->$key; - if (!isset($element)) { - // If field content contains linebreaks, make textarea - otherwise, standard textbox - if (isset($this->_do->$key) && strlen($this->_do->$key) && strstr($this->_do->$key, "\n")) { - $element =& $this->_createTextArea($key); - } else { - $element =& $this->_createTextField($key); - } - } - break; - case ($type & DB_DATAOBJECT_FORMBUILDER_CROSSLINK): - unset($element); - // generate crossLink stuff - if ($pk === false) { - return PEAR::raiseError('A primary key must exist in the base table when using crossLinks.'); - } - $crossLink = $this->crossLinks[$key]; - $groupName = '__crossLink_' . $crossLink['table']; - $crossLinksDo = DB_DataObject::factory($crossLink['table']); - if (PEAR::isError($crossLinksDo)) { - die($crossLinksDo->getMessage()); - } - - $crossLinksLinks = $crossLinksDo->links(); - - list($linkedtable, $linkedfield) = explode(':', $crossLinksLinks[$crossLink['toField']]); - $all_options = $this->_getSelectOptions($linkedtable); - $selected_options = array(); - if (isset($this->_do->$pk) && strlen($this->_do->$pk)) { - $crossLinksDo->{$crossLink['fromField']} = $this->_do->$pk; - if (method_exists($this->_do, 'preparelinkeddataobject')) { - if ($this->useCallTimePassByReference) { - eval('$this->_do->prepareLinkedDataObject(&$crossLinksDo, $key);'); - } else { - $this->_do->prepareLinkedDataObject($crossLinksDo, $key); - } - } - if ($crossLinksDo->find() > 0) { - while ($crossLinksDo->fetch()) { - $selected_options[$crossLinksDo->{$crossLink['toField']}] = clone($crossLinksDo); - } - } - } - - if (isset($crossLink['type']) && $crossLink['type'] == 'select') { - unset($element); - $element =& $this->_createSelectBox($groupName, $all_options, true); - $formValues[$groupName] = array_keys($selected_options); // set defaults later - - // ***X*** generate checkboxes - } else { - $element = array(); - $rowNames = array(); - $colNames = array(''); - foreach ($all_options as $optionKey => $value) { - $crossLinksElement = $this->_createCheckbox($groupName.'['.$optionKey.']', $value, $optionKey); - $elementNamePrefix = $this->elementNamePrefix.$groupName.'__'.$optionKey.'_'; - $elementNamePostfix = '_'.$this->elementNamePostfix;//']'; - if (isset($selected_options[$optionKey])) { - if (!isset($formValues[$groupName])) { - $formValues[$groupName] = array(); - } - $formValues[$groupName][$optionKey] = $optionKey; - } - if (isset($crossLinksDo->fb_crossLinkExtraFields)) { - $row = array(&$crossLinksElement); - if (isset($selected_options[$optionKey])) { - $extraFieldDo = $selected_options[$optionKey]; - } else { - $extraFieldDo = DB_DataObject::factory($crossLink['table']); - } - unset($tempFb); - $tempFb =& DB_DataObject_FormBuilder::create($extraFieldDo); - $extraFieldDo->fb_fieldsToRender = $crossLinksDo->fb_crossLinkExtraFields; - $extraFieldDo->fb_elementNamePrefix = $elementNamePrefix; - $extraFieldDo->fb_elementNamePostfix = $elementNamePostfix; - $this->_extraFieldsFb[$elementNamePrefix.$elementNamePostfix] =& $tempFb; - $tempForm = $tempFb->getForm(); - foreach ($crossLinksDo->fb_crossLinkExtraFields as $extraField) { - if ($tempForm->elementExists($elementNamePrefix.$extraField.$elementNamePostfix)) { - $tempEl =& $tempForm->getElement($elementNamePrefix.$extraField.$elementNamePostfix); - $colNames[$extraField] = $tempEl->getLabel(); - } else { - $tempEl =& $this->_createStaticField($elementNamePrefix.$extraField.$elementNamePostfix, - 'Error - element not found for extra field '.$extraField); - } - $row[] =& $tempEl; - if (!isset($formValues[$groupName.'__extraFields'])) { - $formValues[$groupName.'__extraFields'] = array(); - } - if (!isset($formValues[$groupName.'__extraFields'][$optionKey])) { - $formValues[$groupName.'__extraFields'][$optionKey] = array(); - } - $formValues[$groupName.'__extraFields'][$optionKey][$extraField] = $tempEl->getValue(); - unset($tempEl); - } - $element[] = $row; - unset($tempFb, $tempForm, $extraFieldDo, $row); - $rowNames[] = ''; - $crossLinksElement->setText(''); - } else { - $element[] = $crossLinksElement; - } - unset($crossLinksElement); - } - if (isset($crossLinksDo->fb_crossLinkExtraFields)) { - $this->_addElementTableToForm($form, $groupName, array_values($colNames), $rowNames, $element); - } else { - $this->_addElementGroupToForm($form, $element, $groupName, $this->crossLinkSeparator); - } - unset($element); - unset($rowNames); - unset($colNames); - } - break; - case ($type & DB_DATAOBJECT_FORMBUILDER_TRIPLELINK): - unset($element); - if ($pk === false) { - return PEAR::raiseError('A primary key must exist in the base table when using tripleLinks.'); - } - $tripleLink = $this->tripleLinks[$key]; - $elName = '__tripleLink_' . $tripleLink['table']; - $freeze = array_search($elName, $elements_to_freeze); - $tripleLinkDo = DB_DataObject::factory($tripleLink['table']); - if (PEAR::isError($tripleLinkDo)) { - die($tripleLinkDo->getMessage()); - } - - $tripleLinksLinks = $tripleLinkDo->links(); - - $fromField = $tripleLink['fromField']; - $toField1 = $tripleLink['toField1']; - $toField2 = $tripleLink['toField2']; - - list($linkedtable1, $linkedfield1) = explode(':', $tripleLinksLinks[$toField1]); - list($linkedtable2, $linkedfield2) = explode(':', $tripleLinksLinks[$toField2]); - - $all_options1 = $this->_getSelectOptions($linkedtable1); - $all_options2 = $this->_getSelectOptions($linkedtable2); - $selected_options = array(); - if (isset($this->_do->$pk) && strlen($this->_do->$pk)) { - $tripleLinkDo->$fromField = $this->_do->$pk; - if (method_exists($this->_do, 'preparelinkeddataobject')) { - if ($this->useCallTimePassByReference) { - eval('$this->_do->prepareLinkedDataObject(&$tripleLinkDo, $key);'); - } else { - $this->_do->prepareLinkedDataObject($tripleLinkDo, $key); - } - } - if ($tripleLinkDo->find() > 0) { - while ($tripleLinkDo->fetch()) { - $selected_options[$tripleLinkDo->$toField1][] = $tripleLinkDo->$toField2; - } - } - } - - $columnNames = array(); - foreach ($all_options2 as $key2 => $value2) { - $columnNames[] = $value2; - } - $rows = array(); - $rowNames = array(); - $formValues[$key] = array(); - foreach ($all_options1 as $key1 => $value1) { - $rowNames[] = $value1; - $row = array(); - foreach ($all_options2 as $key2 => $value2) { - unset($tripleLinksElement); - $tripleLinksElement = $this->_createCheckbox($elName.'['.$key1.']['.$key2.']', - '', - $key2 - //false, - //$freeze - ); - if (isset($selected_options[$key1])) { - if (in_array($key2, $selected_options[$key1])) { - if (!isset($formValues['__tripleLink_'.$tripleLink['table']][$key1])) { - $formValues['__tripleLink_'.$tripleLink['table']][$key1] = array(); - } - $formValues['__tripleLink_'.$tripleLink['table']][$key1][$key2] = $key2; - } - } - $row[] =& $tripleLinksElement; - } - $rows[] =& $row; - unset($row); - } - $this->_addElementTableToForm($form, $elName, $columnNames, $rowNames, $rows); - unset($columnNames, $rowNames, $rows); - break; - case ($type & DB_DATAOBJECT_FORMBUILDER_ENUM): - $formValues[$key] = $this->_do->$key; - if (!isset($element)) { - if (isset($this->enumOptions[$key])) { - $options = $this->enumOptions[$key]; - } else { - $options = call_user_func($this->enumOptionsCallback, $this->_do->__table, $key); - } - if (in_array($key, $this->selectAddEmpty) || !$notNull) { - $options = array_merge(array('' => $this->selectAddEmptyLabel), $options); - } - if (!$options) { - return PEAR::raiseError('There are no options defined for the enum field "'.$key.'". You may need to set the options in the enumOptions option or use your own enumOptionsCallback.'); - } - $element = array(); - if (isset($this->linkElementTypes[$key]) && $this->linkElementTypes[$key] == 'radio') { - foreach ($options as $option) { - $element =& $this->_createRadioButtons($key, $options); - } - } else { - $element =& $this->_createSelectBox($key, $options); - } - unset($options); - } - break; - case ($type & DB_DATAOBJECT_FORMBUILDER_REVERSELINK): - unset($element); - $element = array(); - $elName = '__reverseLink_'.$this->reverseLinks[$key]['table'].'_'.$this->reverseLinks[$key]['field']; - $do = DB_DataObject::factory($this->reverseLinks[$key]['table']); - if (method_exists($this->_do, 'preparelinkeddataobject')) { - if ($this->useCallTimePassByReference) { - eval('$this->_do->prepareLinkedDataObject(&$do, $key);'); - } else { - $this->_do->prepareLinkedDataObject($do, $key); - } - } - $rLinks = $do->links(); - $rPk = $this->_getPrimaryKey($do); - //$rFields = $do->table(); - list($lTable, $lField) = explode(':', $rLinks[$this->reverseLinks[$key]['field']]); - $formValues[$elName] = array(); - if ($do->find()) { - while ($do->fetch()) { - $label = $this->getDataObjectString($do); - if ($do->{$this->reverseLinks[$key]['field']} == $this->_do->$lField) { - $formValues[$elName][$do->$rPk] = $do->$rPk; - } elseif ($rLinked =& $do->getLink($this->reverseLinks[$key]['field'])) { - $label .= ''.$this->reverseLinks[$key]['linkText'].$this->getDataObjectString($rLinked).''; - } - $element[] =& $this->_createCheckbox($elName.'['.$do->$rPk.']', $label, $do->$rPk); - } - } - $this->_addElementGroupToForm($form, $element, $elName, $this->crossLinkSeparator); - unset($element); - break; - default: - $formValues[$key] = $this->_do->$key; - if (!isset($element)) { - $element =& $this->_createTextField($key); - } - } // End switch - //} // End else - if ($elValidator !== false) { - if (!isset($rules[$key])) { - $rules[$key] = array(); - } - $rules[$key][] = array('validator' => $elValidator, - 'rule' => $elValidRule, - 'message' => $this->ruleViolationMessage); - } // End if - - } // End else - - //GROUP OR ELEMENT ADDITION - if (isset($this->preDefGroups[$key])) { - $group = $this->preDefGroups[$key]; - $groups[$group][] = $element; - } elseif (isset($element)) { - if (is_array($element)) { - $this->_addElementGroupToForm($form, $element, $key); - } else { - $this->_addElementToForm($form, $element); - } - } // End if - - - //ADD REQURED RULE FOR NOT_NULL FIELDS - if ((!in_array($key, $keys) || $this->hidePrimaryKey == false) - && ($notNull) - && !in_array($key, $elements_to_freeze) - && !($type & DB_DATAOBJECT_BOOL)) { - $this->_setFormElementRequired($form, $key); - } - - // VALIDATION RULES - if (isset($rules[$key])) { - $this->_addFieldRulesToForm($form, $rules[$key], $key); - } - } // End foreach - - // Freeze fields that are not to be edited by the user - $this->_freezeFormElements($form, $elements_to_freeze); - - //GROUP SUBMIT - $flag = true; - if (isset($this->preDefGroups['__submit__'])) { - $group = $this->preDefGroups['__submit__']; - if (count($groups[$group]) > 1) { - $groups[$group][] =& $this->_createSubmitButton('__submit__', $this->submitText); - $flag = false; - } else { - $flag = true; - } - } - - //GROUPING - if (isset($groups) && is_array($groups)) { //apply grouping - reset($groups); - while (list($grp, $elements) = each($groups)) { - if (count($elements) == 1) { - $this->_addElementToForm($form, $elements[0]); - } elseif (count($elements) > 1) { - $this->_addElementGroupToForm($form, $elements, $grp, ' '); - } - } - } - - //ELEMENT SUBMIT - if ($flag == true && $this->createSubmit == true) { - $this->_addSubmitButtonToForm($form, '__submit__', $this->submitText); - } - - //APPEND EXISTING FORM ELEMENTS - if (is_a($this->_form, 'html_quickform') && $this->_appendForm == true) { - // There somehow needs to be a new method in QuickForm that allows to fetch - // a list of all element names currently registered in a form. Otherwise, there - // will be need for some really nasty workarounds once QuickForm adopts PHP5's - // new encapsulation features. - reset($this->_form->_elements); - while (list($elNum, $element) = each($this->_form->_elements)) { - $this->_addElementToForm($form, $element); - } - } - - // Assign default values to the form - $fixedFormValues = array(); - foreach ($formValues as $key => $value) { - $fixedFormValues[$this->getFieldName($key)] = $value; - } - $this->_setFormDefaults($form, $fixedFormValues); - return $form; - } - - - /** - * Gets the name of the field to use in the form. - * - * @param string field's name - * @return string field name to use with form - */ - function getFieldName($fieldName) { - if (($pos = strpos($fieldName, '[')) !== false) { - $fieldName = substr($fieldName, 0, $pos).$this->elementNamePostfix.substr($fieldName, $pos); - } else { - $fieldName .= $this->elementNamePostfix; - } - return $this->elementNamePrefix.$fieldName; - } - - - /** - * DB_DataObject_FormBuilder::_explodeArrString() - * - * Internal method, will convert string representations of arrays as used in .ini files - * to real arrays. String format example: - * key1:value1,key2:value2,key3:value3,... - * - * @param string $str The string to convert to an array - * @access protected - * @return array - */ - function _explodeArrString($str) { - $ret = array(); - $arr = explode(',', $str); - foreach ($arr as $mapping) { - if (strstr($mapping, ':')) { - $map = explode(':', $mapping); - $ret[$map[0]] = $map[1]; - } else { - $ret[] = $mapping; - } - } - return $ret; - } - - - /** - * DB_DataObject_FormBuilder::_reorderElements() - * - * Changes the order in which elements are being processed, so that - * you can use QuickForm's default renderer or dynamic templates without - * being dependent on the field order in the database. - * - * Make a class property named "fb_preDefOrder" in your DataObject-derived classes - * which contains an array with the correct element order to use this feature. - * - * @return mixed Array in correct order or FALSE if reordering was not possible - * @access protected - * @author Fabien Franzen - */ - function _reorderElements() { - if ($this->preDefOrder) { - $this->debug('
...reordering elements...
'); - $elements = $this->_getFieldsToRender(); - $table = $this->_do->table(); - $crossLinks = $this->_getSpecialElementNames(); - - foreach ($this->preDefOrder as $elem) { - if (isset($elements[$elem])) { - $ordered[$elem] = $elements[$elem]; //key=>type - } elseif (!isset($table[$elem]) && !isset($crossLinks[$elem])) { - $this->debug('
...reorder not supported: invalid element(key) found "'.$elem.'"...
'); - return false; - } - } - - $ordered = array_merge($ordered, array_diff_assoc($elements, $ordered)); - - return $ordered; - } else { - $this->debug('
...reorder not supported, fb_preDefOrder is not set or is not an array...
'); - return false; - } - } - - /** - * Returns an array of crosslink and triplelink elements for use the same as - * DB_DataObject::table(). - * - * @return array the key is the name of the cross/triplelink element, the value - * is the type - */ - function _getSpecialElementNames() { - $ret = array(); - foreach ($this->tripleLinks as $tripleLink) { - $ret['__tripleLink_'.$tripleLink['table']] = DB_DATAOBJECT_FORMBUILDER_TRIPLELINK; - } - foreach ($this->crossLinks as $crossLink) { - $ret['__crossLink_'.$crossLink['table']] = DB_DATAOBJECT_FORMBUILDER_CROSSLINK; - } - foreach ($this->reverseLinks as $reverseLink) { - $ret['__reverseLink_'.$reverseLink['table'].'_'.$reverseLink['field']] = DB_DATAOBJECT_FORMBUILDER_REVERSELINK; - } - return $ret; - } - - - /** - * DB_DataObject_FormBuilder::useForm() - * - * Sometimes, it might come in handy not just to create a new QuickForm object, - * but to work with an existing one. Using FormBuilder together with - * HTML_QuickForm_Controller or HTML_QuickForm_Page is such an example ;-) - * If you do not call this method before the form is generated, a new QuickForm - * object will be created (default behaviour). - * - * @param $form object A HTML_QuickForm object (or extended from that) - * @param $append boolean If TRUE, the form will be appended to the one generated by FormBuilder. If false, FormBuilder will just add its own elements to this form. - * @return boolean Returns false if the passed object was not a HTML_QuickForm object or a QuickForm object was already created - * @access public - */ - function useForm(&$form, $append = false) - { - if (is_a($form, 'html_quickform') && !is_object($this->_form)) { - $this->_form =& $form; - $this->_appendForm = $append; - return true; - } - return false; - } - - - - - /** - * DB_DataObject_FormBuilder::getFieldLabel() - * - * Returns the label for the given field name. If no label is specified, - * the fieldname will be returned with ucfirst() applied. - * - * @param $fieldName string The field name - * @return string - * @access public - */ - function getFieldLabel($fieldName) - { - if (isset($this->fieldLabels[$fieldName])) { - return $this->fieldLabels[$fieldName]; - } - return ucfirst($fieldName); - } - - /** - * DB_DataObject_FormBuilder::getDataObjectString() - * - * Returns a string which identitfies this dataobject. - * If multiple display fields are given, will display them all seperated by ", ". - * If a display field is a foreign key (link) the display value for the record it - * points to will be used as long as the linkDisplayLevel has not been reached. - * Its display value will be surrounded by parenthesis as it may have multiple - * display fields of its own. - * - * May be called statically. - * - * Will use display field configurations from these locations, in this order: - * 1) $displayFields parameter - * 2) the fb_linkDisplayFields member variable of the dataobject - * 3) the linkDisplayFields member variable of this class (if not called statically) - * 4) all fields returned by the DO's table() function - * - * @param DB_DataObject the dataobject to get the display value for, must be populated - * @param mixed field to use to display, may be an array with field names or a single field. - * Will only be used for this DO, not linked DOs. If you wish to set the display fields - * all DOs the same, set the option in the FormBuilder class instance. - * @param int the maximum link display level. If null, $this->linkDisplayLebel will be used - * if it exists, otherwise 3 will be used. {@see DB_DataObject_FormBuilder::linkDisplayLevel} - * @param int the current recursion level. For internal use only. - * @return string select display value for this field - * @access public - */ - function getDataObjectString(&$do, $displayFields = false, $linkDisplayLevel = null, $level = 1) { - if ($linkDisplayLevel === null) { - $linkDisplayLevel = (isset($this) && isset($this->linkDisplayLevel)) ? $this->linkDisplayLevel : 3; - } - $links = $do->links(); - if ($displayFields === false) { - if (isset($do->fb_linkDisplayFields)) { - $displayFields = $do->fb_linkDisplayFields; - } elseif (isset($this) && isset($this->linkDisplayFields) && $this->linkDisplayFields) { - $displayFields = $this->linkDisplayFields; - } - if (!$displayFields) { - $displayFields = array_keys($do->table()); - } - } - $ret = ''; - $first = true; - foreach ($displayFields as $field) { - if ($first) { - $first = false; - } else { - $ret .= ', '; - } - if (isset($do->$field)) { - if ($linkDisplayLevel > $level && isset($links[$field]) - && ($subDo = $do->getLink($field))) { - if (isset($this) && is_a($this, 'DB_DataObject_FormBuilder')) { - $ret .= '('.$this->getDataObjectString($subDo, false, $linkDisplayLevel, $level + 1).')'; - } else { - $ret .= '('.DB_DataObject_FormBuilder::getDataObjectString($subDo, false, $linkDisplayLevel, $level + 1).')'; - } - } else { - $ret .= $do->$field; - } - } - } - return $ret; - } - - /** - * DB_DataObject_FormBuilder::getSelectOptions() - * - * Returns an array of options for use with the HTML_QuickForm "select" element. - * It will try to fetch all related objects (if any) for the given field name and - * build the array. - * For the display name of the option, it will try to use - * the settings in the database.formBuilder.ini file. If those are not found, - * the linked object's property "fb_linkDisplayFields". If that one is not present, - * it will try to use the global configuration setting "linkDisplayFields". - * Can also be called with a second parameter containing the name of the display - * field - this will override all other settings. - * Same goes for "linkOrderFields", which determines the field name used for - * sorting the option elements. If neither a config setting nor a class property - * of that name is set, the display field name will be used. - * - * @param string $field The field to fetch the links from. You should make sure the field actually *has* links before calling this function (see: DB_DataObject::links()) - * @param string $displayFields (Optional) The name of the field used for the display text of the options - * @param bool $selectAddEmpty (Optional) If true, an empty option will be added to the list of options - * If false, the selectAddEmpty member var will be checked - * @return array strings representing all of the records in the table $field links to. - * @access public - */ - function getSelectOptions($field, $displayFields = false, $selectAddEmpty = false) - { - if (empty($this->_do->_database)) { - // TEMPORARY WORKAROUND !!! Guarantees that DataObject config has - // been loaded and all link information is available. - $this->_do->keys(); - } - $links = $this->_do->links(); - $link = explode(':', $links[$field]); - - $res = $this->_getSelectOptions($link[0], - $displayFields, - $selectAddEmpty || in_array($field, $this->selectAddEmpty), - $field); - - if ($res !== false) { - return $res; - } - - $this->debug('Error: '.get_class($opts).' does not inherit from DB_DataObject'); - return array(); - } - - /** - * Internal function to get the select potions for a table. - * - * @param string $table The table to get the select display strings for. - * @param array $displayFields array of diaply fields to use. Will default to the FB or DO options. - * @param bool $selectAddEmpty If set to true, there will be an empty option in the returned array. - * @param string $field the field in the current table which we're getting options for - * - * @return array strings representing all of the records in $table. - * @access protected - */ - function _getSelectOptions($table, $displayFields = false, $selectAddEmpty = false, $field = false) { - $opts = DB_DataObject::factory($table); - if (is_a($opts, 'db_dataobject')) { - $pk = $this->_getPrimaryKey($opts); - if ($displayFields === false) { - if (isset($opts->fb_linkDisplayFields)) { - $displayFields = $opts->fb_linkDisplayFields; - } elseif ($this->linkDisplayFields){ - $displayFields = $this->linkDisplayFields; - } else { - $displayFields = array($pk); - } - } - - if (isset($opts->fb_linkOrderFields)) { - $orderFields = $opts->fb_linkOrderFields; - } elseif ($this->linkOrderFields){ - $orderFields = $this->linkOrderFields; - } else { - $orderFields = $displayFields; - } - $orderStr = ''; - $first = true; - foreach ($orderFields as $col) { - if ($first) { - $first = false; - } else { - $orderStr .= ', '; - } - $orderStr .= $col; - } - if ($orderStr) { - $opts->orderBy($orderStr); - } - $list = array(); - - // FIXME! - if ($selectAddEmpty) { - $list[''] = $this->selectAddEmptyLabel; - } - if (method_exists($this->_do, 'preparelinkeddataobject')) { - if ($this->useCallTimePassByReference) { - eval('$this->_do->prepareLinkedDataObject(&$opts, $field);'); - } else { - $this->_do->prepareLinkedDataObject($opts, $field); - } - } - // FINALLY, let's see if there are any results - if ($opts->find() > 0) { - while ($opts->fetch()) { - $list[$opts->$pk] = $this->getDataObjectString($opts, $displayFields); - } - } - - return $list; - } - $this->debug('Error: '.get_class($opts).' does not inherit from DB_DataObject'); - return array(); - } - - /** - * DB_DataObject_FormBuilder::populateOptions() - * - * Populates public member vars with fb_ equivalents in the DataObject. - */ - function populateOptions() { - $badVars = array('linkDisplayFields', 'linkOrderFields'); - foreach (get_object_vars($this) as $var => $value) { - if ($var[0] != '_' && !in_array($var, $badVars) && isset($this->_do->{'fb_'.$var})) { - $this->$var = $this->_do->{'fb_'.$var}; - } - } - } - - /** - * DB_DataObject_FormBuilder::getForm() - * - * Returns a HTML form that was automagically created by _generateForm(). - * You need to use the get() method before calling this one in order to - * prefill the form with the retrieved data. - * - * If you have a method named "preGenerateForm()" in your DataObject-derived class, - * it will be called before _generateForm(). This way, you can create your own elements - * there and add them to the "fb_preDefElements" property, so they will not be auto-generated. - * - * If you have your own "getForm()" method in your class, it will be called instead of - * _generateForm(). This enables you to have some classes that make their own forms completely - * from scratch, without any auto-generation. Use this for highly complex forms. Your getForm() - * method needs to return the complete HTML_QuickForm object by reference. - * - * If you have a method named "postGenerateForm()" in your DataObject-derived class, it will - * be called after _generateForm(). This allows you to remove some elements that have been - * auto-generated from table fields but that you don't want in the form. - * - * Many ways lead to rome. - * - * @param string $action The form action. Optional. If set to false (default), $_SERVER['PHP_SELF'] is used. - * @param string $target The window target of the form. Optional. Defaults to '_self'. - * @param string $formName The name of the form, will be used in "id" and "name" attributes. - * If set to false (default), the class name is used, prefixed with "frm" - * @param string $method The submit method. Defaults to 'post'. - * @return object - * @access public - */ - function &getForm($action = false, $target = '_self', $formName = false, $method = 'post') - { - if (method_exists($this->_do, 'pregenerateform')) { - if ($this->useCallTimePassByReference) { - eval('$this->_do->preGenerateForm(&$this);'); - } else { - $this->_do->preGenerateForm($this); - } - } - $this->populateOptions(); - foreach ($this->crossLinks as $key => $crossLink) { - $groupName = '__crossLink_' . $crossLink['table']; - $do = DB_DataObject::factory($crossLink['table']); - if (PEAR::isError($do)) { - return PEAR::raiseError('Cannot load dataobject for table '.$crossLink['table'].' - '.$do->getMessage()); - } - - $links = $do->links(); - - if (isset($crossLink['fromField'])) { - $fromField = $crossLink['fromField']; - } else { - unset($fromField); - } - if (isset($crossLink['toField'])) { - $toField = $crossLink['toField']; - } else { - unset($toField); - } - if (!isset($toField) || !isset($fromField)) { - foreach ($links as $field => $link) { - list($linkTable, $linkField) = explode(':', $link); - if (!isset($fromField) && $linkTable == $this->_do->__table) { - $fromField = $field; - } elseif (!isset($toField) && (!isset($fromField) || $linkField != $fromField)) { - $toField = $field; - } - } - } - unset($this->crossLinks[$key]); - $this->crossLinks[$groupName] = array_merge($crossLink, - array('fromField' => $fromField, - 'toField' => $toField)); - } - foreach ($this->tripleLinks as $key => $tripleLink) { - $elName = '__tripleLink_' . $tripleLink['table']; - //$freeze = array_search($elName, $elements_to_freeze); - $do = DB_DataObject::factory($tripleLink['table']); - if (PEAR::isError($do)) { - die($do->getMessage()); - } - - $links = $do->links(); - - if (isset($tripleLink['fromField'])) { - $fromField = $tripleLink['fromField']; - } else { - unset($fromField); - } - if (isset($tripleLink['toField1'])) { - $toField1 = $tripleLink['toField1']; - } else { - unset($toField1); - } - if (isset($tripleLink['toField2'])) { - $toField2 = $tripleLink['toField2']; - } else { - unset($toField2); - } - if (!isset($toField2) || !isset($toField1) || !isset($fromField)) { - foreach ($links as $field => $link) { - list($linkTable, $linkField) = explode(':', $link); - if (!isset($fromField) && $linkTable == $this->_do->__table) { - $fromField = $field; - } elseif (!isset($toField1) && (!isset($fromField) || $linkField != $fromField)) { - $toField1 = $field; - } elseif (!isset($toField2) && (!isset($fromField) || $linkField != $fromField) && $linkField != $toField1) { - $toField2 = $field; - } - } - } - unset($this->tripleLinks[$key]); - $this->tripleLinks[$elName] = array_merge($tripleLink, - array('fromField' => $fromField, - 'toField1' => $toField1, - 'toField2' => $toField2)); - } - foreach ($this->reverseLinks as $key => $reverseLink) { - $elName = '__reverseLink_'.$reverseLink['table'].'_'.$reverseLink['field']; - if (!isset($reverseLink['field'])) { - $do = DB_DataObject::factory($reverseLink['table']); - $links = $do->links(); - foreach ($do->links() as $field => $link) { - list($linkTable, $linkField) = explode(':', $link); - if ($linkTable == $this->_do->__table) { - $reverseLink['field'] = $field; - break; - } - } - } - if (!isset($reverseLink['linkText'])) { - $reverseLink['linkText'] = ' - currently linked to - '; - } - unset($this->reverseLinks[$key]); - $this->reverseLinks[$elName] = $reverseLink; - } - - if (method_exists($this->_do, 'getform')) { - $obj = $this->_do->getForm($action, $target, $formName, $method); - } else { - $obj = &$this->_generateForm($action, $target, $formName, $method); - } - if (method_exists($this->_do, 'postgenerateform')) { - if ($this->useCallTimePassByReference) { - eval('$this->_do->postGenerateForm(&$obj, &$this);'); - } else { - $this->_do->postGenerateForm($obj, $this); - } - } - return($obj); - } - - - /** - * DB_DataObject_FormBuilder::_date2array() - * - * Takes a string representing a date or a unix timestamp and turns it into an - * array suitable for use with the QuickForm data element. - * When using a string, make sure the format can be handled by the PEAR::Date constructor! - * - * Beware: For the date conversion to work, you must at least use the letters "d", "m" and "Y" in - * your format string (see "dateElementFormat" option). If you want to enter a time as well, - * you will have to use "H", "i" and "s" as well. Other letters will not work! Exception: You can - * also use "M" instead of "m" if you want plain text month names. - * - * @param mixed $date A unix timestamp or the string representation of a date, compatible to strtotime() - * @return array - * @access protected - */ - function _date2array($date) - { - $da = array(); - if (is_string($date)) { - if (preg_match('/^\d+:\d+(:\d+|)(\s+[ap]m|)$/i', $date)) { - $date = date('Y-m-d ').$date; - $getDate = false; - } else { - $getDate = true; - } - include_once('Date.php'); - $dObj = new Date($date); - if ($getDate) { - $da['d'] = $dObj->getDay(); - $da['l'] = $da['D'] = $dObj->getDayOfWeek(); - $da['m'] = $da['M'] = $da['F'] = $dObj->getMonth(); - $da['Y'] = $da['y'] = $dObj->getYear(); - } - $da['H'] = $dObj->getHour(); - $da['h'] = $da['H'] % 12; - if ($da['h'] == 0) { - $da['h'] = 12; - } - $da['i'] = $dObj->getMinute(); - $da['s'] = $dObj->getSecond(); - if ($da['H'] >= 12) { - $da['a'] = 'pm'; - $da['A'] = 'PM'; - } else { - $da['a'] = 'am'; - $da['A'] = 'AM'; - } - unset($dObj); - } else { - if (is_int($date)) { - $time = $date; - } else { - $time = time(); - } - $da['d'] = date('d', $time); - $da['l'] = $da['D'] = date('w', $time); - $da['m'] = $da['M'] = $da['F'] = date('m', $time); - $da['Y'] = $da['y'] = date('Y', $time); - $da['H'] = date('H', $time); - $da['h'] = date('h', $time); - $da['i'] = date('i', $time); - $da['s'] = date('s', $time); - $da['a'] = date('a', $time); - $da['A'] = date('A', $time); - } - $this->debug('_date2array(): from '.$date.' ...'); - return $da; - } - - - /** - * DB_DataObject_FormBuilder::_array2date() - * - * Takes a date array as used by the QuickForm date element and turns it back into - * a string representation suitable for use with a database date field (format 'YYYY-MM-DD'). - * If second parameter is true, it will return a unix timestamp instead. //FRANK: Not at this point it wont - * - * Beware: For the date conversion to work, you must at least use the letters "d", "m" and "Y" in - * your format string (see "dateElementFormat" option). If you want to enter a time as well, - * you will have to use "H", "i" and "s" as well. Other letters will not work! Exception: You can - * also use "M" instead of "m" if you want plain text month names. - * - * @param array $date An array representation of a date, as user in HTML_QuickForm's date element - * @param boolean $timestamp Optional. If true, return a timestamp instead of a string. Defaults to false. - * @return mixed - * @access protected - */ - function _array2date($dateInput, $timestamp = false) - { - if (isset($dateInput['M'])) { - $month = $dateInput['M']; - } elseif (isset($dateInput['m'])) { - $month = $dateInput['m']; - } elseif (isset($dateInput['F'])) { - $month = $dateInput['F']; - } - if (isset($dateInput['Y'])) { - $year = $dateInput['Y']; - } elseif (isset($dateInput['y'])) { - $year = $dateInput['y']; - } - if (isset($dateInput['H'])) { - $hour = $dateInput['H']; - } elseif (isset($dateInput['h'])) { - $hour = $dateInput['h']; - } - if (isset($dateInput['a'])) { - $ampm = $dateInput['a']; - } elseif (isset($dateInput['A'])) { - $ampm = isset($dateInput['A']); - } - $strDate = ''; - if (isset($year) || isset($month) || isset($dateInput['d'])) { - if (!isset($year)) { - $year = '0000'; - } - if(!isset($month)) { - $month = '00'; - } - if (!isset($dateInput['d'])) { - $dateInput['d'] = '00'; - } - $strDate .= $year.'-'.$month.'-'.$dateInput['d']; - } - if (isset($hour) || isset($dateInput['i']) || isset($dateInput['s'])) { - if (!isset($hour)) { - $hour = '00'; - } - if (!isset($dateInput['i'])) { - $dateInput['i'] = '00'; - } - if (!empty($strDate)) { - $strDate .= ' '; - } - $strDate .= $hour.':'.$dateInput['i']; - if (isset($dateInput['s'])) { - $strDate .= ':'.$dateInput['s']; - } - if (isset($ampm)) { - $strDate .= ' '.$ampm; - } - } - $this->debug('_array2date(): to '.$strDate.' ...'); - return $strDate; - } - - /** - * DB_DataObject_FormBuilder::validateData() - * - * Makes a call to the current DataObject's validate() method and returns the result. - * - * @return mixed - * @access public - * @see DB_DataObject::validate() - */ - function validateData() - { - $this->_validationErrors = $this->_do->validate(); - return $this->_validationErrors; - } - - /** - * DB_DataObject_FormBuilder::getValidationErrors() - * - * Returns errors from data validation. If errors have occured, this will be - * an array with the fields that have errors, otherwise a boolean. - * - * @return mixed - * @access public - * @see DB_DataObject::validate() - */ - function getValidationErrors() - { - return $this->_validationErrors; - } - - - /** - * DB_DataObject_FormBuilder::processForm() - * - * This will take the submitted form data and put it back into the object's properties. - * If the primary key is not set or NULL, it will be assumed that you wish to insert a new - * element into the database, so DataObject's insert() method is invoked. - * Otherwise, an update() will be performed. - * Careful: If you're using natural keys or cross-referencing tables where you don't have - * one dedicated primary key, this will always assume that you want to do an update! As there - * won't be a matching entry in the table, no action will be performed at all - the reason - * for this behaviour can be very hard to detect. Thus, if you have such a situation in one - * of your tables, simply override this method so that instead of the key check it will try - * to do a SELECT on the table using the current settings. If a match is found, do an update. - * If not, do an insert. - * This method is perfect for use with QuickForm's process method. Example: - * - * if ($form->validate()) { - * $form->freeze(); - * $form->process(array(&$formGenerator,'processForm'), false); - * } - * - * - * If you wish to enforce a special type of query, use the forceQueryType() method. - * - * Always remember to pass your objects by reference - otherwise, if the operation was - * an insert, the primary key won't get updated with the new database ID because processForm() - * was using a local copy of the object! - * - * If a method named "preProcessForm()" exists in your derived class, it will be called before - * processForm() starts doing its magic. The data that has been submitted by the form - * will be passed to that method as a parameter. - * Same goes for a method named "postProcessForm()", with the only difference - you might - * have guessed this by now - that it's called after the insert/update operations have - * been done. Use this for filtering data, notifying users of changes etc.pp. ... - * - * @param array $values The values of the submitted form - * @param string $queryType If the standard query behaviour ain't good enough for you, you can force a certain type of query - * @return boolean TRUE if database operations were performed, FALSE if not - * @access public - */ - function processForm($values) - { - if ($this->elementNamePrefix !== '' || $this->elementNamePostfix !== '') { - $origValues = $values; - $values = $this->_getMyValues($values); - } - $this->debug('
...processing form data...
'); - if (method_exists($this->_do, 'preprocessform')) { - if ($this->useCallTimePassByReference) { - eval('$this->_do->preProcessForm(&$values);'); - } else { - $this->_do->preProcessForm($values); - } - } - - $editableFields = $this->_getUserEditableFields(); - $tableFields = $this->_do->table(); - $links = $this->_do->links(); - - foreach ($values as $field => $value) { - $this->debug('Field '.$field.' '); - // Double-check if the field may be edited by the user... if not, don't - // set the submitted value, it could have been faked! - if (in_array($field, $editableFields)) { - if (isset($tableFields[$field])) { - if (($tableFields[$field] & DB_DATAOBJECT_DATE) || in_array($field, $this->dateFields)) { - $this->debug('DATE CONVERSION for using callback from '.$value.' ...'); - $value = call_user_func($this->dateToDatabaseCallback, $value); - } elseif (($tableFields[$field] & DB_DATAOBJECT_TIME) || in_array($field, $this->timeFields)) { - $this->debug('TIME CONVERSION for using callback from '.$value.' ...'); - $value = call_user_func($this->dateToDatabaseCallback, $value); - } elseif (is_array($value)) { - if (isset($value['tmp_name'])) { - $this->debug(' (converting file array) '); - $value = $value['name']; - //JUSTIN - //This is not really a valid assumption IMHO. This should only be done if the type is - // date or the field is in dateFields - /*} else { - $this->debug("DATE CONVERSION using callback from $value ..."); - $value = call_user_func($this->dateToDatabaseCallback, $value);*/ - } - } - if (is_array($links) && isset($links[$field])) { - if ($value === '') { - $this->debug('Casting to NULL'); - require_once('DB/DataObject/Cast.php'); - $value = DB_DataObject_Cast::sql('NULL'); - } - } - $this->debug('is substituted with "'.$value.'".
'); - - // See if a setter method exists in the DataObject - if so, use that one - if (method_exists($this->_do, 'set' . $field)) { - $this->_do->{'set'.$field}($value); - } else { - // Otherwise, just set the property 'normally'... - $this->_do->$field = $value; - } - } else { - $this->debug('is not a valid field.
'); - } - } else { - $this->debug('is defined not to be editable by the user!
'); - } - } - foreach ($this->booleanFields as $boolField) { - if (!isset($values[$boolField])) { - $this->_do->$boolField = 0; - } - } - foreach ($tableFields as $field => $type) { - if ($type & DB_DATAOBJECT_BOOL && !isset($values[$field])) { - $this->_do->$field = 0; - } - } - - $dbOperations = true; - if ($this->validateOnProcess === true) { - $this->debug('Validating data... '); - if (is_array($this->validateData())) { - $dbOperations = false; - } - } - - $pk = $this->_getPrimaryKey($this->_do); - - // Data is valid, let's store it! - if ($dbOperations) { - $action = $this->_queryType; - if ($this->_queryType == DB_DATAOBJECT_FORMBUILDER_QUERY_AUTODETECT) { - // Could the primary key be detected? - if ($pk === false) { - // Nope, so let's exit and return false. Sorry, you can't store data using - // processForm with this DataObject unless you do some tweaking :-( - $this->debug('Primary key not detected - storing data not possible.'); - return false; - } - - $action = DB_DATAOBJECT_FORMBUILDER_QUERY_FORCEUPDATE; - if (!isset($this->_do->$pk) || !strlen($this->_do->$pk)) { - $action = DB_DATAOBJECT_FORMBUILDER_QUERY_FORCEINSERT; - } - } - - switch ($action) { - case DB_DATAOBJECT_FORMBUILDER_QUERY_FORCEINSERT: - $id = $this->_do->insert(); - $this->debug('ID ('.$pk.') of the new object: '.$id.'
'); - break; - case DB_DATAOBJECT_FORMBUILDER_QUERY_FORCEUPDATE: - $this->_do->update(); - $this->debug('Object updated.
'); - break; - } - - //triple/crossLinks only work when a primark key is set - if ($pk && isset($this->_do->$pk) && strlen($this->_do->$pk)) { - // process tripleLinks - foreach ($this->tripleLinks as $tripleLink) { - $do = DB_DataObject::factory($tripleLink['table']); - - $links = $do->links(); - - $fromField = $tripleLink['fromField']; - $toField1 = $tripleLink['toField1']; - $toField2 = $tripleLink['toField2']; - - if (isset($values['__tripleLink_'.$tripleLink['table']])) { - $rows = $values['__tripleLink_'.$tripleLink['table']]; - } else { - $rows = array(); - } - $do->$fromField = $this->_do->$pk; - $do->selectAdd(); - $do->selectAdd($toField1); - $do->selectAdd($toField2); - if (method_exists($this->_do, 'preparelinkeddataobject')) { - if ($this->useCallTimePassByReference) { - eval('$this->_do->prepareLinkedDataObject(&$do, \'__tripleLink_\'.$tripleLink[\'table\']);'); - } else { - $this->_do->prepareLinkedDataObject($do, '__tripleLink_'.$tripleLink['table']); - } - } - $do->find(); - - $oldFieldValues = array(); - while ($do->fetch()) { - if (isset($rows[$do->$toField1]) && in_array($do->$toField2, $rows[$do->$toField1])) { - $oldFieldValues[$do->$toField1][$do->$toField2] = true; - } else { - $do->delete(); - } - } - - if (count($rows) > 0) { - foreach ($rows as $rowid => $row) { - if (count($row) > 0) { - foreach ($row as $fieldvalue) { - if (!isset($oldFieldValues[$rowid]) || !isset($oldFieldValues[$rowid][$fieldvalue])) { - $do = DB_DataObject::factory($tripleLink['table']); - $do->$fromField = $this->_do->$pk; - $do->$toField1 = $rowid; - $do->$toField2 = $fieldvalue; - $do->insert(); - } - } - } - } - } - } - - //process crossLinks - foreach ($this->crossLinks as $crossLink) { - $do = DB_DataObject::factory($crossLink['table']); - $links = $do->links(); - - $fromField = $crossLink['fromField']; - $toField = $crossLink['toField']; - - if (isset($values['__crossLink_'.$crossLink['table']])) { - $fieldvalues = $values['__crossLink_'.$crossLink['table']]; - } else { - $fieldvalues = array(); - } - /*if (isset($values['__crossLink_'.$crossLink['table'].'__extraFields'])) { - $extraFieldValues = $values['__crossLink_'.$crossLink['table'].'__extraFields']; - } else { - $extraFieldValues = array(); - }*/ - $do->$fromField = $this->_do->$pk; - $do->selectAdd(); - $do->selectAdd($toField); - $do->selectAdd($fromField); - if ($doKeys = $do->sequenceKey()) { - $do->selectAdd($doKeys[0]); - } - if (method_exists($this->_do, 'preparelinkeddataobject')) { - if ($this->useCallTimePassByReference) { - eval('$this->_do->prepareLinkedDataObject(&$do, \'__crossLink_\'.$crossLink[\'table\']);'); - } else { - $this->_do->prepareLinkedDataObject($do, '__crossLink_'.$crossLink['table']); - } - } - $do->find(); - - $oldFieldValues = array(); - while ($do->fetch()) { - if (isset($fieldvalues[$do->$toField])) { - $oldFieldValues[$do->$toField] = clone($do); - } else { - $do->delete(); - } - } - if (count($fieldvalues) > 0) { - foreach ($fieldvalues as $fieldvalue) { - $crossLinkPrefix = $this->elementNamePrefix.'__crossLink_'.$crossLink['table'].'__'.$fieldvalue.'_'; - $crossLinkPostfix = '_'.$this->elementNamePostfix; - if (isset($oldFieldValues[$fieldvalue])) { - if (isset($do->fb_crossLinkExtraFields)) { - $this->_extraFieldsFb[$crossLinkPrefix.$crossLinkPostfix]->processForm(isset($origValues) ? $origValues : $values); - /*$do = $oldFieldValues[$fieldvalue]; - $update = false; - foreach ($do->fb_crossLinkExtraFields as $extraField) { - if ($do->$extraField !== $extraFieldValues[$fieldvalue][$extraField]) { - $update = true; - $do->$extraField = $extraFieldValues[$fieldvalue][$extraField]; - } - } - if ($update) { - $do->update(); - }*/ - } - } else { - if (isset($do->fb_crossLinkExtraFields)) { - $insertValues = isset($origValues) ? $origValues : $values; - $insertValues[$crossLinkPrefix.$fromField.$crossLinkPostfix] = $this->_do->$pk; - $insertValues[$crossLinkPrefix.$toField.$crossLinkPostfix] = $fieldvalue; - $this->_extraFieldsFb[$crossLinkPrefix.$crossLinkPostfix]->fieldsToRender[] = $fromField; - $this->_extraFieldsFb[$crossLinkPrefix.$crossLinkPostfix]->fieldsToRender[] = $toField; - $this->_extraFieldsFb[$crossLinkPrefix.$crossLinkPostfix]->processForm($insertValues); - /*foreach ($do->fb_crossLinkExtraFields as $extraField) { - $do->$extraField = $extraFieldValues[$do->$toField][$extraField]; - }*/ - } else { - $do = DB_DataObject::factory($crossLink['table']); - $do->$fromField = $this->_do->$pk; - $do->$toField = $fieldvalue; - $do->insert(); - } - } - } - } - } - - foreach ($this->reverseLinks as $reverseLink) { - $elName = '__reverseLink_'.$reverseLink['table'].'_'.$reverseLink['field']; - $do = DB_DataObject::factory($reverseLink['table']); - if (method_exists($this->_do, 'preparelinkeddataobject')) { - if ($this->useCallTimePassByReference) { - eval('$this->_do->prepareLinkedDataObject(&$do, $key);'); - } else { - $this->_do->prepareLinkedDataObject($do, $key); - } - } - $rLinks = $do->links(); - $rPk = $this->_getPrimaryKey($do); - $rFields = $do->table(); - list($lTable, $lField) = explode(':', $rLinks[$reverseLink['field']]); - if ($do->find()) { - while ($do->fetch()) { - unset($newVal); - if (isset($values[$elName][$do->$rPk])) { - if ($do->{$reverseLink['field']} != $this->_do->$lField) { - $do->{$reverseLink['field']} = $this->_do->$lField; - $do->update(); - } - } elseif ($do->{$reverseLink['field']} == $this->_do->$lField) { - if (isset($reverseLink['defaultLinkValue'])) { - $do->{$reverseLink['field']} = $reverseLink['defaultLinkValue']; - $do->update(); - } else { - if ($rFields[$reverseLink['field']] & DB_DATAOBJECT_NOTNULL) { - //ERROR!! - $this->debug('Checkbox in reverseLinks unset when link field may not be null'); - } else { - require_once('DB/DataObject/Cast.php'); - $do->{$reverseLink['field']} = DB_DataObject_Cast::sql('NULL'); - $do->update(); - } - } - } - } - } - } - } - } - - if (method_exists($this->_do, 'postprocessform')) { - if ($this->useCallTimePassByReference) { - eval('$this->_do->postProcessForm(&$values);'); - } else { - $this->_do->postProcessForm($values); - } - } - - return $dbOperations; - } - - - /** - * Takes a multi-dimentional array and flattens it. If a value in the array is an array, - * its keys are added as [key] to the original key. - * Ex: - * array('a' => 'a', - * 'b' => array('a' => 'a', - * 'b' => array('a' => 'a', - * 'b' => 'b')), - * 'c' => 'c') - * becomes - * array('a' => 'a', - * 'b[a]' => 'a', - * 'b[b][a]' => 'a', - * 'b[b][b]' => 'b', - * 'c' => 'c') - * - * @param array the array to convert - * @return array the flattened array - */ - /*function _multiArrayToSingleArray($arr) { - do { - $arrayFound = false; - foreach ($arr as $key => $val) { - if (is_array($val)) { - unset($arr[$key]); - foreach ($val as $key2 => $val2) { - $arr[$key.'['.$key2.']'] = $val2; - } - $arrayFound = true; - } - } - } while ($arrayFound); - return $arr; - }*/ - - - /** - * Takes a full request array and extracts the values for this formBuilder instance. - * Removes the element name prefix and postfix - * Will only return values whose key is prefixed with the prefix and postfixed by the postfix - * - * @param array array from $_REQUEST - * @return array array indexed by real field name - */ - function _getMyValues(&$arr) { - //$arr = $this->_multiArrayToSingleArray($arr); - $retArr = array(); - $prefixLen = strlen($this->elementNamePrefix); - $postfixLen = strlen($this->elementNamePostfix); - foreach ($arr as $key => $val) { - if ($prefixLen) { - if (substr($key, 0, $prefixLen) == $this->elementNamePrefix) { - $key = substr($key, $prefixLen); - } else { - $key = false; - } - } - if ($key !== false && $postfixLen) { - if (substr($key, -$postfixLen) == $this->elementNamePostfix) { - $key = substr($key, 0, -$postfixLen); - } else { - $key = false; - } - } - if ($key !== false) { - $retArr[$key] = $val; - } - } - return $retArr; - } - - - /** - * DB_DataObject_FormBuilder::forceQueryType() - * - * You can force the behaviour of the processForm() method by passing one of - * the following constants to this method: - * - * - DB_DATAOBJECT_FORMBUILDER_QUERY_FORCEINSERT: - * The submitted data will always be INSERTed into the database - * - DB_DATAOBJECT_FORMBUILDER_QUERY_FORCEUPDATE: - * The submitted data will always be used to perform an UPDATE on the database - * - DB_DATAOBJECT_FORMBUILDER_QUERY_FORCENOACTION: - * The submitted data will overwrite the properties of the DataObject, but no - * action will be performed on the database. - * - DB_DATAOBJECT_FORMBUILDER_QUERY_AUTODETECT: - * The processForm() method will try to detect for itself if an INSERT or UPDATE - * query has to be performed. This will not work if no primary key field can - * be detected for the current DataObject. In this case, no action will be performed. - * This is the default behaviour. - * - * @param integer $queryType The type of the query to be performed. Please use the preset constants for setting this. - * @return boolean - * @access public - */ - function forceQueryType($queryType = DB_DATAOBJECT_FORMBUILDER_QUERY_AUTODETECT) - { - switch ($queryType) { - case DB_DATAOBJECT_FORMBUILDER_QUERY_FORCEINSERT: - case DB_DATAOBJECT_FORMBUILDER_QUERY_FORCEUPDATE: - case DB_DATAOBJECT_FORMBUILDER_QUERY_FORCENOACTION: - case DB_DATAOBJECT_FORMBUILDER_QUERY_AUTODETECT: - $this->_queryType = $queryType; - return true; - break; - default: - return false; - } - } - - - /** - * DB_DataObject_FormBuilder::debug() - * - * Outputs a debug message, if the debug setting in the DataObject.ini file is - * set to 1 or higher. - * - * @param string $message The message to printed to the browser - * @access public - * @see DB_DataObject::debugLevel() - */ - function debug($message) - { - if (DB_DataObject::debugLevel() > 0) { - echo '
FormBuilder: '.$message."
\n"; - } - } - - /** - * DB_DataObject_FormBuilder::_getFieldsToRender() - * - * If the "fb_fieldsToRender" property in a DataObject is not set, all fields - * will be rendered as form fields. - * When the property is set, a field will be rendered only if: - * 1. it is a primary key - * 2. it's explicitly requested in $do->fb_fieldsToRender - * - * @access private - * @return array The fields that shall be rendered - */ - function _getFieldsToRender() - { - $all_fields = array_merge($this->_do->table(), $this->_getSpecialElementNames()); - if ($this->fieldsToRender) { - // a little workaround to get an array like [FIELD_NAME] => FIELD_TYPE (for use in _generateForm) - // maybe there's some better way to do this: - $result = array(); - - $key_fields = $this->_do->keys(); - if (!is_array($key_fields)) { - $key_fields = array(); - } - $fields_to_render = $this->fieldsToRender; - - if (is_array($all_fields)) { - foreach ($all_fields as $key=>$value) { - if ( (in_array($key, $key_fields)) || (in_array($key, $fields_to_render)) ) { - $result[$key] = $all_fields[$key]; - } - } - } - - if (count($result) > 0) { - return $result; - } - return $all_fields; - } - return $all_fields; - } - - - /** - * DB_DataObject_FormBuilder::_getUserEditableFields() - * - * Normally, all fields in a form are editable by the user. If you want to - * make some fields uneditable, you have to set the "fb_userEditableFields" property - * with an array that contains the field names that actually can be edited. - * All other fields will be freezed (which means, they will still be a part of - * the form, and they values will still be displayed, but only as plain text, not - * as form elements). - * - * @access private - * @return array The fields that shall be editable. - */ - function _getUserEditableFields() - { - // if you don't want any of your fields to be editable by the user, set fb_userEditableFields to - // "array()" in your DataObject-derived class - if ($this->userEditableFields) { - return $this->userEditableFields; - } - // all fields may be updated by the user since fb_userEditableFields is not set - if ($this->fieldsToRender) { - return $this->fieldsToRender; - } - return array_keys($this->_getFieldsToRender()); - } - -} - -?> diff --git a/glmPEAR/DB/DataObject/FormBuilder/QuickForm.php b/glmPEAR/DB/DataObject/FormBuilder/QuickForm.php deleted file mode 100755 index 265d049..0000000 --- a/glmPEAR/DB/DataObject/FormBuilder/QuickForm.php +++ /dev/null @@ -1,659 +0,0 @@ - | -// +----------------------------------------------------------------------+ - -/** - * This is a driver class for the DB_DataObject_FormBuilder package. - * It uses HTML_QuickForm to render the forms. - * - * @package DB_DataObject_FormBuilder - * @author Markus Wolff - * @version $Id: QuickForm.php,v 1.1.1.1 2008/04/28 15:20:47 jamie Exp $ - */ - -require_once ('HTML/QuickForm.php'); - -class DB_DataObject_FormBuilder_QuickForm extends DB_DataObject_FormBuilder -{ - /** - * Array to determine what QuickForm element types are being used for which - * general field types. If you configure FormBuilder using arrays, the format is: - * array('nameOfFieldType' => 'QuickForm_Element_name', ...); - * If configured via .ini file, the format looks like this: - * elementTypeMap = shorttext:text,date:date,... - * - * Allowed field types: - *
  • shorttext
  • - *
  • longtext - *
  • date
  • - *
  • integer
  • - *
  • float
- */ - var $elementTypeMap = array('shorttext' => 'text', - 'longtext' => 'textarea', - 'date' => 'date', - 'time' => 'date', - 'datetime' => 'date', - 'integer' => 'text', - 'float' => 'text', - 'select' => 'select', - 'elementTable' => 'elementTable'); - - /** - * Array of attributes for each element type. See the keys of elementTypeMap - * for the allowed element types. - * - * The key is the element type. The value can be a valid attribute string or - * an associative array of attributes. - */ - var $elementTypeAttributes = array(); - - /** - * Array of attributes for each specific field. - * - * The key is the field name. The value can be a valid attribute string or - * an associative array of attributes. - */ - var $fieldAttributes = array(); - - /** - * DB_DataObject_FormBuilder_QuickForm::DB_DataObject_FormBuilder_QuickForm() - * - * The class constructor. - * - * @param object $do The DB_DataObject-derived object for which a form shall be built - * @param array $options An optional associative array of options. - * @access public - */ - function DB_DataObject_FormBuilder_QuickForm(&$do, $options = false) - { - // Call parent class constructor. - parent::DB_DataObject_FormBuilder($do,$options); - } - - /** - * DB_DataObject_FormBuilder_QuickForm::_getQFType() - * - * Returns the QuickForm element type associated with the given field type, - * as defined in the elementTypeMap property. If an unknown field type is given, - * the returned type name will default to 'text'. - * - * @access protected - * @param string $fieldType The internal field type - * @return string The QuickForm element type name - */ - function _getQFType($fieldType) - { - if (isset($this->elementTypeMap[$fieldType])) { - return $this->elementTypeMap[$fieldType]; - } - return 'text'; - } - - /** - * DB_DataObject_FormBuilder_QuickForm::_getAttributes() - * - * Returns the attributes to apply to a field based on the field name and - * element type. The field's attributes take precedence over the element type's. - * - * @param string $elementType the internal type of the element - * @param string $fieldName the name of the field - * @return array an array of attributes to apply to the element - */ - function _getAttributes($elementType, $fieldName) { - if (isset($this->elementTypeAttributes[$elementType])) { - if (is_string($this->elementTypeAttributes[$elementType])) { - $this->elementTypeAttributes[$elementType] = - HTML_Common::_parseAttributes($this->elementTypeAttributes[$elementType]); - } - $attr = $this->elementTypeAttributes[$elementType]; - } else { - $attr = array(); - } - if (isset($this->fieldAttributes[$fieldName])) { - if (is_string($this->fieldAttributes[$fieldName])) { - $this->fieldAttributes[$fieldName] = - HTML_Common::_parseAttributes($this->fieldAttributes[$fieldName]); - } - $attr = array_merge($attr, $this->fieldAttributes[$fieldName]); - } - return $attr; - } - - /** - * DB_DataObject_FormBuilder_QuickForm::_createFormObject() - * - * Creates a QuickForm object to be used by _generateForm(). - * - * @param string $formName The name of the form - * @param string $method Method for transferring form data over HTTP (GET|POST) - * @param string $action The script to transfer the form data to - * @param string $target Name of the target frame/window to use to display the "action" script - * @return object The HTML_QuickForm object. - * @access protected - * @see DB_DataObject_FormBuilder::_generateForm() - */ - function &_createFormObject($formName, $method, $action, $target) - { - // If there is an existing QuickForm object, and the form object should not just be - // appended, use that one. If not, make a new one. - if (is_a($this->_form, 'html_quickform') && $this->_appendForm == false) { - $form =& $this->_form; - } else { - $form =& new HTML_QuickForm($formName, $method, $action, $target); - } - return $form; - } - - /** - * DB_DataObject_FormBuilder_QuickForm::_addFormHeader() - * - * Adds a header to the given form. Will use the header defined in the "formHeaderText" property. - * Used in _generateForm(). - * - * @param object $form The QuickForm object to add the header to - * @access protected - * @see DB_DataObject_FormBuilder::_generateForm() - */ - function _addFormHeader(&$form) - { - // Add a header to the form - set addFormHeader property to false to prevent this - if ($this->addFormHeader == true) { - if (!is_null($this->formHeaderText)) { - $form->addElement('header', '', $this->formHeaderText); - } else { - $form->addElement('header', '', $this->_do->tableName()); - } - } - } - - /** - * DB_DataObject_FormBuilder_QuickForm::_createHiddenField() - * - * Returns a QuickForm element for a hidden field. - * Used in _generateForm(). - * - * @param string $fieldName The field name to use for the QuickForm element - * @access protected - * @see DB_DataObject_FormBuilder::_generateForm() - */ - function &_createHiddenField($fieldName) - { - $element =& HTML_QuickForm::createElement('hidden', - $this->getFieldName($fieldName)); - $attr = $this->_getAttributes('hidden', $fieldName); - $element->updateAttributes($attr); - return $element; - } - - /** - * DB_DataObject_FormBuilder_QuickForm::_createRadioButtons() - * - * Returns a QuickForm element for a group of radio buttons. - * Used in _generateForm(). - * - * @param string $fieldName The field name to use for the QuickForm element group - * @param array $options The list of options to generate the radio buttons for - * @return array Array of HTML_QuickForm_element objects. - * @access protected - * @see DB_DataObject_FormBuilder::_generateForm() - */ - function &_createRadioButtons($fieldName, $options) - { - $element = array(); - $attr = $this->_getAttributes('radio', $fieldName); - foreach($options as $value => $display) { - unset($radio); - $radio =& HTML_QuickForm::createElement('radio', - $this->getFieldName($fieldName), - null, - $display, - $value); - $radio->updateAttributes($attr); - $element[] =& $radio; - } - return $element; - } - - /** - * DB_DataObject_FormBuilder_QuickForm::_createCheckbox() - * - * Returns a QuickForm element for a checkbox. - * Used in _generateForm(). - * - * @param string $fieldName The field name to use for the QuickForm element - * @param string $text Text to label the checkbox - * @param string $value The value that is submitted when the checkbox is checked - * @param boolean $checked Is the checkbox checked? (Default: False) - * @param boolean $freeze Is the checkbox frozen? (Default: False) - * @return object The HTML_QuickForm_element object. - * @access protected - * @see DB_DataObject_FormBuilder::_generateForm() - */ - function &_createCheckbox($fieldName, $text = null, $value = null, $label = null, $checked = false, $freeze = false) - { - $element =& HTML_QuickForm::createElement('checkbox', - $this->getFieldName($fieldName), - $label, - $text); - if ($value !== null) { - $element->updateAttributes(array('value' => $value)); - } - if ($checked) { - $element->setChecked(true); - } - if ($freeze) { - $element->freeze(); - } - $attr = $this->_getAttributes('checkbox', $fieldName); - $element->updateAttributes($attr); - return $element; - } - - /** - * DB_DataObject_FormBuilder_QuickForm::_createTextField() - * - * Returns a QuickForm element for a single-line text field. - * Used in _generateForm(). - * - * @param string $fieldName The field name to use for the QuickForm element - * @return object The HTML_QuickForm_element object. - * @access protected - * @see DB_DataObject_FormBuilder::_generateForm() - */ - function &_createTextField($fieldName) - { - $element =& HTML_QuickForm::createElement($this->_getQFType('shorttext'), - $this->getFieldName($fieldName), - $this->getFieldLabel($fieldName)); - $attr = $this->_getAttributes('shorttext', $fieldName); - $element->updateAttributes($attr); - return $element; - } - - /** - * DB_DataObject_FormBuilder_QuickForm::_createIntegerField() - * - * Returns a QuickForm element for an integer field. - * Used in _generateForm(). - * - * @param string $fieldName The field name to use for the QuickForm element - * @return object The HTML_QuickForm_element object. - * @access protected - * @see DB_DataObject_FormBuilder::_generateForm() - */ - function &_createIntegerField($fieldName) - { - $element =& HTML_QuickForm::createElement($this->_getQFType('integer'), - $this->getFieldName($fieldName), - $this->getFieldLabel($fieldName)); - $attr = $this->_getAttributes('integer', $fieldName); - $element->updateAttributes($attr); - return $element; - } - - /** - * DB_DataObject_FormBuilder_QuickForm::_createTextArea() - * - * Returns a QuickForm element for a long text field. - * Used in _generateForm(). - * - * @param string $fieldName The field name to use for the QuickForm element - * @return object The HTML_QuickForm_element object. - * @access protected - * @see DB_DataObject_FormBuilder::_generateForm() - */ - function &_createTextArea($fieldName) - { - $element =& HTML_QuickForm::createElement($this->_getQFType('longtext'), - $this->getFieldName($fieldName), - $this->getFieldLabel($fieldName)); - $attr = $this->_getAttributes('longtext', $fieldName); - $element->updateAttributes($attr); - return $element; - } - - /** - * DB_DataObject_FormBuilder_QuickForm::_createSelectBox() - * - * Returns a QuickForm element for a selectbox/combobox. - * Used in _generateForm(). - * - * @param string $fieldName The field name to use for the QuickForm element - * @param array $options List of options for populating the selectbox - * @param boolean $multiple If set to true, the select box will be a multi-select - * @return object The HTML_QuickForm_element object. - * @access protected - * @see DB_DataObject_FormBuilder::_generateForm() - */ - function &_createSelectBox($fieldName, $options, $multiple = false) - { - if ($multiple) { - $element =& HTML_QuickForm::createElement($this->_getQFType('select'), - $this->getFieldName($fieldName), - $this->getFieldLabel($fieldName), - $options, - array('multiple' => 'multiple')); - } else { - $element =& HTML_QuickForm::createElement($this->_getQFType('select'), - $this->getFieldName($fieldName), - $this->getFieldLabel($fieldName), - $options); - } - $attr = $this->_getAttributes('select', $fieldName); - $element->updateAttributes($attr); - return $element; - } - - /** - * DB_DataObject_FormBuilder_QuickForm::_createStaticField() - * - * Returns a QuickForm element for displaying static HTML. - * Used in _generateForm(). - * - * @param string $fieldName The field name to use for the QuickForm element - * @param string $text The text or HTML code to display in place of this element - * @return object The HTML_QuickForm_element object. - * @access protected - * @see DB_DataObject_FormBuilder::_generateForm() - */ - function &_createStaticField($fieldName, $text = null) - { - $element =& HTML_QuickForm::createElement('static', - $this->getFieldName($fieldName), - $this->getFieldLabel($fieldName), - $text); - $attr = $this->_getAttributes('static', $fieldName); - $element->updateAttributes($attr); - return $element; - } - - /** - * DB_DataObject_FormBuilder_QuickForm::_addElementGroupToForm() - * - * Adds a group of elements to a form object - * Used in _generateForm(). - * - * @param object $form The QuickForm object to add the group to - * @param array $element Array of QuickForm element objects - * @param string $fieldName The field name to use for the QuickForm element group - * @param string $separator Some text or HTML snippet used to separate the group entries - * @access protected - * @see DB_DataObject_FormBuilder::_generateForm() - */ - function _addElementGroupToForm(&$form, &$element, $fieldName, $separator = '') - { - $form->addGroup($element, - $this->getFieldName($fieldName), - $this->getFieldLabel($fieldName), - $separator, - false); - } - - /** - * DB_DataObject_FormBuilder_QuickForm::_addElementToForm() - * - * Adds a QuickForm element to a form object - * Used in _generateForm(). - * - * @param object $form The form object to add the element to - * @param object $element The element object to be added - * @access protected - * @see DB_DataObject_FormBuilder::_generateForm() - */ - function _addElementToForm(&$form, &$element) - { - $form->addElement($element); - } - - /** - * DB_DataObject_FormBuilder_QuickForm::_addSubmitButtonToForm() - * - * @param HTML_QuickForm the form to add the submit button to - * @param string the name of the submit element to be created - * @param string the text to be put on the submit button - */ - function _addSubmitButtonToForm(&$form, $fieldName, $text) - { - $element =& $this->_createSubmitButton($fieldName, $text); - $this->_addElementToForm($form, $element); - } - - /** - * DB_DataObject_FormBuilder_QuickForm::_createSubmitButton() - * - * Returns a QuickForm element for a submit button. - * Used in _generateForm(). - * - * @param string the name of the submit button - * @param string the text to put in the button - * @return object The HTML_QuickForm_element object. - * @access protected - * @see DB_DataObject_FormBuilder::_generateForm() - */ - function &_createSubmitButton($fieldName, $text) - { - $element =& HTML_QuickForm::createElement('submit', $fieldName, $text); - $attr = $this->_getAttributes('submit', $fieldName); - $element->updateAttributes($attr); - return $element; - } - - /** - * DB_DataObject_FormBuilder_QuickForm::_createDateElement() - * - * Returns a QuickForm element for entering date values. - * Used in _generateForm(). - * - * @param string $fieldName The field name to use for the element - * @return object The HTML_QuickForm_element object. - * @access protected - * @see DB_DataObject_FormBuilder::_generateForm() - */ - function &_createDateElement($fieldName) { - $dateOptions = array('format' => $this->dateElementFormat, - 'language' => $this->dateFieldLanguage); - if (method_exists($this->_do, 'dateoptions')) { - $dateOptions = array_merge($dateOptions, $this->_do->dateOptions($fieldName)); - } - if (!isset($dateOptions['addEmptyOption']) && in_array($fieldName, $this->selectAddEmpty)) { - $dateOptions['addEmptyOption'] = true; - } - $element =& HTML_QuickForm::createElement($this->_getQFType('date'), - $this->getFieldName($fieldName), - $this->getFieldLabel($fieldName), - $dateOptions); - $attr = $this->_getAttributes('date', $fieldName); - $element->updateAttributes($attr); - return $element; - } - - /** - * DB_DataObject_FormBuilder_QuickForm::_createTimeElement() - * - * Returns a QuickForm element for entering time values. - * Used in _generateForm(). - * Note by Frank: The only reason for this is the difference in timeoptions so it - * probably would be better integrated with _createDateElement - * - * @param string $fieldName The field name to use for the element - * @return object The HTML_QuickForm_element object. - * @access protected - * @see DB_DataObject_FormBuilder::_generateForm() - */ - function &_createTimeElement($fieldName) { - $timeOptions = array('format' => $this->timeElementFormat, - 'language' => $this->dateFieldLanguage); - if (method_exists($this->_do, 'timeoptions')) { // Frank: I'm trying to trace this but am unsure of it // - $timeOptions = array_merge($timeOptions, $this->_do->timeOptions($fieldName)); - } - if (!isset($timeOptions['addEmptyOption']) && in_array($fieldName, $this->selectAddEmpty)) { - $timeOptions['addEmptyOption'] = true; - } - $element =& HTML_QuickForm::createElement($this->_getQFType('time'), - $this->getFieldName($fieldName), - $this->getFieldLabel($fieldName), - $timeOptions); - $attr = $this->_getAttributes('time', $fieldName); - $element->updateAttributes($attr); - return $element; - } - - /** - * DB_DataObject_FormBuilder_QuickForm::_createDateTimeElement() - * - * Returns a QuickForm element for entering date values. - * Used in _generateForm(). - * - * @param string $fieldName The field name to use for the element - * @return object The HTML_QuickForm_element object. - * @access protected - * @see DB_DataObject_FormBuilder::_generateForm() - */ - function &_createDateTimeElement($fieldName) { - $dateOptions = array('format' => $this->dateTimeElementFormat, - 'language' => $this->dateFieldLanguage); - if (method_exists($this->_do, 'datetimeoptions')) { - $dateOptions = array_merge($dateOptions, $this->_do->dateTimeOptions($fieldName)); - } - if (!isset($dateOptions['addEmptyOption']) && in_array($fieldName, $this->selectAddEmpty)) { - $dateOptions['addEmptyOption'] = true; - } - $element =& HTML_QuickForm::createElement($this->_getQFType('datetime'), - $this->getFieldName($fieldName), - $this->getFieldLabel($fieldName), - $dateOptions); - $attr = $this->_getAttributes('datetime', $fieldName); - $element->updateAttributes($attr); - return $element; - } - - /** - * DB_DataObject_FormBuilder_QuickForm::_addElementTableToForm - * - * Adds an elementTable to the form - * - * @param HTML_QuickForm $form the form to add the element to - * @param string $fieldName the name of the element to be added - * @param array $columnNames an array of the column names - * @param array $rowNames an array of the row names - * @param array $rows an array of rows, each row being an array of HTML_QuickForm elements - */ - function _addElementTableToForm(&$form, $fieldName, $columnNames, $rowNames, &$rows) { - if (!HTML_QuickForm::isTypeRegistered('elementTable')) { - HTML_QuickForm::registerElementType('elementTable', - 'DB/DataObject/FormBuilder/QuickForm/ElementTable.php', - 'DB_DataObject_FormBuilder_QuickForm_ElementTable'); - } - $element =& HTML_QuickForm::createElement($this->_getQFType('elementTable'), - $this->getFieldName($fieldName), - $this->getFieldLabel($fieldName)); - $element->setColumnNames($columnNames); - $element->setRowNames($rowNames); - $element->setRows($rows); - $attr = $this->_getAttributes('elementTable', $fieldName); - $element->updateAttributes($attr); - $this->_addElementToForm($form, $element); - } - - /** - * DB_DataObject_FormBuilder_QuickForm::_setFormDefaults() - * - * @param HTML_QuickForm the form to set the defaults on - * @param array Assoc array of default values (@see HTML_QuickForm::setDefaults) - */ - function _setFormDefaults(&$form, $defaults) - { - $form->setDefaults($defaults); - } - - /** - * DB_DataObject_FormBuilder_QuickForm::_setFormElementRequired() - * - * Adds a required rule for a specific element to a form - * Used in _generateForm(). - * - * @param object $form The form object to add the rule to - * @param object $fieldName The name of the required field - * @access protected - * @see DB_DataObject_FormBuilder::_generateForm() - */ - function _setFormElementRequired(&$form, $fieldName) - { - $this->_addFieldRulesToForm($form, - array(array('validator' => 'required', - 'rule' => false, - 'message' => $this->requiredRuleMessage)), - $fieldName); - } - - /** - * DB_DataObject_FormBuilder_QuickForm::_addFieldRulesToForm() - * - * Adds a set of rules to a form that will apply to a specific element - * Used in _generateForm(). - * - * @param object $form The form object to add the ruleset to - * @param array $rules Array of rule names to be enforced on the element (must be registered QuickForm rules) - * @param string $fieldName Name of the form element in question - * @access protected - * @see DB_DataObject_FormBuilder::_generateForm() - */ - function _addFieldRulesToForm(&$form, $rules, $fieldName) - { - $fieldLabel = $this->getFieldLabel($fieldName); - $ruleSide = $this->clientRules ? 'client' : 'server'; - foreach ($rules as $rule) { - if ($rule['rule'] === false) { - $form->addRule($this->getFieldName($fieldName), - sprintf($rule['message'], $fieldLabel), - $rule['validator'], - '', - $ruleSide); - } else { - $form->addRule($this->getFieldName($fieldName), - sprintf($rule['message'], $fieldLabel), - $rule['validator'], - $rule['rule'], - $ruleSide); - } // End if - } // End while - } - - /** - * DB_DataObject_FormBuilder_QuickForm::_freezeFormElements() - * - * Freezes a list of form elements (set read-only). - * Used in _generateForm(). - * - * @param object $form The form object in question - * @param array $elements_to_freeze List of element names to be frozen - * @access protected - * @see DB_DataObject_FormBuilder::_generateForm() - */ - function _freezeFormElements(&$form, $elementsToFreeze) - { - foreach ($elementsToFreeze as $elementToFreeze) { - $elementToFreeze = $this->getFieldName($elementToFreeze); - if ($form->elementExists($elementToFreeze)) { - $el =& $form->getElement($elementToFreeze); - $el->freeze(); - } - } - } -} - -?> \ No newline at end of file diff --git a/glmPEAR/DB/DataObject/FormBuilder/QuickForm/ElementTable.php b/glmPEAR/DB/DataObject/FormBuilder/QuickForm/ElementTable.php deleted file mode 100755 index a66efd5..0000000 --- a/glmPEAR/DB/DataObject/FormBuilder/QuickForm/ElementTable.php +++ /dev/null @@ -1,207 +0,0 @@ - | -// +----------------------------------------------------------------------+ - -/** - * @package DB_DataObject_FormBuilder - * @author Justin Patrin - * @version $Id: ElementTable.php,v 1.1.1.1 2008/04/28 15:20:47 jamie Exp $ - */ - -require_once('HTML/QuickForm/element.php'); - -/** - * An HTML_QuickForm element which creates a table of elements - */ -class DB_DataObject_FormBuilder_QuickForm_ElementTable extends HTML_QuickForm_element { - - /** - * Array of arrays of HTML_QuickForm elements - * - * @var array - */ - var $_rows = array(); - - /** - * Array of column names (strings) - * - * @var array - */ - var $_columnNames = array(); - - /** - * Array of row names (strings) - * - * @var array - */ - var $_rowNames = array(); - - /** - * Constructor - * - * @param string name for the element - * @param string label for the element - */ - function DB_DataObject_FormBuilder_QuickForm_ElementTable($name = null, $label = null/*, $columnNames = null, - $rowNames = null, $rows = null, $attributes = null*/) { - parent::HTML_QuickForm_element($name, $label); - //$this->setRows($rows); - //$this->setColumnNames($columnNames); - //$this->setRowNames($rowNames); - } - - /** - * Sets the column names - * - * @param array array of column names (strings) - */ - function setColumnNames($columnNames) { - $this->_columnNames = $columnNames; - } - - /** - * Adds a column name - * - * @param string name of the column - */ - function addColumnName($columnName) { - $this->_columnNames[] = $columnName; - } - - /** - * Set the row names - * - * @param array array of row names (strings) - */ - function setRowNames($rowNames) { - $this->_rowNames = $rowNames; - } - - /** - * Sets the rows - * - * @param array array of HTML_QuickForm elements - */ - function setRows(&$rows) { - $this->_rows =& $rows; - } - - /** - * Adds a row to the table - * - * @param array array of HTML_QuickForm elements - * @param string name of the row - */ - function addRow(&$row, $rowName = null) { - $this->_rows[] =& $row; - if ($rowName !== null) { - $this->addRowName($rowName); - } - } - - /** - * Adds a row name - * - * @param string name of the row - */ - function addRowName($rowName) { - $this->_rowNames[] = $rowName; - } - - /** - * Freezes all checkboxes in the table - */ - function freeze() { - parent::freeze(); - foreach (array_keys($this->_rows) as $key) { - foreach (array_keys($this->_rows[$key]) as $key2) { - $this->_rows[$key][$key2]->freeze(); - } - } - } - - /** - * Returns Html for the group - * - * @access public - * @return string - */ - function toHtml() - { - include_once ('HTML/Table.php'); - $tripleLinkTable = new HTML_Table(); - $tripleLinkTable->setAutoGrow(true); - $tripleLinkTable->setAutoFill(''); - $tripleLinkTable->updateAttributes($this->getAttributes()); - $row = 0; - $col = 0; - - foreach ($this->_columnNames as $key => $value) { - ++$col; - $tripleLinkTable->setCellContents($row, $col, $value); - $tripleLinkTable->setCellAttributes($row, $col, array('style' => 'text-align: center')); - } - - foreach (array_keys($this->_rows) as $key) { - ++$row; - $col = 0; - $tripleLinkTable->setCellContents($row, $col, $this->_rowNames[$key]); - foreach (array_keys($this->_rows[$key]) as $key2) { - ++$col; - $tripleLinkTable->setCellContents($row, $col, $this->_rows[$key][$key2]->toHTML()); - $tripleLinkTable->setCellAttributes($row, $col, array('style' => 'text-align: center')); - } - } - $hrAttrs = array('bgcolor' => 'lightgrey'); - $tripleLinkTable->setRowAttributes(0, $hrAttrs, true); - $tripleLinkTable->setColAttributes(0, $hrAttrs); - return $tripleLinkTable->toHTML(); - - /*include_once('HTML/QuickForm/Renderer/Default.php'); - $renderer =& new HTML_QuickForm_Renderer_Default(); - $renderer->setElementTemplate('{element}'); - $this->accept($renderer); - return $renderer->toHtml();*/ - } //end func toHtml - - /** - * Called by HTML_QuickForm whenever form event is made on this element - * - * @param string Name of event - * @param mixed event arguments - * @param object calling object - * @access public - * @return bool true - */ - function onQuickFormEvent($event, $arg, &$caller) - { - switch ($event) { - case 'updateValue': - foreach (array_keys($this->_rows) as $key) { - foreach (array_keys($this->_rows[$key]) as $key2) { - $this->_rows[$key][$key2]->onQuickFormEvent('updateValue', null, $caller); - } - } - break; - - default: - parent::onQuickFormEvent($event, $arg, $caller); - } - return true; - } -} - -?> \ No newline at end of file diff --git a/glmPEAR/DB/DataObject/Generator.php b/glmPEAR/DB/DataObject/Generator.php deleted file mode 100755 index 2449fde..0000000 --- a/glmPEAR/DB/DataObject/Generator.php +++ /dev/null @@ -1,738 +0,0 @@ - -// +----------------------------------------------------------------------+ -// $Id: Generator.php,v 1.1.1.1 2008/04/28 15:20:47 jamie Exp $ - -/** - * Generation tools for DB_DataObject - * - * Config _$ptions - * [DB_DataObject_Generator] - * ; optional default = DB/DataObject.php - * extends_location = - * ; optional default = DB_DataObject - * extends = - * ; leave blank to not generate template stuff. - * make_template = display,list,edit - * - * ; options for Template Generation (using FlexyTemplate - * [DB_DataObject_Generator_Template_Flexy] - * templateDir = /home/xxx/templates - * compileDir = /home/xxx/compiled", - * filters = php,simpletags,bodyonly - * forceCompile = 0 - * - * ; fileds to flags as hidden for template generation(preg_match format) - * hideFields = password - * ; fields to flag as read only.. (preg_match format) - * readOnlyFields = created|person_created|modified|person_modified - * ; fields to flag as links (from lists->edit/view) (preg_match formate) - * linkFields = id|username|name - * ; alter the extends field when updating a class (defaults to only replacing DB_DataObject) - * generator_class_rewrite = ANY|specific_name // default is DB_DataObject - * - * @package DB_DataObject - * @category DB - */ - -/** - * Needed classes - */ -require_once 'DB/DataObject.php'; -//require_once('Config.php'); - -/** - * Generator class - * - * @package DB_DataObject - */ -class DB_DataObject_Generator extends DB_DataObject -{ - /* =========================================================== */ - /* Utility functions - for building db config files */ - /* =========================================================== */ - - /** - * Array of table names - * - * @var array - * @access private - */ - var $tables; - - /** - * associative array table -> array of table row objects - * - * @var array - * @access private - */ - var $_definitions; - - /** - * active table being output - * - * @var string - * @access private - */ - var $table; // active tablename - - - /** - * The 'starter' = call this to start the process - * - * @access public - * @return none - */ - function start() - { - $options = &PEAR::getStaticProperty('DB_DataObject','options'); - $databases = array(); - foreach($options as $k=>$v) { - if (substr($k,0,9) == 'database_') { - $databases[substr($k,9)] = $v; - } - } - - if (@$options['database']) { - require_once 'DB.php'; - $dsn = DB::parseDSN($options['database']); - if (!isset($database[$dsn['database']])) { - $databases[$dsn['database']] = $options['database']; - } - } - - foreach($databases as $databasename => $database) { - if (!$database) continue; - $this->debug("CREATING FOR $databasename\n"); - $class = get_class($this); - $t = new $class; - $t->_database_dsn = $database; - $t->_database = $databasename; - $t->_createTableList(); - - foreach(get_class_methods($class) as $method) { - if (substr($method,0,8 ) != 'generate') { - continue; - } - $this->debug("calling $method"); - $t->$method(); - } - } - $this->debug("DONE\n\n"); - } - - /** - * Output File was config object, now just string - * Used to generate the Tables - * - * @var string outputbuffer for table definitions - * @access private - */ - var $_newConfig; - - /** - * Build a list of tables; - * Currently this is very Mysql Specific - ideas for more generic stiff welcome - * - * @access private - * @return none - */ - function _createTableList() - { - $this->_connect(); - $options = &PEAR::getStaticProperty('DB_DataObject','options'); - - $__DB= &$GLOBALS['_DB_DATAOBJECT']['CONNECTIONS'][$this->_database_dsn_md5]; - - $this->tables = $__DB->getListOf('tables'); - - if (is_a($this->tables , 'PEAR_Error')) { - return PEAR::raiseError($this->tables->toString(), null, PEAR_ERROR_DIE); - } - // build views as well if asked to. - if (!empty($options['build_views'])) { - $this->tables = array_merge ($this->tables, $__DB->getListOf('views')); - } - - - // declare a temporary table to be filled with matching tables names - $tmp_table = array(); - - - foreach($this->tables as $table) { - if (isset($options['generator_include_regex']) && - !preg_match($options['generator_include_regex'],$table)) { - continue; - } else if (isset($options['generator_exclude_regex']) && - preg_match($options['generator_exclude_regex'],$table)) { - continue; - } - - // we find a matching table, just store it into a temporary array - $tmp_table[] = $table; - - $defs = $__DB->tableInfo($table); - if (is_a($defs,'PEAR_Error')) { - echo $defs->toString(); - exit; - } - // cast all definitions to objects - as we deal with that better. - foreach($defs as $def) { - if (is_array($def)) { - $this->_definitions[$table][] = (object) $def; - } - } - } - // the temporary table array is now the right one (tables names matching - // with regex expressions have been removed) - $this->tables = $tmp_table; - //print_r($this->_definitions); - } - - /** - * Auto generation of table data. - * - * it will output to db_oo_{database} the table definitions - * - * @access private - * @return none - */ - function generateDefinitions() - { - $this->debug("Generating Definitions file: "); - if (!$this->tables) { - $this->debug("-- NO TABLES -- \n"); - return; - } - - $options = &PEAR::getStaticProperty('DB_DataObject','options'); - - - //$this->_newConfig = new Config('IniFile'); - $this->_newConfig = ''; - foreach($this->tables as $this->table) { - $this->_generateDefinitionsTable(); - } - $this->_connect(); - // dont generate a schema if location is not set - // it's created on the fly! - if (!@$options['schema_location'] && @!$options["ini_{$this->_database}"] ) { - return; - } - $base = @$options['schema_location']; - if (isset($options["ini_{$this->_database}"])) { - $file = $options["ini_{$this->_database}"]; - } else { - $file = "{$base}/{$this->_database}.ini"; - } - - if (!file_exists(dirname($file))) { - require_once 'System.php'; - System::mkdir(array('-p','-m',0755,dirname($file))); - } - $this->debug("Writing ini as {$file}\n"); - touch($file); - //print_r($this->_newConfig); - $fh = fopen($file,'w'); - fwrite($fh,$this->_newConfig); - fclose($fh); - //$ret = $this->_newConfig->writeInput($file,false); - - //if (PEAR::isError($ret) ) { - // return PEAR::raiseError($ret->message,null,PEAR_ERROR_DIE); - // } - } - - /** - * The table geneation part - * - * @access private - * @return tabledef and keys array. - */ - function _generateDefinitionsTable() - { - global $_DB_DATAOBJECT; - - $defs = $this->_definitions[$this->table]; - $this->_newConfig .= "\n[{$this->table}]\n"; - $keys_out = "\n[{$this->table}__keys]\n"; - $keys_out_primary = ''; - $keys_out_secondary = ''; - if (@$_DB_DATAOBJECT['CONFIG']['debug'] > 2) { - echo "TABLE STRUCTURE FOR {$this->table}\n"; - print_r($defs); - } - $DB = $this->getDatabaseConnection(); - $dbtype = $DB->phptype; - - $ret = array( - 'table' => array(), - 'keys' => array(), - ); - - $ret_keys_primary = array(); - $ret_keys_secondary = array(); - - - - foreach($defs as $t) { - - $n=0; - - switch (strtoupper($t->type)) { - - case 'INT': - case 'INT2': // postgres - case 'INT4': // postgres - case 'INT8': // postgres - case 'SERIAL4': // postgres - case 'SERIAL8': // postgres - case 'INTEGER': - case 'TINYINT': - case 'SMALLINT': - case 'MEDIUMINT': - case 'BIGINT': - $type = DB_DATAOBJECT_INT; - if ($t->len == 1) { - $type += DB_DATAOBJECT_BOOL; - } - break; - - case 'REAL': - case 'DOUBLE': - case 'FLOAT': - case 'FLOAT8': // double precision (postgres) - case 'DECIMAL': - case 'NUMERIC': - $type = DB_DATAOBJECT_INT; // should really by FLOAT!!! / MONEY... - break; - - case 'YEAR': - $type = DB_DATAOBJECT_INT; - break; - - case 'BIT': - case 'BOOL': - case 'BOOLEAN': - - $type = DB_DATAOBJECT_BOOL; - // postgres needs to quote '0' - if ($dbtype == 'pgsql') { - $type += DB_DATAOBJECT_STR; - } - break; - - case 'STRING': - case 'CHAR': - case 'VARCHAR': - case 'VARCHAR2': - case 'TINYTEXT': - case 'TEXT': - case 'MEDIUMTEXT': - case 'LONGTEXT': - case 'ENUM': - case 'SET': // not really but oh well - case 'TIMESTAMPTZ': // postgres - case 'BPCHAR': // postgres - case 'INTERVAL': // postgres (eg. '12 days') - - case 'CIDR': // postgres IP net spec - case 'INET': // postgres IP - case 'MACADDR': // postgress network Mac address. - - - $type = DB_DATAOBJECT_STR; - break; - - case 'DATE': - $type = DB_DATAOBJECT_STR + DB_DATAOBJECT_DATE; - break; - - case 'TIME': - $type = DB_DATAOBJECT_STR + DB_DATAOBJECT_TIME; - break; - - - case 'DATETIME': - - $type = DB_DATAOBJECT_STR + DB_DATAOBJECT_DATE + DB_DATAOBJECT_TIME; - break; - - case 'TIMESTAMP': // do other databases use this??? - - $type = ($dbtype == 'mysql') ? - DB_DATAOBJECT_MYSQLTIMESTAMP : - DB_DATAOBJECT_STR + DB_DATAOBJECT_DATE + DB_DATAOBJECT_TIME; - break; - - - case 'TINYBLOB': - case 'BLOB': /// these should really be ignored!!!??? - case 'MEDIUMBLOB': - case 'LONGBLOB': - case 'BYTEA': // postgres blob support.. - $type = DB_DATAOBJECT_STR + DB_DATAOBJECT_BLOB; - break; - - - } - - - if (!strlen(trim($t->name))) { - continue; - } - - if (preg_match('/not_null/i',$t->flags)) { - $type += DB_DATAOBJECT_NOTNULL; - } - - $this->_newConfig .= "{$t->name} = $type\n"; - $ret['table'][$t->name] = $type; - // i've no idea if this will work well on other databases? - // only use primary key or nextval(), cause the setFrom blocks you setting all key items... - // if no keys exist fall back to using unique - //echo "\n{$t->name} => {$t->flags}\n"; - if (preg_match("/(auto_increment|nextval\()/i",rawurldecode($t->flags))) { - // native sequences = 2 - $keys_out_primary .= "{$t->name} = N\n"; - $ret_keys_primary[$t->name] = 'N'; - } else if (preg_match("/(primary|unique)/i",$t->flags)) { - // keys.. = 1 - $keys_out_secondary .= "{$t->name} = K\n"; - $ret_keys_secondary[$t->name] = 'K'; - } - - - - - } - - $this->_newConfig .= $keys_out . (empty($keys_out_primary) ? $keys_out_secondary : $keys_out_primary); - $ret['keys'] = empty($keys_out_primary) ? $ret_keys_secondary : $ret_keys_primary; - - if (@$_DB_DATAOBJECT['CONFIG']['debug'] > 2) { - print_r(array("dump for {$this->table}", $ret)); - } - - return $ret; - - - } - - /* - * building the class files - * for each of the tables output a file! - */ - function generateClasses() - { - //echo "Generating Class files: \n"; - $options = &PEAR::getStaticProperty('DB_DataObject','options'); - $base = $options['class_location']; - if (!file_exists($base)) { - require_once 'System.php'; - System::mkdir(array('-p',$base)); - } - $class_prefix = $options['class_prefix']; - if ($extends = @$options['extends']) { - $this->_extends = $extends; - $this->_extendsFile = $options['extends_location']; - } - - foreach($this->tables as $this->table) { - $this->table = trim($this->table); - $this->classname = $class_prefix.preg_replace('/[^A-Z0-9]/i','_',ucfirst($this->table)); - $i = ''; - $outfilename = "{$base}/".preg_replace('/[^A-Z0-9]/i','_',ucfirst($this->table)).".php"; - if (file_exists($outfilename)) - $i = implode('',file($outfilename)); - $out = $this->_generateClassTable($i); - $this->debug( "writing $this->classname\n"); - $fh = fopen($outfilename, "w"); - fputs($fh,$out); - fclose($fh); - } - //echo $out; - } - - /** - * class being extended (can be overridden by [DB_DataObject_Generator] extends=xxxx - * - * @var string - * @access private - */ - var $_extends = 'DB_DataObject'; - - /** - * line to use for require('DB/DataObject.php'); - * - * @var string - * @access private - */ - var $_extendsFile = "DB/DataObject.php"; - - /** - * class being generated - * - * @var string - * @access private - */ - var $_className; - - /** - * The table class geneation part - single file. - * - * @access private - * @return none - */ - function _generateClassTable($input = '') - { - // title = expand me! - $foot = ""; - $head = "table}\n */\n"; - // requires - $head .= "require_once '{$this->_extendsFile}';\n\n"; - // add dummy class header in... - // class - $head .= "class {$this->classname} extends {$this->_extends} \n{"; - - $body = "\n ###START_AUTOCODE\n"; - $body .= " /* the code below is auto generated do not remove the above tag */\n\n"; - // table - $padding = (30 - strlen($this->table)); - if ($padding < 2) $padding =2; - $p = str_repeat(' ',$padding) ; - $body .= " var \$__table = '{$this->table}'; {$p}// table name\n"; - - - // if we are using the option database_{databasename} = dsn - // then we should add var $_database = here - // as database names may not always match.. - $options = &PEAR::getStaticProperty('DB_DataObject','options'); - if (isset($options["database_{$this->_database}"])) { - $body .= " var \$_database = '{$this->_database}'; {$p}// database name (used with database_{*} config)\n"; - } - - - - - $defs = $this->_definitions[$this->table]; - - // show nice information! - $connections = array(); - $sets = array(); - foreach($defs as $t) { - if (!strlen(trim($t->name))) { - continue; - } - $padding = (30 - strlen($t->name)); - if ($padding < 2) $padding =2; - $p = str_repeat(' ',$padding) ; - $body .=" var \${$t->name}; {$p}// {$t->type}({$t->len}) {$t->flags}\n"; - // can not do set as PEAR::DB table info doesnt support it. - //if (substr($t->Type,0,3) == "set") - // $sets[$t->Field] = "array".substr($t->Type,3); - $body .= $this->derivedHookVar($t,$padding); - } - - // THIS IS TOTALLY BORKED old FC creation - // IT WILL BE REMOVED!!!!! in DataObjects 1.6 - // grep -r __clone * to find all it's uses - // and replace them with $x = clone($y); - // due to the change in the PHP5 clone design. - - if ( substr(phpversion(),0,1) < 5) { - $body .= "\n"; - $body .= " /* ZE2 compatibility trick*/\n"; - $body .= " function __clone() { return \$this;}\n"; - } - - // simple creation tools ! (static stuff!) - $body .= "\n"; - $body .= " /* Static get */\n"; - $body .= " function staticGet(\$k,\$v=NULL) { return DB_DataObject::staticGet('{$this->classname}',\$k,\$v); }\n"; - - /* - theoretically there is scope here to introduce 'list' methods - based up 'xxxx_up' column!!! for heiracitcal trees.. - */ - - // set methods - //foreach ($sets as $k=>$v) { - // $kk = strtoupper($k); - // $body .=" function getSets{$k}() { return {$v}; }\n"; - //} - $body .= $this->derivedHookFunctions(); - - $body .= "\n /* the code above is auto generated do not remove the tag below */"; - $body .= "\n ###END_AUTOCODE\n"; - - $foot .= "}\n"; - $full = $head . $body . $foot; - - if (!$input) { - return $full; - } - if (!preg_match('/(\n|\r\n)\s*###START_AUTOCODE(\n|\r\n)/s',$input)) { - return $full; - } - if (!preg_match('/(\n|\r\n)\s*###END_AUTOCODE(\n|\r\n)/s',$input)) { - return $full; - } - - - /* this will only replace extends DB_DataObject by default, - unless use set generator_class_rewrite to ANY or a name*/ - - $class_rewrite = 'DB_DataObject'; - $options = &PEAR::getStaticProperty('DB_DataObject','options'); - if (!($class_rewrite = @$options['generator_class_rewrite'])) { - $class_rewrite = 'DB_DataObject'; - } - if ($class_rewrite == 'ANY') { - $class_rewrite = '[a-z_]+'; - } - - $input = preg_replace( - '/(\n|\r\n)class\s*[a-z0-9_]+\s*extends\s*' .$class_rewrite . '\s*\{(\n|\r\n)/si', - "\nclass {$this->classname} extends {$this->_extends} \n{\n", - $input); - - return preg_replace( - '/(\n|\r\n)\s*###START_AUTOCODE(\n|\r\n).*(\n|\r\n)\s*###END_AUTOCODE(\n|\r\n)/s', - $body,$input); - } - - /** - * hook to add extra methods to all classes - * - * called once for each class, use with $this->table and - * $this->_definitions[$this->table], to get data out of the current table, - * use it to add extra methods to the default classes. - * - * @access public - * @return string added to class eg. functions. - */ - function derivedHookFunctions() - { - // This is so derived generator classes can generate functions - // It MUST NOT be changed here!!! - return ""; - } - - /** - * hook for var lines - * called each time a var line is generated, override to add extra var - * lines - * - * @param object t containing type,len,flags etc. from tableInfo call - * @param int padding number of spaces - * @access public - * @return string added to class eg. functions. - */ - function derivedHookVar(&$t,$padding) - { - // This is so derived generator classes can generate variabels - // It MUST NOT be changed here!!! - return ""; - } - - - /** - * getProxyFull - create a class definition on the fly and instantate it.. - * - * similar to generated files - but also evals the class definitoin code. - * - * - * @param string database name - * @param string table name of table to create proxy for. - * - * - * @return object Instance of class. or PEAR Error - * @access public - */ - function getProxyFull($database,$table) { - - if ($err = $this->fillTableSchema($database,$table)) { - return $err; - } - - - $options = &PEAR::getStaticProperty('DB_DataObject','options'); - $class_prefix = $options['class_prefix']; - - if ($extends = @$options['extends']) { - $this->_extends = $extends; - $this->_extendsFile = $options['extends_location']; - } - - - $classname = $this->classname = $class_prefix.preg_replace('/[^A-Z0-9]/i','_',ucfirst(trim($this->table))); - - $out = $this->_generateClassTable(); - //echo $out; - eval('?>'.$out); - return new $classname; - - } - - /** - * fillTableSchema - set the database schema on the fly - * - * - * - * @param string database name - * @param string table name of table to create schema info for - * - * @return none | PEAR::error() - * @access public - */ - function fillTableSchema($database,$table) { - global $_DB_DATAOBJECT; - $this->_database = $database; - $this->_connect(); - $table = trim($table); - - $__DB= &$GLOBALS['_DB_DATAOBJECT']['CONNECTIONS'][$this->_database_dsn_md5]; - - $defs = $__DB->tableInfo($table); - if (PEAR::isError($defs)) { - return $defs; - } - if (@$_DB_DATAOBJECT['CONFIG']['debug'] > 2) { - $this->debug("getting def for $database/$table",'fillTable'); - $this->debug(print_r($defs,true),'defs'); - } - // cast all definitions to objects - as we deal with that better. - - - foreach($defs as $def) { - if (is_array($def)) { - $this->_definitions[$table][] = (object) $def; - } - } - - $this->table = trim($table); - $ret = $this->_generateDefinitionsTable(); - - $_DB_DATAOBJECT['INI'][$database][$table] = $ret['table']; - $_DB_DATAOBJECT['INI'][$database][$table.'__keys'] = $ret['keys']; - return false; - - } - - - -} diff --git a/glmPEAR/DB/DataObject/createTables.php b/glmPEAR/DB/DataObject/createTables.php deleted file mode 100755 index cd45eab..0000000 --- a/glmPEAR/DB/DataObject/createTables.php +++ /dev/null @@ -1,47 +0,0 @@ -#!/usr/bin/php -q - -// +----------------------------------------------------------------------+ -// -// $Id: createTables.php,v 1.1.1.1 2008/04/28 15:20:47 jamie Exp $ -// -define('DB_DATAOBJECT_NO_OVERLOAD', 0); -require_once 'DB/DataObject/Generator.php'; - -if (!ini_get('register_argc_argv')) { - PEAR::raiseError("\nERROR: You must turn register_argc_argv On in you php.ini file for this to work\neg.\n\nregister_argc_argv = On\n\n", null, PEAR_ERROR_DIE); - exit; -} - -if (!@$_SERVER['argv'][1]) { - PEAR::raiseError("\nERROR: createTable.php usage:\n\nC:\php\pear\DB\DataObjects\createTable.php example.ini\n\n", null, PEAR_ERROR_DIE); - exit; -} - -$config = parse_ini_file($_SERVER['argv'][1], true); - -$options = &PEAR::getStaticProperty('DB_DataObject','options'); -$options = $config['DB_DataObject']; - -if (!$options) { - PEAR::raiseError("\nERROR: could not read ini file\n\n", null, PEAR_ERROR_DIE); - exit; -} -set_time_limit(0); -DB_DataObject::debugLevel(1); -$generator = new DB_DataObject_Generator; -$generator->start(); - diff --git a/glmPEAR/DB/common.php b/glmPEAR/DB/common.php deleted file mode 100755 index 9b5e2c7..0000000 --- a/glmPEAR/DB/common.php +++ /dev/null @@ -1,2027 +0,0 @@ - | -// | Tomas V.V.Cox | -// | Maintainer: Daniel Convissor | -// +----------------------------------------------------------------------+ -// -// $Id: common.php,v 1.1.1.1 2008/04/28 15:20:47 jamie Exp $ - -require_once 'PEAR.php'; - -/** - * DB_common is a base class for DB implementations, and must be - * inherited by all such - * - * @package DB - * @version $Id: common.php,v 1.1.1.1 2008/04/28 15:20:47 jamie Exp $ - * @category Database - * @author Stig Bakken - * @author Tomas V.V.Cox - */ -class DB_common extends PEAR -{ - // {{{ properties - - /** - * assoc of capabilities for this DB implementation - * $features['limit'] => 'emulate' => emulate with fetch row by number - * 'alter' => alter the query - * false => skip rows - * @var array - */ - var $features = array(); - - /** - * assoc mapping native error codes to DB ones - * @var array - */ - var $errorcode_map = array(); - - /** - * DB type (mysql, oci8, odbc etc.) - * @var string - */ - var $phptype; - - /** - * @var string - */ - var $prepare_tokens; - - /** - * @var string - */ - var $prepare_types; - - /** - * @var string - */ - var $prepared_queries; - - /** - * @var integer - */ - var $prepare_maxstmt = 0; - - /** - * @var string - */ - var $last_query = ''; - - /** - * @var integer - */ - var $fetchmode = DB_FETCHMODE_ORDERED; - - /** - * @var string - */ - var $fetchmode_object_class = 'stdClass'; - - /** - * Run-time configuration options. - * - * The 'optimize' option has been deprecated. Use the 'portability' - * option instead. - * - * @see DB_common::setOption() - * @var array - */ - var $options = array( - 'persistent' => false, - 'ssl' => false, - 'debug' => 0, - 'seqname_format' => '%s_seq', - 'autofree' => false, - 'portability' => DB_PORTABILITY_NONE, - 'optimize' => 'performance', // Deprecated. Use 'portability'. - ); - - /** - * DB handle - * @var resource - */ - var $dbh; - - // }}} - // {{{ toString() - - /** - * String conversation - * - * @return string - * @access private - */ - function toString() - { - $info = strtolower(get_class($this)); - $info .= ': (phptype=' . $this->phptype . - ', dbsyntax=' . $this->dbsyntax . - ')'; - - if ($this->connection) { - $info .= ' [connected]'; - } - - return $info; - } - - // }}} - // {{{ constructor - - /** - * Constructor - */ - function DB_common() - { - $this->PEAR('DB_Error'); - } - - // }}} - // {{{ quoteString() - - /** - * DEPRECATED: Quotes a string so it can be safely used within string - * delimiters in a query - * - * @return string quoted string - * - * @see DB_common::quoteSmart(), DB_common::escapeSimple() - * @deprecated Deprecated in release 1.2 or lower - * @internal - */ - function quoteString($string) - { - $string = $this->quote($string); - if ($string{0} == "'") { - return substr($string, 1, -1); - } - return $string; - } - - // }}} - // {{{ quote() - - /** - * DEPRECATED: Quotes a string so it can be safely used in a query - * - * @param string $string the input string to quote - * - * @return string The NULL string or the string quotes - * in magic_quote_sybase style - * - * @see DB_common::quoteSmart(), DB_common::escapeSimple() - * @deprecated Deprecated in release 1.6.0 - * @internal - */ - function quote($string = null) - { - return ($string === null) ? 'NULL' : "'".str_replace("'", "''", $string)."'"; - } - - // }}} - // {{{ quoteIdentifier() - - /** - * Quote a string so it can be safely used as a table or column name - * - * Delimiting style depends on which database driver is being used. - * - * NOTE: just because you CAN use delimited identifiers doesn't mean - * you SHOULD use them. In general, they end up causing way more - * problems than they solve. - * - * Portability is broken by using the following characters inside - * delimited identifiers: - * + backtick (`) -- due to MySQL - * + double quote (") -- due to Oracle - * + brackets ([ or ]) -- due to Access - * - * Delimited identifiers are known to generally work correctly under - * the following drivers: - * + mssql - * + mysql - * + mysqli - * + oci8 - * + odbc(access) - * + odbc(db2) - * + pgsql - * + sqlite - * + sybase - * - * InterBase doesn't seem to be able to use delimited identifiers - * via PHP 4. They work fine under PHP 5. - * - * @param string $str identifier name to be quoted - * - * @return string quoted identifier string - * - * @since 1.6.0 - * @access public - */ - function quoteIdentifier($str) - { - return '"' . str_replace('"', '""', $str) . '"'; - } - - // }}} - // {{{ quoteSmart() - - /** - * Format input so it can be safely used in a query - * - * The output depends on the PHP data type of input and the database - * type being used. - * - * @param mixed $in data to be quoted - * - * @return mixed the format of the results depends on the input's - * PHP type: - * - *
    - *
  • - * input -> returns - *
  • - *
  • - * null -> the string NULL - *
  • - *
  • - * integer or double -> the unquoted number - *
  • - *
  • - * &type.bool; -> output depends on the driver in use - * Most drivers return integers: 1 if - * true or 0 if - * false. - * Some return strings: TRUE if - * true or FALSE if - * false. - * Finally one returns strings: T if - * true or F if - * false. Here is a list of each DBMS, - * the values returned and the suggested column type: - *
      - *
    • - * dbase -> T/F - * (Logical) - *
    • - *
    • - * fbase -> TRUE/FALSE - * (BOOLEAN) - *
    • - *
    • - * ibase -> 1/0 - * (SMALLINT) [1] - *
    • - *
    • - * ifx -> 1/0 - * (SMALLINT) [1] - *
    • - *
    • - * msql -> 1/0 - * (INTEGER) - *
    • - *
    • - * mssql -> 1/0 - * (BIT) - *
    • - *
    • - * mysql -> 1/0 - * (TINYINT(1)) - *
    • - *
    • - * mysqli -> 1/0 - * (TINYINT(1)) - *
    • - *
    • - * oci8 -> 1/0 - * (NUMBER(1)) - *
    • - *
    • - * odbc -> 1/0 - * (SMALLINT) [1] - *
    • - *
    • - * pgsql -> TRUE/FALSE - * (BOOLEAN) - *
    • - *
    • - * sqlite -> 1/0 - * (INTEGER) - *
    • - *
    • - * sybase -> 1/0 - * (TINYINT(1)) - *
    • - *
    - * [1] Accommodate the lowest common denominator because not all - * versions of have BOOLEAN. - *
  • - *
  • - * other (including strings and numeric strings) -> - * the data with single quotes escaped by preceeding - * single quotes, backslashes are escaped by preceeding - * backslashes, then the whole string is encapsulated - * between single quotes - *
  • - *
- * - * @since 1.6.0 - * @see DB_common::escapeSimple() - * @access public - */ - function quoteSmart($in) - { - if (is_int($in) || is_double($in)) { - return $in; - } elseif (is_bool($in)) { - return $in ? 1 : 0; - } elseif (is_null($in)) { - return 'NULL'; - } else { - return "'" . $this->escapeSimple($in) . "'"; - } - } - - // }}} - // {{{ escapeSimple() - - /** - * Escape a string according to the current DBMS's standards - * - * In SQLite, this makes things safe for inserts/updates, but may - * cause problems when performing text comparisons against columns - * containing binary data. See the - * {@link http://php.net/sqlite_escape_string PHP manual} for more info. - * - * @param string $str the string to be escaped - * - * @return string the escaped string - * - * @since 1.6.0 - * @see DB_common::quoteSmart() - * @access public - */ - function escapeSimple($str) { - return str_replace("'", "''", $str); - } - - // }}} - // {{{ provides() - - /** - * Tell whether a DB implementation or its backend extension - * supports a given feature - * - * @param array $feature name of the feature (see the DB class doc) - * @return bool whether this DB implementation supports $feature - * @access public - */ - function provides($feature) - { - return $this->features[$feature]; - } - - // }}} - // {{{ errorCode() - - /** - * Map native error codes to DB's portable ones - * - * Requires that the DB implementation's constructor fills - * in the $errorcode_map property. - * - * @param mixed $nativecode the native error code, as returned by the - * backend database extension (string or integer) - * - * @return int a portable DB error code, or DB_ERROR if this DB - * implementation has no mapping for the given error code. - * - * @access public - */ - function errorCode($nativecode) - { - if (isset($this->errorcode_map[$nativecode])) { - return $this->errorcode_map[$nativecode]; - } - // Fall back to DB_ERROR if there was no mapping. - return DB_ERROR; - } - - // }}} - // {{{ errorMessage() - - /** - * Map a DB error code to a textual message. This is actually - * just a wrapper for DB::errorMessage() - * - * @param integer $dbcode the DB error code - * - * @return string the corresponding error message, of false - * if the error code was unknown - * - * @access public - */ - function errorMessage($dbcode) - { - return DB::errorMessage($this->errorcode_map[$dbcode]); - } - - // }}} - // {{{ raiseError() - - /** - * Communicate an error and invoke error callbacks, etc - * - * Basically a wrapper for PEAR::raiseError without the message string. - * - * @param mixed integer error code, or a PEAR error object (all - * other parameters are ignored if this parameter is - * an object - * - * @param int error mode, see PEAR_Error docs - * - * @param mixed If error mode is PEAR_ERROR_TRIGGER, this is the - * error level (E_USER_NOTICE etc). If error mode is - * PEAR_ERROR_CALLBACK, this is the callback function, - * either as a function name, or as an array of an - * object and method name. For other error modes this - * parameter is ignored. - * - * @param string Extra debug information. Defaults to the last - * query and native error code. - * - * @param mixed Native error code, integer or string depending the - * backend. - * - * @return object a PEAR error object - * - * @access public - * @see PEAR_Error - */ - function &raiseError($code = DB_ERROR, $mode = null, $options = null, - $userinfo = null, $nativecode = null) - { - // The error is yet a DB error object - if (is_object($code)) { - // because we the static PEAR::raiseError, our global - // handler should be used if it is set - if ($mode === null && !empty($this->_default_error_mode)) { - $mode = $this->_default_error_mode; - $options = $this->_default_error_options; - } - $tmp = PEAR::raiseError($code, null, $mode, $options, null, null, true); - return $tmp; - } - - if ($userinfo === null) { - $userinfo = $this->last_query; - } - - if ($nativecode) { - $userinfo .= ' [nativecode=' . trim($nativecode) . ']'; - } - - $tmp = PEAR::raiseError(null, $code, $mode, $options, $userinfo, - 'DB_Error', true); - return $tmp; - } - - // }}} - // {{{ setFetchMode() - - /** - * Sets which fetch mode should be used by default on queries - * on this connection - * - * @param integer $fetchmode DB_FETCHMODE_ORDERED or - * DB_FETCHMODE_ASSOC, possibly bit-wise OR'ed with - * DB_FETCHMODE_FLIPPED. - * - * @param string $object_class The class of the object - * to be returned by the fetch methods when - * the DB_FETCHMODE_OBJECT mode is selected. - * If no class is specified by default a cast - * to object from the assoc array row will be done. - * There is also the posibility to use and extend the - * 'DB_row' class. - * - * @see DB_FETCHMODE_ORDERED - * @see DB_FETCHMODE_ASSOC - * @see DB_FETCHMODE_FLIPPED - * @see DB_FETCHMODE_OBJECT - * @see DB_row::DB_row() - * @access public - */ - function setFetchMode($fetchmode, $object_class = 'stdClass') - { - switch ($fetchmode) { - case DB_FETCHMODE_OBJECT: - $this->fetchmode_object_class = $object_class; - case DB_FETCHMODE_ORDERED: - case DB_FETCHMODE_ASSOC: - $this->fetchmode = $fetchmode; - break; - default: - return $this->raiseError('invalid fetchmode mode'); - } - } - - // }}} - // {{{ setOption() - - /** - * Set run-time configuration options for PEAR DB - * - * Options, their data types, default values and description: - *
    - *
  • - * autofree boolean = false - *
    should results be freed automatically when there are no - * more rows? - *
  • - * debug integer = 0 - *
    debug level - *
  • - * persistent boolean = false - *
    should the connection be persistent? - *
  • - * portability integer = DB_PORTABILITY_NONE - *
    portability mode constant (see below) - *
  • - * seqname_format string = %s_seq - *
    the sprintf() format string used on sequence names. This - * format is applied to sequence names passed to - * createSequence(), nextID() and dropSequence(). - *
  • - * ssl boolean = false - *
    use ssl to connect? - *
  • - *
- * - * ----------------------------------------- - * - * PORTABILITY MODES - * - * These modes are bitwised, so they can be combined using | - * and removed using ^. See the examples section below on how - * to do this. - * - * DB_PORTABILITY_NONE - * turn off all portability features - * - * This mode gets automatically turned on if the deprecated - * optimize option gets set to performance. - * - * - * DB_PORTABILITY_LOWERCASE - * convert names of tables and fields to lower case when using - * get*(), fetch*() and tableInfo() - * - * This mode gets automatically turned on in the following databases - * if the deprecated option optimize gets set to - * portability: - * + oci8 - * - * - * DB_PORTABILITY_RTRIM - * right trim the data output by get*() fetch*() - * - * - * DB_PORTABILITY_DELETE_COUNT - * force reporting the number of rows deleted - * - * Some DBMS's don't count the number of rows deleted when performing - * simple DELETE FROM tablename queries. This portability - * mode tricks such DBMS's into telling the count by adding - * WHERE 1=1 to the end of DELETE queries. - * - * This mode gets automatically turned on in the following databases - * if the deprecated option optimize gets set to - * portability: - * + fbsql - * + mysql - * + mysqli - * + sqlite - * - * - * DB_PORTABILITY_NUMROWS - * enable hack that makes numRows() work in Oracle - * - * This mode gets automatically turned on in the following databases - * if the deprecated option optimize gets set to - * portability: - * + oci8 - * - * - * DB_PORTABILITY_ERRORS - * makes certain error messages in certain drivers compatible - * with those from other DBMS's - * - * + mysql, mysqli: change unique/primary key constraints - * DB_ERROR_ALREADY_EXISTS -> DB_ERROR_CONSTRAINT - * - * + odbc(access): MS's ODBC driver reports 'no such field' as code - * 07001, which means 'too few parameters.' When this option is on - * that code gets mapped to DB_ERROR_NOSUCHFIELD. - * DB_ERROR_MISMATCH -> DB_ERROR_NOSUCHFIELD - * - * - * DB_PORTABILITY_NULL_TO_EMPTY - * convert null values to empty strings in data output by get*() and - * fetch*(). Needed because Oracle considers empty strings to be null, - * while most other DBMS's know the difference between empty and null. - * - * - * DB_PORTABILITY_ALL - * turn on all portability features - * - * ----------------------------------------- - * - * Example 1. Simple setOption() example - * setOption('autofree', true); - * ?> - * - * Example 2. Portability for lowercasing and trimming - * setOption('portability', - * DB_PORTABILITY_LOWERCASE | DB_PORTABILITY_RTRIM); - * ?> - * - * Example 3. All portability options except trimming - * setOption('portability', - * DB_PORTABILITY_ALL ^ DB_PORTABILITY_RTRIM); - * ?> - * - * @param string $option option name - * @param mixed $value value for the option - * - * @return int DB_OK on success. DB_Error object on failure. - * - * @see DB_common::$options - */ - function setOption($option, $value) - { - if (isset($this->options[$option])) { - $this->options[$option] = $value; - - /* - * Backwards compatibility check for the deprecated 'optimize' - * option. Done here in case settings change after connecting. - */ - if ($option == 'optimize') { - if ($value == 'portability') { - switch ($this->phptype) { - case 'oci8': - $this->options['portability'] = - DB_PORTABILITY_LOWERCASE | - DB_PORTABILITY_NUMROWS; - break; - case 'fbsql': - case 'mysql': - case 'mysqli': - case 'sqlite': - $this->options['portability'] = - DB_PORTABILITY_DELETE_COUNT; - break; - } - } else { - $this->options['portability'] = DB_PORTABILITY_NONE; - } - } - - return DB_OK; - } - return $this->raiseError("unknown option $option"); - } - - // }}} - // {{{ getOption() - - /** - * Returns the value of an option - * - * @param string $option option name - * - * @return mixed the option value - */ - function getOption($option) - { - if (isset($this->options[$option])) { - return $this->options[$option]; - } - return $this->raiseError("unknown option $option"); - } - - // }}} - // {{{ prepare() - - /** - * Prepares a query for multiple execution with execute() - * - * Creates a query that can be run multiple times. Each time it is run, - * the placeholders, if any, will be replaced by the contents of - * execute()'s $data argument. - * - * Three types of placeholders can be used: - * + ? scalar value (i.e. strings, integers). The system - * will automatically quote and escape the data. - * + ! value is inserted 'as is' - * + & requires a file name. The file's contents get - * inserted into the query (i.e. saving binary - * data in a db) - * - * Example 1. - * prepare('INSERT INTO tbl (a, b, c) VALUES (?, !, &)'); - * $data = array( - * "John's text", - * "'it''s good'", - * 'filename.txt' - * ); - * $res = $dbh->execute($sth, $data); - * ?> - * - * Use backslashes to escape placeholder characters if you don't want - * them to be interpreted as placeholders: - *
-     *    "UPDATE foo SET col=? WHERE col='over \& under'"
-     * 
- * - * With some database backends, this is emulated. - * - * {@internal ibase and oci8 have their own prepare() methods.}} - * - * @param string $query query to be prepared - * - * @return mixed DB statement resource on success. DB_Error on failure. - * - * @see DB_common::execute() - * @access public - */ - function prepare($query) - { - $tokens = preg_split('/((?prepare_tokens[] = &$newtokens; - end($this->prepare_tokens); - - $k = key($this->prepare_tokens); - $this->prepare_types[$k] = $types; - $this->prepared_queries[$k] = implode(' ', $newtokens); - - return $k; - } - - // }}} - // {{{ autoPrepare() - - /** - * Automaticaly generate an insert or update query and pass it to prepare() - * - * @param string $table name of the table - * @param array $table_fields ordered array containing the fields names - * @param int $mode type of query to make (DB_AUTOQUERY_INSERT or DB_AUTOQUERY_UPDATE) - * @param string $where in case of update queries, this string will be put after the sql WHERE statement - * @return resource handle for the query - * @see DB_common::prepare(), DB_common::buildManipSQL() - * @access public - */ - function autoPrepare($table, $table_fields, $mode = DB_AUTOQUERY_INSERT, $where = false) - { - $query = $this->buildManipSQL($table, $table_fields, $mode, $where); - return $this->prepare($query); - } - - // }}} - // {{{ autoExecute() - - /** - * Automaticaly generate an insert or update query and call prepare() - * and execute() with it - * - * @param string $table name of the table - * @param array $fields_values assoc ($key=>$value) where $key is a field name and $value its value - * @param int $mode type of query to make (DB_AUTOQUERY_INSERT or DB_AUTOQUERY_UPDATE) - * @param string $where in case of update queries, this string will be put after the sql WHERE statement - * @return mixed a new DB_Result or a DB_Error when fail - * @see DB_common::autoPrepare(), DB_common::buildManipSQL() - * @access public - */ - function autoExecute($table, $fields_values, $mode = DB_AUTOQUERY_INSERT, $where = false) - { - $sth = $this->autoPrepare($table, array_keys($fields_values), $mode, $where); - $ret =& $this->execute($sth, array_values($fields_values)); - $this->freePrepared($sth); - return $ret; - - } - - // }}} - // {{{ buildManipSQL() - - /** - * Make automaticaly an sql query for prepare() - * - * Example : buildManipSQL('table_sql', array('field1', 'field2', 'field3'), DB_AUTOQUERY_INSERT) - * will return the string : INSERT INTO table_sql (field1,field2,field3) VALUES (?,?,?) - * NB : - This belongs more to a SQL Builder class, but this is a simple facility - * - Be carefull ! If you don't give a $where param with an UPDATE query, all - * the records of the table will be updated ! - * - * @param string $table name of the table - * @param array $table_fields ordered array containing the fields names - * @param int $mode type of query to make (DB_AUTOQUERY_INSERT or DB_AUTOQUERY_UPDATE) - * @param string $where in case of update queries, this string will be put after the sql WHERE statement - * @return string sql query for prepare() - * @access public - */ - function buildManipSQL($table, $table_fields, $mode, $where = false) - { - if (count($table_fields) == 0) { - $this->raiseError(DB_ERROR_NEED_MORE_DATA); - } - $first = true; - switch ($mode) { - case DB_AUTOQUERY_INSERT: - $values = ''; - $names = ''; - foreach ($table_fields as $value) { - if ($first) { - $first = false; - } else { - $names .= ','; - $values .= ','; - } - $names .= $value; - $values .= '?'; - } - return "INSERT INTO $table ($names) VALUES ($values)"; - case DB_AUTOQUERY_UPDATE: - $set = ''; - foreach ($table_fields as $value) { - if ($first) { - $first = false; - } else { - $set .= ','; - } - $set .= "$value = ?"; - } - $sql = "UPDATE $table SET $set"; - if ($where) { - $sql .= " WHERE $where"; - } - return $sql; - default: - $this->raiseError(DB_ERROR_SYNTAX); - } - } - - // }}} - // {{{ execute() - - /** - * Executes a DB statement prepared with prepare() - * - * Example 1. - * prepare('INSERT INTO tbl (a, b, c) VALUES (?, !, &)'); - * $data = array( - * "John's text", - * "'it''s good'", - * 'filename.txt' - * ); - * $res =& $dbh->execute($sth, $data); - * ?> - * - * @param resource $stmt a DB statement resource returned from prepare() - * @param mixed $data array, string or numeric data to be used in - * execution of the statement. Quantity of items - * passed must match quantity of placeholders in - * query: meaning 1 placeholder for non-array - * parameters or 1 placeholder per array element. - * - * @return object a new DB_Result or a DB_Error when fail - * - * {@internal ibase and oci8 have their own execute() methods.}} - * - * @see DB_common::prepare() - * @access public - */ - function &execute($stmt, $data = array()) - { - $realquery = $this->executeEmulateQuery($stmt, $data); - if (DB::isError($realquery)) { - return $realquery; - } - $result = $this->simpleQuery($realquery); - - if (DB::isError($result) || $result === DB_OK) { - return $result; - } else { - $tmp =& new DB_result($this, $result); - return $tmp; - } - } - - // }}} - // {{{ executeEmulateQuery() - - /** - * Emulates the execute statement, when not supported - * - * @param resource $stmt a DB statement resource returned from execute() - * @param mixed $data array, string or numeric data to be used in - * execution of the statement. Quantity of items - * passed must match quantity of placeholders in - * query: meaning 1 placeholder for non-array - * parameters or 1 placeholder per array element. - * - * @return mixed a string containing the real query run when emulating - * prepare/execute. A DB error code is returned on failure. - * - * @see DB_common::execute() - * @access private - */ - function executeEmulateQuery($stmt, $data = array()) - { - if (!is_array($data)) { - $data = array($data); - } - - if (count($this->prepare_types[$stmt]) != count($data)) { - $this->last_query = $this->prepared_queries[$stmt]; - return $this->raiseError(DB_ERROR_MISMATCH); - } - - $realquery = $this->prepare_tokens[$stmt][0]; - - $i = 0; - foreach ($data as $value) { - if ($this->prepare_types[$stmt][$i] == DB_PARAM_SCALAR) { - $realquery .= $this->quoteSmart($value); - } elseif ($this->prepare_types[$stmt][$i] == DB_PARAM_OPAQUE) { - $fp = @fopen($value, 'rb'); - if (!$fp) { - return $this->raiseError(DB_ERROR_ACCESS_VIOLATION); - } - $realquery .= $this->quoteSmart(fread($fp, filesize($value))); - fclose($fp); - } else { - $realquery .= $value; - } - - $realquery .= $this->prepare_tokens[$stmt][++$i]; - } - - return $realquery; - } - - // }}} - // {{{ executeMultiple() - - /** - * This function does several execute() calls on the same - * statement handle - * - * $data must be an array indexed numerically - * from 0, one execute call is done for every "row" in the array. - * - * If an error occurs during execute(), executeMultiple() does not - * execute the unfinished rows, but rather returns that error. - * - * @param resource $stmt query handle from prepare() - * @param array $data numeric array containing the - * data to insert into the query - * - * @return mixed DB_OK or DB_Error - * - * @see DB_common::prepare(), DB_common::execute() - * @access public - */ - function executeMultiple($stmt, $data) - { - foreach ($data as $value) { - $res =& $this->execute($stmt, $value); - if (DB::isError($res)) { - return $res; - } - } - return DB_OK; - } - - // }}} - // {{{ freePrepared() - - /** - * Free the resource used in a prepared query - * - * @param $stmt The resurce returned by the prepare() function - * @see DB_common::prepare() - */ - function freePrepared($stmt) - { - // Free the internal prepared vars - if (isset($this->prepare_tokens[$stmt])) { - unset($this->prepare_tokens[$stmt]); - unset($this->prepare_types[$stmt]); - unset($this->prepared_queries[$stmt]); - return true; - } - return false; - } - - // }}} - // {{{ modifyQuery() - - /** - * This method is used by backends to alter queries for various - * reasons - * - * It is defined here to assure that all implementations - * have this method defined. - * - * @param string $query query to modify - * - * @return the new (modified) query - * - * @access private - */ - function modifyQuery($query) { - return $query; - } - - // }}} - // {{{ modifyLimitQuery() - - /** - * This method is used by backends to alter limited queries - * - * @param string $query query to modify - * @param integer $from the row to start to fetching - * @param integer $count the numbers of rows to fetch - * - * @return the new (modified) query - * - * @access private - */ - function modifyLimitQuery($query, $from, $count, $params = array()) - { - return $query; - } - - // }}} - // {{{ query() - - /** - * Send a query to the database and return any results with a - * DB_result object - * - * The query string can be either a normal statement to be sent directly - * to the server OR if $params are passed the query can have - * placeholders and it will be passed through prepare() and execute(). - * - * @param string $query the SQL query or the statement to prepare - * @param mixed $params array, string or numeric data to be used in - * execution of the statement. Quantity of items - * passed must match quantity of placeholders in - * query: meaning 1 placeholder for non-array - * parameters or 1 placeholder per array element. - * - * @return mixed a DB_result object or DB_OK on success, a DB - * error on failure - * - * @see DB_result, DB_common::prepare(), DB_common::execute() - * @access public - */ - function &query($query, $params = array()) - { - if (sizeof($params) > 0) { - $sth = $this->prepare($query); - if (DB::isError($sth)) { - return $sth; - } - $ret =& $this->execute($sth, $params); - $this->freePrepared($sth); - return $ret; - } else { - $result = $this->simpleQuery($query); - if (DB::isError($result) || $result === DB_OK) { - return $result; - } else { - $tmp =& new DB_result($this, $result); - return $tmp; - } - } - } - - // }}} - // {{{ limitQuery() - - /** - * Generates a limited query - * - * @param string $query query - * @param integer $from the row to start to fetching - * @param integer $count the numbers of rows to fetch - * @param array $params required for a statement - * - * @return mixed a DB_Result object, DB_OK or a DB_Error - * - * @access public - */ - function &limitQuery($query, $from, $count, $params = array()) - { - $query = $this->modifyLimitQuery($query, $from, $count, $params); - if (DB::isError($query)){ - return $query; - } - $result =& $this->query($query, $params); - if (is_a($result, 'DB_result')) { - $result->setOption('limit_from', $from); - $result->setOption('limit_count', $count); - } - return $result; - } - - // }}} - // {{{ getOne() - - /** - * Fetch the first column of the first row of data returned from - * a query - * - * Takes care of doing the query and freeing the results when finished. - * - * @param string $query the SQL query - * @param mixed $params array, string or numeric data to be used in - * execution of the statement. Quantity of items - * passed must match quantity of placeholders in - * query: meaning 1 placeholder for non-array - * parameters or 1 placeholder per array element. - * - * @return mixed the returned value of the query. DB_Error on failure. - * - * @access public - */ - function &getOne($query, $params = array()) - { - settype($params, 'array'); - if (sizeof($params) > 0) { - $sth = $this->prepare($query); - if (DB::isError($sth)) { - return $sth; - } - $res =& $this->execute($sth, $params); - $this->freePrepared($sth); - } else { - $res =& $this->query($query); - } - - if (DB::isError($res)) { - return $res; - } - - $err = $res->fetchInto($row, DB_FETCHMODE_ORDERED); - $res->free(); - - if ($err !== DB_OK) { - return $err; - } - - return $row[0]; - } - - // }}} - // {{{ getRow() - - /** - * Fetch the first row of data returned from a query - * - * Takes care of doing the query and freeing the results when finished. - * - * @param string $query the SQL query - * @param array $params array to be used in execution of the statement. - * Quantity of array elements must match quantity - * of placeholders in query. This function does - * NOT support scalars. - * @param int $fetchmode the fetch mode to use - * - * @return array the first row of results as an array indexed from - * 0, or a DB error code. - * - * @access public - */ - function &getRow($query, - $params = array(), - $fetchmode = DB_FETCHMODE_DEFAULT) - { - // compat check, the params and fetchmode parameters used to - // have the opposite order - if (!is_array($params)) { - if (is_array($fetchmode)) { - if ($params === null) { - $tmp = DB_FETCHMODE_DEFAULT; - } else { - $tmp = $params; - } - $params = $fetchmode; - $fetchmode = $tmp; - } elseif ($params !== null) { - $fetchmode = $params; - $params = array(); - } - } - - if (sizeof($params) > 0) { - $sth = $this->prepare($query); - if (DB::isError($sth)) { - return $sth; - } - $res =& $this->execute($sth, $params); - $this->freePrepared($sth); - } else { - $res =& $this->query($query); - } - - if (DB::isError($res)) { - return $res; - } - - $err = $res->fetchInto($row, $fetchmode); - - $res->free(); - - if ($err !== DB_OK) { - return $err; - } - - return $row; - } - - // }}} - // {{{ getCol() - - /** - * Fetch a single column from a result set and return it as an - * indexed array - * - * @param string $query the SQL query - * @param mixed $col which column to return (integer [column number, - * starting at 0] or string [column name]) - * @param mixed $params array, string or numeric data to be used in - * execution of the statement. Quantity of items - * passed must match quantity of placeholders in - * query: meaning 1 placeholder for non-array - * parameters or 1 placeholder per array element. - * - * @return array an indexed array with the data from the first - * row at index 0, or a DB error code - * - * @see DB_common::query() - * @access public - */ - function &getCol($query, $col = 0, $params = array()) - { - settype($params, 'array'); - if (sizeof($params) > 0) { - $sth = $this->prepare($query); - - if (DB::isError($sth)) { - return $sth; - } - - $res =& $this->execute($sth, $params); - $this->freePrepared($sth); - } else { - $res =& $this->query($query); - } - - if (DB::isError($res)) { - return $res; - } - - $fetchmode = is_int($col) ? DB_FETCHMODE_ORDERED : DB_FETCHMODE_ASSOC; - $ret = array(); - - while (is_array($row = $res->fetchRow($fetchmode))) { - $ret[] = $row[$col]; - } - - $res->free(); - - if (DB::isError($row)) { - $ret = $row; - } - - return $ret; - } - - // }}} - // {{{ getAssoc() - - /** - * Fetch the entire result set of a query and return it as an - * associative array using the first column as the key - * - * If the result set contains more than two columns, the value - * will be an array of the values from column 2-n. If the result - * set contains only two columns, the returned value will be a - * scalar with the value of the second column (unless forced to an - * array with the $force_array parameter). A DB error code is - * returned on errors. If the result set contains fewer than two - * columns, a DB_ERROR_TRUNCATED error is returned. - * - * For example, if the table "mytable" contains: - * - *
-     *  ID      TEXT       DATE
-     * --------------------------------
-     *  1       'one'      944679408
-     *  2       'two'      944679408
-     *  3       'three'    944679408
-     * 
- * - * Then the call getAssoc('SELECT id,text FROM mytable') returns: - *
-     *   array(
-     *     '1' => 'one',
-     *     '2' => 'two',
-     *     '3' => 'three',
-     *   )
-     * 
- * - * ...while the call getAssoc('SELECT id,text,date FROM mytable') returns: - *
-     *   array(
-     *     '1' => array('one', '944679408'),
-     *     '2' => array('two', '944679408'),
-     *     '3' => array('three', '944679408')
-     *   )
-     * 
- * - * If the more than one row occurs with the same value in the - * first column, the last row overwrites all previous ones by - * default. Use the $group parameter if you don't want to - * overwrite like this. Example: - * - *
-     * getAssoc('SELECT category,id,name FROM mytable', false, null,
-     *          DB_FETCHMODE_ASSOC, true) returns:
-     *
-     *   array(
-     *     '1' => array(array('id' => '4', 'name' => 'number four'),
-     *                  array('id' => '6', 'name' => 'number six')
-     *            ),
-     *     '9' => array(array('id' => '4', 'name' => 'number four'),
-     *                  array('id' => '6', 'name' => 'number six')
-     *            )
-     *   )
-     * 
- * - * Keep in mind that database functions in PHP usually return string - * values for results regardless of the database's internal type. - * - * @param string $query the SQL query - * @param boolean $force_array used only when the query returns - * exactly two columns. If true, the values - * of the returned array will be one-element - * arrays instead of scalars. - * @param mixed $params array, string or numeric data to be used in - * execution of the statement. Quantity of items - * passed must match quantity of placeholders in - * query: meaning 1 placeholder for non-array - * parameters or 1 placeholder per array element. - * @param boolean $group if true, the values of the returned array - * is wrapped in another array. If the same - * key value (in the first column) repeats - * itself, the values will be appended to - * this array instead of overwriting the - * existing values. - * - * @return array associative array with results from the query. - * DB Error on failure. - * - * @access public - */ - function &getAssoc($query, $force_array = false, $params = array(), - $fetchmode = DB_FETCHMODE_DEFAULT, $group = false) - { - settype($params, 'array'); - if (sizeof($params) > 0) { - $sth = $this->prepare($query); - - if (DB::isError($sth)) { - return $sth; - } - - $res =& $this->execute($sth, $params); - $this->freePrepared($sth); - } else { - $res =& $this->query($query); - } - - if (DB::isError($res)) { - return $res; - } - if ($fetchmode == DB_FETCHMODE_DEFAULT) { - $fetchmode = $this->fetchmode; - } - $cols = $res->numCols(); - - if ($cols < 2) { - $tmp =& $this->raiseError(DB_ERROR_TRUNCATED); - return $tmp; - } - - $results = array(); - - if ($cols > 2 || $force_array) { - // return array values - // XXX this part can be optimized - if ($fetchmode == DB_FETCHMODE_ASSOC) { - while (is_array($row = $res->fetchRow(DB_FETCHMODE_ASSOC))) { - reset($row); - $key = current($row); - unset($row[key($row)]); - if ($group) { - $results[$key][] = $row; - } else { - $results[$key] = $row; - } - } - } elseif ($fetchmode == DB_FETCHMODE_OBJECT) { - while ($row = $res->fetchRow(DB_FETCHMODE_OBJECT)) { - $arr = get_object_vars($row); - $key = current($arr); - if ($group) { - $results[$key][] = $row; - } else { - $results[$key] = $row; - } - } - } else { - while (is_array($row = $res->fetchRow(DB_FETCHMODE_ORDERED))) { - // we shift away the first element to get - // indices running from 0 again - $key = array_shift($row); - if ($group) { - $results[$key][] = $row; - } else { - $results[$key] = $row; - } - } - } - if (DB::isError($row)) { - $results = $row; - } - } else { - // return scalar values - while (is_array($row = $res->fetchRow(DB_FETCHMODE_ORDERED))) { - if ($group) { - $results[$row[0]][] = $row[1]; - } else { - $results[$row[0]] = $row[1]; - } - } - if (DB::isError($row)) { - $results = $row; - } - } - - $res->free(); - - return $results; - } - - // }}} - // {{{ getAll() - - /** - * Fetch all the rows returned from a query - * - * @param string $query the SQL query - * @param array $params array to be used in execution of the statement. - * Quantity of array elements must match quantity - * of placeholders in query. This function does - * NOT support scalars. - * @param int $fetchmode the fetch mode to use - * - * @return array an nested array. DB error on failure. - * - * @access public - */ - function &getAll($query, - $params = array(), - $fetchmode = DB_FETCHMODE_DEFAULT) - { - // compat check, the params and fetchmode parameters used to - // have the opposite order - if (!is_array($params)) { - if (is_array($fetchmode)) { - if ($params === null) { - $tmp = DB_FETCHMODE_DEFAULT; - } else { - $tmp = $params; - } - $params = $fetchmode; - $fetchmode = $tmp; - } elseif ($params !== null) { - $fetchmode = $params; - $params = array(); - } - } - - if (sizeof($params) > 0) { - $sth = $this->prepare($query); - - if (DB::isError($sth)) { - return $sth; - } - - $res =& $this->execute($sth, $params); - $this->freePrepared($sth); - } else { - $res =& $this->query($query); - } - - if (DB::isError($res) || $res === DB_OK) { - return $res; - } - - $results = array(); - while (DB_OK === $res->fetchInto($row, $fetchmode)) { - if ($fetchmode & DB_FETCHMODE_FLIPPED) { - foreach ($row as $key => $val) { - $results[$key][] = $val; - } - } else { - $results[] = $row; - } - } - - $res->free(); - - if (DB::isError($row)) { - $tmp =& $this->raiseError($row); - return $tmp; - } - return $results; - } - - // }}} - // {{{ autoCommit() - - /** - * enable automatic Commit - * - * @param boolean $onoff - * @return mixed DB_Error - * - * @access public - */ - function autoCommit($onoff=false) - { - return $this->raiseError(DB_ERROR_NOT_CAPABLE); - } - - // }}} - // {{{ commit() - - /** - * starts a Commit - * - * @return mixed DB_Error - * - * @access public - */ - function commit() - { - return $this->raiseError(DB_ERROR_NOT_CAPABLE); - } - - // }}} - // {{{ rollback() - - /** - * starts a rollback - * - * @return mixed DB_Error - * - * @access public - */ - function rollback() - { - return $this->raiseError(DB_ERROR_NOT_CAPABLE); - } - - // }}} - // {{{ numRows() - - /** - * Returns the number of rows in a result object - * - * @param object DB_Result the result object to check - * - * @return mixed DB_Error or the number of rows - * - * @access public - */ - function numRows($result) - { - return $this->raiseError(DB_ERROR_NOT_CAPABLE); - } - - // }}} - // {{{ affectedRows() - - /** - * Returns the affected rows of a query - * - * @return mixed DB_Error or number of rows - * - * @access public - */ - function affectedRows() - { - return $this->raiseError(DB_ERROR_NOT_CAPABLE); - } - - // }}} - // {{{ errorNative() - - /** - * Returns an errormessage, provides by the database - * - * @return mixed DB_Error or message - * - * @access public - */ - function errorNative() - { - return $this->raiseError(DB_ERROR_NOT_CAPABLE); - } - - // }}} - // {{{ getSequenceName() - - /** - * Generate the name used inside the database for a sequence - * - * The createSequence() docblock contains notes about storing sequence - * names. - * - * @param string $sqn the sequence's public name - * - * @return string the sequence's name in the backend - * - * @see DB_common::createSequence(), DB_common::dropSequence(), - * DB_common::nextID(), DB_common::setOption() - * @access private - */ - function getSequenceName($sqn) - { - return sprintf($this->getOption('seqname_format'), - preg_replace('/[^a-z0-9_.]/i', '_', $sqn)); - } - - // }}} - // {{{ nextId() - - /** - * Returns the next free id in a sequence - * - * @param string $seq_name name of the sequence - * @param boolean $ondemand when true, the seqence is automatically - * created if it does not exist - * - * @return int the next id number in the sequence. DB_Error if problem. - * - * @see DB_common::createSequence(), DB_common::dropSequence(), - * DB_common::getSequenceName() - * @access public - */ - function nextId($seq_name, $ondemand = true) - { - return $this->raiseError(DB_ERROR_NOT_CAPABLE); - } - - // }}} - // {{{ createSequence() - - /** - * Creates a new sequence - * - * The name of a given sequence is determined by passing the string - * provided in the $seq_name argument through PHP's sprintf() - * function using the value from the seqname_format option as - * the sprintf()'s format argument. - * - * seqname_format is set via setOption(). - * - * @param string $seq_name name of the new sequence - * - * @return int DB_OK on success. A DB_Error object is returned if - * problems arise. - * - * @see DB_common::dropSequence(), DB_common::getSequenceName(), - * DB_common::nextID() - * @access public - */ - function createSequence($seq_name) - { - return $this->raiseError(DB_ERROR_NOT_CAPABLE); - } - - // }}} - // {{{ dropSequence() - - /** - * Deletes a sequence - * - * @param string $seq_name name of the sequence to be deleted - * - * @return int DB_OK on success. DB_Error if problems. - * - * @see DB_common::createSequence(), DB_common::getSequenceName(), - * DB_common::nextID() - * @access public - */ - function dropSequence($seq_name) - { - return $this->raiseError(DB_ERROR_NOT_CAPABLE); - } - - // }}} - // {{{ tableInfo() - - /** - * Returns information about a table or a result set - * - * The format of the resulting array depends on which $mode - * you select. The sample output below is based on this query: - *
-     *    SELECT tblFoo.fldID, tblFoo.fldPhone, tblBar.fldId
-     *    FROM tblFoo
-     *    JOIN tblBar ON tblFoo.fldId = tblBar.fldId
-     * 
- * - *
    - *
  • - * - * null (default) - *
    -     *   [0] => Array (
    -     *       [table] => tblFoo
    -     *       [name] => fldId
    -     *       [type] => int
    -     *       [len] => 11
    -     *       [flags] => primary_key not_null
    -     *   )
    -     *   [1] => Array (
    -     *       [table] => tblFoo
    -     *       [name] => fldPhone
    -     *       [type] => string
    -     *       [len] => 20
    -     *       [flags] =>
    -     *   )
    -     *   [2] => Array (
    -     *       [table] => tblBar
    -     *       [name] => fldId
    -     *       [type] => int
    -     *       [len] => 11
    -     *       [flags] => primary_key not_null
    -     *   )
    -     *   
    - * - *
  • - * - * DB_TABLEINFO_ORDER - * - *

    In addition to the information found in the default output, - * a notation of the number of columns is provided by the - * num_fields element while the order - * element provides an array with the column names as the keys and - * their location index number (corresponding to the keys in the - * the default output) as the values.

    - * - *

    If a result set has identical field names, the last one is - * used.

    - * - *
    -     *   [num_fields] => 3
    -     *   [order] => Array (
    -     *       [fldId] => 2
    -     *       [fldTrans] => 1
    -     *   )
    -     *   
    - * - *
  • - * - * DB_TABLEINFO_ORDERTABLE - * - *

    Similar to DB_TABLEINFO_ORDER but adds more - * dimensions to the array in which the table names are keys and - * the field names are sub-keys. This is helpful for queries that - * join tables which have identical field names.

    - * - *
    -     *   [num_fields] => 3
    -     *   [ordertable] => Array (
    -     *       [tblFoo] => Array (
    -     *           [fldId] => 0
    -     *           [fldPhone] => 1
    -     *       )
    -     *       [tblBar] => Array (
    -     *           [fldId] => 2
    -     *       )
    -     *   )
    -     *   
    - * - *
  • - *
- * - * The flags element contains a space separated list - * of extra information about the field. This data is inconsistent - * between DBMS's due to the way each DBMS works. - * + primary_key - * + unique_key - * + multiple_key - * + not_null - * - * Most DBMS's only provide the table and flags - * elements if $result is a table name. The following DBMS's - * provide full information from queries: - * + fbsql - * + mysql - * - * If the 'portability' option has DB_PORTABILITY_LOWERCASE - * turned on, the names of tables and fields will be lowercased. - * - * @param object|string $result DB_result object from a query or a - * string containing the name of a table. - * While this also accepts a query result - * resource identifier, this behavior is - * deprecated. - * @param int $mode either unused or one of the tableInfo modes: - * DB_TABLEINFO_ORDERTABLE, - * DB_TABLEINFO_ORDER or - * DB_TABLEINFO_FULL (which does both). - * These are bitwise, so the first two can be - * combined using |. - * @return array an associative array with the information requested. - * If something goes wrong an error object is returned. - * - * @see DB_common::setOption() - * @access public - */ - function tableInfo($result, $mode = null) - { - /* - * If the DB_ class has a tableInfo() method, that one - * overrides this one. But, if the driver doesn't have one, - * this method runs and tells users about that fact. - */ - return $this->raiseError(DB_ERROR_NOT_CAPABLE); - } - - // }}} - // {{{ getTables() - - /** - * @deprecated Deprecated in release 1.2 or lower - */ - function getTables() - { - return $this->getListOf('tables'); - } - - // }}} - // {{{ getListOf() - - /** - * list internal DB info - * valid values for $type are db dependent, - * often: databases, users, view, functions - * - * @param string $type type of requested info - * - * @return mixed DB_Error or the requested data - * - * @access public - */ - function getListOf($type) - { - $sql = $this->getSpecialQuery($type); - if ($sql === null) { // No support - return $this->raiseError(DB_ERROR_UNSUPPORTED); - } elseif (is_int($sql) || DB::isError($sql)) { // Previous error - return $this->raiseError($sql); - } elseif (is_array($sql)) { // Already the result - return $sql; - } - return $this->getCol($sql); // Launch this query - } - - // }}} - // {{{ getSpecialQuery() - - /** - * Returns the query needed to get some backend info - * - * @param string $type What kind of info you want to retrieve - * - * @return string The SQL query string - * - * @access public - */ - function getSpecialQuery($type) - { - return $this->raiseError(DB_ERROR_UNSUPPORTED); - } - - // }}} - // {{{ _rtrimArrayValues() - - /** - * Right trim all strings in an array - * - * @param array $array the array to be trimmed (passed by reference) - * @return void - * @access private - */ - function _rtrimArrayValues(&$array) - { - foreach ($array as $key => $value) { - if (is_string($value)) { - $array[$key] = rtrim($value); - } - } - } - - // }}} - // {{{ _convertNullArrayValuesToEmpty() - - /** - * Convert all null values in an array to empty strings - * - * @param array $array the array to be de-nullified (passed by reference) - * @return void - * @access private - */ - function _convertNullArrayValuesToEmpty(&$array) - { - foreach ($array as $key => $value) { - if (is_null($value)) { - $array[$key] = ''; - } - } - } - - // }}} -} - -/* - * Local variables: - * tab-width: 4 - * c-basic-offset: 4 - * End: - */ - -?> diff --git a/glmPEAR/DB/dbase.php b/glmPEAR/DB/dbase.php deleted file mode 100755 index 234d894..0000000 --- a/glmPEAR/DB/dbase.php +++ /dev/null @@ -1,220 +0,0 @@ - | -// | Maintainer: Daniel Convissor | -// +----------------------------------------------------------------------+ -// -// $Id: dbase.php,v 1.1.1.1 2008/04/28 15:20:47 jamie Exp $ - - -// XXX legend: -// You have to compile your PHP with the --enable-dbase option - - -require_once 'DB/common.php'; - -/** - * Database independent query interface definition for PHP's dbase - * extension. - * - * @package DB - * @version $Id: dbase.php,v 1.1.1.1 2008/04/28 15:20:47 jamie Exp $ - * @category Database - * @author Stig Bakken - */ -class DB_dbase extends DB_common -{ - // {{{ properties - - var $connection; - var $phptype, $dbsyntax; - var $prepare_tokens = array(); - var $prepare_types = array(); - var $res_row = array(); - var $result = 0; - - // }}} - // {{{ constructor - - /** - * DB_mysql constructor. - * - * @access public - */ - function DB_dbase() - { - $this->DB_common(); - $this->phptype = 'dbase'; - $this->dbsyntax = 'dbase'; - $this->features = array( - 'prepare' => false, - 'pconnect' => false, - 'transactions' => false, - 'limit' => false - ); - $this->errorcode_map = array(); - } - - // }}} - // {{{ connect() - - function connect($dsninfo, $persistent = false) - { - if (!DB::assertExtension('dbase')) { - return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND); - } - $this->dsn = $dsninfo; - ob_start(); - $conn = @dbase_open($dsninfo['database'], 0); - $error = ob_get_contents(); - ob_end_clean(); - if (!$conn) { - return $this->raiseError(DB_ERROR_CONNECT_FAILED, null, - null, null, strip_tags($error)); - } - $this->connection = $conn; - return DB_OK; - } - - // }}} - // {{{ disconnect() - - function disconnect() - { - $ret = @dbase_close($this->connection); - $this->connection = null; - return $ret; - } - - // }}} - // {{{ &query() - - function &query($query = null) - { - // emulate result resources - $this->res_row[$this->result] = 0; - $tmp =& new DB_result($this, $this->result++); - return $tmp; - } - - // }}} - // {{{ fetchInto() - - /** - * Fetch a row and insert the data into an existing array. - * - * Formating of the array and the data therein are configurable. - * See DB_result::fetchInto() for more information. - * - * @param resource $result query result identifier - * @param array $arr (reference) array where data from the row - * should be placed - * @param int $fetchmode how the resulting array should be indexed - * @param int $rownum the row number to fetch - * - * @return mixed DB_OK on success, null when end of result set is - * reached or on failure - * - * @see DB_result::fetchInto() - * @access private - */ - function fetchInto($result, &$arr, $fetchmode, $rownum=null) - { - if ($rownum === null) { - $rownum = $this->res_row[$result]++; - } - if ($fetchmode & DB_FETCHMODE_ASSOC) { - $arr = @dbase_get_record_with_names($this->connection, $rownum); - if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) { - $arr = array_change_key_case($arr, CASE_LOWER); - } - } else { - $arr = @dbase_get_record($this->connection, $rownum); - } - if (!$arr) { - return null; - } - if ($this->options['portability'] & DB_PORTABILITY_RTRIM) { - $this->_rtrimArrayValues($arr); - } - if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) { - $this->_convertNullArrayValuesToEmpty($arr); - } - return DB_OK; - } - - // }}} - // {{{ numCols() - - function numCols($foo) - { - return @dbase_numfields($this->connection); - } - - // }}} - // {{{ numRows() - - function numRows($foo) - { - return @dbase_numrecords($this->connection); - } - - // }}} - // {{{ quoteSmart() - - /** - * Format input so it can be safely used in a query - * - * @param mixed $in data to be quoted - * - * @return mixed Submitted variable's type = returned value: - * + null = the string NULL - * + boolean = T if true or - * F if false. Use the Logical - * data type. - * + integer or double = the unquoted number - * + other (including strings and numeric strings) = - * the data with single quotes escaped by preceeding - * single quotes then the whole string is encapsulated - * between single quotes - * - * @internal - */ - function quoteSmart($in) - { - if (is_int($in) || is_double($in)) { - return $in; - } elseif (is_bool($in)) { - return $in ? 'T' : 'F'; - } elseif (is_null($in)) { - return 'NULL'; - } else { - return "'" . $this->escapeSimple($in) . "'"; - } - } - - // }}} - -} - -/* - * Local variables: - * tab-width: 4 - * c-basic-offset: 4 - * End: - */ - -?> diff --git a/glmPEAR/DB/fbsql.php b/glmPEAR/DB/fbsql.php deleted file mode 100755 index 1a66c2e..0000000 --- a/glmPEAR/DB/fbsql.php +++ /dev/null @@ -1,655 +0,0 @@ - | -// | Maintainer: Daniel Convissor | -// +----------------------------------------------------------------------+ -// -// $Id: fbsql.php,v 1.1.1.1 2008/04/28 15:20:47 jamie Exp $ - - -// XXX legend: -// -// XXX ERRORMSG: The error message from the fbsql function should -// be registered here. -// -// TODO/wishlist: -// longReadlen -// binmode - - -require_once 'DB/common.php'; - -/** - * Database independent query interface definition for PHP's FrontBase - * extension. - * - * @package DB - * @version $Id: fbsql.php,v 1.1.1.1 2008/04/28 15:20:47 jamie Exp $ - * @category Database - * @author Frank M. Kromann - */ -class DB_fbsql extends DB_common -{ - // {{{ properties - - var $connection; - var $phptype, $dbsyntax; - var $prepare_tokens = array(); - var $prepare_types = array(); - var $num_rows = array(); - var $fetchmode = DB_FETCHMODE_ORDERED; /* Default fetch mode */ - - // }}} - // {{{ constructor - - /** - * DB_fbsql constructor. - * - * @access public - */ - function DB_fbsql() - { - $this->DB_common(); - $this->phptype = 'fbsql'; - $this->dbsyntax = 'fbsql'; - $this->features = array( - 'prepare' => false, - 'pconnect' => true, - 'transactions' => true, - 'limit' => 'emulate' - ); - $this->errorcode_map = array( - 1004 => DB_ERROR_CANNOT_CREATE, - 1005 => DB_ERROR_CANNOT_CREATE, - 1006 => DB_ERROR_CANNOT_CREATE, - 1007 => DB_ERROR_ALREADY_EXISTS, - 1008 => DB_ERROR_CANNOT_DROP, - 1046 => DB_ERROR_NODBSELECTED, - 1050 => DB_ERROR_ALREADY_EXISTS, - 1051 => DB_ERROR_NOSUCHTABLE, - 1054 => DB_ERROR_NOSUCHFIELD, - 1062 => DB_ERROR_ALREADY_EXISTS, - 1064 => DB_ERROR_SYNTAX, - 1100 => DB_ERROR_NOT_LOCKED, - 1136 => DB_ERROR_VALUE_COUNT_ON_ROW, - 1146 => DB_ERROR_NOSUCHTABLE, - ); - } - - // }}} - // {{{ connect() - - /** - * Connect to a database and log in as the specified user. - * - * @param $dsn the data source name (see DB::parseDSN for syntax) - * @param $persistent (optional) whether the connection should - * be persistent - * @access public - * @return int DB_OK on success, a DB error on failure - */ - function connect($dsninfo, $persistent = false) - { - if (!DB::assertExtension('fbsql')) { - return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND); - } - - $this->dsn = $dsninfo; - $dbhost = $dsninfo['hostspec'] ? $dsninfo['hostspec'] : 'localhost'; - - $php_errormsg = ''; - $connect_function = $persistent ? 'fbsql_pconnect' : 'fbsql_connect'; - - if ($dbhost && $dsninfo['username'] && $dsninfo['password']) { - $conn = @$connect_function($dbhost, $dsninfo['username'], - $dsninfo['password']); - } elseif ($dbhost && $dsninfo['username']) { - $conn = @$connect_function($dbhost, $dsninfo['username']); - } elseif ($dbhost) { - $conn = @$connect_function($dbhost); - } else { - $conn = false; - } - if (!$conn) { - if (empty($php_errormsg)) { - return $this->raiseError(DB_ERROR_CONNECT_FAILED); - } else { - return $this->raiseError(DB_ERROR_CONNECT_FAILED, null, null, - null, $php_errormsg); - } - } - - if ($dsninfo['database']) { - if (!fbsql_select_db($dsninfo['database'], $conn)) { - return $this->fbsqlRaiseError(); - } - } - - $this->connection = $conn; - return DB_OK; - } - - // }}} - // {{{ disconnect() - - /** - * Log out and disconnect from the database. - * - * @access public - * - * @return bool true on success, false if not connected. - */ - function disconnect() - { - $ret = @fbsql_close($this->connection); - $this->connection = null; - return $ret; - } - - // }}} - // {{{ simpleQuery() - - /** - * Send a query to fbsql and return the results as a fbsql resource - * identifier. - * - * @param the SQL query - * - * @access public - * - * @return mixed returns a valid fbsql result for successful SELECT - * queries, DB_OK for other successful queries. A DB error is - * returned on failure. - */ - function simpleQuery($query) - { - $this->last_query = $query; - $query = $this->modifyQuery($query); - $result = @fbsql_query("$query;", $this->connection); - if (!$result) { - return $this->fbsqlRaiseError(); - } - // Determine which queries that should return data, and which - // should return an error code only. - if (DB::isManip($query)) { - return DB_OK; - } - $numrows = $this->numrows($result); - if (is_object($numrows)) { - return $numrows; - } - $this->num_rows[$result] = $numrows; - return $result; - } - - // }}} - // {{{ nextResult() - - /** - * Move the internal fbsql result pointer to the next available result - * - * @param a valid fbsql result resource - * - * @access public - * - * @return true if a result is available otherwise return false - */ - function nextResult($result) - { - return @fbsql_next_result($result); - } - - // }}} - // {{{ fetchInto() - - /** - * Fetch a row and insert the data into an existing array. - * - * Formating of the array and the data therein are configurable. - * See DB_result::fetchInto() for more information. - * - * @param resource $result query result identifier - * @param array $arr (reference) array where data from the row - * should be placed - * @param int $fetchmode how the resulting array should be indexed - * @param int $rownum the row number to fetch - * - * @return mixed DB_OK on success, null when end of result set is - * reached or on failure - * - * @see DB_result::fetchInto() - * @access private - */ - function fetchInto($result, &$arr, $fetchmode, $rownum=null) - { - if ($rownum !== null) { - if (!@fbsql_data_seek($result, $rownum)) { - return null; - } - } - if ($fetchmode & DB_FETCHMODE_ASSOC) { - $arr = @fbsql_fetch_array($result, FBSQL_ASSOC); - if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) { - $arr = array_change_key_case($arr, CASE_LOWER); - } - } else { - $arr = @fbsql_fetch_row($result); - } - if (!$arr) { - $errno = @fbsql_errno($this->connection); - if (!$errno) { - return null; - } - return $this->fbsqlRaiseError($errno); - } - if ($this->options['portability'] & DB_PORTABILITY_RTRIM) { - $this->_rtrimArrayValues($arr); - } - if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) { - $this->_convertNullArrayValuesToEmpty($arr); - } - return DB_OK; - } - - // }}} - // {{{ freeResult() - - /** - * Free the internal resources associated with $result. - * - * @param $result fbsql result identifier - * - * @access public - * - * @return bool true on success, false if $result is invalid - */ - function freeResult($result) - { - return @fbsql_free_result($result); - } - - // }}} - // {{{ autoCommit() - - function autoCommit($onoff=false) - { - if ($onoff) { - $this->query("SET COMMIT TRUE"); - } else { - $this->query("SET COMMIT FALSE"); - } - } - - // }}} - // {{{ commit() - - function commit() - { - @fbsql_commit(); - } - - // }}} - // {{{ rollback() - - function rollback() - { - @fbsql_rollback(); - } - - // }}} - // {{{ numCols() - - /** - * Get the number of columns in a result set. - * - * @param $result fbsql result identifier - * - * @access public - * - * @return int the number of columns per row in $result - */ - function numCols($result) - { - $cols = @fbsql_num_fields($result); - - if (!$cols) { - return $this->fbsqlRaiseError(); - } - - return $cols; - } - - // }}} - // {{{ numRows() - - /** - * Get the number of rows in a result set. - * - * @param $result fbsql result identifier - * - * @access public - * - * @return int the number of rows in $result - */ - function numRows($result) - { - $rows = @fbsql_num_rows($result); - if ($rows === null) { - return $this->fbsqlRaiseError(); - } - return $rows; - } - - // }}} - // {{{ affectedRows() - - /** - * Gets the number of rows affected by the data manipulation - * query. For other queries, this function returns 0. - * - * @return number of rows affected by the last query - */ - function affectedRows() - { - if (DB::isManip($this->last_query)) { - $result = @fbsql_affected_rows($this->connection); - } else { - $result = 0; - } - return $result; - } - - // }}} - // {{{ errorNative() - - /** - * Get the native error code of the last error (if any) that - * occured on the current connection. - * - * @access public - * - * @return int native fbsql error code - */ - function errorNative() - { - return @fbsql_errno($this->connection); - } - - // }}} - // {{{ nextId() - - /** - * Returns the next free id in a sequence - * - * @param string $seq_name name of the sequence - * @param boolean $ondemand when true, the seqence is automatically - * created if it does not exist - * - * @return int the next id number in the sequence. DB_Error if problem. - * - * @internal - * @see DB_common::nextID() - * @access public - */ - function nextId($seq_name, $ondemand = true) - { - $seqname = $this->getSequenceName($seq_name); - $repeat = 0; - do { - $result = $this->query("INSERT INTO ${seqname} VALUES(NULL)"); - if ($ondemand && DB::isError($result) && - $result->getCode() == DB_ERROR_NOSUCHTABLE) { - $repeat = 1; - $result = $this->createSequence($seq_name); - if (DB::isError($result)) { - return $result; - } - } else { - $repeat = 0; - } - } while ($repeat); - if (DB::isError($result)) { - return $result; - } - return @fbsql_insert_id($this->connection); - } - - /** - * Creates a new sequence - * - * @param string $seq_name name of the new sequence - * - * @return int DB_OK on success. A DB_Error object is returned if - * problems arise. - * - * @internal - * @see DB_common::createSequence() - * @access public - */ - function createSequence($seq_name) - { - $seqname = $this->getSequenceName($seq_name); - return $this->query("CREATE TABLE ${seqname} ". - '(id INTEGER UNSIGNED AUTO_INCREMENT NOT NULL,'. - ' PRIMARY KEY(id))'); - } - - // }}} - // {{{ dropSequence() - - /** - * Deletes a sequence - * - * @param string $seq_name name of the sequence to be deleted - * - * @return int DB_OK on success. DB_Error if problems. - * - * @internal - * @see DB_common::dropSequence() - * @access public - */ - function dropSequence($seq_name) - { - $seqname = $this->getSequenceName($seq_name); - return $this->query("DROP TABLE ${seqname} RESTRICT"); - } - - // }}} - // {{{ modifyQuery() - - function modifyQuery($query) - { - if ($this->options['portability'] & DB_PORTABILITY_DELETE_COUNT) { - // "DELETE FROM table" gives 0 affected rows in fbsql. - // This little hack lets you know how many rows were deleted. - if (preg_match('/^\s*DELETE\s+FROM\s+(\S+)\s*$/i', $query)) { - $query = preg_replace('/^\s*DELETE\s+FROM\s+(\S+)\s*$/', - 'DELETE FROM \1 WHERE 1=1', $query); - } - } - return $query; - } - - // }}} - // {{{ quoteSmart() - - /** - * Format input so it can be safely used in a query - * - * @param mixed $in data to be quoted - * - * @return mixed Submitted variable's type = returned value: - * + null = the string NULL - * + boolean = string TRUE or FALSE - * + integer or double = the unquoted number - * + other (including strings and numeric strings) = - * the data escaped according to MySQL's settings - * then encapsulated between single quotes - * - * @internal - */ - function quoteSmart($in) - { - if (is_int($in) || is_double($in)) { - return $in; - } elseif (is_bool($in)) { - return $in ? 'TRUE' : 'FALSE'; - } elseif (is_null($in)) { - return 'NULL'; - } else { - return "'" . $this->escapeSimple($in) . "'"; - } - } - - // }}} - // {{{ fbsqlRaiseError() - - /** - * Gather information about an error, then use that info to create a - * DB error object and finally return that object. - * - * @param integer $errno PEAR error number (usually a DB constant) if - * manually raising an error - * @return object DB error object - * @see DB_common::errorCode() - * @see DB_common::raiseError() - */ - function fbsqlRaiseError($errno = null) - { - if ($errno === null) { - $errno = $this->errorCode(fbsql_errno($this->connection)); - } - return $this->raiseError($errno, null, null, null, - @fbsql_error($this->connection)); - } - - // }}} - // {{{ tableInfo() - - /** - * Returns information about a table or a result set. - * - * @param object|string $result DB_result object from a query or a - * string containing the name of a table - * @param int $mode a valid tableInfo mode - * @return array an associative array with the information requested - * or an error object if something is wrong - * @access public - * @internal - * @see DB_common::tableInfo() - */ - function tableInfo($result, $mode = null) { - if (isset($result->result)) { - /* - * Probably received a result object. - * Extract the result resource identifier. - */ - $id = $result->result; - $got_string = false; - } elseif (is_string($result)) { - /* - * Probably received a table name. - * Create a result resource identifier. - */ - $id = @fbsql_list_fields($this->dsn['database'], - $result, $this->connection); - $got_string = true; - } else { - /* - * Probably received a result resource identifier. - * Copy it. - * Depricated. Here for compatibility only. - */ - $id = $result; - $got_string = false; - } - - if (!is_resource($id)) { - return $this->fbsqlRaiseError(DB_ERROR_NEED_MORE_DATA); - } - - if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) { - $case_func = 'strtolower'; - } else { - $case_func = 'strval'; - } - - $count = @fbsql_num_fields($id); - - // made this IF due to performance (one if is faster than $count if's) - if (!$mode) { - for ($i=0; $i<$count; $i++) { - $res[$i]['table'] = $case_func(@fbsql_field_table($id, $i)); - $res[$i]['name'] = $case_func(@fbsql_field_name($id, $i)); - $res[$i]['type'] = @fbsql_field_type($id, $i); - $res[$i]['len'] = @fbsql_field_len($id, $i); - $res[$i]['flags'] = @fbsql_field_flags($id, $i); - } - } else { // full - $res["num_fields"]= $count; - - for ($i=0; $i<$count; $i++) { - $res[$i]['table'] = $case_func(@fbsql_field_table($id, $i)); - $res[$i]['name'] = $case_func(@fbsql_field_name($id, $i)); - $res[$i]['type'] = @fbsql_field_type($id, $i); - $res[$i]['len'] = @fbsql_field_len($id, $i); - $res[$i]['flags'] = @fbsql_field_flags($id, $i); - - if ($mode & DB_TABLEINFO_ORDER) { - $res['order'][$res[$i]['name']] = $i; - } - if ($mode & DB_TABLEINFO_ORDERTABLE) { - $res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i; - } - } - } - - // free the result only if we were called on a table - if ($got_string) { - @fbsql_free_result($id); - } - return $res; - } - - // }}} - // {{{ getSpecialQuery() - - /** - * Returns the query needed to get some backend info - * @param string $type What kind of info you want to retrieve - * @return string The SQL query string - */ - function getSpecialQuery($type) - { - switch ($type) { - case 'tables': - return 'select "table_name" from information_schema.tables'; - default: - return null; - } - } - - // }}} -} - -/* - * Local variables: - * tab-width: 4 - * c-basic-offset: 4 - * End: - */ - -?> diff --git a/glmPEAR/DB/ibase.php b/glmPEAR/DB/ibase.php deleted file mode 100755 index 5600cfb..0000000 --- a/glmPEAR/DB/ibase.php +++ /dev/null @@ -1,784 +0,0 @@ - | -// | Maintainer: Daniel Convissor | -// +----------------------------------------------------------------------+ -// -// $Id: ibase.php,v 1.1.1.1 2008/04/28 15:20:47 jamie Exp $ - - -// Bugs: -// - If dbsyntax is not firebird, the limitQuery may fail - - -require_once 'DB/common.php'; - -/** - * Database independent query interface definition for PHP's Interbase - * extension. - * - * @package DB - * @version $Id: ibase.php,v 1.1.1.1 2008/04/28 15:20:47 jamie Exp $ - * @category Database - * @author Sterling Hughes - */ -class DB_ibase extends DB_common -{ - - // {{{ properties - - var $connection; - var $phptype, $dbsyntax; - var $autocommit = 1; - var $manip_query = array(); - - // }}} - // {{{ constructor - - function DB_ibase() - { - $this->DB_common(); - $this->phptype = 'ibase'; - $this->dbsyntax = 'ibase'; - $this->features = array( - 'prepare' => true, - 'pconnect' => true, - 'transactions' => true, - 'limit' => false - ); - // just a few of the tons of Interbase error codes listed in the - // Language Reference section of the Interbase manual - $this->errorcode_map = array( - -104 => DB_ERROR_SYNTAX, - -150 => DB_ERROR_ACCESS_VIOLATION, - -151 => DB_ERROR_ACCESS_VIOLATION, - -155 => DB_ERROR_NOSUCHTABLE, - 88 => DB_ERROR_NOSUCHTABLE, - -157 => DB_ERROR_NOSUCHFIELD, - -158 => DB_ERROR_VALUE_COUNT_ON_ROW, - -170 => DB_ERROR_MISMATCH, - -171 => DB_ERROR_MISMATCH, - -172 => DB_ERROR_INVALID, - -204 => DB_ERROR_INVALID, - -205 => DB_ERROR_NOSUCHFIELD, - -206 => DB_ERROR_NOSUCHFIELD, - -208 => DB_ERROR_INVALID, - -219 => DB_ERROR_NOSUCHTABLE, - -297 => DB_ERROR_CONSTRAINT, - -530 => DB_ERROR_CONSTRAINT, - -607 => DB_ERROR_NOSUCHTABLE, - -803 => DB_ERROR_CONSTRAINT, - -551 => DB_ERROR_ACCESS_VIOLATION, - -552 => DB_ERROR_ACCESS_VIOLATION, - -922 => DB_ERROR_NOSUCHDB, - -923 => DB_ERROR_CONNECT_FAILED, - -924 => DB_ERROR_CONNECT_FAILED - ); - } - - // }}} - // {{{ connect() - - function connect($dsninfo, $persistent = false) - { - if (!DB::assertExtension('interbase')) { - return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND); - } - $this->dsn = $dsninfo; - $dbhost = $dsninfo['hostspec'] ? - ($dsninfo['hostspec'] . ':' . $dsninfo['database']) : - $dsninfo['database']; - - $connect_function = $persistent ? 'ibase_pconnect' : 'ibase_connect'; - - $params = array(); - $params[] = $dbhost; - $params[] = $dsninfo['username'] ? $dsninfo['username'] : null; - $params[] = $dsninfo['password'] ? $dsninfo['password'] : null; - $params[] = isset($dsninfo['charset']) ? $dsninfo['charset'] : null; - $params[] = isset($dsninfo['buffers']) ? $dsninfo['buffers'] : null; - $params[] = isset($dsninfo['dialect']) ? $dsninfo['dialect'] : null; - $params[] = isset($dsninfo['role']) ? $dsninfo['role'] : null; - - $conn = @call_user_func_array($connect_function, $params); - if (!$conn) { - return $this->ibaseRaiseError(DB_ERROR_CONNECT_FAILED); - } - $this->connection = $conn; - if ($this->dsn['dbsyntax'] == 'firebird') { - $this->features['limit'] = 'alter'; - } - return DB_OK; - } - - // }}} - // {{{ disconnect() - - function disconnect() - { - $ret = @ibase_close($this->connection); - $this->connection = null; - return $ret; - } - - // }}} - // {{{ simpleQuery() - - function simpleQuery($query) - { - $ismanip = DB::isManip($query); - $this->last_query = $query; - $query = $this->modifyQuery($query); - $result = @ibase_query($this->connection, $query); - if (!$result) { - return $this->ibaseRaiseError(); - } - if ($this->autocommit && $ismanip) { - @ibase_commit($this->connection); - } - // Determine which queries that should return data, and which - // should return an error code only. - return $ismanip ? DB_OK : $result; - } - - // }}} - // {{{ modifyLimitQuery() - - /** - * This method is used by backends to alter limited queries - * Uses the new FIRST n SKIP n Firebird 1.0 syntax, so it is - * only compatible with Firebird 1.x - * - * @param string $query query to modify - * @param integer $from the row to start to fetching - * @param integer $count the numbers of rows to fetch - * - * @return the new (modified) query - * @author Ludovico Magnocavallo - * @access private - */ - function modifyLimitQuery($query, $from, $count, $params = array()) - { - if ($this->dsn['dbsyntax'] == 'firebird') { - //$from++; // SKIP starts from 1, ie SKIP 1 starts from the first record - // (cox) Seems that SKIP starts in 0 - $query = preg_replace('/^\s*select\s(.*)$/is', - "SELECT FIRST $count SKIP $from $1", $query); - } - return $query; - } - - // }}} - // {{{ nextResult() - - /** - * Move the internal ibase result pointer to the next available result - * - * @param a valid fbsql result resource - * - * @access public - * - * @return true if a result is available otherwise return false - */ - function nextResult($result) - { - return false; - } - - // }}} - // {{{ fetchInto() - - /** - * Fetch a row and insert the data into an existing array. - * - * Formating of the array and the data therein are configurable. - * See DB_result::fetchInto() for more information. - * - * @param resource $result query result identifier - * @param array $arr (reference) array where data from the row - * should be placed - * @param int $fetchmode how the resulting array should be indexed - * @param int $rownum the row number to fetch - * - * @return mixed DB_OK on success, null when end of result set is - * reached or on failure - * - * @see DB_result::fetchInto() - * @access private - */ - function fetchInto($result, &$arr, $fetchmode, $rownum=null) - { - if ($rownum !== null) { - return $this->ibaseRaiseError(DB_ERROR_NOT_CAPABLE); - } - if ($fetchmode & DB_FETCHMODE_ASSOC) { - if (function_exists('ibase_fetch_assoc')) { - $arr = @ibase_fetch_assoc($result); - } else { - $arr = get_object_vars(ibase_fetch_object($result)); - } - if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) { - $arr = array_change_key_case($arr, CASE_LOWER); - } - } else { - $arr = @ibase_fetch_row($result); - } - if (!$arr) { - if ($errmsg = @ibase_errmsg()) { - return $this->ibaseRaiseError(null, $errmsg); - } else { - return null; - } - } - if ($this->options['portability'] & DB_PORTABILITY_RTRIM) { - $this->_rtrimArrayValues($arr); - } - if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) { - $this->_convertNullArrayValuesToEmpty($arr); - } - return DB_OK; - } - - // }}} - // {{{ freeResult() - - function freeResult($result) - { - return @ibase_free_result($result); - } - - // }}} - // {{{ freeQuery() - - function freeQuery($query) - { - @ibase_free_query($query); - return true; - } - - // }}} - // {{{ numCols() - - function numCols($result) - { - $cols = @ibase_num_fields($result); - if (!$cols) { - return $this->ibaseRaiseError(); - } - return $cols; - } - - // }}} - // {{{ prepare() - - /** - * Prepares a query for multiple execution with execute(). - * - * prepare() requires a generic query as string like - * INSERT INTO numbers VALUES (?, ?, ?) - * . The ? characters are placeholders. - * - * Three types of placeholders can be used: - * + ? a quoted scalar value, i.e. strings, integers - * + ! value is inserted 'as is' - * + & requires a file name. The file's contents get - * inserted into the query (i.e. saving binary - * data in a db) - * - * Use backslashes to escape placeholder characters if you don't want - * them to be interpreted as placeholders. Example: - * "UPDATE foo SET col=? WHERE col='over \& under'" - * - * - * @param string $query query to be prepared - * @return mixed DB statement resource on success. DB_Error on failure. - */ - function prepare($query) - { - $tokens = preg_split('/((? $val) { - switch ($val) { - case '?': - $types[$token++] = DB_PARAM_SCALAR; - break; - case '&': - $types[$token++] = DB_PARAM_OPAQUE; - break; - case '!': - $types[$token++] = DB_PARAM_MISC; - break; - default: - $tokens[$key] = preg_replace('/\\\([&?!])/', "\\1", $val); - $newquery .= $tokens[$key] . '?'; - } - } - - $newquery = substr($newquery, 0, -1); - $this->last_query = $query; - $newquery = $this->modifyQuery($newquery); - $stmt = @ibase_prepare($this->connection, $newquery); - $this->prepare_types[(int)$stmt] = $types; - $this->manip_query[(int)$stmt] = DB::isManip($query); - return $stmt; - } - - // }}} - // {{{ execute() - - /** - * Executes a DB statement prepared with prepare(). - * - * @param resource $stmt a DB statement resource returned from prepare() - * @param mixed $data array, string or numeric data to be used in - * execution of the statement. Quantity of items - * passed must match quantity of placeholders in - * query: meaning 1 for non-array items or the - * quantity of elements in the array. - * @return object a new DB_Result or a DB_Error when fail - * @see DB_ibase::prepare() - * @access public - */ - function &execute($stmt, $data = array()) - { - if (!is_array($data)) { - $data = array($data); - } - - $types =& $this->prepare_types[$stmt]; - if (count($types) != count($data)) { - $tmp =& $this->raiseError(DB_ERROR_MISMATCH); - return $tmp; - } - - $i = 0; - foreach ($data as $key => $value) { - if ($types[$i] == DB_PARAM_MISC) { - /* - * ibase doesn't seem to have the ability to pass a - * parameter along unchanged, so strip off quotes from start - * and end, plus turn two single quotes to one single quote, - * in order to avoid the quotes getting escaped by - * ibase and ending up in the database. - */ - $data[$key] = preg_replace("/^'(.*)'$/", "\\1", $data[$key]); - $data[$key] = str_replace("''", "'", $data[$key]); - } elseif ($types[$i] == DB_PARAM_OPAQUE) { - $fp = @fopen($data[$key], 'rb'); - if (!$fp) { - $tmp =& $this->raiseError(DB_ERROR_ACCESS_VIOLATION); - return $tmp; - } - $data[$key] = fread($fp, filesize($data[$key])); - fclose($fp); - } - $i++; - } - - array_unshift($data, $stmt); - - $res = call_user_func_array('ibase_execute', $data); - if (!$res) { - $tmp =& $this->ibaseRaiseError(); - return $tmp; - } - /* XXX need this? - if ($this->autocommit && $this->manip_query[(int)$stmt]) { - @ibase_commit($this->connection); - }*/ - if ($this->manip_query[(int)$stmt]) { - $tmp = DB_OK; - } else { - $tmp =& new DB_result($this, $res); - } - return $tmp; - } - - /** - * Free the internal resources associated with a prepared query. - * - * @param $stmt The interbase_query resource type - * - * @return bool true on success, false if $result is invalid - */ - function freePrepared($stmt) - { - if (!is_resource($stmt)) { - return false; - } - @ibase_free_query($stmt); - unset($this->prepare_tokens[(int)$stmt]); - unset($this->prepare_types[(int)$stmt]); - unset($this->manip_query[(int)$stmt]); - return true; - } - - // }}} - // {{{ autoCommit() - - function autoCommit($onoff = false) - { - $this->autocommit = $onoff ? 1 : 0; - return DB_OK; - } - - // }}} - // {{{ commit() - - function commit() - { - return @ibase_commit($this->connection); - } - - // }}} - // {{{ rollback() - - function rollback() - { - return @ibase_rollback($this->connection); - } - - // }}} - // {{{ transactionInit() - - function transactionInit($trans_args = 0) - { - return $trans_args ? @ibase_trans($trans_args, $this->connection) : @ibase_trans(); - } - - // }}} - // {{{ nextId() - - /** - * Returns the next free id in a sequence - * - * @param string $seq_name name of the sequence - * @param boolean $ondemand when true, the seqence is automatically - * created if it does not exist - * - * @return int the next id number in the sequence. DB_Error if problem. - * - * @internal - * @see DB_common::nextID() - * @access public - */ - function nextId($seq_name, $ondemand = true) - { - $sqn = strtoupper($this->getSequenceName($seq_name)); - $repeat = 0; - do { - $this->pushErrorHandling(PEAR_ERROR_RETURN); - $result =& $this->query("SELECT GEN_ID(${sqn}, 1) " - . 'FROM RDB$GENERATORS ' - . "WHERE RDB\$GENERATOR_NAME='${sqn}'"); - $this->popErrorHandling(); - if ($ondemand && DB::isError($result)) { - $repeat = 1; - $result = $this->createSequence($seq_name); - if (DB::isError($result)) { - return $result; - } - } else { - $repeat = 0; - } - } while ($repeat); - if (DB::isError($result)) { - return $this->raiseError($result); - } - $arr = $result->fetchRow(DB_FETCHMODE_ORDERED); - $result->free(); - return $arr[0]; - } - - // }}} - // {{{ createSequence() - - /** - * Create the sequence - * - * @param string $seq_name the name of the sequence - * @return mixed DB_OK on success or DB error on error - * @access public - */ - function createSequence($seq_name) - { - $sqn = strtoupper($this->getSequenceName($seq_name)); - $this->pushErrorHandling(PEAR_ERROR_RETURN); - $result = $this->query("CREATE GENERATOR ${sqn}"); - $this->popErrorHandling(); - - return $result; - } - - // }}} - // {{{ dropSequence() - - /** - * Drop a sequence - * - * @param string $seq_name the name of the sequence - * @return mixed DB_OK on success or DB error on error - * @access public - */ - function dropSequence($seq_name) - { - $sqn = strtoupper($this->getSequenceName($seq_name)); - return $this->query('DELETE FROM RDB$GENERATORS ' - . "WHERE RDB\$GENERATOR_NAME='${sqn}'"); - } - - // }}} - // {{{ _ibaseFieldFlags() - - /** - * get the Flags of a Field - * - * @param string $field_name the name of the field - * @param string $table_name the name of the table - * - * @return string The flags of the field ("primary_key", "unique_key", "not_null" - * "default", "computed" and "blob" are supported) - * @access private - */ - function _ibaseFieldFlags($field_name, $table_name) - { - $sql = 'SELECT R.RDB$CONSTRAINT_TYPE CTYPE' - .' FROM RDB$INDEX_SEGMENTS I' - .' JOIN RDB$RELATION_CONSTRAINTS R ON I.RDB$INDEX_NAME=R.RDB$INDEX_NAME' - .' WHERE I.RDB$FIELD_NAME=\'' . $field_name . '\'' - .' AND UPPER(R.RDB$RELATION_NAME)=\'' . strtoupper($table_name) . '\''; - - $result = @ibase_query($this->connection, $sql); - if (!$result) { - return $this->ibaseRaiseError(); - } - - $flags = ''; - if ($obj = @ibase_fetch_object($result)) { - @ibase_free_result($result); - if (isset($obj->CTYPE) && trim($obj->CTYPE) == 'PRIMARY KEY') { - $flags .= 'primary_key '; - } - if (isset($obj->CTYPE) && trim($obj->CTYPE) == 'UNIQUE') { - $flags .= 'unique_key '; - } - } - - $sql = 'SELECT R.RDB$NULL_FLAG AS NFLAG,' - .' R.RDB$DEFAULT_SOURCE AS DSOURCE,' - .' F.RDB$FIELD_TYPE AS FTYPE,' - .' F.RDB$COMPUTED_SOURCE AS CSOURCE' - .' FROM RDB$RELATION_FIELDS R ' - .' JOIN RDB$FIELDS F ON R.RDB$FIELD_SOURCE=F.RDB$FIELD_NAME' - .' WHERE UPPER(R.RDB$RELATION_NAME)=\'' . strtoupper($table_name) . '\'' - .' AND R.RDB$FIELD_NAME=\'' . $field_name . '\''; - - $result = @ibase_query($this->connection, $sql); - if (!$result) { - return $this->ibaseRaiseError(); - } - if ($obj = @ibase_fetch_object($result)) { - @ibase_free_result($result); - if (isset($obj->NFLAG)) { - $flags .= 'not_null '; - } - if (isset($obj->DSOURCE)) { - $flags .= 'default '; - } - if (isset($obj->CSOURCE)) { - $flags .= 'computed '; - } - if (isset($obj->FTYPE) && $obj->FTYPE == 261) { - $flags .= 'blob '; - } - } - - return trim($flags); - } - - // }}} - // {{{ tableInfo() - - /** - * Returns information about a table or a result set. - * - * NOTE: only supports 'table' and 'flags' if $result - * is a table name. - * - * @param object|string $result DB_result object from a query or a - * string containing the name of a table - * @param int $mode a valid tableInfo mode - * @return array an associative array with the information requested - * or an error object if something is wrong - * @access public - * @internal - * @see DB_common::tableInfo() - */ - function tableInfo($result, $mode = null) - { - if (isset($result->result)) { - /* - * Probably received a result object. - * Extract the result resource identifier. - */ - $id = $result->result; - $got_string = false; - } elseif (is_string($result)) { - /* - * Probably received a table name. - * Create a result resource identifier. - */ - $id = @ibase_query($this->connection, - "SELECT * FROM $result WHERE 1=0"); - $got_string = true; - } else { - /* - * Probably received a result resource identifier. - * Copy it. - * Depricated. Here for compatibility only. - */ - $id = $result; - $got_string = false; - } - - if (!is_resource($id)) { - return $this->ibaseRaiseError(DB_ERROR_NEED_MORE_DATA); - } - - if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) { - $case_func = 'strtolower'; - } else { - $case_func = 'strval'; - } - - $count = @ibase_num_fields($id); - - // made this IF due to performance (one if is faster than $count if's) - if (!$mode) { - for ($i=0; $i<$count; $i++) { - $info = @ibase_field_info($id, $i); - $res[$i]['table'] = $got_string ? $case_func($result) : ''; - $res[$i]['name'] = $case_func($info['name']); - $res[$i]['type'] = $info['type']; - $res[$i]['len'] = $info['length']; - $res[$i]['flags'] = ($got_string) ? $this->_ibaseFieldFlags($info['name'], $result) : ''; - } - } else { // full - $res['num_fields']= $count; - - for ($i=0; $i<$count; $i++) { - $info = @ibase_field_info($id, $i); - $res[$i]['table'] = $got_string ? $case_func($result) : ''; - $res[$i]['name'] = $case_func($info['name']); - $res[$i]['type'] = $info['type']; - $res[$i]['len'] = $info['length']; - $res[$i]['flags'] = ($got_string) ? $this->_ibaseFieldFlags($info['name'], $result) : ''; - - if ($mode & DB_TABLEINFO_ORDER) { - $res['order'][$res[$i]['name']] = $i; - } - if ($mode & DB_TABLEINFO_ORDERTABLE) { - $res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i; - } - } - } - - // free the result only if we were called on a table - if ($got_string) { - @ibase_free_result($id); - } - return $res; - } - - // }}} - // {{{ ibaseRaiseError() - - /** - * Gather information about an error, then use that info to create a - * DB error object and finally return that object. - * - * @param integer $db_errno PEAR error number (usually a DB constant) if - * manually raising an error - * @param string $native_errmsg text of error message if known - * @return object DB error object - * @see DB_common::errorCode() - * @see DB_common::raiseError() - */ - function &ibaseRaiseError($db_errno = null, $native_errmsg = null) - { - if ($native_errmsg === null) { - $native_errmsg = @ibase_errmsg(); - } - // memo for the interbase php module hackers: we need something similar - // to mysql_errno() to retrieve error codes instead of this ugly hack - if (preg_match('/^([^0-9\-]+)([0-9\-]+)\s+(.*)$/', $native_errmsg, $m)) { - $native_errno = (int)$m[2]; - } else { - $native_errno = null; - } - // try to map the native error to the DB one - if ($db_errno === null) { - if ($native_errno) { - // try to interpret Interbase error code (that's why we need ibase_errno() - // in the interbase module to return the real error code) - switch ($native_errno) { - case -204: - if (is_int(strpos($m[3], 'Table unknown'))) { - $db_errno = DB_ERROR_NOSUCHTABLE; - } - break; - default: - $db_errno = $this->errorCode($native_errno); - } - } else { - $error_regexps = array( - '/[tT]able not found/' => DB_ERROR_NOSUCHTABLE, - '/[tT]able .* already exists/' => DB_ERROR_ALREADY_EXISTS, - '/validation error for column .* value "\*\*\* null/' => DB_ERROR_CONSTRAINT_NOT_NULL, - '/violation of [\w ]+ constraint/' => DB_ERROR_CONSTRAINT, - '/conversion error from string/' => DB_ERROR_INVALID_NUMBER, - '/no permission for/' => DB_ERROR_ACCESS_VIOLATION, - '/arithmetic exception, numeric overflow, or string truncation/' => DB_ERROR_DIVZERO - ); - foreach ($error_regexps as $regexp => $code) { - if (preg_match($regexp, $native_errmsg)) { - $db_errno = $code; - $native_errno = null; - break; - } - } - } - } - $tmp =& $this->raiseError($db_errno, null, null, null, $native_errmsg); - return $tmp; - } - - // }}} - -} - -/* - * Local variables: - * tab-width: 4 - * c-basic-offset: 4 - * End: - */ - -?> diff --git a/glmPEAR/DB/ifx.php b/glmPEAR/DB/ifx.php deleted file mode 100755 index efd66b0..0000000 --- a/glmPEAR/DB/ifx.php +++ /dev/null @@ -1,579 +0,0 @@ - | -// | Maintainer: Daniel Convissor | -// +----------------------------------------------------------------------+ -// -// $Id: ifx.php,v 1.1.1.1 2008/04/28 15:20:47 jamie Exp $ - - -// Legend: -// For more info on Informix errors see: -// http://www.informix.com/answers/english/ierrors.htm -// -// TODO: -// - set needed env Informix vars on connect -// - implement native prepare/execute - - -require_once 'DB/common.php'; - -/** - * Database independent query interface definition for PHP's Informix - * extension. - * - * @package DB - * @version $Id: ifx.php,v 1.1.1.1 2008/04/28 15:20:47 jamie Exp $ - * @category Database - * @author Tomas V.V.Cox - */ -class DB_ifx extends DB_common -{ - // {{{ properties - - var $connection; - var $affected = 0; - var $dsn = array(); - var $transaction_opcount = 0; - var $autocommit = true; - var $fetchmode = DB_FETCHMODE_ORDERED; /* Default fetch mode */ - - // }}} - // {{{ constructor - - function DB_ifx() - { - $this->phptype = 'ifx'; - $this->dbsyntax = 'ifx'; - $this->features = array( - 'prepare' => false, - 'pconnect' => true, - 'transactions' => true, - 'limit' => 'emulate' - ); - $this->errorcode_map = array( - '-201' => DB_ERROR_SYNTAX, - '-206' => DB_ERROR_NOSUCHTABLE, - '-217' => DB_ERROR_NOSUCHFIELD, - '-239' => DB_ERROR_CONSTRAINT, - '-253' => DB_ERROR_SYNTAX, - '-292' => DB_ERROR_CONSTRAINT_NOT_NULL, - '-310' => DB_ERROR_ALREADY_EXISTS, - '-329' => DB_ERROR_NODBSELECTED, - '-346' => DB_ERROR_CONSTRAINT, - '-386' => DB_ERROR_CONSTRAINT_NOT_NULL, - '-391' => DB_ERROR_CONSTRAINT_NOT_NULL, - '-554' => DB_ERROR_SYNTAX, - '-691' => DB_ERROR_CONSTRAINT, - '-703' => DB_ERROR_CONSTRAINT_NOT_NULL, - '-1204' => DB_ERROR_INVALID_DATE, - '-1205' => DB_ERROR_INVALID_DATE, - '-1206' => DB_ERROR_INVALID_DATE, - '-1209' => DB_ERROR_INVALID_DATE, - '-1210' => DB_ERROR_INVALID_DATE, - '-1212' => DB_ERROR_INVALID_DATE, - '-1213' => DB_ERROR_INVALID_NUMBER, - ); - } - - // }}} - // {{{ connect() - - /** - * Connect to a database and log in as the specified user. - * - * @param $dsn the data source name (see DB::parseDSN for syntax) - * @param $persistent (optional) whether the connection should - * be persistent - * - * @return int DB_OK on success, a DB error code on failure - */ - function connect($dsninfo, $persistent = false) - { - if (!DB::assertExtension('informix') && - !DB::assertExtension('Informix')) - { - return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND); - } - $this->dsn = $dsninfo; - $dbhost = $dsninfo['hostspec'] ? '@' . $dsninfo['hostspec'] : ''; - $dbname = $dsninfo['database'] ? $dsninfo['database'] . $dbhost : ''; - $user = $dsninfo['username'] ? $dsninfo['username'] : ''; - $pw = $dsninfo['password'] ? $dsninfo['password'] : ''; - - $connect_function = $persistent ? 'ifx_pconnect' : 'ifx_connect'; - - $this->connection = @$connect_function($dbname, $user, $pw); - if (!is_resource($this->connection)) { - return $this->ifxraiseError(DB_ERROR_CONNECT_FAILED); - } - return DB_OK; - } - - // }}} - // {{{ disconnect() - - /** - * Log out and disconnect from the database. - * - * @return bool true on success, false if not connected. - */ - function disconnect() - { - $ret = @ifx_close($this->connection); - $this->connection = null; - return $ret; - } - - // }}} - // {{{ simpleQuery() - - /** - * Send a query to Informix and return the results as a - * Informix resource identifier. - * - * @param $query the SQL query - * - * @return int returns a valid Informix result for successful SELECT - * queries, DB_OK for other successful queries. A DB error code - * is returned on failure. - */ - function simpleQuery($query) - { - $ismanip = DB::isManip($query); - $this->last_query = $query; - $this->affected = null; - if (preg_match('/(SELECT)/i', $query)) { //TESTME: Use !DB::isManip()? - // the scroll is needed for fetching absolute row numbers - // in a select query result - $result = @ifx_query($query, $this->connection, IFX_SCROLL); - } else { - if (!$this->autocommit && $ismanip) { - if ($this->transaction_opcount == 0) { - $result = @ifx_query('BEGIN WORK', $this->connection); - if (!$result) { - return $this->ifxraiseError(); - } - } - $this->transaction_opcount++; - } - $result = @ifx_query($query, $this->connection); - } - if (!$result) { - return $this->ifxraiseError(); - } - $this->affected = @ifx_affected_rows($result); - // Determine which queries should return data, and which - // should return an error code only. - if (preg_match('/(SELECT)/i', $query)) { - return $result; - } - // XXX Testme: free results inside a transaction - // may cause to stop it and commit the work? - - // Result has to be freed even with a insert or update - @ifx_free_result($result); - - return DB_OK; - } - - // }}} - // {{{ nextResult() - - /** - * Move the internal ifx result pointer to the next available result - * - * @param a valid fbsql result resource - * - * @access public - * - * @return true if a result is available otherwise return false - */ - function nextResult($result) - { - return false; - } - - // }}} - // {{{ affectedRows() - - /** - * Gets the number of rows affected by the last query. - * if the last query was a select, returns 0. - * - * @return number of rows affected by the last query - */ - function affectedRows() - { - if (DB::isManip($this->last_query)) { - return $this->affected; - } else { - return 0; - } - - } - - // }}} - // {{{ fetchInto() - - /** - * Fetch a row and insert the data into an existing array. - * - * Formating of the array and the data therein are configurable. - * See DB_result::fetchInto() for more information. - * - * @param resource $result query result identifier - * @param array $arr (reference) array where data from the row - * should be placed - * @param int $fetchmode how the resulting array should be indexed - * @param int $rownum the row number to fetch - * - * @return mixed DB_OK on success, null when end of result set is - * reached or on failure - * - * @see DB_result::fetchInto() - * @access private - */ - function fetchInto($result, &$arr, $fetchmode, $rownum=null) - { - if (($rownum !== null) && ($rownum < 0)) { - return null; - } - if ($rownum === null) { - /* - * Even though fetch_row() should return the next row if - * $rownum is null, it doesn't in all cases. Bug 598. - */ - $rownum = 'NEXT'; - } else { - // Index starts at row 1, unlike most DBMS's starting at 0. - $rownum++; - } - if (!$arr = @ifx_fetch_row($result, $rownum)) { - return null; - } - if ($fetchmode !== DB_FETCHMODE_ASSOC) { - $i=0; - $order = array(); - foreach ($arr as $val) { - $order[$i++] = $val; - } - $arr = $order; - } elseif ($fetchmode == DB_FETCHMODE_ASSOC && - $this->options['portability'] & DB_PORTABILITY_LOWERCASE) - { - $arr = array_change_key_case($arr, CASE_LOWER); - } - if ($this->options['portability'] & DB_PORTABILITY_RTRIM) { - $this->_rtrimArrayValues($arr); - } - if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) { - $this->_convertNullArrayValuesToEmpty($arr); - } - return DB_OK; - } - - // }}} - // {{{ numRows() - - function numRows($result) - { - return $this->raiseError(DB_ERROR_NOT_CAPABLE); - } - - // }}} - // {{{ numCols() - - /** - * Get the number of columns in a result set. - * - * @param $result Informix result identifier - * - * @return int the number of columns per row in $result - */ - function numCols($result) - { - if (!$cols = @ifx_num_fields($result)) { - return $this->ifxraiseError(); - } - return $cols; - } - - // }}} - // {{{ freeResult() - - /** - * Free the internal resources associated with $result. - * - * @param $result Informix result identifier - * - * @return bool true on success, false if $result is invalid - */ - function freeResult($result) - { - return @ifx_free_result($result); - } - - // }}} - // {{{ autoCommit() - - /** - * Enable/disable automatic commits - */ - function autoCommit($onoff = true) - { - // XXX if $this->transaction_opcount > 0, we should probably - // issue a warning here. - $this->autocommit = $onoff ? true : false; - return DB_OK; - } - - // }}} - // {{{ commit() - - /** - * Commit the current transaction. - */ - function commit() - { - if ($this->transaction_opcount > 0) { - $result = @ifx_query('COMMIT WORK', $this->connection); - $this->transaction_opcount = 0; - if (!$result) { - return $this->ifxRaiseError(); - } - } - return DB_OK; - } - - // }}} - // {{{ rollback() - - /** - * Roll back (undo) the current transaction. - */ - function rollback() - { - if ($this->transaction_opcount > 0) { - $result = @ifx_query('ROLLBACK WORK', $this->connection); - $this->transaction_opcount = 0; - if (!$result) { - return $this->ifxRaiseError(); - } - } - return DB_OK; - } - - // }}} - // {{{ ifxraiseError() - - /** - * Gather information about an error, then use that info to create a - * DB error object and finally return that object. - * - * @param integer $errno PEAR error number (usually a DB constant) if - * manually raising an error - * @return object DB error object - * @see errorNative() - * @see errorCode() - * @see DB_common::raiseError() - */ - function ifxraiseError($errno = null) - { - if ($errno === null) { - $errno = $this->errorCode(ifx_error()); - } - - return $this->raiseError($errno, null, null, null, - $this->errorNative()); - } - - // }}} - // {{{ errorCode() - - /** - * Map native error codes to DB's portable ones. - * - * Requires that the DB implementation's constructor fills - * in the $errorcode_map property. - * - * @param string $nativecode error code returned by the database - * @return int a portable DB error code, or DB_ERROR if this DB - * implementation has no mapping for the given error code. - */ - function errorCode($nativecode) - { - if (ereg('SQLCODE=(.*)]', $nativecode, $match)) { - $code = $match[1]; - if (isset($this->errorcode_map[$code])) { - return $this->errorcode_map[$code]; - } - } - return DB_ERROR; - } - - // }}} - // {{{ errorNative() - - /** - * Get the native error message of the last error (if any) that - * occured on the current connection. - * - * @return int native Informix error code - */ - function errorNative() - { - return @ifx_error() . ' ' . @ifx_errormsg(); - } - - // }}} - // {{{ getSpecialQuery() - - /** - * Returns the query needed to get some backend info - * @param string $type What kind of info you want to retrieve - * @return string The SQL query string - */ - function getSpecialQuery($type) - { - switch ($type) { - case 'tables': - return 'select tabname from systables where tabid >= 100'; - default: - return null; - } - } - - // }}} - // {{{ tableInfo() - - /** - * Returns information about a table or a result set. - * - * NOTE: only supports 'table' if $result is a table name. - * - * If analyzing a query result and the result has duplicate field names, - * an error will be raised saying - * can't distinguish duplicate field names. - * - * @param object|string $result DB_result object from a query or a - * string containing the name of a table - * @param int $mode a valid tableInfo mode - * @return array an associative array with the information requested - * or an error object if something is wrong - * @access public - * @internal - * @since 1.6.0 - * @see DB_common::tableInfo() - */ - function tableInfo($result, $mode = null) - { - if (isset($result->result)) { - /* - * Probably received a result object. - * Extract the result resource identifier. - */ - $id = $result->result; - $got_string = false; - } elseif (is_string($result)) { - /* - * Probably received a table name. - * Create a result resource identifier. - */ - $id = @ifx_query("SELECT * FROM $result WHERE 1=0", - $this->connection); - $got_string = true; - } else { - /* - * Probably received a result resource identifier. - * Copy it. - */ - $id = $result; - $got_string = false; - } - - if (!is_resource($id)) { - return $this->ifxRaiseError(DB_ERROR_NEED_MORE_DATA); - } - - $flds = @ifx_fieldproperties($id); - $count = @ifx_num_fields($id); - - if (count($flds) != $count) { - return $this->raiseError("can't distinguish duplicate field names"); - } - - if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) { - $case_func = 'strtolower'; - } else { - $case_func = 'strval'; - } - - $i = 0; - // made this IF due to performance (one if is faster than $count if's) - if (!$mode) { - foreach ($flds as $key => $value) { - $props = explode(';', $value); - - $res[$i]['table'] = $got_string ? $case_func($result) : ''; - $res[$i]['name'] = $case_func($key); - $res[$i]['type'] = $props[0]; - $res[$i]['len'] = $props[1]; - $res[$i]['flags'] = $props[4] == 'N' ? 'not_null' : ''; - $i++; - } - - } else { // full - $res['num_fields'] = $count; - - foreach ($flds as $key => $value) { - $props = explode(';', $value); - - $res[$i]['table'] = $got_string ? $case_func($result) : ''; - $res[$i]['name'] = $case_func($key); - $res[$i]['type'] = $props[0]; - $res[$i]['len'] = $props[1]; - $res[$i]['flags'] = $props[4] == 'N' ? 'not_null' : ''; - - if ($mode & DB_TABLEINFO_ORDER) { - $res['order'][$res[$i]['name']] = $i; - } - if ($mode & DB_TABLEINFO_ORDERTABLE) { - $res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i; - } - $i++; - } - } - - // free the result only if we were called on a table - if ($got_string) { - @ifx_free_result($id); - } - return $res; - } - - // }}} - -} - -/* - * Local variables: - * tab-width: 4 - * c-basic-offset: 4 - * End: - */ - -?> diff --git a/glmPEAR/DB/msql.php b/glmPEAR/DB/msql.php deleted file mode 100755 index 0077ad8..0000000 --- a/glmPEAR/DB/msql.php +++ /dev/null @@ -1,242 +0,0 @@ - | -// | Maintainer: Daniel Convissor | -// +----------------------------------------------------------------------+ -// -// $Id: msql.php,v 1.1.1.1 2008/04/28 15:20:47 jamie Exp $ - -require_once 'DB/common.php'; - -/** - * Database independent query interface definition for PHP's Mini-SQL - * extension. - * - * @package DB - * @version $Id: msql.php,v 1.1.1.1 2008/04/28 15:20:47 jamie Exp $ - * @category Database - * @author Sterling Hughes - */ -class DB_msql extends DB_common -{ - // {{{ properties - - var $connection; - var $phptype, $dbsyntax; - var $prepare_tokens = array(); - var $prepare_types = array(); - - // }}} - // {{{ constructor - - function DB_msql() - { - $this->DB_common(); - $this->phptype = 'msql'; - $this->dbsyntax = 'msql'; - $this->features = array( - 'prepare' => false, - 'pconnect' => true, - 'transactions' => false, - 'limit' => 'emulate' - ); - } - - // }}} - // {{{ connect() - - function connect($dsninfo, $persistent = false) - { - if (!DB::assertExtension('msql')) { - return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND); - } - - $this->dsn = $dsninfo; - $dbhost = $dsninfo['hostspec'] ? $dsninfo['hostspec'] : 'localhost'; - - $connect_function = $persistent ? 'msql_pconnect' : 'msql_connect'; - - if ($dbhost && $dsninfo['username'] && $dsninfo['password']) { - $conn = $connect_function($dbhost, $dsninfo['username'], - $dsninfo['password']); - } elseif ($dbhost && $dsninfo['username']) { - $conn = $connect_function($dbhost, $dsninfo['username']); - } else { - $conn = $connect_function($dbhost); - } - if (!$conn) { - $this->raiseError(DB_ERROR_CONNECT_FAILED); - } - if (!@msql_select_db($dsninfo['database'], $conn)){ - return $this->raiseError(DB_ERROR_NODBSELECTED); - } - $this->connection = $conn; - return DB_OK; - } - - // }}} - // {{{ disconnect() - - function disconnect() - { - $ret = @msql_close($this->connection); - $this->connection = null; - return $ret; - } - - // }}} - // {{{ simpleQuery() - - function simpleQuery($query) - { - $this->last_query = $query; - $query = $this->modifyQuery($query); - $result = @msql_query($query, $this->connection); - if (!$result) { - return $this->raiseError(); - } - // Determine which queries that should return data, and which - // should return an error code only. - return DB::isManip($query) ? DB_OK : $result; - } - - - // }}} - // {{{ nextResult() - - /** - * Move the internal msql result pointer to the next available result - * - * @param a valid fbsql result resource - * - * @access public - * - * @return true if a result is available otherwise return false - */ - function nextResult($result) - { - return false; - } - - // }}} - // {{{ fetchInto() - - /** - * Fetch a row and insert the data into an existing array. - * - * Formating of the array and the data therein are configurable. - * See DB_result::fetchInto() for more information. - * - * @param resource $result query result identifier - * @param array $arr (reference) array where data from the row - * should be placed - * @param int $fetchmode how the resulting array should be indexed - * @param int $rownum the row number to fetch - * - * @return mixed DB_OK on success, null when end of result set is - * reached or on failure - * - * @see DB_result::fetchInto() - * @access private - */ - function fetchInto($result, &$arr, $fetchmode, $rownum=null) - { - if ($rownum !== null) { - if (!@msql_data_seek($result, $rownum)) { - return null; - } - } - if ($fetchmode & DB_FETCHMODE_ASSOC) { - $arr = @msql_fetch_array($result, MSQL_ASSOC); - if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) { - $arr = array_change_key_case($arr, CASE_LOWER); - } - } else { - $arr = @msql_fetch_row($result); - } - if (!$arr) { - if ($error = @msql_error()) { - return $this->raiseError($error); - } else { - return null; - } - } - if ($this->options['portability'] & DB_PORTABILITY_RTRIM) { - $this->_rtrimArrayValues($arr); - } - if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) { - $this->_convertNullArrayValuesToEmpty($arr); - } - return DB_OK; - } - - // }}} - // {{{ freeResult() - - function freeResult($result) - { - return @msql_free_result($result); - } - - // }}} - // {{{ numCols() - - function numCols($result) - { - $cols = @msql_num_fields($result); - if (!$cols) { - return $this->raiseError(); - } - return $cols; - } - - // }}} - // {{{ numRows() - - function numRows($result) - { - $rows = @msql_num_rows($result); - if (!$rows) { - return $this->raiseError(); - } - return $rows; - } - - // }}} - // {{{ affected() - - /** - * Gets the number of rows affected by a query. - * - * @return number of rows affected by the last query - */ - function affectedRows() - { - return @msql_affected_rows($this->connection); - } - - // }}} - -} - -/* - * Local variables: - * tab-width: 4 - * c-basic-offset: 4 - * End: - */ - -?> diff --git a/glmPEAR/DB/mssql.php b/glmPEAR/DB/mssql.php deleted file mode 100755 index 269071f..0000000 --- a/glmPEAR/DB/mssql.php +++ /dev/null @@ -1,738 +0,0 @@ - | -// | Maintainer: Daniel Convissor | -// +----------------------------------------------------------------------+ -// -// $Id: mssql.php,v 1.1.1.1 2008/04/28 15:20:47 jamie Exp $ - -require_once 'DB/common.php'; - -/** - * Database independent query interface definition for PHP's Microsoft SQL Server - * extension. - * - * @package DB - * @version $Id: mssql.php,v 1.1.1.1 2008/04/28 15:20:47 jamie Exp $ - * @category Database - * @author Sterling Hughes - */ -class DB_mssql extends DB_common -{ - // {{{ properties - - var $connection; - var $phptype, $dbsyntax; - var $prepare_tokens = array(); - var $prepare_types = array(); - var $transaction_opcount = 0; - var $autocommit = true; - var $_db = null; - - // }}} - // {{{ constructor - - function DB_mssql() - { - $this->DB_common(); - $this->phptype = 'mssql'; - $this->dbsyntax = 'mssql'; - $this->features = array( - 'prepare' => false, - 'pconnect' => true, - 'transactions' => true, - 'limit' => 'emulate' - ); - // XXX Add here error codes ie: 'S100E' => DB_ERROR_SYNTAX - $this->errorcode_map = array( - 170 => DB_ERROR_SYNTAX, - 207 => DB_ERROR_NOSUCHFIELD, - 208 => DB_ERROR_NOSUCHTABLE, - 245 => DB_ERROR_INVALID_NUMBER, - 515 => DB_ERROR_CONSTRAINT_NOT_NULL, - 547 => DB_ERROR_CONSTRAINT, - 2627 => DB_ERROR_CONSTRAINT, - 2714 => DB_ERROR_ALREADY_EXISTS, - 3701 => DB_ERROR_NOSUCHTABLE, - 8134 => DB_ERROR_DIVZERO, - ); - } - - // }}} - // {{{ connect() - - function connect($dsninfo, $persistent = false) - { - if (!DB::assertExtension('mssql') && !DB::assertExtension('sybase') - && !DB::assertExtension('sybase_ct')) - { - return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND); - } - $this->dsn = $dsninfo; - $dbhost = $dsninfo['hostspec'] ? $dsninfo['hostspec'] : 'localhost'; - $dbhost .= $dsninfo['port'] ? ':' . $dsninfo['port'] : ''; - - $connect_function = $persistent ? 'mssql_pconnect' : 'mssql_connect'; - - if ($dbhost && $dsninfo['username'] && $dsninfo['password']) { - $conn = @$connect_function($dbhost, $dsninfo['username'], - $dsninfo['password']); - } elseif ($dbhost && $dsninfo['username']) { - $conn = @$connect_function($dbhost, $dsninfo['username']); - } else { - $conn = @$connect_function($dbhost); - } - if (!$conn) { - return $this->raiseError(DB_ERROR_CONNECT_FAILED, null, null, - null, @mssql_get_last_message()); - } - if ($dsninfo['database']) { - if (!@mssql_select_db($dsninfo['database'], $conn)) { - return $this->raiseError(DB_ERROR_NODBSELECTED, null, null, - null, @mssql_get_last_message()); - } - $this->_db = $dsninfo['database']; - } - $this->connection = $conn; - return DB_OK; - } - - // }}} - // {{{ disconnect() - - function disconnect() - { - $ret = @mssql_close($this->connection); - $this->connection = null; - return $ret; - } - - // }}} - // {{{ simpleQuery() - - function simpleQuery($query) - { - $ismanip = DB::isManip($query); - $this->last_query = $query; - if (!@mssql_select_db($this->_db, $this->connection)) { - return $this->mssqlRaiseError(DB_ERROR_NODBSELECTED); - } - $query = $this->modifyQuery($query); - if (!$this->autocommit && $ismanip) { - if ($this->transaction_opcount == 0) { - $result = @mssql_query('BEGIN TRAN', $this->connection); - if (!$result) { - return $this->mssqlRaiseError(); - } - } - $this->transaction_opcount++; - } - $result = @mssql_query($query, $this->connection); - if (!$result) { - return $this->mssqlRaiseError(); - } - // Determine which queries that should return data, and which - // should return an error code only. - return $ismanip ? DB_OK : $result; - } - - // }}} - // {{{ nextResult() - - /** - * Move the internal mssql result pointer to the next available result - * - * @param a valid fbsql result resource - * - * @access public - * - * @return true if a result is available otherwise return false - */ - function nextResult($result) - { - return @mssql_next_result($result); - } - - // }}} - // {{{ fetchInto() - - /** - * Fetch a row and insert the data into an existing array. - * - * Formating of the array and the data therein are configurable. - * See DB_result::fetchInto() for more information. - * - * @param resource $result query result identifier - * @param array $arr (reference) array where data from the row - * should be placed - * @param int $fetchmode how the resulting array should be indexed - * @param int $rownum the row number to fetch - * - * @return mixed DB_OK on success, null when end of result set is - * reached or on failure - * - * @see DB_result::fetchInto() - * @access private - */ - function fetchInto($result, &$arr, $fetchmode, $rownum=null) - { - if ($rownum !== null) { - if (!@mssql_data_seek($result, $rownum)) { - return null; - } - } - if ($fetchmode & DB_FETCHMODE_ASSOC) { - $arr = @mssql_fetch_array($result, MSSQL_ASSOC); - if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) { - $arr = array_change_key_case($arr, CASE_LOWER); - } - } else { - $arr = @mssql_fetch_row($result); - } - if (!$arr) { - /* This throws informative error messages, - don't use it for now - if ($msg = @mssql_get_last_message()) { - return $this->raiseError($msg); - } - */ - return null; - } - if ($this->options['portability'] & DB_PORTABILITY_RTRIM) { - $this->_rtrimArrayValues($arr); - } - if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) { - $this->_convertNullArrayValuesToEmpty($arr); - } - return DB_OK; - } - - // }}} - // {{{ freeResult() - - function freeResult($result) - { - return @mssql_free_result($result); - } - - // }}} - // {{{ numCols() - - function numCols($result) - { - $cols = @mssql_num_fields($result); - if (!$cols) { - return $this->mssqlRaiseError(); - } - return $cols; - } - - // }}} - // {{{ numRows() - - function numRows($result) - { - $rows = @mssql_num_rows($result); - if ($rows === false) { - return $this->mssqlRaiseError(); - } - return $rows; - } - - // }}} - // {{{ autoCommit() - - /** - * Enable/disable automatic commits - */ - function autoCommit($onoff = false) - { - // XXX if $this->transaction_opcount > 0, we should probably - // issue a warning here. - $this->autocommit = $onoff ? true : false; - return DB_OK; - } - - // }}} - // {{{ commit() - - /** - * Commit the current transaction. - */ - function commit() - { - if ($this->transaction_opcount > 0) { - if (!@mssql_select_db($this->_db, $this->connection)) { - return $this->mssqlRaiseError(DB_ERROR_NODBSELECTED); - } - $result = @mssql_query('COMMIT TRAN', $this->connection); - $this->transaction_opcount = 0; - if (!$result) { - return $this->mssqlRaiseError(); - } - } - return DB_OK; - } - - // }}} - // {{{ rollback() - - /** - * Roll back (undo) the current transaction. - */ - function rollback() - { - if ($this->transaction_opcount > 0) { - if (!@mssql_select_db($this->_db, $this->connection)) { - return $this->mssqlRaiseError(DB_ERROR_NODBSELECTED); - } - $result = @mssql_query('ROLLBACK TRAN', $this->connection); - $this->transaction_opcount = 0; - if (!$result) { - return $this->mssqlRaiseError(); - } - } - return DB_OK; - } - - // }}} - // {{{ affectedRows() - - /** - * Gets the number of rows affected by the last query. - * if the last query was a select, returns 0. - * - * @return number of rows affected by the last query or DB_ERROR - */ - function affectedRows() - { - if (DB::isManip($this->last_query)) { - $res = @mssql_query('select @@rowcount', $this->connection); - if (!$res) { - return $this->mssqlRaiseError(); - } - $ar = @mssql_fetch_row($res); - if (!$ar) { - $result = 0; - } else { - @mssql_free_result($res); - $result = $ar[0]; - } - } else { - $result = 0; - } - return $result; - } - - // }}} - // {{{ nextId() - - /** - * Returns the next free id in a sequence - * - * @param string $seq_name name of the sequence - * @param boolean $ondemand when true, the seqence is automatically - * created if it does not exist - * - * @return int the next id number in the sequence. DB_Error if problem. - * - * @internal - * @see DB_common::nextID() - * @access public - */ - function nextId($seq_name, $ondemand = true) - { - $seqname = $this->getSequenceName($seq_name); - if (!@mssql_select_db($this->_db, $this->connection)) { - return $this->mssqlRaiseError(DB_ERROR_NODBSELECTED); - } - $repeat = 0; - do { - $this->pushErrorHandling(PEAR_ERROR_RETURN); - $result = $this->query("INSERT INTO $seqname (vapor) VALUES (0)"); - $this->popErrorHandling(); - if ($ondemand && DB::isError($result) && - ($result->getCode() == DB_ERROR || $result->getCode() == DB_ERROR_NOSUCHTABLE)) - { - $repeat = 1; - $result = $this->createSequence($seq_name); - if (DB::isError($result)) { - return $this->raiseError($result); - } - } elseif (!DB::isError($result)) { - $result =& $this->query("SELECT @@IDENTITY FROM $seqname"); - $repeat = 0; - } else { - $repeat = false; - } - } while ($repeat); - if (DB::isError($result)) { - return $this->raiseError($result); - } - $result = $result->fetchRow(DB_FETCHMODE_ORDERED); - return $result[0]; - } - - /** - * Creates a new sequence - * - * @param string $seq_name name of the new sequence - * - * @return int DB_OK on success. A DB_Error object is returned if - * problems arise. - * - * @internal - * @see DB_common::createSequence() - * @access public - */ - function createSequence($seq_name) - { - $seqname = $this->getSequenceName($seq_name); - return $this->query("CREATE TABLE $seqname ". - '([id] [int] IDENTITY (1, 1) NOT NULL ,' . - '[vapor] [int] NULL)'); - } - - // }}} - // {{{ dropSequence() - - /** - * Deletes a sequence - * - * @param string $seq_name name of the sequence to be deleted - * - * @return int DB_OK on success. DB_Error if problems. - * - * @internal - * @see DB_common::dropSequence() - * @access public - */ - function dropSequence($seq_name) - { - $seqname = $this->getSequenceName($seq_name); - return $this->query("DROP TABLE $seqname"); - } - - // }}} - // {{{ errorNative() - - /** - * Determine MS SQL Server error code by querying @@ERROR. - * - * @return mixed mssql's native error code or DB_ERROR if unknown. - */ - function errorNative() - { - $res = @mssql_query('select @@ERROR as ErrorCode', $this->connection); - if (!$res) { - return DB_ERROR; - } - $row = @mssql_fetch_row($res); - return $row[0]; - } - - // }}} - // {{{ errorCode() - - /** - * Determine PEAR::DB error code from mssql's native codes. - * - * If $nativecode isn't known yet, it will be looked up. - * - * @param mixed $nativecode mssql error code, if known - * @return integer an error number from a DB error constant - * @see errorNative() - */ - function errorCode($nativecode = null) - { - if (!$nativecode) { - $nativecode = $this->errorNative(); - } - if (isset($this->errorcode_map[$nativecode])) { - return $this->errorcode_map[$nativecode]; - } else { - return DB_ERROR; - } - } - - // }}} - // {{{ mssqlRaiseError() - - /** - * Gather information about an error, then use that info to create a - * DB error object and finally return that object. - * - * @param integer $code PEAR error number (usually a DB constant) if - * manually raising an error - * @return object DB error object - * @see errorCode() - * @see errorNative() - * @see DB_common::raiseError() - */ - function mssqlRaiseError($code = null) - { - $message = @mssql_get_last_message(); - if (!$code) { - $code = $this->errorNative(); - } - return $this->raiseError($this->errorCode($code), null, null, null, - "$code - $message"); - } - - // }}} - // {{{ tableInfo() - - /** - * Returns information about a table or a result set. - * - * NOTE: only supports 'table' and 'flags' if $result - * is a table name. - * - * @param object|string $result DB_result object from a query or a - * string containing the name of a table - * @param int $mode a valid tableInfo mode - * @return array an associative array with the information requested - * or an error object if something is wrong - * @access public - * @internal - * @see DB_common::tableInfo() - */ - function tableInfo($result, $mode = null) - { - if (isset($result->result)) { - /* - * Probably received a result object. - * Extract the result resource identifier. - */ - $id = $result->result; - $got_string = false; - } elseif (is_string($result)) { - /* - * Probably received a table name. - * Create a result resource identifier. - */ - if (!@mssql_select_db($this->_db, $this->connection)) { - return $this->mssqlRaiseError(DB_ERROR_NODBSELECTED); - } - $id = @mssql_query("SELECT * FROM $result WHERE 1=0", - $this->connection); - $got_string = true; - } else { - /* - * Probably received a result resource identifier. - * Copy it. - * Depricated. Here for compatibility only. - */ - $id = $result; - $got_string = false; - } - - if (!is_resource($id)) { - return $this->mssqlRaiseError(DB_ERROR_NEED_MORE_DATA); - } - - if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) { - $case_func = 'strtolower'; - } else { - $case_func = 'strval'; - } - - $count = @mssql_num_fields($id); - - // made this IF due to performance (one if is faster than $count if's) - if (!$mode) { - for ($i=0; $i<$count; $i++) { - $res[$i]['table'] = $got_string ? $case_func($result) : ''; - $res[$i]['name'] = $case_func(@mssql_field_name($id, $i)); - $res[$i]['type'] = @mssql_field_type($id, $i); - $res[$i]['len'] = @mssql_field_length($id, $i); - // We only support flags for tables - $res[$i]['flags'] = $got_string ? $this->_mssql_field_flags($result, $res[$i]['name']) : ''; - } - - } else { // full - $res['num_fields']= $count; - - for ($i=0; $i<$count; $i++) { - $res[$i]['table'] = $got_string ? $case_func($result) : ''; - $res[$i]['name'] = $case_func(@mssql_field_name($id, $i)); - $res[$i]['type'] = @mssql_field_type($id, $i); - $res[$i]['len'] = @mssql_field_length($id, $i); - // We only support flags for tables - $res[$i]['flags'] = $got_string ? $this->_mssql_field_flags($result, $res[$i]['name']) : ''; - - if ($mode & DB_TABLEINFO_ORDER) { - $res['order'][$res[$i]['name']] = $i; - } - if ($mode & DB_TABLEINFO_ORDERTABLE) { - $res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i; - } - } - } - - // free the result only if we were called on a table - if ($got_string) { - @mssql_free_result($id); - } - return $res; - } - - // }}} - // {{{ getSpecialQuery() - - /** - * Returns the query needed to get some backend info - * @param string $type What kind of info you want to retrieve - * @return string The SQL query string - */ - function getSpecialQuery($type) - { - switch ($type) { - case 'tables': - return "select name from sysobjects where type = 'U' order by name"; - case 'views': - return "select name from sysobjects where type = 'V'"; - default: - return null; - } - } - - // }}} - // {{{ _mssql_field_flags() - - /** - * Get the flags for a field, currently supports "not_null", "primary_key", - * "auto_increment" (mssql identity), "timestamp" (mssql timestamp), - * "unique_key" (mssql unique index, unique check or primary_key) and - * "multiple_key" (multikey index) - * - * mssql timestamp is NOT similar to the mysql timestamp so this is maybe - * not useful at all - is the behaviour of mysql_field_flags that primary - * keys are alway unique? is the interpretation of multiple_key correct? - * - * @param string The table name - * @param string The field - * @author Joern Barthel - * @access private - */ - function _mssql_field_flags($table, $column) - { - static $tableName = null; - static $flags = array(); - - if ($table != $tableName) { - - $flags = array(); - $tableName = $table; - - // get unique and primary keys - $res = $this->getAll("EXEC SP_HELPINDEX[$table]", DB_FETCHMODE_ASSOC); - - foreach ($res as $val) { - $keys = explode(', ', $val['index_keys']); - - if (sizeof($keys) > 1) { - foreach ($keys as $key) { - $this->_add_flag($flags[$key], 'multiple_key'); - } - } - - if (strpos($val['index_description'], 'primary key')) { - foreach ($keys as $key) { - $this->_add_flag($flags[$key], 'primary_key'); - } - } elseif (strpos($val['index_description'], 'unique')) { - foreach ($keys as $key) { - $this->_add_flag($flags[$key], 'unique_key'); - } - } - } - - // get auto_increment, not_null and timestamp - $res = $this->getAll("EXEC SP_COLUMNS[$table]", DB_FETCHMODE_ASSOC); - - foreach ($res as $val) { - $val = array_change_key_case($val, CASE_LOWER); - if ($val['nullable'] == '0') { - $this->_add_flag($flags[$val['column_name']], 'not_null'); - } - if (strpos($val['type_name'], 'identity')) { - $this->_add_flag($flags[$val['column_name']], 'auto_increment'); - } - if (strpos($val['type_name'], 'timestamp')) { - $this->_add_flag($flags[$val['column_name']], 'timestamp'); - } - } - } - - if (array_key_exists($column, $flags)) { - return(implode(' ', $flags[$column])); - } - return ''; - } - - // }}} - // {{{ _add_flag() - - /** - * Adds a string to the flags array if the flag is not yet in there - * - if there is no flag present the array is created. - * - * @param reference Reference to the flag-array - * @param value The flag value - * @access private - * @author Joern Barthel - */ - function _add_flag(&$array, $value) - { - if (!is_array($array)) { - $array = array($value); - } elseif (!in_array($value, $array)) { - array_push($array, $value); - } - } - - // }}} - // {{{ quoteIdentifier() - - /** - * Quote a string so it can be safely used as a table / column name - * - * Quoting style depends on which database driver is being used. - * - * @param string $str identifier name to be quoted - * - * @return string quoted identifier string - * - * @since 1.6.0 - * @access public - */ - function quoteIdentifier($str) - { - return '[' . str_replace(']', ']]', $str) . ']'; - } - - // }}} -} - -/* - * Local variables: - * tab-width: 4 - * c-basic-offset: 4 - * End: - */ - -?> diff --git a/glmPEAR/DB/mysql.php b/glmPEAR/DB/mysql.php deleted file mode 100755 index 6d42c63..0000000 --- a/glmPEAR/DB/mysql.php +++ /dev/null @@ -1,915 +0,0 @@ - | -// | Maintainer: Daniel Convissor | -// +----------------------------------------------------------------------+ -// -// $Id: mysql.php,v 1.1.1.1 2008/04/28 15:20:47 jamie Exp $ - - -// XXX legend: -// -// XXX ERRORMSG: The error message from the mysql function should -// be registered here. -// -// TODO/wishlist: -// longReadlen -// binmode - - -require_once 'DB/common.php'; - -/** - * Database independent query interface definition for PHP's MySQL - * extension. - * - * This is for MySQL versions 4.0 and below. - * - * @package DB - * @version $Id: mysql.php,v 1.1.1.1 2008/04/28 15:20:47 jamie Exp $ - * @category Database - * @author Stig Bakken - */ -class DB_mysql extends DB_common -{ - // {{{ properties - - var $connection; - var $phptype, $dbsyntax; - var $prepare_tokens = array(); - var $prepare_types = array(); - var $num_rows = array(); - var $transaction_opcount = 0; - var $autocommit = true; - var $fetchmode = DB_FETCHMODE_ORDERED; /* Default fetch mode */ - var $_db = false; - - // }}} - // {{{ constructor - - /** - * DB_mysql constructor. - * - * @access public - */ - function DB_mysql() - { - $this->DB_common(); - $this->phptype = 'mysql'; - $this->dbsyntax = 'mysql'; - $this->features = array( - 'prepare' => false, - 'pconnect' => true, - 'transactions' => true, - 'limit' => 'alter' - ); - $this->errorcode_map = array( - 1004 => DB_ERROR_CANNOT_CREATE, - 1005 => DB_ERROR_CANNOT_CREATE, - 1006 => DB_ERROR_CANNOT_CREATE, - 1007 => DB_ERROR_ALREADY_EXISTS, - 1008 => DB_ERROR_CANNOT_DROP, - 1022 => DB_ERROR_ALREADY_EXISTS, - 1046 => DB_ERROR_NODBSELECTED, - 1050 => DB_ERROR_ALREADY_EXISTS, - 1051 => DB_ERROR_NOSUCHTABLE, - 1054 => DB_ERROR_NOSUCHFIELD, - 1062 => DB_ERROR_ALREADY_EXISTS, - 1064 => DB_ERROR_SYNTAX, - 1100 => DB_ERROR_NOT_LOCKED, - 1136 => DB_ERROR_VALUE_COUNT_ON_ROW, - 1146 => DB_ERROR_NOSUCHTABLE, - 1048 => DB_ERROR_CONSTRAINT, - 1216 => DB_ERROR_CONSTRAINT - ); - } - - // }}} - // {{{ connect() - - /** - * Connect to a database and log in as the specified user. - * - * @param $dsn the data source name (see DB::parseDSN for syntax) - * @param $persistent (optional) whether the connection should - * be persistent - * @access public - * @return int DB_OK on success, a DB error on failure - */ - function connect($dsninfo, $persistent = false) - { - if (!DB::assertExtension('mysql')) { - return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND); - } - $this->dsn = $dsninfo; - if ($dsninfo['protocol'] && $dsninfo['protocol'] == 'unix') { - $dbhost = ':' . $dsninfo['socket']; - } else { - $dbhost = $dsninfo['hostspec'] ? $dsninfo['hostspec'] : 'localhost'; - if ($dsninfo['port']) { - $dbhost .= ':' . $dsninfo['port']; - } - } - - $connect_function = $persistent ? 'mysql_pconnect' : 'mysql_connect'; - - if ($dbhost && $dsninfo['username'] && isset($dsninfo['password'])) { - $conn = @$connect_function($dbhost, $dsninfo['username'], - $dsninfo['password']); - } elseif ($dbhost && $dsninfo['username']) { - $conn = @$connect_function($dbhost, $dsninfo['username']); - } elseif ($dbhost) { - $conn = @$connect_function($dbhost); - } else { - $conn = false; - } - if (!$conn) { - if (($err = @mysql_error()) != '') { - return $this->raiseError(DB_ERROR_CONNECT_FAILED, null, null, - null, $err); - } elseif (empty($php_errormsg)) { - return $this->raiseError(DB_ERROR_CONNECT_FAILED); - } else { - return $this->raiseError(DB_ERROR_CONNECT_FAILED, null, null, - null, $php_errormsg); - } - } - - if ($dsninfo['database']) { - if (!@mysql_select_db($dsninfo['database'], $conn)) { - switch(mysql_errno($conn)) { - case 1049: - return $this->raiseError(DB_ERROR_NOSUCHDB, null, null, - null, @mysql_error($conn)); - case 1044: - return $this->raiseError(DB_ERROR_ACCESS_VIOLATION, null, null, - null, @mysql_error($conn)); - default: - return $this->raiseError(DB_ERROR, null, null, - null, @mysql_error($conn)); - } - } - // fix to allow calls to different databases in the same script - $this->_db = $dsninfo['database']; - } - - $this->connection = $conn; - return DB_OK; - } - - // }}} - // {{{ disconnect() - - /** - * Log out and disconnect from the database. - * - * @access public - * - * @return bool true on success, false if not connected. - */ - function disconnect() - { - $ret = @mysql_close($this->connection); - $this->connection = null; - return $ret; - } - - // }}} - // {{{ simpleQuery() - - /** - * Send a query to MySQL and return the results as a MySQL resource - * identifier. - * - * @param the SQL query - * - * @access public - * - * @return mixed returns a valid MySQL result for successful SELECT - * queries, DB_OK for other successful queries. A DB error is - * returned on failure. - */ - function simpleQuery($query) - { - $ismanip = DB::isManip($query); - $this->last_query = $query; - $query = $this->modifyQuery($query); - if ($this->_db) { - if (!@mysql_select_db($this->_db, $this->connection)) { - return $this->mysqlRaiseError(DB_ERROR_NODBSELECTED); - } - } - if (!$this->autocommit && $ismanip) { - if ($this->transaction_opcount == 0) { - $result = @mysql_query('SET AUTOCOMMIT=0', $this->connection); - $result = @mysql_query('BEGIN', $this->connection); - if (!$result) { - return $this->mysqlRaiseError(); - } - } - $this->transaction_opcount++; - } - $result = @mysql_query($query, $this->connection); - if (!$result) { - return $this->mysqlRaiseError(); - } - if (is_resource($result)) { - $numrows = $this->numrows($result); - if (is_object($numrows)) { - return $numrows; - } - $this->num_rows[(int)$result] = $numrows; - return $result; - } - return DB_OK; - } - - // }}} - // {{{ nextResult() - - /** - * Move the internal mysql result pointer to the next available result - * - * This method has not been implemented yet. - * - * @param a valid sql result resource - * - * @access public - * - * @return false - */ - function nextResult($result) - { - return false; - } - - // }}} - // {{{ fetchInto() - - /** - * Fetch a row and insert the data into an existing array. - * - * Formating of the array and the data therein are configurable. - * See DB_result::fetchInto() for more information. - * - * @param resource $result query result identifier - * @param array $arr (reference) array where data from the row - * should be placed - * @param int $fetchmode how the resulting array should be indexed - * @param int $rownum the row number to fetch - * - * @return mixed DB_OK on success, null when end of result set is - * reached or on failure - * - * @see DB_result::fetchInto() - * @access private - */ - function fetchInto($result, &$arr, $fetchmode, $rownum=null) - { - if ($rownum !== null) { - if (!@mysql_data_seek($result, $rownum)) { - return null; - } - } - if ($fetchmode & DB_FETCHMODE_ASSOC) { - $arr = @mysql_fetch_array($result, MYSQL_ASSOC); - if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) { - $arr = array_change_key_case($arr, CASE_LOWER); - } - } else { - $arr = @mysql_fetch_row($result); - } - if (!$arr) { - // See: http://bugs.php.net/bug.php?id=22328 - // for why we can't check errors on fetching - return null; - /* - $errno = @mysql_errno($this->connection); - if (!$errno) { - return null; - } - return $this->mysqlRaiseError($errno); - */ - } - if ($this->options['portability'] & DB_PORTABILITY_RTRIM) { - /* - * Even though this DBMS already trims output, we do this because - * a field might have intentional whitespace at the end that - * gets removed by DB_PORTABILITY_RTRIM under another driver. - */ - $this->_rtrimArrayValues($arr); - } - if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) { - $this->_convertNullArrayValuesToEmpty($arr); - } - return DB_OK; - } - - // }}} - // {{{ freeResult() - - /** - * Free the internal resources associated with $result. - * - * @param $result MySQL result identifier - * - * @access public - * - * @return bool true on success, false if $result is invalid - */ - function freeResult($result) - { - unset($this->num_rows[(int)$result]); - return @mysql_free_result($result); - } - - // }}} - // {{{ numCols() - - /** - * Get the number of columns in a result set. - * - * @param $result MySQL result identifier - * - * @access public - * - * @return int the number of columns per row in $result - */ - function numCols($result) - { - $cols = @mysql_num_fields($result); - - if (!$cols) { - return $this->mysqlRaiseError(); - } - - return $cols; - } - - // }}} - // {{{ numRows() - - /** - * Get the number of rows in a result set. - * - * @param $result MySQL result identifier - * - * @access public - * - * @return int the number of rows in $result - */ - function numRows($result) - { - $rows = @mysql_num_rows($result); - if ($rows === null) { - return $this->mysqlRaiseError(); - } - return $rows; - } - - // }}} - // {{{ autoCommit() - - /** - * Enable/disable automatic commits - */ - function autoCommit($onoff = false) - { - // XXX if $this->transaction_opcount > 0, we should probably - // issue a warning here. - $this->autocommit = $onoff ? true : false; - return DB_OK; - } - - // }}} - // {{{ commit() - - /** - * Commit the current transaction. - */ - function commit() - { - if ($this->transaction_opcount > 0) { - if ($this->_db) { - if (!@mysql_select_db($this->_db, $this->connection)) { - return $this->mysqlRaiseError(DB_ERROR_NODBSELECTED); - } - } - $result = @mysql_query('COMMIT', $this->connection); - $result = @mysql_query('SET AUTOCOMMIT=1', $this->connection); - $this->transaction_opcount = 0; - if (!$result) { - return $this->mysqlRaiseError(); - } - } - return DB_OK; - } - - // }}} - // {{{ rollback() - - /** - * Roll back (undo) the current transaction. - */ - function rollback() - { - if ($this->transaction_opcount > 0) { - if ($this->_db) { - if (!@mysql_select_db($this->_db, $this->connection)) { - return $this->mysqlRaiseError(DB_ERROR_NODBSELECTED); - } - } - $result = @mysql_query('ROLLBACK', $this->connection); - $result = @mysql_query('SET AUTOCOMMIT=1', $this->connection); - $this->transaction_opcount = 0; - if (!$result) { - return $this->mysqlRaiseError(); - } - } - return DB_OK; - } - - // }}} - // {{{ affectedRows() - - /** - * Gets the number of rows affected by the data manipulation - * query. For other queries, this function returns 0. - * - * @return number of rows affected by the last query - */ - function affectedRows() - { - if (DB::isManip($this->last_query)) { - return @mysql_affected_rows($this->connection); - } else { - return 0; - } - } - - // }}} - // {{{ errorNative() - - /** - * Get the native error code of the last error (if any) that - * occured on the current connection. - * - * @access public - * - * @return int native MySQL error code - */ - function errorNative() - { - return @mysql_errno($this->connection); - } - - // }}} - // {{{ nextId() - - /** - * Returns the next free id in a sequence - * - * @param string $seq_name name of the sequence - * @param boolean $ondemand when true, the seqence is automatically - * created if it does not exist - * - * @return int the next id number in the sequence. DB_Error if problem. - * - * @internal - * @see DB_common::nextID() - * @access public - */ - function nextId($seq_name, $ondemand = true) - { - $seqname = $this->getSequenceName($seq_name); - do { - $repeat = 0; - $this->pushErrorHandling(PEAR_ERROR_RETURN); - $result = $this->query("UPDATE ${seqname} ". - 'SET id=LAST_INSERT_ID(id+1)'); - $this->popErrorHandling(); - if ($result === DB_OK) { - /** COMMON CASE **/ - $id = @mysql_insert_id($this->connection); - if ($id != 0) { - return $id; - } - /** EMPTY SEQ TABLE **/ - // Sequence table must be empty for some reason, so fill it and return 1 - // Obtain a user-level lock - $result = $this->getOne("SELECT GET_LOCK('${seqname}_lock',10)"); - if (DB::isError($result)) { - return $this->raiseError($result); - } - if ($result == 0) { - // Failed to get the lock, bail with a DB_ERROR_NOT_LOCKED error - return $this->mysqlRaiseError(DB_ERROR_NOT_LOCKED); - } - - // add the default value - $result = $this->query("REPLACE INTO ${seqname} VALUES (0)"); - if (DB::isError($result)) { - return $this->raiseError($result); - } - - // Release the lock - $result = $this->getOne("SELECT RELEASE_LOCK('${seqname}_lock')"); - if (DB::isError($result)) { - return $this->raiseError($result); - } - // We know what the result will be, so no need to try again - return 1; - - /** ONDEMAND TABLE CREATION **/ - } elseif ($ondemand && DB::isError($result) && - $result->getCode() == DB_ERROR_NOSUCHTABLE) - { - $result = $this->createSequence($seq_name); - if (DB::isError($result)) { - return $this->raiseError($result); - } else { - $repeat = 1; - } - - /** BACKWARDS COMPAT **/ - } elseif (DB::isError($result) && - $result->getCode() == DB_ERROR_ALREADY_EXISTS) - { - // see _BCsequence() comment - $result = $this->_BCsequence($seqname); - if (DB::isError($result)) { - return $this->raiseError($result); - } - $repeat = 1; - } - } while ($repeat); - - return $this->raiseError($result); - } - - // }}} - // {{{ createSequence() - - /** - * Creates a new sequence - * - * @param string $seq_name name of the new sequence - * - * @return int DB_OK on success. A DB_Error object is returned if - * problems arise. - * - * @internal - * @see DB_common::createSequence() - * @access public - */ - function createSequence($seq_name) - { - $seqname = $this->getSequenceName($seq_name); - $res = $this->query("CREATE TABLE ${seqname} ". - '(id INTEGER UNSIGNED AUTO_INCREMENT NOT NULL,'. - ' PRIMARY KEY(id))'); - if (DB::isError($res)) { - return $res; - } - // insert yields value 1, nextId call will generate ID 2 - $res = $this->query("INSERT INTO ${seqname} VALUES(0)"); - if (DB::isError($res)) { - return $res; - } - // so reset to zero - return $this->query("UPDATE ${seqname} SET id = 0;"); - } - - // }}} - // {{{ dropSequence() - - /** - * Deletes a sequence - * - * @param string $seq_name name of the sequence to be deleted - * - * @return int DB_OK on success. DB_Error if problems. - * - * @internal - * @see DB_common::dropSequence() - * @access public - */ - function dropSequence($seq_name) - { - return $this->query('DROP TABLE ' . $this->getSequenceName($seq_name)); - } - - // }}} - // {{{ _BCsequence() - - /** - * Backwards compatibility with old sequence emulation implementation - * (clean up the dupes) - * - * @param string $seqname The sequence name to clean up - * @return mixed DB_Error or true - */ - function _BCsequence($seqname) - { - // Obtain a user-level lock... this will release any previous - // application locks, but unlike LOCK TABLES, it does not abort - // the current transaction and is much less frequently used. - $result = $this->getOne("SELECT GET_LOCK('${seqname}_lock',10)"); - if (DB::isError($result)) { - return $result; - } - if ($result == 0) { - // Failed to get the lock, can't do the conversion, bail - // with a DB_ERROR_NOT_LOCKED error - return $this->mysqlRaiseError(DB_ERROR_NOT_LOCKED); - } - - $highest_id = $this->getOne("SELECT MAX(id) FROM ${seqname}"); - if (DB::isError($highest_id)) { - return $highest_id; - } - // This should kill all rows except the highest - // We should probably do something if $highest_id isn't - // numeric, but I'm at a loss as how to handle that... - $result = $this->query("DELETE FROM ${seqname} WHERE id <> $highest_id"); - if (DB::isError($result)) { - return $result; - } - - // If another thread has been waiting for this lock, - // it will go thru the above procedure, but will have no - // real effect - $result = $this->getOne("SELECT RELEASE_LOCK('${seqname}_lock')"); - if (DB::isError($result)) { - return $result; - } - return true; - } - - // }}} - // {{{ quoteIdentifier() - - /** - * Quote a string so it can be safely used as a table or column name - * - * Quoting style depends on which database driver is being used. - * - * MySQL can't handle the backtick character (`) in - * table or column names. - * - * @param string $str identifier name to be quoted - * - * @return string quoted identifier string - * - * @since 1.6.0 - * @access public - * @internal - */ - function quoteIdentifier($str) - { - return '`' . $str . '`'; - } - - // }}} - // {{{ quote() - - /** - * @deprecated Deprecated in release 1.6.0 - * @internal - */ - function quote($str) { - return $this->quoteSmart($str); - } - - // }}} - // {{{ escapeSimple() - - /** - * Escape a string according to the current DBMS's standards - * - * @param string $str the string to be escaped - * - * @return string the escaped string - * - * @internal - */ - function escapeSimple($str) { - if (function_exists('mysql_real_escape_string')) { - return @mysql_real_escape_string($str, $this->connection); - } else { - return @mysql_escape_string($str); - } - } - - // }}} - // {{{ modifyQuery() - - function modifyQuery($query) - { - if ($this->options['portability'] & DB_PORTABILITY_DELETE_COUNT) { - // "DELETE FROM table" gives 0 affected rows in MySQL. - // This little hack lets you know how many rows were deleted. - if (preg_match('/^\s*DELETE\s+FROM\s+(\S+)\s*$/i', $query)) { - $query = preg_replace('/^\s*DELETE\s+FROM\s+(\S+)\s*$/', - 'DELETE FROM \1 WHERE 1=1', $query); - } - } - return $query; - } - - // }}} - // {{{ modifyLimitQuery() - - function modifyLimitQuery($query, $from, $count, $params = array()) - { - if (DB::isManip($query)) { - return $query . " LIMIT $count"; - } else { - return $query . " LIMIT $from, $count"; - } - } - - // }}} - // {{{ mysqlRaiseError() - - /** - * Gather information about an error, then use that info to create a - * DB error object and finally return that object. - * - * @param integer $errno PEAR error number (usually a DB constant) if - * manually raising an error - * @return object DB error object - * @see DB_common::errorCode() - * @see DB_common::raiseError() - */ - function mysqlRaiseError($errno = null) - { - if ($errno === null) { - if ($this->options['portability'] & DB_PORTABILITY_ERRORS) { - $this->errorcode_map[1022] = DB_ERROR_CONSTRAINT; - $this->errorcode_map[1048] = DB_ERROR_CONSTRAINT_NOT_NULL; - $this->errorcode_map[1062] = DB_ERROR_CONSTRAINT; - } else { - // Doing this in case mode changes during runtime. - $this->errorcode_map[1022] = DB_ERROR_ALREADY_EXISTS; - $this->errorcode_map[1048] = DB_ERROR_CONSTRAINT; - $this->errorcode_map[1062] = DB_ERROR_ALREADY_EXISTS; - } - $errno = $this->errorCode(mysql_errno($this->connection)); - } - return $this->raiseError($errno, null, null, null, - @mysql_errno($this->connection) . ' ** ' . - @mysql_error($this->connection)); - } - - // }}} - // {{{ tableInfo() - - /** - * Returns information about a table or a result set. - * - * @param object|string $result DB_result object from a query or a - * string containing the name of a table - * @param int $mode a valid tableInfo mode - * @return array an associative array with the information requested - * or an error object if something is wrong - * @access public - * @internal - * @see DB_common::tableInfo() - */ - function tableInfo($result, $mode = null) { - if (isset($result->result)) { - /* - * Probably received a result object. - * Extract the result resource identifier. - */ - $id = $result->result; - $got_string = false; - } elseif (is_string($result)) { - /* - * Probably received a table name. - * Create a result resource identifier. - */ - $id = @mysql_list_fields($this->dsn['database'], - $result, $this->connection); - $got_string = true; - } else { - /* - * Probably received a result resource identifier. - * Copy it. - * Deprecated. Here for compatibility only. - */ - $id = $result; - $got_string = false; - } - - if (!is_resource($id)) { - return $this->mysqlRaiseError(DB_ERROR_NEED_MORE_DATA); - } - - if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) { - $case_func = 'strtolower'; - } else { - $case_func = 'strval'; - } - - $count = @mysql_num_fields($id); - - // made this IF due to performance (one if is faster than $count if's) - if (!$mode) { - for ($i=0; $i<$count; $i++) { - $res[$i]['table'] = $case_func(@mysql_field_table($id, $i)); - $res[$i]['name'] = $case_func(@mysql_field_name($id, $i)); - $res[$i]['type'] = @mysql_field_type($id, $i); - $res[$i]['len'] = @mysql_field_len($id, $i); - $res[$i]['flags'] = @mysql_field_flags($id, $i); - } - } else { // full - $res['num_fields']= $count; - - for ($i=0; $i<$count; $i++) { - $res[$i]['table'] = $case_func(@mysql_field_table($id, $i)); - $res[$i]['name'] = $case_func(@mysql_field_name($id, $i)); - $res[$i]['type'] = @mysql_field_type($id, $i); - $res[$i]['len'] = @mysql_field_len($id, $i); - $res[$i]['flags'] = @mysql_field_flags($id, $i); - - if ($mode & DB_TABLEINFO_ORDER) { - $res['order'][$res[$i]['name']] = $i; - } - if ($mode & DB_TABLEINFO_ORDERTABLE) { - $res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i; - } - } - } - - // free the result only if we were called on a table - if ($got_string) { - @mysql_free_result($id); - } - return $res; - } - - // }}} - // {{{ getSpecialQuery() - - /** - * Returns the query needed to get some backend info - * @param string $type What kind of info you want to retrieve - * @return string The SQL query string - */ - function getSpecialQuery($type) - { - switch ($type) { - case 'tables': - return 'SHOW TABLES'; - case 'views': - return DB_ERROR_NOT_CAPABLE; - case 'users': - $sql = 'select distinct User from user'; - if ($this->dsn['database'] != 'mysql') { - $dsn = $this->dsn; - $dsn['database'] = 'mysql'; - if (DB::isError($db = DB::connect($dsn))) { - return $db; - } - $sql = $db->getCol($sql); - $db->disconnect(); - // XXX Fixme the mysql driver should take care of this - if (!@mysql_select_db($this->dsn['database'], $this->connection)) { - return $this->mysqlRaiseError(DB_ERROR_NODBSELECTED); - } - } - return $sql; - case 'databases': - return 'SHOW DATABASES'; - default: - return null; - } - } - - // }}} - -} - -/* - * Local variables: - * tab-width: 4 - * c-basic-offset: 4 - * End: - */ - -?> diff --git a/glmPEAR/DB/mysqli.php b/glmPEAR/DB/mysqli.php deleted file mode 100755 index 4d13dbb..0000000 --- a/glmPEAR/DB/mysqli.php +++ /dev/null @@ -1,935 +0,0 @@ - | -// | Based on mysql.php by Stig Bakken | -// | Maintainer: Daniel Convissor | -// +----------------------------------------------------------------------+ -// -// $Id: mysqli.php,v 1.1.1.1 2008/04/28 15:20:47 jamie Exp $ - - -// EXPERIMENTAL - - -require_once 'DB/common.php'; - -/** - * Database independent query interface definition for PHP's mysqli - * extension. - * - * This is for MySQL versions 4.1 and above. Requires PHP 5. - * - * Note that persistent connections no longer exist. - * - * @package DB - * @version $Id: mysqli.php,v 1.1.1.1 2008/04/28 15:20:47 jamie Exp $ - * @category Database - * @author Chaillan Nicolas - */ -class DB_mysqli extends DB_common -{ - // {{{ properties - - var $connection; - var $phptype, $dbsyntax; - var $prepare_tokens = array(); - var $prepare_types = array(); - var $num_rows = array(); - var $transaction_opcount = 0; - var $autocommit = true; - var $fetchmode = DB_FETCHMODE_ORDERED; /* Default fetch mode */ - var $_db = false; - - // }}} - // {{{ constructor - - /** - * DB_mysql constructor. - * - * @access public - */ - function DB_mysqli() - { - $this->DB_common(); - $this->phptype = 'mysqli'; - $this->dbsyntax = 'mysqli'; - $this->features = array( - 'prepare' => false, - 'ssl' => true, - 'transactions' => true, - 'limit' => 'alter' - ); - $this->errorcode_map = array( - 1004 => DB_ERROR_CANNOT_CREATE, - 1005 => DB_ERROR_CANNOT_CREATE, - 1006 => DB_ERROR_CANNOT_CREATE, - 1007 => DB_ERROR_ALREADY_EXISTS, - 1008 => DB_ERROR_CANNOT_DROP, - 1022 => DB_ERROR_ALREADY_EXISTS, - 1046 => DB_ERROR_NODBSELECTED, - 1050 => DB_ERROR_ALREADY_EXISTS, - 1051 => DB_ERROR_NOSUCHTABLE, - 1054 => DB_ERROR_NOSUCHFIELD, - 1062 => DB_ERROR_ALREADY_EXISTS, - 1064 => DB_ERROR_SYNTAX, - 1100 => DB_ERROR_NOT_LOCKED, - 1136 => DB_ERROR_VALUE_COUNT_ON_ROW, - 1146 => DB_ERROR_NOSUCHTABLE, - 1048 => DB_ERROR_CONSTRAINT, - 1216 => DB_ERROR_CONSTRAINT, - ); - } - - // }}} - // {{{ connect() - - /** - * Connect to a database and log in as the specified user. - * - * @param string $dsn the data source name (see DB::parseDSN for syntax) - * @param boolean $persistent (optional) whether the connection should - * be persistent - * @return mixed DB_OK on success, a DB error on failure - * @access public - */ - function connect($dsninfo, $persistent = false) - { - if (!DB::assertExtension('mysqli')) { - return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND); - } - - $this->dsn = $dsninfo; - if ($dsninfo['protocol'] && $dsninfo['protocol'] == 'unix') { - $dbhost = ':' . $dsninfo['socket']; - } else { - $dbhost = $dsninfo['hostspec'] ? $dsninfo['hostspec'] : 'localhost'; - if ($dsninfo['port']) { - $dbhost .= ':' . $dsninfo['port']; - } - } - - $ssl_mode = $this->getOption('ssl') === true ? 'CLIENT_SSL' : NULL; - - @ini_set('track_errors', true); - - if ($dbhost && $dsninfo['username'] && $dsninfo['password']) { - // Need to verify if arguments are okay - $conn = @mysqli_connect($dbhost, $dsninfo['username'], - $dsninfo['password'], $ssl_mode); - } elseif ($dbhost && isset($dsninfo['username'])) { - $conn = @mysqli_connect($dbhost, $dsninfo['username'], null, - $ssl_mode); - } elseif ($dbhost) { - $conn = @mysqli_connect($dbhost, null, null, $ssl_mode); - } else { - $conn = false; - } - - @ini_restore('track_errors'); - - if (!$conn) { - if (($err = @mysqli_error()) != '') { - return $this->raiseError(DB_ERROR_CONNECT_FAILED, null, null, - null, $err); - } elseif (empty($php_errormsg)) { - return $this->raiseError(DB_ERROR_CONNECT_FAILED); - } else { - return $this->raiseError(DB_ERROR_CONNECT_FAILED, null, null, - null, $php_errormsg); - } - } - - if ($dsninfo['database']) { - if (!@mysqli_select_db($conn, $dsninfo['database'])) { - switch(mysqli_errno($conn)) { - case 1049: - return $this->raiseError(DB_ERROR_NOSUCHDB, null, null, - null, @mysqli_error($conn)); - case 1044: - return $this->raiseError(DB_ERROR_ACCESS_VIOLATION, null, null, - null, @mysqli_error($conn)); - default: - return $this->raiseError(DB_ERROR, null, null, - null, @mysqli_error($conn)); - } - } - // fix to allow calls to different databases in the same script - $this->_db = $dsninfo['database']; - } - - $this->connection = $conn; - return DB_OK; - } - - // }}} - // {{{ disconnect() - - /** - * Log out and disconnect from the database. - * - * @return boolean true on success, false if not connected - * @access public - */ - function disconnect() - { - $ret = @mysqli_close($this->connection); - $this->connection = null; - return $ret; - } - - // }}} - // {{{ simpleQuery() - - /** - * Send a query to MySQL and return the results as a MySQL resource - * identifier. - * - * @param string $query the SQL query - * @return mixed a valid MySQL result for successful SELECT - * queries, DB_OK for other successful queries. - * A DB error is returned on failure. - * @access public - */ - function simpleQuery($query) - { - $ismanip = DB::isManip($query); - $this->last_query = $query; - $query = $this->modifyQuery($query); - if ($this->_db) { - if (!@mysqli_select_db($this->connection, $this->_db)) { - return $this->mysqlRaiseError(DB_ERROR_NODBSELECTED); - } - } - if (!$this->autocommit && $ismanip) { - if ($this->transaction_opcount == 0) { - $result = @mysqli_query($this->connection, 'SET AUTOCOMMIT=0'); - $result = @mysqli_query($this->connection, 'BEGIN'); - if (!$result) { - return $this->mysqlRaiseError(); - } - } - $this->transaction_opcount++; - } - $result = @mysqli_query($this->connection, $query); - if (!$result) { - return $this->mysqlRaiseError(); - } -# this next block is still sketchy.. - if (is_object($result)) { - $numrows = $this->numrows($result); - if (is_object($numrows)) { - return $numrows; - } -# need to come up with different means for next line -# since $result is object (int)$result won't fly... - $this->num_rows[(int)$result] = $numrows; - return $result; - } - return DB_OK; - } - - // }}} - // {{{ nextResult() - - /** - * Move the internal mysql result pointer to the next available result. - * - * This method has not been implemented yet. - * - * @param resource $result a valid sql result resource - * @return false - * @access public - */ - function nextResult($result) - { - return false; - } - - // }}} - // {{{ fetchInto() - - /** - * Fetch a row and insert the data into an existing array. - * - * Formating of the array and the data therein are configurable. - * See DB_result::fetchInto() for more information. - * - * @param resource $result query result identifier - * @param array $arr (reference) array where data from the row - * should be placed - * @param int $fetchmode how the resulting array should be indexed - * @param int $rownum the row number to fetch - * - * @return mixed DB_OK on success, null when end of result set is - * reached or on failure - * - * @see DB_result::fetchInto() - * @access private - */ - function fetchInto($result, &$arr, $fetchmode, $rownum=null) - { - if ($rownum !== null) { - if (!@mysqli_data_seek($result, $rownum)) { - return null; - } - } - if ($fetchmode & DB_FETCHMODE_ASSOC) { - $arr = @mysqli_fetch_array($result, MYSQLI_ASSOC); - if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) { - $arr = array_change_key_case($arr, CASE_LOWER); - } - } else { - $arr = @mysqli_fetch_row($result); - } - if (!$arr) { - $errno = @mysqli_errno($this->connection); - if (!$errno) { - return null; - } - return $this->mysqlRaiseError($errno); - } - if ($this->options['portability'] & DB_PORTABILITY_RTRIM) { - /* - * Even though this DBMS already trims output, we do this because - * a field might have intentional whitespace at the end that - * gets removed by DB_PORTABILITY_RTRIM under another driver. - */ - $this->_rtrimArrayValues($arr); - } - if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) { - $this->_convertNullArrayValuesToEmpty($arr); - } - return DB_OK; - } - - // }}} - // {{{ freeResult() - - /** - * Free the internal resources associated with $result. - * - * @param resource $result MySQL result identifier - * @return bool true on success, false if $result is invalid - * @access public - */ - function freeResult($result) - { -# need to come up with different means for next line -# since $result is object (int)$result won't fly... - unset($this->num_rows[(int)$result]); - return @mysqli_free_result($result); - } - - // }}} - // {{{ numCols() - - /** - * Get the number of columns in a result set. - * - * @param $result MySQL result identifier - * - * @access public - * - * @return int the number of columns per row in $result - */ - function numCols($result) - { - $cols = @mysqli_num_fields($result); - - if (!$cols) { - return $this->mysqlRaiseError(); - } - - return $cols; - } - - // }}} - // {{{ numRows() - - /** - * Get the number of rows in a result set. - * - * @param resource $result MySQL result identifier - * @return int the number of rows in $result - * @access public - */ - function numRows($result) - { - $rows = @mysqli_num_rows($result); - if ($rows === null) { - return $this->mysqlRaiseError(); - } - return $rows; - } - - // }}} - // {{{ autoCommit() - - /** - * Enable/disable automatic commits. - */ - function autoCommit($onoff = false) - { - // XXX if $this->transaction_opcount > 0, we should probably - // issue a warning here. - $this->autocommit = $onoff ? true : false; - return DB_OK; - } - - // }}} - // {{{ commit() - - /** - * Commit the current transaction. - */ - function commit() - { - if ($this->transaction_opcount > 0) { - if ($this->_db) { - if (!@mysqli_select_db($this->_db, $this->connection)) { - return $this->mysqlRaiseError(DB_ERROR_NODBSELECTED); - } - } - $result = @mysqli_query('COMMIT', $this->connection); - $result = @mysqli_query('SET AUTOCOMMIT=1', $this->connection); - $this->transaction_opcount = 0; - if (!$result) { - return $this->mysqlRaiseError(); - } - } - return DB_OK; - } - - // }}} - // {{{ rollback() - - /** - * Roll back (undo) the current transaction. - */ - function rollback() - { - if ($this->transaction_opcount > 0) { - if ($this->_db) { - if (!@mysqli_select_db($this->_db, $this->connection)) { - return $this->mysqlRaiseError(DB_ERROR_NODBSELECTED); - } - } - $result = @mysqli_query('ROLLBACK', $this->connection); - $result = @mysqli_query('SET AUTOCOMMIT=1', $this->connection); - $this->transaction_opcount = 0; - if (!$result) { - return $this->mysqlRaiseError(); - } - } - return DB_OK; - } - - // }}} - // {{{ affectedRows() - - /** - * Gets the number of rows affected by the data manipulation - * query. For other queries, this function returns 0. - * - * @return integer number of rows affected by the last query - */ - function affectedRows() - { - if (DB::isManip($this->last_query)) { - return @mysqli_affected_rows($this->connection); - } else { - return 0; - } - } - - // }}} - // {{{ errorNative() - - /** - * Get the native error code of the last error (if any) that - * occured on the current connection. - * - * @return int native MySQL error code - * @access public - */ - function errorNative() - { - return @mysqli_errno($this->connection); - } - - // }}} - // {{{ nextId() - - /** - * Returns the next free id in a sequence - * - * @param string $seq_name name of the sequence - * @param boolean $ondemand when true, the seqence is automatically - * created if it does not exist - * - * @return int the next id number in the sequence. DB_Error if problem. - * - * @internal - * @see DB_common::nextID() - * @access public - */ - function nextId($seq_name, $ondemand = true) - { - $seqname = $this->getSequenceName($seq_name); - do { - $repeat = 0; - $this->pushErrorHandling(PEAR_ERROR_RETURN); - $result = $this->query("UPDATE ${seqname} ". - 'SET id=LAST_INSERT_ID(id+1)'); - $this->popErrorHandling(); - if ($result === DB_OK) { - /** COMMON CASE **/ - $id = @mysqli_insert_id($this->connection); - if ($id != 0) { - return $id; - } - /** EMPTY SEQ TABLE **/ - // Sequence table must be empty for some reason, so fill it and return 1 - // Obtain a user-level lock - $result = $this->getOne("SELECT GET_LOCK('${seqname}_lock',10)"); - if (DB::isError($result)) { - return $this->raiseError($result); - } - if ($result == 0) { - // Failed to get the lock, bail with a DB_ERROR_NOT_LOCKED error - return $this->mysqlRaiseError(DB_ERROR_NOT_LOCKED); - } - - // add the default value - $result = $this->query("REPLACE INTO ${seqname} VALUES (0)"); - if (DB::isError($result)) { - return $this->raiseError($result); - } - - // Release the lock - $result = $this->getOne("SELECT RELEASE_LOCK('${seqname}_lock')"); - if (DB::isError($result)) { - return $this->raiseError($result); - } - // We know what the result will be, so no need to try again - return 1; - - /** ONDEMAND TABLE CREATION **/ - } elseif ($ondemand && DB::isError($result) && - $result->getCode() == DB_ERROR_NOSUCHTABLE) - { - $result = $this->createSequence($seq_name); - // Since createSequence initializes the ID to be 1, - // we do not need to retrieve the ID again (or we will get 2) - if (DB::isError($result)) { - return $this->raiseError($result); - } else { - // First ID of a newly created sequence is 1 - return 1; - } - - /** BACKWARDS COMPAT **/ - } elseif (DB::isError($result) && - $result->getCode() == DB_ERROR_ALREADY_EXISTS) - { - // see _BCsequence() comment - $result = $this->_BCsequence($seqname); - if (DB::isError($result)) { - return $this->raiseError($result); - } - $repeat = 1; - } - } while ($repeat); - - return $this->raiseError($result); - } - - /** - * Creates a new sequence - * - * @param string $seq_name name of the new sequence - * - * @return int DB_OK on success. A DB_Error object is returned if - * problems arise. - * - * @internal - * @see DB_common::createSequence() - * @access public - */ - function createSequence($seq_name) - { - $seqname = $this->getSequenceName($seq_name); - $res = $this->query("CREATE TABLE ${seqname} ". - '(id INTEGER UNSIGNED AUTO_INCREMENT NOT NULL,'. - ' PRIMARY KEY(id))'); - if (DB::isError($res)) { - return $res; - } - // insert yields value 1, nextId call will generate ID 2 - return $this->query("INSERT INTO ${seqname} VALUES(0)"); - } - - // }}} - // {{{ dropSequence() - - /** - * Deletes a sequence - * - * @param string $seq_name name of the sequence to be deleted - * - * @return int DB_OK on success. DB_Error if problems. - * - * @internal - * @see DB_common::dropSequence() - * @access public - */ - function dropSequence($seq_name) - { - return $this->query('DROP TABLE ' . $this->getSequenceName($seq_name)); - } - - // }}} - // {{{ _BCsequence() - - /** - * Backwards compatibility with old sequence emulation implementation - * (clean up the dupes). - * - * @param string $seqname The sequence name to clean up - * @return mixed DB_Error or true - */ - function _BCsequence($seqname) - { - // Obtain a user-level lock... this will release any previous - // application locks, but unlike LOCK TABLES, it does not abort - // the current transaction and is much less frequently used. - $result = $this->getOne("SELECT GET_LOCK('${seqname}_lock',10)"); - if (DB::isError($result)) { - return $result; - } - if ($result == 0) { - // Failed to get the lock, can't do the conversion, bail - // with a DB_ERROR_NOT_LOCKED error - return $this->mysqlRaiseError(DB_ERROR_NOT_LOCKED); - } - - $highest_id = $this->getOne("SELECT MAX(id) FROM ${seqname}"); - if (DB::isError($highest_id)) { - return $highest_id; - } - // This should kill all rows except the highest - // We should probably do something if $highest_id isn't - // numeric, but I'm at a loss as how to handle that... - $result = $this->query("DELETE FROM ${seqname} WHERE id <> $highest_id"); - if (DB::isError($result)) { - return $result; - } - - // If another thread has been waiting for this lock, - // it will go thru the above procedure, but will have no - // real effect - $result = $this->getOne("SELECT RELEASE_LOCK('${seqname}_lock')"); - if (DB::isError($result)) { - return $result; - } - return true; - } - - // }}} - // {{{ quoteIdentifier() - - /** - * Quote a string so it can be safely used as a table or column name - * - * Quoting style depends on which database driver is being used. - * - * MySQL can't handle the backtick character (`) in - * table or column names. - * - * @param string $str identifier name to be quoted - * - * @return string quoted identifier string - * - * @since 1.6.0 - * @access public - * @internal - */ - function quoteIdentifier($str) - { - return '`' . $str . '`'; - } - - // }}} - // {{{ escapeSimple() - - /** - * Escape a string according to the current DBMS's standards - * - * @param string $str the string to be escaped - * - * @return string the escaped string - * - * @internal - */ - function escapeSimple($str) { - return @mysqli_real_escape_string($str, $this->connection); - } - - // }}} - // {{{ modifyQuery() - - function modifyQuery($query) - { - if ($this->options['portability'] & DB_PORTABILITY_DELETE_COUNT) { - // "DELETE FROM table" gives 0 affected rows in MySQL. - // This little hack lets you know how many rows were deleted. - if (preg_match('/^\s*DELETE\s+FROM\s+(\S+)\s*$/i', $query)) { - $query = preg_replace('/^\s*DELETE\s+FROM\s+(\S+)\s*$/', - 'DELETE FROM \1 WHERE 1=1', $query); - } - } - return $query; - } - - // }}} - // {{{ modifyLimitQuery() - - function modifyLimitQuery($query, $from, $count, $params = array()) - { - if (DB::isManip($query)) { - return $query . " LIMIT $count"; - } else { - return $query . " LIMIT $from, $count"; - } - } - - // }}} - // {{{ mysqlRaiseError() - - /** - * Gather information about an error, then use that info to create a - * DB error object and finally return that object. - * - * @param integer $errno PEAR error number (usually a DB constant) if - * manually raising an error - * @return object DB error object - * @see DB_common::errorCode() - * @see DB_common::raiseError() - */ - function mysqlRaiseError($errno = null) - { - if ($errno === null) { - if ($this->options['portability'] & DB_PORTABILITY_ERRORS) { - $this->errorcode_map[1022] = DB_ERROR_CONSTRAINT; - $this->errorcode_map[1048] = DB_ERROR_CONSTRAINT_NOT_NULL; - $this->errorcode_map[1062] = DB_ERROR_CONSTRAINT; - } else { - // Doing this in case mode changes during runtime. - $this->errorcode_map[1022] = DB_ERROR_ALREADY_EXISTS; - $this->errorcode_map[1048] = DB_ERROR_CONSTRAINT; - $this->errorcode_map[1062] = DB_ERROR_ALREADY_EXISTS; - } - $errno = $this->errorCode(mysqli_errno($this->connection)); - } - return $this->raiseError($errno, null, null, null, - @mysqli_errno($this->connection) . ' ** ' . - @mysqli_error($this->connection)); - } - - // }}} - // {{{ tableInfo() - - /** - * Returns information about a table or a result set. - * - * WARNING: this method will probably not work because the mysqli_*() - * functions it relies upon may not exist. - * - * @param object|string $result DB_result object from a query or a - * string containing the name of a table - * @param int $mode a valid tableInfo mode - * @return array an associative array with the information requested - * or an error object if something is wrong - * @access public - * @internal - * @see DB_common::tableInfo() - */ - function tableInfo($result, $mode = null) { - if (isset($result->result)) { - /* - * Probably received a result object. - * Extract the result resource identifier. - */ - $id = $result->result; - $got_string = false; - } elseif (is_string($result)) { - /* - * Probably received a table name. - * Create a result resource identifier. - */ - $id = @mysqli_list_fields($this->dsn['database'], - $result, $this->connection); - $got_string = true; - } else { - /* - * Probably received a result resource identifier. - * Copy it. - * Depricated. Here for compatibility only. - */ - $id = $result; - $got_string = false; - } - - if (!is_resource($id)) { - return $this->mysqlRaiseError(DB_ERROR_NEED_MORE_DATA); - } - - if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) { - $case_func = 'strtolower'; - } else { - $case_func = 'strval'; - } - - $count = @mysqli_num_fields($id); - - // made this IF due to performance (one if is faster than $count if's) - if (!$mode) { - for ($i=0; $i<$count; $i++) { - $tmp = @mysqli_fetch_field($id); - $res[$i]['table'] = $case_func($tmp->table); - $res[$i]['name'] = $case_func($tmp->name); - $res[$i]['type'] = $tmp->type; - $res[$i]['len'] = $tmp->max_length; - - $res[$i]['flags'] = ''; - if ($tmp->flags & MYSQLI_NOT_NULL_FLAG) { - $res[$i]['flags'] .= 'not_null '; - } - if ($tmp->flags & MYSQLI_PRI_KEY_FLAG) { - $res[$i]['flags'] .= 'primary_key '; - } - if ($tmp->flags & MYSQLI_UNIQUE_KEY_FLAG) { - $res[$i]['flags'] .= 'unique_key '; - } - if ($tmp->flags & MYSQLI_MULTIPLE_KEY_FLAG) { - $res[$i]['flags'] .= 'multiple_key '; - } - if ($tmp->flags & MYSQLI_BLOB_FLAG) { - $res[$i]['flags'] .= 'blob '; - } - if ($tmp->def) { - $res[$i]['flags'] .= 'default_' . rawurlencode($tmp->def); - } - $res[$i]['flags'] = trim($res[$i]['flags']); - } - } else { // full - $res['num_fields']= $count; - - for ($i=0; $i<$count; $i++) { - $tmp = @mysqli_fetch_field($id); - $res[$i]['table'] = $case_func($tmp->table); - $res[$i]['name'] = $case_func($tmp->name); - $res[$i]['type'] = $tmp->type; - $res[$i]['len'] = $tmp->max_length; - - $res[$i]['flags'] = ''; - if ($tmp->flags & MYSQLI_NOT_NULL_FLAG) { - $res[$i]['flags'] .= 'not_null '; - } - if ($tmp->flags & MYSQLI_PRI_KEY_FLAG) { - $res[$i]['flags'] .= 'primary_key '; - } - if ($tmp->flags & MYSQLI_UNIQUE_KEY_FLAG) { - $res[$i]['flags'] .= 'unique_key '; - } - if ($tmp->flags & MYSQLI_MULTIPLE_KEY_FLAG) { - $res[$i]['flags'] .= 'multiple_key '; - } - if ($tmp->flags & MYSQLI_BLOB_FLAG) { - $res[$i]['flags'] .= 'blob '; - } - if ($tmp->def) { - $res[$i]['flags'] .= 'default_' . rawurlencode($tmp->def); - } - $res[$i]['flags'] = trim($res[$i]['flags']); - - if ($mode & DB_TABLEINFO_ORDER) { - $res['order'][$res[$i]['name']] = $i; - } - if ($mode & DB_TABLEINFO_ORDERTABLE) { - $res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i; - } - } - } - - // free the result only if we were called on a table - if ($got_string) { - @mysqli_free_result($id); - } - return $res; - } - - // }}} - // {{{ getSpecialQuery() - - /** - * Returns the query needed to get some backend info. - * - * @param string $type What kind of info you want to retrieve - * @return string The SQL query string - */ - function getSpecialQuery($type) - { - switch ($type) { - case 'tables': - return 'SHOW TABLES'; - case 'views': - return DB_ERROR_NOT_CAPABLE; - case 'users': - $sql = 'select distinct User from user'; - if ($this->dsn['database'] != 'mysql') { - $dsn = $this->dsn; - $dsn['database'] = 'mysql'; - if (DB::isError($db = DB::connect($dsn))) { - return $db; - } - $sql = $db->getCol($sql); - $db->disconnect(); - // XXX Fixme the mysql driver should take care of this - if (!@mysqli_select_db($this->connection, $this->dsn['database'])) { - return $this->mysqlRaiseError(DB_ERROR_NODBSELECTED); - } - } - return $sql; - case 'databases': - return 'SHOW DATABASES'; - default: - return null; - } - } - - // }}} - -} - -/* - * Local variables: - * tab-width: 4 - * c-basic-offset: 4 - * End: - */ - -?> diff --git a/glmPEAR/DB/oci8.php b/glmPEAR/DB/oci8.php deleted file mode 100755 index 593d5df..0000000 --- a/glmPEAR/DB/oci8.php +++ /dev/null @@ -1,898 +0,0 @@ - | -// | Maintainer: Daniel Convissor | -// +----------------------------------------------------------------------+ -// -// $Id: oci8.php,v 1.1.1.1 2008/04/28 15:20:47 jamie Exp $ - - -// be aware... OCIError() only appears to return anything when given a -// statement, so functions return the generic DB_ERROR instead of more -// useful errors that have to do with feedback from the database. - - -require_once 'DB/common.php'; - -/** - * Database independent query interface definition for PHP's Oracle 8 - * call-interface extension. - * - * Definitely works with versions 8 and 9 of Oracle. - * - * @package DB - * @version $Id: oci8.php,v 1.1.1.1 2008/04/28 15:20:47 jamie Exp $ - * @category Database - * @author James L. Pine - */ -class DB_oci8 extends DB_common -{ - // {{{ properties - - var $connection; - var $phptype, $dbsyntax; - var $manip_query = array(); - var $prepare_types = array(); - var $autoCommit = 1; - var $last_stmt = false; - - /** - * stores the $data passed to execute() in the oci8 driver - * - * Gets reset to array() when simpleQuery() is run. - * - * Needed in case user wants to call numRows() after prepare/execute - * was used. - * - * @var array - * @access private - */ - var $_data = array(); - - // }}} - // {{{ constructor - - function DB_oci8() - { - $this->DB_common(); - $this->phptype = 'oci8'; - $this->dbsyntax = 'oci8'; - $this->features = array( - 'prepare' => false, - 'pconnect' => true, - 'transactions' => true, - 'limit' => 'alter' - ); - $this->errorcode_map = array( - 1 => DB_ERROR_CONSTRAINT, - 900 => DB_ERROR_SYNTAX, - 904 => DB_ERROR_NOSUCHFIELD, - 921 => DB_ERROR_SYNTAX, - 923 => DB_ERROR_SYNTAX, - 942 => DB_ERROR_NOSUCHTABLE, - 955 => DB_ERROR_ALREADY_EXISTS, - 1400 => DB_ERROR_CONSTRAINT_NOT_NULL, - 1407 => DB_ERROR_CONSTRAINT_NOT_NULL, - 1476 => DB_ERROR_DIVZERO, - 1722 => DB_ERROR_INVALID_NUMBER, - 2289 => DB_ERROR_NOSUCHTABLE, - 2291 => DB_ERROR_CONSTRAINT, - 2449 => DB_ERROR_CONSTRAINT, - ); - } - - // }}} - // {{{ connect() - - /** - * Connect to a database and log in as the specified user. - * - * @param $dsn the data source name (see DB::parseDSN for syntax) - * @param $persistent (optional) whether the connection should - * be persistent - * - * @return int DB_OK on success, a DB error code on failure - */ - function connect($dsninfo, $persistent = false) - { - if (!DB::assertExtension('oci8')) { - return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND); - } - $this->dsn = $dsninfo; - - $connect_function = $persistent ? 'OCIPLogon' : 'OCILogon'; - - if ($dsninfo['hostspec']) { - $conn = @$connect_function($dsninfo['username'], - $dsninfo['password'], - $dsninfo['hostspec']); - } elseif ($dsninfo['username'] || $dsninfo['password']) { - $conn = @$connect_function($dsninfo['username'], - $dsninfo['password']); - } else { - $conn = false; - } - if ($conn == false) { - $error = OCIError(); - $error = (is_array($error)) ? $error['message'] : null; - return $this->raiseError(DB_ERROR_CONNECT_FAILED, null, null, - null, $error); - } - $this->connection = $conn; - return DB_OK; - } - - // }}} - // {{{ disconnect() - - /** - * Log out and disconnect from the database. - * - * @return bool true on success, false if not connected. - */ - function disconnect() - { - $ret = @OCILogOff($this->connection); - $this->connection = null; - return $ret; - } - - // }}} - // {{{ simpleQuery() - - /** - * Send a query to oracle and return the results as an oci8 resource - * identifier. - * - * @param $query the SQL query - * - * @return int returns a valid oci8 result for successful SELECT - * queries, DB_OK for other successful queries. A DB error code - * is returned on failure. - */ - function simpleQuery($query) - { - $this->_data = array(); - $this->last_query = $query; - $query = $this->modifyQuery($query); - $result = @OCIParse($this->connection, $query); - if (!$result) { - return $this->oci8RaiseError(); - } - if ($this->autoCommit) { - $success = @OCIExecute($result,OCI_COMMIT_ON_SUCCESS); - } else { - $success = @OCIExecute($result,OCI_DEFAULT); - } - if (!$success) { - return $this->oci8RaiseError($result); - } - $this->last_stmt=$result; - // Determine which queries that should return data, and which - // should return an error code only. - return DB::isManip($query) ? DB_OK : $result; - } - - // }}} - // {{{ nextResult() - - /** - * Move the internal oracle result pointer to the next available result - * - * @param a valid oci8 result resource - * - * @access public - * - * @return true if a result is available otherwise return false - */ - function nextResult($result) - { - return false; - } - - // }}} - // {{{ fetchInto() - - /** - * Fetch a row and insert the data into an existing array. - * - * Formating of the array and the data therein are configurable. - * See DB_result::fetchInto() for more information. - * - * @param resource $result query result identifier - * @param array $arr (reference) array where data from the row - * should be placed - * @param int $fetchmode how the resulting array should be indexed - * @param int $rownum the row number to fetch - * - * @return mixed DB_OK on success, null when end of result set is - * reached or on failure - * - * @see DB_result::fetchInto() - * @access private - */ - function fetchInto($result, &$arr, $fetchmode, $rownum=null) - { - if ($rownum !== null) { - return $this->raiseError(DB_ERROR_NOT_CAPABLE); - } - if ($fetchmode & DB_FETCHMODE_ASSOC) { - $moredata = @OCIFetchInto($result,$arr,OCI_ASSOC+OCI_RETURN_NULLS+OCI_RETURN_LOBS); - if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && - $moredata) - { - $arr = array_change_key_case($arr, CASE_LOWER); - } - } else { - $moredata = OCIFetchInto($result,$arr,OCI_RETURN_NULLS+OCI_RETURN_LOBS); - } - if (!$moredata) { - return null; - } - if ($this->options['portability'] & DB_PORTABILITY_RTRIM) { - $this->_rtrimArrayValues($arr); - } - if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) { - $this->_convertNullArrayValuesToEmpty($arr); - } - return DB_OK; - } - - // }}} - // {{{ freeResult() - - /** - * Free the internal resources associated with $result. - * - * @param $result oci8 result identifier - * - * @return bool true on success, false if $result is invalid - */ - function freeResult($result) - { - return @OCIFreeStatement($result); - } - - /** - * Free the internal resources associated with a prepared query. - * - * @param $stmt oci8 statement identifier - * - * @return bool true on success, false if $result is invalid - */ - function freePrepared($stmt) - { - if (isset($this->prepare_types[(int)$stmt])) { - unset($this->prepare_types[(int)$stmt]); - unset($this->manip_query[(int)$stmt]); - } else { - return false; - } - return true; - } - - // }}} - // {{{ numRows() - - function numRows($result) - { - // emulate numRows for Oracle. yuck. - if ($this->options['portability'] & DB_PORTABILITY_NUMROWS && - $result === $this->last_stmt) - { - $countquery = 'SELECT COUNT(*) FROM ('.$this->last_query.')'; - $save_query = $this->last_query; - $save_stmt = $this->last_stmt; - - if (count($this->_data)) { - $smt = $this->prepare('SELECT COUNT(*) FROM ('.$this->last_query.')'); - $count = $this->execute($smt, $this->_data); - } else { - $count =& $this->query($countquery); - } - - if (DB::isError($count) || - DB::isError($row = $count->fetchRow(DB_FETCHMODE_ORDERED))) - { - $this->last_query = $save_query; - $this->last_stmt = $save_stmt; - return $this->raiseError(DB_ERROR_NOT_CAPABLE); - } - return $row[0]; - } - return $this->raiseError(DB_ERROR_NOT_CAPABLE); - } - - // }}} - // {{{ numCols() - - /** - * Get the number of columns in a result set. - * - * @param $result oci8 result identifier - * - * @return int the number of columns per row in $result - */ - function numCols($result) - { - $cols = @OCINumCols($result); - if (!$cols) { - return $this->oci8RaiseError($result); - } - return $cols; - } - - // }}} - // {{{ errorNative() - - /** - * Get the native error code of the last error (if any) that occured - * on the current connection. This does not work, as OCIError does - * not work unless given a statement. If OCIError does return - * something, so will this. - * - * @return int native oci8 error code - */ - function errorNative() - { - if (is_resource($this->last_stmt)) { - $error = @OCIError($this->last_stmt); - } else { - $error = @OCIError($this->connection); - } - if (is_array($error)) { - return $error['code']; - } - return false; - } - - // }}} - // {{{ prepare() - - /** - * Prepares a query for multiple execution with execute(). - * - * With oci8, this is emulated. - * - * prepare() requires a generic query as string like - * INSERT INTO numbers VALUES (?, ?, ?) - * . The ? characters are placeholders. - * - * Three types of placeholders can be used: - * + ? a quoted scalar value, i.e. strings, integers - * + ! value is inserted 'as is' - * + & requires a file name. The file's contents get - * inserted into the query (i.e. saving binary - * data in a db) - * - * Use backslashes to escape placeholder characters if you don't want - * them to be interpreted as placeholders. Example: - * "UPDATE foo SET col=? WHERE col='over \& under'" - * - * - * @param string $query query to be prepared - * @return mixed DB statement resource on success. DB_Error on failure. - */ - function prepare($query) - { - $tokens = preg_split('/((? $val) { - switch ($val) { - case '?': - $types[$token++] = DB_PARAM_SCALAR; - unset($tokens[$key]); - break; - case '&': - $types[$token++] = DB_PARAM_OPAQUE; - unset($tokens[$key]); - break; - case '!': - $types[$token++] = DB_PARAM_MISC; - unset($tokens[$key]); - break; - default: - $tokens[$key] = preg_replace('/\\\([&?!])/', "\\1", $val); - if ($key != $binds) { - $newquery .= $tokens[$key] . ':bind' . $token; - } else { - $newquery .= $tokens[$key]; - } - } - } - - $this->last_query = $query; - $newquery = $this->modifyQuery($newquery); - if (!$stmt = @OCIParse($this->connection, $newquery)) { - return $this->oci8RaiseError(); - } - $this->prepare_types[$stmt] = $types; - $this->manip_query[(int)$stmt] = DB::isManip($query); - return $stmt; - } - - // }}} - // {{{ execute() - - /** - * Executes a DB statement prepared with prepare(). - * - * @param resource $stmt a DB statement resource returned from prepare() - * @param mixed $data array, string or numeric data to be used in - * execution of the statement. Quantity of items - * passed must match quantity of placeholders in - * query: meaning 1 for non-array items or the - * quantity of elements in the array. - * @return int returns an oci8 result resource for successful - * SELECT queries, DB_OK for other successful queries. A DB error - * code is returned on failure. - * @see DB_oci::prepare() - */ - function &execute($stmt, $data = array()) - { - if (!is_array($data)) { - $data = array($data); - } - - $this->_data = $data; - - $types =& $this->prepare_types[$stmt]; - if (count($types) != count($data)) { - $tmp =& $this->raiseError(DB_ERROR_MISMATCH); - return $tmp; - } - - $i = 0; - foreach ($data as $key => $value) { - if ($types[$i] == DB_PARAM_MISC) { - /* - * Oracle doesn't seem to have the ability to pass a - * parameter along unchanged, so strip off quotes from start - * and end, plus turn two single quotes to one single quote, - * in order to avoid the quotes getting escaped by - * Oracle and ending up in the database. - */ - $data[$key] = preg_replace("/^'(.*)'$/", "\\1", $data[$key]); - $data[$key] = str_replace("''", "'", $data[$key]); - } elseif ($types[$i] == DB_PARAM_OPAQUE) { - $fp = @fopen($data[$key], 'rb'); - if (!$fp) { - $tmp =& $this->raiseError(DB_ERROR_ACCESS_VIOLATION); - return $tmp; - } - $data[$key] = fread($fp, filesize($data[$key])); - fclose($fp); - } - if (!@OCIBindByName($stmt, ':bind' . $i, $data[$key], -1)) { - $tmp = $this->oci8RaiseError($stmt); - return $tmp; - } - $i++; - } - if ($this->autoCommit) { - $success = @OCIExecute($stmt, OCI_COMMIT_ON_SUCCESS); - } else { - $success = @OCIExecute($stmt, OCI_DEFAULT); - } - if (!$success) { - $tmp = $this->oci8RaiseError($stmt); - return $tmp; - } - $this->last_stmt = $stmt; - if ($this->manip_query[(int)$stmt]) { - $tmp = DB_OK; - } else { - $tmp =& new DB_result($this, $stmt); - } - return $tmp; - } - - // }}} - // {{{ autoCommit() - - /** - * Enable/disable automatic commits - * - * @param $onoff true/false whether to autocommit - */ - function autoCommit($onoff = false) - { - $this->autoCommit = (bool)$onoff;; - return DB_OK; - } - - // }}} - // {{{ commit() - - /** - * Commit transactions on the current connection - * - * @return DB_ERROR or DB_OK - */ - function commit() - { - $result = @OCICommit($this->connection); - if (!$result) { - return $this->oci8RaiseError(); - } - return DB_OK; - } - - // }}} - // {{{ rollback() - - /** - * Roll back all uncommitted transactions on the current connection. - * - * @return DB_ERROR or DB_OK - */ - function rollback() - { - $result = @OCIRollback($this->connection); - if (!$result) { - return $this->oci8RaiseError(); - } - return DB_OK; - } - - // }}} - // {{{ affectedRows() - - /** - * Gets the number of rows affected by the last query. - * if the last query was a select, returns 0. - * - * @return number of rows affected by the last query or DB_ERROR - */ - function affectedRows() - { - if ($this->last_stmt === false) { - return $this->oci8RaiseError(); - } - $result = @OCIRowCount($this->last_stmt); - if ($result === false) { - return $this->oci8RaiseError($this->last_stmt); - } - return $result; - } - - // }}} - // {{{ modifyQuery() - - function modifyQuery($query) - { - // "SELECT 2+2" must be "SELECT 2+2 FROM dual" in Oracle - if (preg_match('/^\s*SELECT/i', $query) && - !preg_match('/\sFROM\s/i', $query)) { - $query .= ' FROM dual'; - } - return $query; - } - - // }}} - // {{{ modifyLimitQuery() - - /** - * Emulate the row limit support altering the query - * - * @param string $query The query to treat - * @param int $from The row to start to fetch from - * @param int $count The offset - * @return string The modified query - * - * @author Tomas V.V.Cox - */ - function modifyLimitQuery($query, $from, $count, $params = array()) - { - // Let Oracle return the name of the columns instead of - // coding a "home" SQL parser - - if (count($params)) { - $result = $this->prepare("SELECT * FROM ($query) " - . 'WHERE NULL = NULL'); - $tmp =& $this->execute($result, $params); - } else { - $q_fields = "SELECT * FROM ($query) WHERE NULL = NULL"; - - if (!$result = @OCIParse($this->connection, $q_fields)) { - $this->last_query = $q_fields; - return $this->oci8RaiseError(); - } - if (!@OCIExecute($result, OCI_DEFAULT)) { - $this->last_query = $q_fields; - return $this->oci8RaiseError($result); - } - } - - $ncols = OCINumCols($result); - $cols = array(); - for ( $i = 1; $i <= $ncols; $i++ ) { - $cols[] = '"' . OCIColumnName($result, $i) . '"'; - } - $fields = implode(', ', $cols); - // XXX Test that (tip by John Lim) - //if (preg_match('/^\s*SELECT\s+/is', $query, $match)) { - // // Introduce the FIRST_ROWS Oracle query optimizer - // $query = substr($query, strlen($match[0]), strlen($query)); - // $query = "SELECT /* +FIRST_ROWS */ " . $query; - //} - - // Construct the query - // more at: http://marc.theaimsgroup.com/?l=php-db&m=99831958101212&w=2 - // Perhaps this could be optimized with the use of Unions - $query = "SELECT $fields FROM". - " (SELECT rownum as linenum, $fields FROM". - " ($query)". - ' WHERE rownum <= '. ($from + $count) . - ') WHERE linenum >= ' . ++$from; - return $query; - } - - // }}} - // {{{ nextId() - - /** - * Returns the next free id in a sequence - * - * @param string $seq_name name of the sequence - * @param boolean $ondemand when true, the seqence is automatically - * created if it does not exist - * - * @return int the next id number in the sequence. DB_Error if problem. - * - * @internal - * @see DB_common::nextID() - * @access public - */ - function nextId($seq_name, $ondemand = true) - { - $seqname = $this->getSequenceName($seq_name); - $repeat = 0; - do { - $this->expectError(DB_ERROR_NOSUCHTABLE); - $result =& $this->query("SELECT ${seqname}.nextval FROM dual"); - $this->popExpect(); - if ($ondemand && DB::isError($result) && - $result->getCode() == DB_ERROR_NOSUCHTABLE) { - $repeat = 1; - $result = $this->createSequence($seq_name); - if (DB::isError($result)) { - return $this->raiseError($result); - } - } else { - $repeat = 0; - } - } while ($repeat); - if (DB::isError($result)) { - return $this->raiseError($result); - } - $arr = $result->fetchRow(DB_FETCHMODE_ORDERED); - return $arr[0]; - } - - /** - * Creates a new sequence - * - * @param string $seq_name name of the new sequence - * - * @return int DB_OK on success. A DB_Error object is returned if - * problems arise. - * - * @internal - * @see DB_common::createSequence() - * @access public - */ - function createSequence($seq_name) - { - $seqname = $this->getSequenceName($seq_name); - return $this->query("CREATE SEQUENCE ${seqname}"); - } - - // }}} - // {{{ dropSequence() - - /** - * Deletes a sequence - * - * @param string $seq_name name of the sequence to be deleted - * - * @return int DB_OK on success. DB_Error if problems. - * - * @internal - * @see DB_common::dropSequence() - * @access public - */ - function dropSequence($seq_name) - { - $seqname = $this->getSequenceName($seq_name); - return $this->query("DROP SEQUENCE ${seqname}"); - } - - // }}} - // {{{ oci8RaiseError() - - /** - * Gather information about an error, then use that info to create a - * DB error object and finally return that object. - * - * @param integer $errno PEAR error number (usually a DB constant) if - * manually raising an error - * @return object DB error object - * @see DB_common::errorCode() - * @see DB_common::raiseError() - */ - function oci8RaiseError($errno = null) - { - if ($errno === null) { - $error = @OCIError($this->connection); - return $this->raiseError($this->errorCode($error['code']), - null, null, null, $error['message']); - } elseif (is_resource($errno)) { - $error = @OCIError($errno); - return $this->raiseError($this->errorCode($error['code']), - null, null, null, $error['message']); - } - return $this->raiseError($this->errorCode($errno)); - } - - // }}} - // {{{ getSpecialQuery() - - /** - * Returns the query needed to get some backend info - * @param string $type What kind of info you want to retrieve - * @return string The SQL query string - */ - function getSpecialQuery($type) - { - switch ($type) { - case 'tables': - return 'SELECT table_name FROM user_tables'; - default: - return null; - } - } - - // }}} - // {{{ tableInfo() - - /** - * Returns information about a table or a result set. - * - * NOTE: only supports 'table' and 'flags' if $result - * is a table name. - * - * NOTE: flags won't contain index information. - * - * @param object|string $result DB_result object from a query or a - * string containing the name of a table - * @param int $mode a valid tableInfo mode - * @return array an associative array with the information requested - * or an error object if something is wrong - * @access public - * @internal - * @see DB_common::tableInfo() - */ - function tableInfo($result, $mode = null) - { - if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) { - $case_func = 'strtolower'; - } else { - $case_func = 'strval'; - } - - if (is_string($result)) { - /* - * Probably received a table name. - * Create a result resource identifier. - */ - $result = strtoupper($result); - $q_fields = 'SELECT column_name, data_type, data_length, ' - . 'nullable ' - . 'FROM user_tab_columns ' - . "WHERE table_name='$result' ORDER BY column_id"; - - $this->last_query = $q_fields; - - if (!$stmt = @OCIParse($this->connection, $q_fields)) { - return $this->oci8RaiseError(DB_ERROR_NEED_MORE_DATA); - } - if (!@OCIExecute($stmt, OCI_DEFAULT)) { - return $this->oci8RaiseError($stmt); - } - - $i = 0; - while (@OCIFetch($stmt)) { - $res[$i]['table'] = $case_func($result); - $res[$i]['name'] = $case_func(@OCIResult($stmt, 1)); - $res[$i]['type'] = @OCIResult($stmt, 2); - $res[$i]['len'] = @OCIResult($stmt, 3); - $res[$i]['flags'] = (@OCIResult($stmt, 4) == 'N') ? 'not_null' : ''; - - if ($mode & DB_TABLEINFO_ORDER) { - $res['order'][$res[$i]['name']] = $i; - } - if ($mode & DB_TABLEINFO_ORDERTABLE) { - $res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i; - } - $i++; - } - - if ($mode) { - $res['num_fields'] = $i; - } - @OCIFreeStatement($stmt); - - } else { - if (isset($result->result)) { - /* - * Probably received a result object. - * Extract the result resource identifier. - */ - $result = $result->result; - } else { - /* - * ELSE, probably received a result resource identifier. - * Depricated. Here for compatibility only. - */ - } - - if ($result === $this->last_stmt) { - $count = @OCINumCols($result); - - for ($i=0; $i<$count; $i++) { - $res[$i]['table'] = ''; - $res[$i]['name'] = $case_func(@OCIColumnName($result, $i+1)); - $res[$i]['type'] = @OCIColumnType($result, $i+1); - $res[$i]['len'] = @OCIColumnSize($result, $i+1); - $res[$i]['flags'] = ''; - - if ($mode & DB_TABLEINFO_ORDER) { - $res['order'][$res[$i]['name']] = $i; - } - if ($mode & DB_TABLEINFO_ORDERTABLE) { - $res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i; - } - } - - if ($mode) { - $res['num_fields'] = $count; - } - - } else { - return $this->raiseError(DB_ERROR_NOT_CAPABLE); - } - } - return $res; - } - - // }}} - -} - -/* - * Local variables: - * tab-width: 4 - * c-basic-offset: 4 - * End: - */ - -?> diff --git a/glmPEAR/DB/odbc.php b/glmPEAR/DB/odbc.php deleted file mode 100755 index d3d5da8..0000000 --- a/glmPEAR/DB/odbc.php +++ /dev/null @@ -1,577 +0,0 @@ - | -// | Maintainer: Daniel Convissor | -// +----------------------------------------------------------------------+ -// -// $Id: odbc.php,v 1.1.1.1 2008/04/28 15:20:47 jamie Exp $ - - -// XXX legend: -// More info on ODBC errors could be found here: -// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/trblsql/tr_err_odbc_5stz.asp -// -// XXX ERRORMSG: The error message from the odbc function should -// be registered here. - - -require_once 'DB/common.php'; - -/** - * Database independent query interface definition for PHP's ODBC - * extension. - * - * @package DB - * @version $Id: odbc.php,v 1.1.1.1 2008/04/28 15:20:47 jamie Exp $ - * @category Database - * @author Stig Bakken - */ -class DB_odbc extends DB_common -{ - // {{{ properties - - var $connection; - var $phptype, $dbsyntax; - var $row = array(); - - // }}} - // {{{ constructor - - function DB_odbc() - { - $this->DB_common(); - $this->phptype = 'odbc'; - $this->dbsyntax = 'sql92'; - $this->features = array( - 'prepare' => true, - 'pconnect' => true, - 'transactions' => false, - 'limit' => 'emulate' - ); - $this->errorcode_map = array( - '01004' => DB_ERROR_TRUNCATED, - '07001' => DB_ERROR_MISMATCH, - '21S01' => DB_ERROR_MISMATCH, - '21S02' => DB_ERROR_MISMATCH, - '22003' => DB_ERROR_INVALID_NUMBER, - '22005' => DB_ERROR_INVALID_NUMBER, - '22008' => DB_ERROR_INVALID_DATE, - '22012' => DB_ERROR_DIVZERO, - '23000' => DB_ERROR_CONSTRAINT, - '23502' => DB_ERROR_CONSTRAINT_NOT_NULL, - '23503' => DB_ERROR_CONSTRAINT, - '23505' => DB_ERROR_CONSTRAINT, - '24000' => DB_ERROR_INVALID, - '34000' => DB_ERROR_INVALID, - '37000' => DB_ERROR_SYNTAX, - '42000' => DB_ERROR_SYNTAX, - '42601' => DB_ERROR_SYNTAX, - 'IM001' => DB_ERROR_UNSUPPORTED, - 'S0000' => DB_ERROR_NOSUCHTABLE, - 'S0001' => DB_ERROR_ALREADY_EXISTS, - 'S0002' => DB_ERROR_NOSUCHTABLE, - 'S0011' => DB_ERROR_ALREADY_EXISTS, - 'S0012' => DB_ERROR_NOT_FOUND, - 'S0021' => DB_ERROR_ALREADY_EXISTS, - 'S0022' => DB_ERROR_NOSUCHFIELD, - 'S1000' => DB_ERROR_CONSTRAINT_NOT_NULL, - 'S1009' => DB_ERROR_INVALID, - 'S1090' => DB_ERROR_INVALID, - 'S1C00' => DB_ERROR_NOT_CAPABLE - ); - } - - // }}} - // {{{ connect() - - /** - * Connect to a database and log in as the specified user. - * - * @param $dsn the data source name (see DB::parseDSN for syntax) - * @param $persistent (optional) whether the connection should - * be persistent - * - * @return int DB_OK on success, a DB error code on failure - */ - function connect($dsninfo, $persistent = false) - { - if (!DB::assertExtension('odbc')) { - return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND); - } - - $this->dsn = $dsninfo; - if ($dsninfo['dbsyntax']) { - $this->dbsyntax = $dsninfo['dbsyntax']; - } - switch ($this->dbsyntax) { - case 'solid': - $this->features = array( - 'prepare' => true, - 'pconnect' => true, - 'transactions' => true - ); - break; - case 'navision': - // the Navision driver doesn't support fetch row by number - $this->features['limit'] = false; - } - - /* - * This is hear for backwards compatibility. - * Should have been using 'database' all along, but used hostspec. - */ - if ($dsninfo['database']) { - $odbcdsn = $dsninfo['database']; - } elseif ($dsninfo['hostspec']) { - $odbcdsn = $dsninfo['hostspec']; - } else { - $odbcdsn = 'localhost'; - } - - if ($this->provides('pconnect')) { - $connect_function = $persistent ? 'odbc_pconnect' : 'odbc_connect'; - } else { - $connect_function = 'odbc_connect'; - } - $conn = @$connect_function($odbcdsn, $dsninfo['username'], - $dsninfo['password']); - if (!is_resource($conn)) { - return $this->raiseError(DB_ERROR_CONNECT_FAILED, null, null, - null, $this->errorNative()); - } - $this->connection = $conn; - return DB_OK; - } - - // }}} - // {{{ disconnect() - - function disconnect() - { - $err = @odbc_close($this->connection); - $this->connection = null; - return $err; - } - - // }}} - // {{{ simpleQuery() - - /** - * Send a query to ODBC and return the results as a ODBC resource - * identifier. - * - * @param $query the SQL query - * - * @return int returns a valid ODBC result for successful SELECT - * queries, DB_OK for other successful queries. A DB error code - * is returned on failure. - */ - function simpleQuery($query) - { - $this->last_query = $query; - $query = $this->modifyQuery($query); - $result = @odbc_exec($this->connection, $query); - if (!$result) { - return $this->odbcRaiseError(); // XXX ERRORMSG - } - // Determine which queries that should return data, and which - // should return an error code only. - if (DB::isManip($query)) { - $this->manip_result = $result; // For affectedRows() - return DB_OK; - } - $this->row[(int)$result] = 0; - $this->manip_result = 0; - return $result; - } - - // }}} - // {{{ nextResult() - - /** - * Move the internal odbc result pointer to the next available result - * - * @param a valid fbsql result resource - * - * @access public - * - * @return true if a result is available otherwise return false - */ - function nextResult($result) - { - return @odbc_next_result($result); - } - - // }}} - // {{{ fetchInto() - - /** - * Fetch a row and insert the data into an existing array. - * - * Formating of the array and the data therein are configurable. - * See DB_result::fetchInto() for more information. - * - * @param resource $result query result identifier - * @param array $arr (reference) array where data from the row - * should be placed - * @param int $fetchmode how the resulting array should be indexed - * @param int $rownum the row number to fetch - * - * @return mixed DB_OK on success, null when end of result set is - * reached or on failure - * - * @see DB_result::fetchInto() - * @access private - */ - function fetchInto($result, &$arr, $fetchmode, $rownum=null) - { - $arr = array(); - if ($rownum !== null) { - $rownum++; // ODBC first row is 1 - if (version_compare(phpversion(), '4.2.0', 'ge')) { - $cols = @odbc_fetch_into($result, $arr, $rownum); - } else { - $cols = @odbc_fetch_into($result, $rownum, $arr); - } - } else { - $cols = @odbc_fetch_into($result, $arr); - } - - if (!$cols) { - /* XXX FIXME: doesn't work with unixODBC and easysoft - (get corrupted $errno values) - if ($errno = @odbc_error($this->connection)) { - return $this->RaiseError($errno); - }*/ - return null; - } - if ($fetchmode !== DB_FETCHMODE_ORDERED) { - for ($i = 0; $i < count($arr); $i++) { - $colName = @odbc_field_name($result, $i+1); - $a[$colName] = $arr[$i]; - } - if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) { - $a = array_change_key_case($a, CASE_LOWER); - } - $arr = $a; - } - if ($this->options['portability'] & DB_PORTABILITY_RTRIM) { - $this->_rtrimArrayValues($arr); - } - if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) { - $this->_convertNullArrayValuesToEmpty($arr); - } - return DB_OK; - } - - // }}} - // {{{ freeResult() - - function freeResult($result) - { - unset($this->row[(int)$result]); - return @odbc_free_result($result); - } - - // }}} - // {{{ numCols() - - function numCols($result) - { - $cols = @odbc_num_fields($result); - if (!$cols) { - return $this->odbcRaiseError(); - } - return $cols; - } - - // }}} - // {{{ affectedRows() - - /** - * Returns the number of rows affected by a manipulative query - * (INSERT, DELETE, UPDATE) - * @return mixed int affected rows, 0 when non manip queries or - * DB error on error - */ - function affectedRows() - { - if (empty($this->manip_result)) { // In case of SELECT stms - return 0; - } - $nrows = @odbc_num_rows($this->manip_result); - if ($nrows == -1) { - return $this->odbcRaiseError(); - } - return $nrows; - } - - // }}} - // {{{ numRows() - - /** - * ODBC may or may not support counting rows in the result set of - * SELECTs. - * - * @param $result the odbc result resource - * @return the number of rows, or 0 - */ - function numRows($result) - { - $nrows = @odbc_num_rows($result); - if ($nrows == -1) { - return $this->odbcRaiseError(DB_ERROR_UNSUPPORTED); - } - return $nrows; - } - - // }}} - // {{{ quoteIdentifier() - - /** - * Quote a string so it can be safely used as a table / column name - * - * Quoting style depends on which dbsyntax was passed in the DSN. - * - * Use 'mssql' as the dbsyntax in the DB DSN only if you've unchecked - * "Use ANSI quoted identifiers" when setting up the ODBC data source. - * - * @param string $str identifier name to be quoted - * - * @return string quoted identifier string - * - * @since 1.6.0 - * @access public - */ - function quoteIdentifier($str) - { - switch ($this->dsn['dbsyntax']) { - case 'access': - return '[' . $str . ']'; - case 'mssql': - case 'sybase': - return '[' . str_replace(']', ']]', $str) . ']'; - case 'mysql': - case 'mysqli': - return '`' . $str . '`'; - default: - return '"' . str_replace('"', '""', $str) . '"'; - } - } - - // }}} - // {{{ quote() - - /** - * @deprecated Deprecated in release 1.6.0 - * @internal - */ - function quote($str) { - return $this->quoteSmart($str); - } - - // }}} - // {{{ errorNative() - - /** - * Get the native error code of the last error (if any) that - * occured on the current connection. - * - * @access public - * - * @return int ODBC error code - */ - function errorNative() - { - if (!isset($this->connection) || !is_resource($this->connection)) { - return @odbc_error() . ' ' . @odbc_errormsg(); - } - return @odbc_error($this->connection) . ' ' . @odbc_errormsg($this->connection); - } - - // }}} - // {{{ nextId() - - /** - * Returns the next free id in a sequence - * - * @param string $seq_name name of the sequence - * @param boolean $ondemand when true, the seqence is automatically - * created if it does not exist - * - * @return int the next id number in the sequence. DB_Error if problem. - * - * @internal - * @see DB_common::nextID() - * @access public - */ - function nextId($seq_name, $ondemand = true) - { - $seqname = $this->getSequenceName($seq_name); - $repeat = 0; - do { - $this->pushErrorHandling(PEAR_ERROR_RETURN); - $result = $this->query("update ${seqname} set id = id + 1"); - $this->popErrorHandling(); - if ($ondemand && DB::isError($result) && - $result->getCode() == DB_ERROR_NOSUCHTABLE) { - $repeat = 1; - $this->pushErrorHandling(PEAR_ERROR_RETURN); - $result = $this->createSequence($seq_name); - $this->popErrorHandling(); - if (DB::isError($result)) { - return $this->raiseError($result); - } - $result = $this->query("insert into ${seqname} (id) values(0)"); - } else { - $repeat = 0; - } - } while ($repeat); - - if (DB::isError($result)) { - return $this->raiseError($result); - } - - $result = $this->query("select id from ${seqname}"); - if (DB::isError($result)) { - return $result; - } - - $row = $result->fetchRow(DB_FETCHMODE_ORDERED); - if (DB::isError($row || !$row)) { - return $row; - } - - return $row[0]; - } - - /** - * Creates a new sequence - * - * @param string $seq_name name of the new sequence - * - * @return int DB_OK on success. A DB_Error object is returned if - * problems arise. - * - * @internal - * @see DB_common::createSequence() - * @access public - */ - function createSequence($seq_name) - { - $seqname = $this->getSequenceName($seq_name); - return $this->query("CREATE TABLE ${seqname} ". - '(id integer NOT NULL,'. - ' PRIMARY KEY(id))'); - } - - // }}} - // {{{ dropSequence() - - /** - * Deletes a sequence - * - * @param string $seq_name name of the sequence to be deleted - * - * @return int DB_OK on success. DB_Error if problems. - * - * @internal - * @see DB_common::dropSequence() - * @access public - */ - function dropSequence($seq_name) - { - $seqname = $this->getSequenceName($seq_name); - return $this->query("DROP TABLE ${seqname}"); - } - - // }}} - // {{{ autoCommit() - - function autoCommit($onoff = false) - { - if (!@odbc_autocommit($this->connection, $onoff)) { - return $this->odbcRaiseError(); - } - return DB_OK; - } - - // }}} - // {{{ commit() - - function commit() - { - if (!@odbc_commit($this->connection)) { - return $this->odbcRaiseError(); - } - return DB_OK; - } - - // }}} - // {{{ rollback() - - function rollback() - { - if (!@odbc_rollback($this->connection)) { - return $this->odbcRaiseError(); - } - return DB_OK; - } - - // }}} - // {{{ odbcRaiseError() - - /** - * Gather information about an error, then use that info to create a - * DB error object and finally return that object. - * - * @param integer $errno PEAR error number (usually a DB constant) if - * manually raising an error - * @return object DB error object - * @see errorNative() - * @see DB_common::errorCode() - * @see DB_common::raiseError() - */ - function odbcRaiseError($errno = null) - { - if ($errno === null) { - switch ($this->dbsyntax) { - case 'access': - if ($this->options['portability'] & DB_PORTABILITY_ERRORS) { - $this->errorcode_map['07001'] = DB_ERROR_NOSUCHFIELD; - } else { - // Doing this in case mode changes during runtime. - $this->errorcode_map['07001'] = DB_ERROR_MISMATCH; - } - } - $errno = $this->errorCode(odbc_error($this->connection)); - } - return $this->raiseError($errno, null, null, null, - $this->errorNative()); - } - - // }}} - -} - -/* - * Local variables: - * tab-width: 4 - * c-basic-offset: 4 - * End: - */ - -?> diff --git a/glmPEAR/DB/pgsql.php b/glmPEAR/DB/pgsql.php deleted file mode 100755 index cf24652..0000000 --- a/glmPEAR/DB/pgsql.php +++ /dev/null @@ -1,840 +0,0 @@ - | -// | Stig Bakken | -// | Maintainer: Daniel Convissor | -// +----------------------------------------------------------------------+ -// -// $Id: pgsql.php,v 1.1.1.1 2008/04/28 15:20:47 jamie Exp $ - -require_once 'DB/common.php'; - -/** - * Database independent query interface definition for PHP's PostgreSQL - * extension. - * - * @package DB - * @version $Id: pgsql.php,v 1.1.1.1 2008/04/28 15:20:47 jamie Exp $ - * @category Database - * @author Rui Hirokawa - * @author Stig Bakken - */ -class DB_pgsql extends DB_common -{ - // {{{ properties - - var $connection; - var $phptype, $dbsyntax; - var $prepare_tokens = array(); - var $prepare_types = array(); - var $transaction_opcount = 0; - var $dsn = array(); - var $row = array(); - var $num_rows = array(); - var $affected = 0; - var $autocommit = true; - var $fetchmode = DB_FETCHMODE_ORDERED; - - // }}} - // {{{ constructor - - function DB_pgsql() - { - $this->DB_common(); - $this->phptype = 'pgsql'; - $this->dbsyntax = 'pgsql'; - $this->features = array( - 'prepare' => false, - 'pconnect' => true, - 'transactions' => true, - 'limit' => 'alter' - ); - $this->errorcode_map = array( - ); - } - - // }}} - // {{{ connect() - - /** - * Connect to a database and log in as the specified user. - * - * @param $dsn the data source name (see DB::parseDSN for syntax) - * @param $persistent (optional) whether the connection should - * be persistent - * - * @return int DB_OK on success, a DB error code on failure. - */ - function connect($dsninfo, $persistent = false) - { - if (!DB::assertExtension('pgsql')) { - return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND); - } - - $this->dsn = $dsninfo; - $protocol = $dsninfo['protocol'] ? $dsninfo['protocol'] : 'tcp'; - $connstr = ''; - - if ($protocol == 'tcp') { - if ($dsninfo['hostspec']) { - $connstr .= 'host=' . $dsninfo['hostspec']; - } - if ($dsninfo['port']) { - $connstr .= ' port=' . $dsninfo['port']; - } - } elseif ($protocol == 'unix') { - // Allow for pg socket in non-standard locations. - if ($dsninfo['socket']) { - $connstr .= 'host=' . $dsninfo['socket']; - } - } - - if ($dsninfo['database']) { - $connstr .= ' dbname=\'' . addslashes($dsninfo['database']) . '\''; - } - if ($dsninfo['username']) { - $connstr .= ' user=\'' . addslashes($dsninfo['username']) . '\''; - } - if ($dsninfo['password']) { - $connstr .= ' password=\'' . addslashes($dsninfo['password']) . '\''; - } - if (!empty($dsninfo['options'])) { - $connstr .= ' options=' . $dsninfo['options']; - } - if (!empty($dsninfo['tty'])) { - $connstr .= ' tty=' . $dsninfo['tty']; - } - - $connect_function = $persistent ? 'pg_pconnect' : 'pg_connect'; - // catch error - ob_start(); - $conn = $connect_function($connstr); - $error = ob_get_contents(); - ob_end_clean(); - if ($conn == false) { - return $this->raiseError(DB_ERROR_CONNECT_FAILED, null, - null, null, strip_tags($error)); - } - $this->connection = $conn; - return DB_OK; - } - - // }}} - // {{{ disconnect() - - /** - * Log out and disconnect from the database. - * - * @return bool true on success, false if not connected. - */ - function disconnect() - { - $ret = @pg_close($this->connection); - $this->connection = null; - return $ret; - } - - // }}} - // {{{ simpleQuery() - - /** - * Send a query to PostgreSQL and return the results as a - * PostgreSQL resource identifier. - * - * @param $query the SQL query - * - * @return int returns a valid PostgreSQL result for successful SELECT - * queries, DB_OK for other successful queries. A DB error code - * is returned on failure. - */ - function simpleQuery($query) - { - $ismanip = DB::isManip($query); - $this->last_query = $query; - $query = $this->modifyQuery($query); - if (!$this->autocommit && $ismanip) { - if ($this->transaction_opcount == 0) { - $result = @pg_exec($this->connection, 'begin;'); - if (!$result) { - return $this->pgsqlRaiseError(); - } - } - $this->transaction_opcount++; - } - $result = @pg_exec($this->connection, $query); - if (!$result) { - return $this->pgsqlRaiseError(); - } - // Determine which queries that should return data, and which - // should return an error code only. - if ($ismanip) { - $this->affected = @pg_cmdtuples($result); - return DB_OK; - } elseif (preg_match('/^\s*\(?\s*(SELECT(?!\s+INTO)|EXPLAIN|SHOW)\s/si', $query)) { - /* PostgreSQL commands: - ABORT, ALTER, BEGIN, CLOSE, CLUSTER, COMMIT, COPY, - CREATE, DECLARE, DELETE, DROP TABLE, EXPLAIN, FETCH, - GRANT, INSERT, LISTEN, LOAD, LOCK, MOVE, NOTIFY, RESET, - REVOKE, ROLLBACK, SELECT, SELECT INTO, SET, SHOW, - UNLISTEN, UPDATE, VACUUM - */ - $this->row[(int)$result] = 0; // reset the row counter. - $numrows = $this->numrows($result); - if (is_object($numrows)) { - return $numrows; - } - $this->num_rows[(int)$result] = $numrows; - $this->affected = 0; - return $result; - } else { - $this->affected = 0; - return DB_OK; - } - } - - // }}} - // {{{ nextResult() - - /** - * Move the internal pgsql result pointer to the next available result - * - * @param a valid fbsql result resource - * - * @access public - * - * @return true if a result is available otherwise return false - */ - function nextResult($result) - { - return false; - } - - // }}} - // {{{ errorCode() - - /** - * Determine PEAR::DB error code from the database's text error message. - * - * @param string $errormsg error message returned from the database - * @return integer an error number from a DB error constant - */ - function errorCode($errormsg) - { - static $error_regexps; - if (!isset($error_regexps)) { - $error_regexps = array( - '/(([Rr]elation|[Ss]equence|[Tt]able)( [\"\'].*[\"\'])? does not exist|[Cc]lass ".+" not found)$/' => DB_ERROR_NOSUCHTABLE, - '/[Cc]olumn [\"\'].*[\"\'] does not exist/' => DB_ERROR_NOSUCHFIELD, - '/[Rr]elation [\"\'].*[\"\'] already exists|[Cc]annot insert a duplicate key into (a )?unique index.*/' => DB_ERROR_ALREADY_EXISTS, - '/(divide|division) by zero$/' => DB_ERROR_DIVZERO, - '/pg_atoi: error in .*: can\'t parse /' => DB_ERROR_INVALID_NUMBER, - '/invalid input syntax for integer/' => DB_ERROR_INVALID_NUMBER, - '/ttribute [\"\'].*[\"\'] not found$|[Rr]elation [\"\'].*[\"\'] does not have attribute [\"\'].*[\"\']/' => DB_ERROR_NOSUCHFIELD, - '/parser: parse error at or near \"/' => DB_ERROR_SYNTAX, - '/syntax error at/' => DB_ERROR_SYNTAX, - '/violates not-null constraint/' => DB_ERROR_CONSTRAINT_NOT_NULL, - '/violates [\w ]+ constraint/' => DB_ERROR_CONSTRAINT, - '/referential integrity violation/' => DB_ERROR_CONSTRAINT - ); - } - foreach ($error_regexps as $regexp => $code) { - if (preg_match($regexp, $errormsg)) { - return $code; - } - } - // Fall back to DB_ERROR if there was no mapping. - return DB_ERROR; - } - - // }}} - // {{{ fetchInto() - - /** - * Fetch a row and insert the data into an existing array. - * - * Formating of the array and the data therein are configurable. - * See DB_result::fetchInto() for more information. - * - * @param resource $result query result identifier - * @param array $arr (reference) array where data from the row - * should be placed - * @param int $fetchmode how the resulting array should be indexed - * @param int $rownum the row number to fetch - * - * @return mixed DB_OK on success, null when end of result set is - * reached or on failure - * - * @see DB_result::fetchInto() - * @access private - */ - function fetchInto($result, &$arr, $fetchmode, $rownum=null) - { - $rownum = ($rownum !== null) ? $rownum : $this->row[$result]; - if ($rownum >= $this->num_rows[$result]) { - return null; - } - if ($fetchmode & DB_FETCHMODE_ASSOC) { - $arr = @pg_fetch_array($result, $rownum, PGSQL_ASSOC); - if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) { - $arr = array_change_key_case($arr, CASE_LOWER); - } - } else { - $arr = @pg_fetch_row($result, $rownum); - } - if (!$arr) { - $err = pg_errormessage($this->connection); - if (!$err) { - return null; - } - return $this->pgsqlRaiseError(); - } - if ($this->options['portability'] & DB_PORTABILITY_RTRIM) { - $this->_rtrimArrayValues($arr); - } - if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) { - $this->_convertNullArrayValuesToEmpty($arr); - } - $this->row[$result] = ++$rownum; - return DB_OK; - } - - // }}} - // {{{ freeResult() - - /** - * Free the internal resources associated with $result. - * - * @param $result int PostgreSQL result identifier - * - * @return bool true on success, false if $result is invalid - */ - function freeResult($result) - { - if (is_resource($result)) { - unset($this->row[(int)$result]); - unset($this->num_rows[(int)$result]); - $this->affected = 0; - return @pg_freeresult($result); - } - return false; - } - - // }}} - // {{{ quote() - - /** - * @deprecated Deprecated in release 1.6.0 - * @internal - */ - function quote($str) { - return $this->quoteSmart($str); - } - - // }}} - // {{{ quoteSmart() - - /** - * Format input so it can be safely used in a query - * - * @param mixed $in data to be quoted - * - * @return mixed Submitted variable's type = returned value: - * + null = the string NULL - * + boolean = string TRUE or FALSE - * + integer or double = the unquoted number - * + other (including strings and numeric strings) = - * the data escaped according to MySQL's settings - * then encapsulated between single quotes - * - * @internal - */ - function quoteSmart($in) - { - if (is_int($in) || is_double($in)) { - return $in; - } elseif (is_bool($in)) { - return $in ? 'TRUE' : 'FALSE'; - } elseif (is_null($in)) { - return 'NULL'; - } else { - return "'" . $this->escapeSimple($in) . "'"; - } - } - - // }}} - // {{{ escapeSimple() - - /** - * Escape a string according to the current DBMS's standards - * - * PostgreSQL treats a backslash as an escape character, so they are - * removed. - * - * Not using pg_escape_string() yet because it requires PostgreSQL - * to be at version 7.2 or greater. - * - * @param string $str the string to be escaped - * - * @return string the escaped string - * - * @internal - */ - function escapeSimple($str) { - return str_replace("'", "''", str_replace('\\', '\\\\', $str)); - } - - // }}} - // {{{ numCols() - - /** - * Get the number of columns in a result set. - * - * @param $result resource PostgreSQL result identifier - * - * @return int the number of columns per row in $result - */ - function numCols($result) - { - $cols = @pg_numfields($result); - if (!$cols) { - return $this->pgsqlRaiseError(); - } - return $cols; - } - - // }}} - // {{{ numRows() - - /** - * Get the number of rows in a result set. - * - * @param $result resource PostgreSQL result identifier - * - * @return int the number of rows in $result - */ - function numRows($result) - { - $rows = @pg_numrows($result); - if ($rows === null) { - return $this->pgsqlRaiseError(); - } - return $rows; - } - - // }}} - // {{{ errorNative() - - /** - * Get the native error code of the last error (if any) that - * occured on the current connection. - * - * @return int native PostgreSQL error code - */ - function errorNative() - { - return pg_errormessage($this->connection); - } - - // }}} - // {{{ autoCommit() - - /** - * Enable/disable automatic commits - */ - function autoCommit($onoff = false) - { - // XXX if $this->transaction_opcount > 0, we should probably - // issue a warning here. - $this->autocommit = $onoff ? true : false; - return DB_OK; - } - - // }}} - // {{{ commit() - - /** - * Commit the current transaction. - */ - function commit() - { - if ($this->transaction_opcount > 0) { - // (disabled) hack to shut up error messages from libpq.a - //@fclose(@fopen("php://stderr", "w")); - $result = @pg_exec($this->connection, 'end;'); - $this->transaction_opcount = 0; - if (!$result) { - return $this->pgsqlRaiseError(); - } - } - return DB_OK; - } - - // }}} - // {{{ rollback() - - /** - * Roll back (undo) the current transaction. - */ - function rollback() - { - if ($this->transaction_opcount > 0) { - $result = @pg_exec($this->connection, 'abort;'); - $this->transaction_opcount = 0; - if (!$result) { - return $this->pgsqlRaiseError(); - } - } - return DB_OK; - } - - // }}} - // {{{ affectedRows() - - /** - * Gets the number of rows affected by the last query. - * if the last query was a select, returns 0. - * - * @return int number of rows affected by the last query or DB_ERROR - */ - function affectedRows() - { - return $this->affected; - } - - // }}} - // {{{ nextId() - - /** - * Returns the next free id in a sequence - * - * @param string $seq_name name of the sequence - * @param boolean $ondemand when true, the seqence is automatically - * created if it does not exist - * - * @return int the next id number in the sequence. DB_Error if problem. - * - * @internal - * @see DB_common::nextID() - * @access public - */ - function nextId($seq_name, $ondemand = true) - { - $seqname = $this->getSequenceName($seq_name); - $repeat = false; - do { - $this->pushErrorHandling(PEAR_ERROR_RETURN); - $result =& $this->query("SELECT NEXTVAL('${seqname}')"); - $this->popErrorHandling(); - if ($ondemand && DB::isError($result) && - $result->getCode() == DB_ERROR_NOSUCHTABLE) { - $repeat = true; - $this->pushErrorHandling(PEAR_ERROR_RETURN); - $result = $this->createSequence($seq_name); - $this->popErrorHandling(); - if (DB::isError($result)) { - return $this->raiseError($result); - } - } else { - $repeat = false; - } - } while ($repeat); - if (DB::isError($result)) { - return $this->raiseError($result); - } - $arr = $result->fetchRow(DB_FETCHMODE_ORDERED); - $result->free(); - return $arr[0]; - } - - // }}} - // {{{ createSequence() - - /** - * Create the sequence - * - * @param string $seq_name the name of the sequence - * @return mixed DB_OK on success or DB error on error - * @access public - */ - function createSequence($seq_name) - { - $seqname = $this->getSequenceName($seq_name); - $result = $this->query("CREATE SEQUENCE ${seqname}"); - return $result; - } - - // }}} - // {{{ dropSequence() - - /** - * Drop a sequence - * - * @param string $seq_name the name of the sequence - * @return mixed DB_OK on success or DB error on error - * @access public - */ - function dropSequence($seq_name) - { - $seqname = $this->getSequenceName($seq_name); - return $this->query("DROP SEQUENCE ${seqname}"); - } - - // }}} - // {{{ modifyLimitQuery() - - function modifyLimitQuery($query, $from, $count, $params = array()) - { - $query = $query . " LIMIT $count OFFSET $from"; - return $query; - } - - // }}} - // {{{ pgsqlRaiseError() - - /** - * Gather information about an error, then use that info to create a - * DB error object and finally return that object. - * - * @param integer $errno PEAR error number (usually a DB constant) if - * manually raising an error - * @return object DB error object - * @see errorNative() - * @see errorCode() - * @see DB_common::raiseError() - */ - function pgsqlRaiseError($errno = null) - { - $native = $this->errorNative(); - if ($errno === null) { - $err = $this->errorCode($native); - } else { - $err = $errno; - } - return $this->raiseError($err, null, null, null, $native); - } - - // }}} - // {{{ _pgFieldFlags() - - /** - * Flags of a Field - * - * @param int $resource PostgreSQL result identifier - * @param int $num_field the field number - * - * @return string The flags of the field ("not_null", "default_value", - * "primary_key", "unique_key" and "multiple_key" - * are supported). The default value is passed - * through rawurlencode() in case there are spaces in it. - * @access private - */ - function _pgFieldFlags($resource, $num_field, $table_name) - { - $field_name = @pg_fieldname($resource, $num_field); - - $result = @pg_exec($this->connection, "SELECT f.attnotnull, f.atthasdef - FROM pg_attribute f, pg_class tab, pg_type typ - WHERE tab.relname = typ.typname - AND typ.typrelid = f.attrelid - AND f.attname = '$field_name' - AND tab.relname = '$table_name'"); - if (@pg_numrows($result) > 0) { - $row = @pg_fetch_row($result, 0); - $flags = ($row[0] == 't') ? 'not_null ' : ''; - - if ($row[1] == 't') { - $result = @pg_exec($this->connection, "SELECT a.adsrc - FROM pg_attribute f, pg_class tab, pg_type typ, pg_attrdef a - WHERE tab.relname = typ.typname AND typ.typrelid = f.attrelid - AND f.attrelid = a.adrelid AND f.attname = '$field_name' - AND tab.relname = '$table_name' AND f.attnum = a.adnum"); - $row = @pg_fetch_row($result, 0); - $num = preg_replace("/'(.*)'::\w+/", "\\1", $row[0]); - $flags .= 'default_' . rawurlencode($num) . ' '; - } - } else { - $flags = ''; - } - $result = @pg_exec($this->connection, "SELECT i.indisunique, i.indisprimary, i.indkey - FROM pg_attribute f, pg_class tab, pg_type typ, pg_index i - WHERE tab.relname = typ.typname - AND typ.typrelid = f.attrelid - AND f.attrelid = i.indrelid - AND f.attname = '$field_name' - AND tab.relname = '$table_name'"); - $count = @pg_numrows($result); - - for ($i = 0; $i < $count ; $i++) { - $row = @pg_fetch_row($result, $i); - $keys = explode(' ', $row[2]); - - if (in_array($num_field + 1, $keys)) { - $flags .= ($row[0] == 't' && $row[1] == 'f') ? 'unique_key ' : ''; - $flags .= ($row[1] == 't') ? 'primary_key ' : ''; - if (count($keys) > 1) - $flags .= 'multiple_key '; - } - } - - return trim($flags); - } - - // }}} - // {{{ tableInfo() - - /** - * Returns information about a table or a result set. - * - * NOTE: only supports 'table' and 'flags' if $result - * is a table name. - * - * @param object|string $result DB_result object from a query or a - * string containing the name of a table - * @param int $mode a valid tableInfo mode - * @return array an associative array with the information requested - * or an error object if something is wrong - * @access public - * @internal - * @see DB_common::tableInfo() - */ - function tableInfo($result, $mode = null) - { - if (isset($result->result)) { - /* - * Probably received a result object. - * Extract the result resource identifier. - */ - $id = $result->result; - $got_string = false; - } elseif (is_string($result)) { - /* - * Probably received a table name. - * Create a result resource identifier. - */ - $id = @pg_exec($this->connection, "SELECT * FROM $result LIMIT 0"); - $got_string = true; - } else { - /* - * Probably received a result resource identifier. - * Copy it. - * Deprecated. Here for compatibility only. - */ - $id = $result; - $got_string = false; - } - - if (!is_resource($id)) { - return $this->pgsqlRaiseError(DB_ERROR_NEED_MORE_DATA); - } - - if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) { - $case_func = 'strtolower'; - } else { - $case_func = 'strval'; - } - - $count = @pg_numfields($id); - - // made this IF due to performance (one if is faster than $count if's) - if (!$mode) { - - for ($i=0; $i<$count; $i++) { - $res[$i]['table'] = $got_string ? $case_func($result) : ''; - $res[$i]['name'] = $case_func(@pg_fieldname($id, $i)); - $res[$i]['type'] = @pg_fieldtype($id, $i); - $res[$i]['len'] = @pg_fieldsize($id, $i); - $res[$i]['flags'] = $got_string ? $this->_pgFieldflags($id, $i, $result) : ''; - } - - } else { // full - $res['num_fields']= $count; - - for ($i=0; $i<$count; $i++) { - $res[$i]['table'] = $got_string ? $case_func($result) : ''; - $res[$i]['name'] = $case_func(@pg_fieldname($id, $i)); - $res[$i]['type'] = @pg_fieldtype($id, $i); - $res[$i]['len'] = @pg_fieldsize($id, $i); - $res[$i]['flags'] = $got_string ? $this->_pgFieldFlags($id, $i, $result) : ''; - - if ($mode & DB_TABLEINFO_ORDER) { - $res['order'][$res[$i]['name']] = $i; - } - if ($mode & DB_TABLEINFO_ORDERTABLE) { - $res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i; - } - } - } - - // free the result only if we were called on a table - if ($got_string) { - @pg_freeresult($id); - } - return $res; - } - - // }}} - // {{{ getTablesQuery() - - /** - * Returns the query needed to get some backend info - * @param string $type What kind of info you want to retrieve - * @return string The SQL query string - */ - function getSpecialQuery($type) - { - switch ($type) { - case 'tables': - return "SELECT c.relname as \"Name\" - FROM pg_class c, pg_user u - WHERE c.relowner = u.usesysid AND c.relkind = 'r' - AND not exists (select 1 from pg_views where viewname = c.relname) - AND c.relname !~ '^pg_' - AND c.relname !~ '^sql_' - UNION - SELECT c.relname as \"Name\" - FROM pg_class c - WHERE c.relkind = 'r' - AND not exists (select 1 from pg_views where viewname = c.relname) - AND not exists (select 1 from pg_user where usesysid = c.relowner) - AND c.relname !~ '^pg_' - AND c.relname !~ '^sql_'"; - case 'views': - // Table cols: viewname | viewowner | definition - return 'SELECT viewname FROM pg_views'; - case 'users': - // cols: usename |usesysid|usecreatedb|usetrace|usesuper|usecatupd|passwd |valuntil - return 'SELECT usename FROM pg_user'; - case 'databases': - return 'SELECT datname FROM pg_database'; - case 'functions': - return 'SELECT proname FROM pg_proc'; - default: - return null; - } - } - - // }}} - -} - -/* - * Local variables: - * tab-width: 4 - * c-basic-offset: 4 - * End: - */ - -?> diff --git a/glmPEAR/DB/sqlite.php b/glmPEAR/DB/sqlite.php deleted file mode 100755 index 8d904f6..0000000 --- a/glmPEAR/DB/sqlite.php +++ /dev/null @@ -1,695 +0,0 @@ - | -// | Mika Tuupola | -// | Maintainer: Daniel Convissor | -// +----------------------------------------------------------------------+ -// -// $Id: sqlite.php,v 1.1.1.1 2008/04/28 15:20:47 jamie Exp $ - -require_once 'DB/common.php'; - -/** - * Database independent query interface definition for the SQLite - * PECL extension. - * - * @package DB - * @version $Id: sqlite.php,v 1.1.1.1 2008/04/28 15:20:47 jamie Exp $ - * @category Database - * @author Urs Gehrig - * @author Mika Tuupola - */ -class DB_sqlite extends DB_common -{ - // {{{ properties - - var $connection; - var $phptype, $dbsyntax; - var $prepare_tokens = array(); - var $prepare_types = array(); - var $_lasterror = ''; - - // }}} - // {{{ constructor - - /** - * Constructor for this class. - * - * Error codes according to sqlite_exec. Error Codes specification is - * in the {@link http://sqlite.org/c_interface.html online manual}. - * - * This errorhandling based on sqlite_exec is not yet implemented. - * - * @access public - */ - function DB_sqlite() - { - - $this->DB_common(); - $this->phptype = 'sqlite'; - $this->dbsyntax = 'sqlite'; - $this->features = array ( - 'prepare' => false, - 'pconnect' => true, - 'transactions' => false, - 'limit' => 'alter' - ); - - // SQLite data types, http://www.sqlite.org/datatypes.html - $this->keywords = array ( - 'BLOB' => '', - 'BOOLEAN' => '', - 'CHARACTER' => '', - 'CLOB' => '', - 'FLOAT' => '', - 'INTEGER' => '', - 'KEY' => '', - 'NATIONAL' => '', - 'NUMERIC' => '', - 'NVARCHAR' => '', - 'PRIMARY' => '', - 'TEXT' => '', - 'TIMESTAMP' => '', - 'UNIQUE' => '', - 'VARCHAR' => '', - 'VARYING' => '' - ); - $this->errorcode_map = array( - ); - } - - // }}} - // {{{ connect() - - /** - * Connect to a database represented by a file. - * - * @param $dsn the data source name; the file is taken as - * database; "sqlite://root:@host/test.db?mode=0644" - * @param $persistent (optional) whether the connection should - * be persistent - * @access public - * @return int DB_OK on success, a DB error on failure - */ - function connect($dsninfo, $persistent = false) - { - if (!DB::assertExtension('sqlite')) { - return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND); - } - - $this->dsn = $dsninfo; - - if ($dsninfo['database']) { - if (!file_exists($dsninfo['database'])) { - if (!touch($dsninfo['database'])) { - return $this->sqliteRaiseError(DB_ERROR_NOT_FOUND); - } - if (!isset($dsninfo['mode']) || - !is_numeric($dsninfo['mode'])) - { - $mode = 0644; - } else { - $mode = octdec($dsninfo['mode']); - } - if (!chmod($dsninfo['database'], $mode)) { - return $this->sqliteRaiseError(DB_ERROR_NOT_FOUND); - } - if (!file_exists($dsninfo['database'])) { - return $this->sqliteRaiseError(DB_ERROR_NOT_FOUND); - } - } - if (!is_file($dsninfo['database'])) { - return $this->sqliteRaiseError(DB_ERROR_INVALID); - } - if (!is_readable($dsninfo['database'])) { - return $this->sqliteRaiseError(DB_ERROR_ACCESS_VIOLATION); - } - } else { - return $this->sqliteRaiseError(DB_ERROR_ACCESS_VIOLATION); - } - - $connect_function = $persistent ? 'sqlite_popen' : 'sqlite_open'; - if (!($conn = @$connect_function($dsninfo['database']))) { - return $this->sqliteRaiseError(DB_ERROR_NODBSELECTED); - } - $this->connection = $conn; - - return DB_OK; - } - - // }}} - // {{{ disconnect() - - /** - * Log out and disconnect from the database. - * - * @access public - * @return bool true on success, false if not connected. - * @todo fix return values - */ - function disconnect() - { - $ret = @sqlite_close($this->connection); - $this->connection = null; - return $ret; - } - - // }}} - // {{{ simpleQuery() - - /** - * Send a query to SQLite and returns the results as a SQLite resource - * identifier. - * - * @param the SQL query - * @access public - * @return mixed returns a valid SQLite result for successful SELECT - * queries, DB_OK for other successful queries. A DB error is - * returned on failure. - */ - function simpleQuery($query) - { - $ismanip = DB::isManip($query); - $this->last_query = $query; - $query = $this->_modifyQuery($query); - ini_set('track_errors', true); - $result = @sqlite_query($query, $this->connection); - ini_restore('track_errors'); - $this->_lasterror = isset($php_errormsg) ? $php_errormsg : ''; - $this->result = $result; - if (!$this->result) { - return $this->sqliteRaiseError(null); - } - - /* sqlite_query() seems to allways return a resource */ - /* so cant use that. Using $ismanip instead */ - if (!$ismanip) { - $numRows = $this->numRows($result); - - /* if numRows() returned PEAR_Error */ - if (is_object($numRows)) { - return $numRows; - } - return $result; - } - return DB_OK; - } - - // }}} - // {{{ nextResult() - - /** - * Move the internal sqlite result pointer to the next available result. - * - * @param a valid sqlite result resource - * @access public - * @return true if a result is available otherwise return false - */ - function nextResult($result) - { - return false; - } - - // }}} - // {{{ fetchInto() - - /** - * Fetch a row and insert the data into an existing array. - * - * Formating of the array and the data therein are configurable. - * See DB_result::fetchInto() for more information. - * - * @param resource $result query result identifier - * @param array $arr (reference) array where data from the row - * should be placed - * @param int $fetchmode how the resulting array should be indexed - * @param int $rownum the row number to fetch - * - * @return mixed DB_OK on success, null when end of result set is - * reached or on failure - * - * @see DB_result::fetchInto() - * @access private - */ - function fetchInto($result, &$arr, $fetchmode, $rownum=null) - { - if ($rownum !== null) { - if (!@sqlite_seek($this->result, $rownum)) { - return null; - } - } - if ($fetchmode & DB_FETCHMODE_ASSOC) { - $arr = @sqlite_fetch_array($result, SQLITE_ASSOC); - if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) { - $arr = array_change_key_case($arr, CASE_LOWER); - } - } else { - $arr = @sqlite_fetch_array($result, SQLITE_NUM); - } - if (!$arr) { - /* See: http://bugs.php.net/bug.php?id=22328 */ - return null; - } - if ($this->options['portability'] & DB_PORTABILITY_RTRIM) { - /* - * Even though this DBMS already trims output, we do this because - * a field might have intentional whitespace at the end that - * gets removed by DB_PORTABILITY_RTRIM under another driver. - */ - $this->_rtrimArrayValues($arr); - } - if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) { - $this->_convertNullArrayValuesToEmpty($arr); - } - return DB_OK; - } - - // }}} - // {{{ freeResult() - - /** - * Free the internal resources associated with $result. - * - * @param $result SQLite result identifier - * @access public - * @return bool true on success, false if $result is invalid - */ - function freeResult(&$result) - { - // XXX No native free? - if (!is_resource($result)) { - return false; - } - $result = null; - return true; - } - - // }}} - // {{{ numCols() - - /** - * Gets the number of columns in a result set. - * - * @return number of columns in a result set - */ - function numCols($result) - { - $cols = @sqlite_num_fields($result); - if (!$cols) { - return $this->sqliteRaiseError(); - } - return $cols; - } - - // }}} - // {{{ numRows() - - /** - * Gets the number of rows affected by a query. - * - * @return number of rows affected by the last query - */ - function numRows($result) - { - $rows = @sqlite_num_rows($result); - if (!is_integer($rows)) { - return $this->raiseError(); - } - return $rows; - } - - // }}} - // {{{ affected() - - /** - * Gets the number of rows affected by a query. - * - * @return number of rows affected by the last query - */ - function affectedRows() - { - return @sqlite_changes($this->connection); - } - - // }}} - // {{{ errorNative() - - /** - * Get the native error string of the last error (if any) that - * occured on the current connection. - * - * This is used to retrieve more meaningfull error messages DB_pgsql - * way since sqlite_last_error() does not provide adequate info. - * - * @return string native SQLite error message - */ - function errorNative() - { - return($this->_lasterror); - } - - // }}} - // {{{ errorCode() - - /** - * Determine PEAR::DB error code from the database's text error message. - * - * @param string $errormsg error message returned from the database - * @return integer an error number from a DB error constant - */ - function errorCode($errormsg) - { - static $error_regexps; - if (!isset($error_regexps)) { - $error_regexps = array( - '/^no such table:/' => DB_ERROR_NOSUCHTABLE, - '/^table .* already exists$/' => DB_ERROR_ALREADY_EXISTS, - '/PRIMARY KEY must be unique/i' => DB_ERROR_CONSTRAINT, - '/is not unique/' => DB_ERROR_CONSTRAINT, - '/uniqueness constraint failed/' => DB_ERROR_CONSTRAINT, - '/may not be NULL/' => DB_ERROR_CONSTRAINT_NOT_NULL, - '/^no such column:/' => DB_ERROR_NOSUCHFIELD, - '/^near ".*": syntax error$/' => DB_ERROR_SYNTAX - ); - } - foreach ($error_regexps as $regexp => $code) { - if (preg_match($regexp, $errormsg)) { - return $code; - } - } - // Fall back to DB_ERROR if there was no mapping. - return DB_ERROR; - } - - // }}} - // {{{ dropSequence() - - /** - * Deletes a sequence - * - * @param string $seq_name name of the sequence to be deleted - * - * @return int DB_OK on success. DB_Error if problems. - * - * @internal - * @see DB_common::dropSequence() - * @access public - */ - function dropSequence($seq_name) - { - $seqname = $this->getSequenceName($seq_name); - return $this->query("DROP TABLE $seqname"); - } - - /** - * Creates a new sequence - * - * @param string $seq_name name of the new sequence - * - * @return int DB_OK on success. A DB_Error object is returned if - * problems arise. - * - * @internal - * @see DB_common::createSequence() - * @access public - */ - function createSequence($seq_name) - { - $seqname = $this->getSequenceName($seq_name); - $query = 'CREATE TABLE ' . $seqname . - ' (id INTEGER UNSIGNED PRIMARY KEY) '; - $result = $this->query($query); - if (DB::isError($result)) { - return($result); - } - $query = "CREATE TRIGGER ${seqname}_cleanup AFTER INSERT ON $seqname - BEGIN - DELETE FROM $seqname WHERE idquery($query); - if (DB::isError($result)) { - return($result); - } - } - - // }}} - // {{{ nextId() - - /** - * Returns the next free id in a sequence - * - * @param string $seq_name name of the sequence - * @param boolean $ondemand when true, the seqence is automatically - * created if it does not exist - * - * @return int the next id number in the sequence. DB_Error if problem. - * - * @internal - * @see DB_common::nextID() - * @access public - */ - function nextId($seq_name, $ondemand = true) - { - $seqname = $this->getSequenceName($seq_name); - - do { - $repeat = 0; - $this->pushErrorHandling(PEAR_ERROR_RETURN); - $result = $this->query("INSERT INTO $seqname VALUES (NULL)"); - $this->popErrorHandling(); - if ($result === DB_OK) { - $id = @sqlite_last_insert_rowid($this->connection); - if ($id != 0) { - return $id; - } - } elseif ($ondemand && DB::isError($result) && - $result->getCode() == DB_ERROR_NOSUCHTABLE) - { - $result = $this->createSequence($seq_name); - if (DB::isError($result)) { - return $this->raiseError($result); - } else { - $repeat = 1; - } - } - } while ($repeat); - - return $this->raiseError($result); - } - - // }}} - // {{{ getSpecialQuery() - - /** - * Returns the query needed to get some backend info. - * - * Refer to the online manual at http://sqlite.org/sqlite.html. - * - * @param string $type What kind of info you want to retrieve - * @return string The SQL query string - */ - function getSpecialQuery($type, $args=array()) - { - if (!is_array($args)) - return $this->raiseError('no key specified', null, null, null, - 'Argument has to be an array.'); - switch (strtolower($type)) { - case 'master': - return 'SELECT * FROM sqlite_master;'; - case 'tables': - return "SELECT name FROM sqlite_master WHERE type='table' " - . 'UNION ALL SELECT name FROM sqlite_temp_master ' - . "WHERE type='table' ORDER BY name;"; - case 'schema': - return 'SELECT sql FROM (SELECT * FROM sqlite_master UNION ALL ' - . 'SELECT * FROM sqlite_temp_master) ' - . "WHERE type!='meta' ORDER BY tbl_name, type DESC, name;"; - case 'schemax': - case 'schema_x': - /* - * Use like: - * $res = $db->query($db->getSpecialQuery('schema_x', array('table' => 'table3'))); - */ - return 'SELECT sql FROM (SELECT * FROM sqlite_master UNION ALL ' - . 'SELECT * FROM sqlite_temp_master) ' - . "WHERE tbl_name LIKE '{$args['table']}' AND type!='meta' " - . 'ORDER BY type DESC, name;'; - case 'alter': - /* - * SQLite does not support ALTER TABLE; this is a helper query - * to handle this. 'table' represents the table name, 'rows' - * the news rows to create, 'save' the row(s) to keep _with_ - * the data. - * - * Use like: - * $args = array( - * 'table' => $table, - * 'rows' => "id INTEGER PRIMARY KEY, firstname TEXT, surname TEXT, datetime TEXT", - * 'save' => "NULL, titel, content, datetime" - * ); - * $res = $db->query( $db->getSpecialQuery('alter', $args)); - */ - $rows = strtr($args['rows'], $this->keywords); - - $q = array( - 'BEGIN TRANSACTION', - "CREATE TEMPORARY TABLE {$args['table']}_backup ({$args['rows']})", - "INSERT INTO {$args['table']}_backup SELECT {$args['save']} FROM {$args['table']}", - "DROP TABLE {$args['table']}", - "CREATE TABLE {$args['table']} ({$args['rows']})", - "INSERT INTO {$args['table']} SELECT {$rows} FROM {$args['table']}_backup", - "DROP TABLE {$args['table']}_backup", - 'COMMIT', - ); - - // This is a dirty hack, since the above query will no get executed with a single - // query call; so here the query method will be called directly and return a select instead. - foreach ($q as $query) { - $this->query($query); - } - return "SELECT * FROM {$args['table']};"; - default: - return null; - } - } - - // }}} - // {{{ getDbFileStats() - - /** - * Get the file stats for the current database. - * - * Possible arguments are dev, ino, mode, nlink, uid, gid, rdev, size, - * atime, mtime, ctime, blksize, blocks or a numeric key between - * 0 and 12. - * - * @param string $arg Array key for stats() - * @return mixed array on an unspecified key, integer on a passed arg and - * false at a stats error. - */ - function getDbFileStats($arg = '') - { - $stats = stat($this->dsn['database']); - if ($stats == false) { - return false; - } - if (is_array($stats)) { - if (is_numeric($arg)) { - if (((int)$arg <= 12) & ((int)$arg >= 0)) { - return false; - } - return $stats[$arg ]; - } - if (array_key_exists(trim($arg), $stats)) { - return $stats[$arg ]; - } - } - return $stats; - } - - // }}} - // {{{ escapeSimple() - - /** - * Escape a string according to the current DBMS's standards - * - * In SQLite, this makes things safe for inserts/updates, but may - * cause problems when performing text comparisons against columns - * containing binary data. See the - * {@link http://php.net/sqlite_escape_string PHP manual} for more info. - * - * @param string $str the string to be escaped - * - * @return string the escaped string - * - * @since 1.6.1 - * @see DB_common::escapeSimple() - * @internal - */ - function escapeSimple($str) { - return @sqlite_escape_string($str); - } - - // }}} - // {{{ modifyLimitQuery() - - function modifyLimitQuery($query, $from, $count, $params = array()) - { - $query = $query . " LIMIT $count OFFSET $from"; - return $query; - } - - // }}} - // {{{ modifyQuery() - - /** - * "DELETE FROM table" gives 0 affected rows in SQLite. - * - * This little hack lets you know how many rows were deleted. - * - * @param string $query The SQL query string - * @return string The SQL query string - */ - function _modifyQuery($query) - { - if ($this->options['portability'] & DB_PORTABILITY_DELETE_COUNT) { - if (preg_match('/^\s*DELETE\s+FROM\s+(\S+)\s*$/i', $query)) { - $query = preg_replace('/^\s*DELETE\s+FROM\s+(\S+)\s*$/', - 'DELETE FROM \1 WHERE 1=1', $query); - } - } - return $query; - } - - // }}} - // {{{ sqliteRaiseError() - - /** - * Gather information about an error, then use that info to create a - * DB error object and finally return that object. - * - * @param integer $errno PEAR error number (usually a DB constant) if - * manually raising an error - * @return object DB error object - * @see errorNative() - * @see errorCode() - * @see DB_common::raiseError() - */ - function sqliteRaiseError($errno = null) - { - - $native = $this->errorNative(); - if ($errno === null) { - $errno = $this->errorCode($native); - } - - $errorcode = @sqlite_last_error($this->connection); - $userinfo = "$errorcode ** $this->last_query"; - - return $this->raiseError($errno, null, null, $userinfo, $native); - } - - // }}} -} - -/* - * Local variables: - * tab-width: 4 - * c-basic-offset: 4 - * End: - */ - -?> diff --git a/glmPEAR/DB/storage.php b/glmPEAR/DB/storage.php deleted file mode 100755 index 49cf0d2..0000000 --- a/glmPEAR/DB/storage.php +++ /dev/null @@ -1,495 +0,0 @@ - | -// | Maintainer: Daniel Convissor | -// +----------------------------------------------------------------------+ -// -// $Id: storage.php,v 1.1.1.1 2008/04/28 15:20:47 jamie Exp $ - -require_once 'DB.php'; - -/** - * Provides an object interface to a table row. - * - * It lets you add, delete and change rows using objects rather than SQL - * statements. - * - * @package DB - * @version $Id: storage.php,v 1.1.1.1 2008/04/28 15:20:47 jamie Exp $ - * @category Database - * @author Stig Bakken - */ -class DB_storage extends PEAR -{ - // {{{ properties - - /** the name of the table (or view, if the backend database supports - updates in views) we hold data from */ - var $_table = null; - - /** which column(s) in the table contains primary keys, can be a - string for single-column primary keys, or an array of strings - for multiple-column primary keys */ - var $_keycolumn = null; - - /** DB connection handle used for all transactions */ - var $_dbh = null; - - /** an assoc with the names of database fields stored as properties - in this object */ - var $_properties = array(); - - /** an assoc with the names of the properties in this object that - have been changed since they were fetched from the database */ - var $_changes = array(); - - /** flag that decides if data in this object can be changed. - objects that don't have their table's key column in their - property lists will be flagged as read-only. */ - var $_readonly = false; - - /** function or method that implements a validator for fields that - are set, this validator function returns true if the field is - valid, false if not */ - var $_validator = null; - - // }}} - // {{{ constructor - - /** - * Constructor - * - * @param $table string the name of the database table - * - * @param $keycolumn mixed string with name of key column, or array of - * strings if the table has a primary key of more than one column - * - * @param $dbh object database connection object - * - * @param $validator mixed function or method used to validate - * each new value, called with three parameters: the name of the - * field/column that is changing, a reference to the new value and - * a reference to this object - * - */ - function DB_storage($table, $keycolumn, &$dbh, $validator = null) - { - $this->PEAR('DB_Error'); - $this->_table = $table; - $this->_keycolumn = $keycolumn; - $this->_dbh = $dbh; - $this->_readonly = false; - $this->_validator = $validator; - } - - // }}} - // {{{ _makeWhere() - - /** - * Utility method to build a "WHERE" clause to locate ourselves in - * the table. - * - * XXX future improvement: use rowids? - * - * @access private - */ - function _makeWhere($keyval = null) - { - if (is_array($this->_keycolumn)) { - if ($keyval === null) { - for ($i = 0; $i < sizeof($this->_keycolumn); $i++) { - $keyval[] = $this->{$this->_keycolumn[$i]}; - } - } - $whereclause = ''; - for ($i = 0; $i < sizeof($this->_keycolumn); $i++) { - if ($i > 0) { - $whereclause .= ' AND '; - } - $whereclause .= $this->_keycolumn[$i]; - if (is_null($keyval[$i])) { - // there's not much point in having a NULL key, - // but we support it anyway - $whereclause .= ' IS NULL'; - } else { - $whereclause .= ' = ' . $this->_dbh->quote($keyval[$i]); - } - } - } else { - if ($keyval === null) { - $keyval = @$this->{$this->_keycolumn}; - } - $whereclause = $this->_keycolumn; - if (is_null($keyval)) { - // there's not much point in having a NULL key, - // but we support it anyway - $whereclause .= ' IS NULL'; - } else { - $whereclause .= ' = ' . $this->_dbh->quote($keyval); - } - } - return $whereclause; - } - - // }}} - // {{{ setup() - - /** - * Method used to initialize a DB_storage object from the - * configured table. - * - * @param $keyval mixed the key[s] of the row to fetch (string or array) - * - * @return int DB_OK on success, a DB error if not - */ - function setup($keyval) - { - $whereclause = $this->_makeWhere($keyval); - $query = 'SELECT * FROM ' . $this->_table . ' WHERE ' . $whereclause; - $sth = $this->_dbh->query($query); - if (DB::isError($sth)) { - return $sth; - } - $row = $sth->fetchRow(DB_FETCHMODE_ASSOC); - if (DB::isError($row)) { - return $row; - } - if (!$row) { - return $this->raiseError(null, DB_ERROR_NOT_FOUND, null, null, - $query, null, true); - } - foreach ($row as $key => $value) { - $this->_properties[$key] = true; - $this->$key = $value; - } - return DB_OK; - } - - // }}} - // {{{ insert() - - /** - * Create a new (empty) row in the configured table for this - * object. - */ - function insert($newpk) - { - if (is_array($this->_keycolumn)) { - $primarykey = $this->_keycolumn; - } else { - $primarykey = array($this->_keycolumn); - } - settype($newpk, "array"); - for ($i = 0; $i < sizeof($primarykey); $i++) { - $pkvals[] = $this->_dbh->quote($newpk[$i]); - } - - $sth = $this->_dbh->query("INSERT INTO $this->_table (" . - implode(",", $primarykey) . ") VALUES(" . - implode(",", $pkvals) . ")"); - if (DB::isError($sth)) { - return $sth; - } - if (sizeof($newpk) == 1) { - $newpk = $newpk[0]; - } - $this->setup($newpk); - } - - // }}} - // {{{ toString() - - /** - * Output a simple description of this DB_storage object. - * @return string object description - */ - function toString() - { - $info = strtolower(get_class($this)); - $info .= " (table="; - $info .= $this->_table; - $info .= ", keycolumn="; - if (is_array($this->_keycolumn)) { - $info .= "(" . implode(",", $this->_keycolumn) . ")"; - } else { - $info .= $this->_keycolumn; - } - $info .= ", dbh="; - if (is_object($this->_dbh)) { - $info .= $this->_dbh->toString(); - } else { - $info .= "null"; - } - $info .= ")"; - if (sizeof($this->_properties)) { - $info .= " [loaded, key="; - $keyname = $this->_keycolumn; - if (is_array($keyname)) { - $info .= "("; - for ($i = 0; $i < sizeof($keyname); $i++) { - if ($i > 0) { - $info .= ","; - } - $info .= $this->$keyname[$i]; - } - $info .= ")"; - } else { - $info .= $this->$keyname; - } - $info .= "]"; - } - if (sizeof($this->_changes)) { - $info .= " [modified]"; - } - return $info; - } - - // }}} - // {{{ dump() - - /** - * Dump the contents of this object to "standard output". - */ - function dump() - { - foreach ($this->_properties as $prop => $foo) { - print "$prop = "; - print htmlentities($this->$prop); - print "
\n"; - } - } - - // }}} - // {{{ &create() - - /** - * Static method used to create new DB storage objects. - * @param $data assoc. array where the keys are the names - * of properties/columns - * @return object a new instance of DB_storage or a subclass of it - */ - function &create($table, &$data) - { - $classname = strtolower(get_class($this)); - $obj =& new $classname($table); - foreach ($data as $name => $value) { - $obj->_properties[$name] = true; - $obj->$name = &$value; - } - return $obj; - } - - // }}} - // {{{ loadFromQuery() - - /** - * Loads data into this object from the given query. If this - * object already contains table data, changes will be saved and - * the object re-initialized first. - * - * @param $query SQL query - * - * @param $params parameter list in case you want to use - * prepare/execute mode - * - * @return int DB_OK on success, DB_WARNING_READ_ONLY if the - * returned object is read-only (because the object's specified - * key column was not found among the columns returned by $query), - * or another DB error code in case of errors. - */ -// XXX commented out for now -/* - function loadFromQuery($query, $params = null) - { - if (sizeof($this->_properties)) { - if (sizeof($this->_changes)) { - $this->store(); - $this->_changes = array(); - } - $this->_properties = array(); - } - $rowdata = $this->_dbh->getRow($query, DB_FETCHMODE_ASSOC, $params); - if (DB::isError($rowdata)) { - return $rowdata; - } - reset($rowdata); - $found_keycolumn = false; - while (list($key, $value) = each($rowdata)) { - if ($key == $this->_keycolumn) { - $found_keycolumn = true; - } - $this->_properties[$key] = true; - $this->$key = &$value; - unset($value); // have to unset, or all properties will - // refer to the same value - } - if (!$found_keycolumn) { - $this->_readonly = true; - return DB_WARNING_READ_ONLY; - } - return DB_OK; - } - */ - - // }}} - // {{{ set() - - /** - * Modify an attriute value. - */ - function set($property, $newvalue) - { - // only change if $property is known and object is not - // read-only - if ($this->_readonly) { - return $this->raiseError(null, DB_WARNING_READ_ONLY, null, - null, null, null, true); - } - if (@isset($this->_properties[$property])) { - if (empty($this->_validator)) { - $valid = true; - } else { - $valid = @call_user_func($this->_validator, - $this->_table, - $property, - $newvalue, - $this->$property, - $this); - } - if ($valid) { - $this->$property = $newvalue; - if (empty($this->_changes[$property])) { - $this->_changes[$property] = 0; - } else { - $this->_changes[$property]++; - } - } else { - return $this->raiseError(null, DB_ERROR_INVALID, null, - null, "invalid field: $property", - null, true); - } - return true; - } - return $this->raiseError(null, DB_ERROR_NOSUCHFIELD, null, - null, "unknown field: $property", - null, true); - } - - // }}} - // {{{ &get() - - /** - * Fetch an attribute value. - * - * @param string attribute name - * - * @return attribute contents, or null if the attribute name is - * unknown - */ - function &get($property) - { - // only return if $property is known - if (isset($this->_properties[$property])) { - return $this->$property; - } - $tmp = null; - return $tmp; - } - - // }}} - // {{{ _DB_storage() - - /** - * Destructor, calls DB_storage::store() if there are changes - * that are to be kept. - */ - function _DB_storage() - { - if (sizeof($this->_changes)) { - $this->store(); - } - $this->_properties = array(); - $this->_changes = array(); - $this->_table = null; - } - - // }}} - // {{{ store() - - /** - * Stores changes to this object in the database. - * - * @return DB_OK or a DB error - */ - function store() - { - foreach ($this->_changes as $name => $foo) { - $params[] = &$this->$name; - $vars[] = $name . ' = ?'; - } - if ($vars) { - $query = 'UPDATE ' . $this->_table . ' SET ' . - implode(', ', $vars) . ' WHERE ' . - $this->_makeWhere(); - $stmt = $this->_dbh->prepare($query); - $res = $this->_dbh->execute($stmt, $params); - if (DB::isError($res)) { - return $res; - } - $this->_changes = array(); - } - return DB_OK; - } - - // }}} - // {{{ remove() - - /** - * Remove the row represented by this object from the database. - * - * @return mixed DB_OK or a DB error - */ - function remove() - { - if ($this->_readonly) { - return $this->raiseError(null, DB_WARNING_READ_ONLY, null, - null, null, null, true); - } - $query = 'DELETE FROM ' . $this->_table .' WHERE '. - $this->_makeWhere(); - $res = $this->_dbh->query($query); - if (DB::isError($res)) { - return $res; - } - foreach ($this->_properties as $prop => $foo) { - unset($this->$prop); - } - $this->_properties = array(); - $this->_changes = array(); - return DB_OK; - } - - // }}} -} - -/* - * Local variables: - * tab-width: 4 - * c-basic-offset: 4 - * End: - */ - -?> diff --git a/glmPEAR/DB/sybase.php b/glmPEAR/DB/sybase.php deleted file mode 100755 index 1632e72..0000000 --- a/glmPEAR/DB/sybase.php +++ /dev/null @@ -1,837 +0,0 @@ - | -// | Antônio Carlos Venâncio Júnior | -// | Maintainer: Daniel Convissor | -// +----------------------------------------------------------------------+ -// -// $Id: sybase.php,v 1.1.1.1 2008/04/28 15:20:47 jamie Exp $ - - -// TODO -// - This driver may fail with multiple connections under the same -// user/pass/host and different databases - - -require_once 'DB/common.php'; - -/** - * Database independent query interface definition for PHP's Sybase - * extension. - * - * @package DB - * @version $Id: sybase.php,v 1.1.1.1 2008/04/28 15:20:47 jamie Exp $ - * @category Database - * @author Sterling Hughes - * @author Antônio Carlos Venâncio Júnior - */ -class DB_sybase extends DB_common -{ - // {{{ properties - - var $connection; - var $phptype, $dbsyntax; - var $prepare_tokens = array(); - var $prepare_types = array(); - var $transaction_opcount = 0; - var $autocommit = true; - - // }}} - // {{{ constructor - - /** - * DB_sybase constructor. - * - * @access public - */ - function DB_sybase() - { - $this->DB_common(); - $this->phptype = 'sybase'; - $this->dbsyntax = 'sybase'; - $this->features = array( - 'prepare' => false, - 'pconnect' => true, - 'transactions' => false, - 'limit' => 'emulate' - ); - $this->errorcode_map = array( - ); - } - - // }}} - // {{{ connect() - - /** - * Connect to a database and log in as the specified user. - * - * @param $dsn the data source name (see DB::parseDSN for syntax) - * @param $persistent (optional) whether the connection should - * be persistent - * @access public - * @return int DB_OK on success, a DB error on failure - */ - function connect($dsninfo, $persistent = false) - { - if (!DB::assertExtension('sybase') && - !DB::assertExtension('sybase_ct')) - { - return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND); - } - - $this->dsn = $dsninfo; - - $interface = $dsninfo['hostspec'] ? $dsninfo['hostspec'] : 'localhost'; - $connect_function = $persistent ? 'sybase_pconnect' : 'sybase_connect'; - - if ($interface && $dsninfo['username'] && $dsninfo['password']) { - $conn = @$connect_function($interface, $dsninfo['username'], - $dsninfo['password']); - } elseif ($interface && $dsninfo['username']) { - /* - * Using false for pw as a workaround to avoid segfault. - * See PEAR bug 631 - */ - $conn = @$connect_function($interface, $dsninfo['username'], - false); - } else { - $conn = false; - } - - if (!$conn) { - return $this->raiseError(DB_ERROR_CONNECT_FAILED); - } - - if ($dsninfo['database']) { - if (!@sybase_select_db($dsninfo['database'], $conn)) { - return $this->raiseError(DB_ERROR_NODBSELECTED, null, - null, null, @sybase_get_last_message()); - } - $this->_db = $dsninfo['database']; - } - - $this->connection = $conn; - return DB_OK; - } - - // }}} - // {{{ disconnect() - - /** - * Log out and disconnect from the database. - * - * @access public - * - * @return bool true on success, false if not connected. - */ - function disconnect() - { - $ret = @sybase_close($this->connection); - $this->connection = null; - return $ret; - } - - // }}} - // {{{ errorNative() - - /** - * Get the last server error messge (if any) - * - * @return string sybase last error message - */ - function errorNative() - { - return @sybase_get_last_message(); - } - - // }}} - // {{{ errorCode() - - /** - * Determine PEAR::DB error code from the database's text error message. - * - * @param string $errormsg error message returned from the database - * @return integer an error number from a DB error constant - */ - function errorCode($errormsg) - { - static $error_regexps; - if (!isset($error_regexps)) { - $error_regexps = array( - '/Incorrect syntax near/' - => DB_ERROR_SYNTAX, - '/^Unclosed quote before the character string [\"\'].*[\"\']\./' - => DB_ERROR_SYNTAX, - '/Implicit conversion from datatype [\"\'].+[\"\'] to [\"\'].+[\"\'] is not allowed\./' - => DB_ERROR_INVALID_NUMBER, - '/Cannot drop the table [\"\'].+[\"\'], because it doesn\'t exist in the system catalogs\./' - => DB_ERROR_NOSUCHTABLE, - '/Only the owner of object [\"\'].+[\"\'] or a user with System Administrator \(SA\) role can run this command\./' - => DB_ERROR_ACCESS_VIOLATION, - '/^.+ permission denied on object .+, database .+, owner .+/' - => DB_ERROR_ACCESS_VIOLATION, - '/^.* permission denied, database .+, owner .+/' - => DB_ERROR_ACCESS_VIOLATION, - '/[^.*] not found\./' - => DB_ERROR_NOSUCHTABLE, - '/There is already an object named/' - => DB_ERROR_ALREADY_EXISTS, - '/Invalid column name/' - => DB_ERROR_NOSUCHFIELD, - '/does not allow null values/' - => DB_ERROR_CONSTRAINT_NOT_NULL, - '/Command has been aborted/' - => DB_ERROR_CONSTRAINT, - ); - } - - foreach ($error_regexps as $regexp => $code) { - if (preg_match($regexp, $errormsg)) { - return $code; - } - } - return DB_ERROR; - } - - // }}} - // {{{ sybaseRaiseError() - - /** - * Gather information about an error, then use that info to create a - * DB error object and finally return that object. - * - * @param integer $errno PEAR error number (usually a DB constant) if - * manually raising an error - * @return object DB error object - * @see errorNative() - * @see errorCode() - * @see DB_common::raiseError() - */ - function sybaseRaiseError($errno = null) - { - $native = $this->errorNative(); - if ($errno === null) { - $errno = $this->errorCode($native); - } - return $this->raiseError($errno, null, null, null, $native); - } - - // }}} - // {{{ simpleQuery() - - /** - * Send a query to Sybase and return the results as a Sybase resource - * identifier. - * - * @param the SQL query - * - * @access public - * - * @return mixed returns a valid Sybase result for successful SELECT - * queries, DB_OK for other successful queries. A DB error is - * returned on failure. - */ - function simpleQuery($query) - { - $ismanip = DB::isManip($query); - $this->last_query = $query; - if (!@sybase_select_db($this->_db, $this->connection)) { - return $this->sybaseRaiseError(DB_ERROR_NODBSELECTED); - } - $query = $this->modifyQuery($query); - if (!$this->autocommit && $ismanip) { - if ($this->transaction_opcount == 0) { - $result = @sybase_query('BEGIN TRANSACTION', $this->connection); - if (!$result) { - return $this->sybaseRaiseError(); - } - } - $this->transaction_opcount++; - } - $result = @sybase_query($query, $this->connection); - if (!$result) { - return $this->sybaseRaiseError(); - } - if (is_resource($result)) { - $numrows = $this->numRows($result); - if (is_object($numrows)) { - return $numrows; - } - $this->num_rows[(int)$result] = $numrows; - return $result; - } - // Determine which queries that should return data, and which - // should return an error code only. - return $ismanip ? DB_OK : $result; - } - - // }}} - // {{{ nextResult() - - /** - * Move the internal sybase result pointer to the next available result - * - * @param a valid sybase result resource - * - * @access public - * - * @return true if a result is available otherwise return false - */ - function nextResult($result) - { - return false; - } - - // }}} - // {{{ fetchInto() - - /** - * Fetch a row and insert the data into an existing array. - * - * Formating of the array and the data therein are configurable. - * See DB_result::fetchInto() for more information. - * - * @param resource $result query result identifier - * @param array $arr (reference) array where data from the row - * should be placed - * @param int $fetchmode how the resulting array should be indexed - * @param int $rownum the row number to fetch - * - * @return mixed DB_OK on success, null when end of result set is - * reached or on failure - * - * @see DB_result::fetchInto() - * @access private - */ - function fetchInto($result, &$arr, $fetchmode, $rownum=null) - { - if ($rownum !== null) { - if (!@sybase_data_seek($result, $rownum)) { - return null; - } - } - if ($fetchmode & DB_FETCHMODE_ASSOC) { - if (function_exists('sybase_fetch_assoc')) { - $arr = @sybase_fetch_assoc($result); - } else { - if ($arr = @sybase_fetch_array($result)) { - foreach ($arr as $key => $value) { - if (is_int($key)) { - unset($arr[$key]); - } - } - } - } - if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) { - $arr = array_change_key_case($arr, CASE_LOWER); - } - } else { - $arr = @sybase_fetch_row($result); - } - if (!$arr) { - // reported not work as seems that sybase_get_last_message() - // always return a message here - //if ($errmsg = @sybase_get_last_message()) { - // return $this->sybaseRaiseError($errmsg); - //} else { - return null; - //} - } - if ($this->options['portability'] & DB_PORTABILITY_RTRIM) { - $this->_rtrimArrayValues($arr); - } - if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) { - $this->_convertNullArrayValuesToEmpty($arr); - } - return DB_OK; - } - - // }}} - // {{{ freeResult() - - /** - * Free the internal resources associated with $result. - * - * @param $result Sybase result identifier - * - * @access public - * - * @return bool true on success, false if $result is invalid - */ - function freeResult($result) - { - unset($this->num_rows[(int)$result]); - return @sybase_free_result($result); - } - - // }}} - // {{{ numCols() - - /** - * Get the number of columns in a result set. - * - * @param $result Sybase result identifier - * - * @access public - * - * @return int the number of columns per row in $result - */ - function numCols($result) - { - $cols = @sybase_num_fields($result); - if (!$cols) { - return $this->sybaseRaiseError(); - } - return $cols; - } - - // }}} - // {{{ numRows() - - /** - * Get the number of rows in a result set. - * - * @param $result Sybase result identifier - * - * @access public - * - * @return int the number of rows in $result - */ - function numRows($result) - { - $rows = @sybase_num_rows($result); - if ($rows === false) { - return $this->sybaseRaiseError(); - } - return $rows; - } - - // }}} - // {{{ affectedRows() - - /** - * Gets the number of rows affected by the data manipulation - * query. For other queries, this function returns 0. - * - * @return number of rows affected by the last query - */ - function affectedRows() - { - if (DB::isManip($this->last_query)) { - $result = @sybase_affected_rows($this->connection); - } else { - $result = 0; - } - return $result; - } - - // }}} - // {{{ nextId() - - /** - * Returns the next free id in a sequence - * - * @param string $seq_name name of the sequence - * @param boolean $ondemand when true, the seqence is automatically - * created if it does not exist - * - * @return int the next id number in the sequence. DB_Error if problem. - * - * @internal - * @see DB_common::nextID() - * @access public - */ - function nextId($seq_name, $ondemand = true) - { - $seqname = $this->getSequenceName($seq_name); - if (!@sybase_select_db($this->_db, $this->connection)) { - return $this->sybaseRaiseError(DB_ERROR_NODBSELECTED); - } - $repeat = 0; - do { - $this->pushErrorHandling(PEAR_ERROR_RETURN); - $result = $this->query("INSERT INTO $seqname (vapor) VALUES (0)"); - $this->popErrorHandling(); - if ($ondemand && DB::isError($result) && - ($result->getCode() == DB_ERROR || $result->getCode() == DB_ERROR_NOSUCHTABLE)) - { - $repeat = 1; - $result = $this->createSequence($seq_name); - if (DB::isError($result)) { - return $this->raiseError($result); - } - } elseif (!DB::isError($result)) { - $result =& $this->query("SELECT @@IDENTITY FROM $seqname"); - $repeat = 0; - } else { - $repeat = false; - } - } while ($repeat); - if (DB::isError($result)) { - return $this->raiseError($result); - } - $result = $result->fetchRow(DB_FETCHMODE_ORDERED); - return $result[0]; - } - - /** - * Creates a new sequence - * - * @param string $seq_name name of the new sequence - * - * @return int DB_OK on success. A DB_Error object is returned if - * problems arise. - * - * @internal - * @see DB_common::createSequence() - * @access public - */ - function createSequence($seq_name) - { - $seqname = $this->getSequenceName($seq_name); - return $this->query("CREATE TABLE $seqname ". - '(id numeric(10,0) IDENTITY NOT NULL ,' . - 'vapor int NULL)'); - } - - // }}} - // {{{ dropSequence() - - /** - * Deletes a sequence - * - * @param string $seq_name name of the sequence to be deleted - * - * @return int DB_OK on success. DB_Error if problems. - * - * @internal - * @see DB_common::dropSequence() - * @access public - */ - function dropSequence($seq_name) - { - $seqname = $this->getSequenceName($seq_name); - return $this->query("DROP TABLE $seqname"); - } - - // }}} - // {{{ getSpecialQuery() - - /** - * Returns the query needed to get some backend info - * @param string $type What kind of info you want to retrieve - * @return string The SQL query string - */ - function getSpecialQuery($type) - { - switch ($type) { - case 'tables': - return "select name from sysobjects where type = 'U' order by name"; - case 'views': - return "select name from sysobjects where type = 'V'"; - default: - return null; - } - } - - // }}} - // {{{ autoCommit() - - /** - * Enable/disable automatic commits - */ - function autoCommit($onoff = false) - { - // XXX if $this->transaction_opcount > 0, we should probably - // issue a warning here. - $this->autocommit = $onoff ? true : false; - return DB_OK; - } - - // }}} - // {{{ commit() - - /** - * Commit the current transaction. - */ - function commit() - { - if ($this->transaction_opcount > 0) { - if (!@sybase_select_db($this->_db, $this->connection)) { - return $this->sybaseRaiseError(DB_ERROR_NODBSELECTED); - } - $result = @sybase_query('COMMIT', $this->connection); - $this->transaction_opcount = 0; - if (!$result) { - return $this->sybaseRaiseError(); - } - } - return DB_OK; - } - - // }}} - // {{{ rollback() - - /** - * Roll back (undo) the current transaction. - */ - function rollback() - { - if ($this->transaction_opcount > 0) { - if (!@sybase_select_db($this->_db, $this->connection)) { - return $this->sybaseRaiseError(DB_ERROR_NODBSELECTED); - } - $result = @sybase_query('ROLLBACK', $this->connection); - $this->transaction_opcount = 0; - if (!$result) { - return $this->sybaseRaiseError(); - } - } - return DB_OK; - } - - // }}} - // {{{ tableInfo() - - /** - * Returns information about a table or a result set. - * - * NOTE: only supports 'table' and 'flags' if $result - * is a table name. - * - * @param object|string $result DB_result object from a query or a - * string containing the name of a table - * @param int $mode a valid tableInfo mode - * @return array an associative array with the information requested - * or an error object if something is wrong - * @access public - * @internal - * @since 1.6.0 - * @see DB_common::tableInfo() - */ - function tableInfo($result, $mode = null) - { - if (isset($result->result)) { - /* - * Probably received a result object. - * Extract the result resource identifier. - */ - $id = $result->result; - $got_string = false; - } elseif (is_string($result)) { - /* - * Probably received a table name. - * Create a result resource identifier. - */ - if (!@sybase_select_db($this->_db, $this->connection)) { - return $this->sybaseRaiseError(DB_ERROR_NODBSELECTED); - } - $id = @sybase_query("SELECT * FROM $result WHERE 1=0", - $this->connection); - $got_string = true; - } else { - /* - * Probably received a result resource identifier. - * Copy it. - * Depricated. Here for compatibility only. - */ - $id = $result; - $got_string = false; - } - - if (!is_resource($id)) { - return $this->sybaseRaiseError(DB_ERROR_NEED_MORE_DATA); - } - - if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) { - $case_func = 'strtolower'; - } else { - $case_func = 'strval'; - } - - $count = @sybase_num_fields($id); - - // made this IF due to performance (one if is faster than $count if's) - if (!$mode) { - - for ($i=0; $i<$count; $i++) { - $f = @sybase_fetch_field($id, $i); - - // column_source is often blank - if ($got_string) { - $res[$i]['table'] = $case_func($result); - } else { - $res[$i]['table'] = $case_func($f->column_source); - } - $res[$i]['name'] = $case_func($f->name); - $res[$i]['type'] = $f->type; - $res[$i]['len'] = $f->max_length; - if ($res[$i]['table']) { - $res[$i]['flags'] = $this->_sybase_field_flags( - $res[$i]['table'], $res[$i]['name']); - } else { - $res[$i]['flags'] = ''; - } - } - - } else { - // get full info - - $res['num_fields'] = $count; - - for ($i=0; $i<$count; $i++) { - $f = @sybase_fetch_field($id, $i); - - // column_source is often blank - if ($got_string) { - $res[$i]['table'] = $case_func($result); - } else { - $res[$i]['table'] = $case_func($f->column_source); - } - $res[$i]['name'] = $case_func($f->name); - $res[$i]['type'] = $f->type; - $res[$i]['len'] = $f->max_length; - if ($res[$i]['table']) { - $res[$i]['flags'] = $this->_sybase_field_flags( - $res[$i]['table'], $res[$i]['name']); - } else { - $res[$i]['flags'] = ''; - } - - if ($mode & DB_TABLEINFO_ORDER) { - $res['order'][$res[$i]['name']] = $i; - } - if ($mode & DB_TABLEINFO_ORDERTABLE) { - $res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i; - } - } - } - - // free the result only if we were called on a table - if ($got_string) { - @sybase_free_result($id); - } - return $res; - } - - // }}} - // {{{ _sybase_field_flags() - - /** - * Get the flags for a field. - * - * Currently supports: - * + unique_key (unique index, unique check or primary_key) - * + multiple_key (multi-key index) - * - * @param string $table table name - * @param string $column field name - * @return string space delimited string of flags. Empty string if none. - * @access private - */ - function _sybase_field_flags($table, $column) - { - static $tableName = null; - static $flags = array(); - - if ($table != $tableName) { - $flags = array(); - $tableName = $table; - - // get unique/primary keys - $res = $this->getAll("sp_helpindex $table", DB_FETCHMODE_ASSOC); - - if (!isset($res[0]['index_description'])) { - return ''; - } - - foreach ($res as $val) { - $keys = explode(', ', trim($val['index_keys'])); - - if (sizeof($keys) > 1) { - foreach ($keys as $key) { - $this->_add_flag($flags[$key], 'multiple_key'); - } - } - - if (strpos($val['index_description'], 'unique')) { - foreach ($keys as $key) { - $this->_add_flag($flags[$key], 'unique_key'); - } - } - } - - } - - if (array_key_exists($column, $flags)) { - return(implode(' ', $flags[$column])); - } - - return ''; - } - - // }}} - // {{{ _add_flag() - - /** - * Adds a string to the flags array if the flag is not yet in there - * - if there is no flag present the array is created. - * - * @param array $array reference of flags array to add a value to - * @param mixed $value value to add to the flag array - * @access private - */ - function _add_flag(&$array, $value) - { - if (!is_array($array)) { - $array = array($value); - } elseif (!in_array($value, $array)) { - array_push($array, $value); - } - } - - // }}} - // {{{ quoteIdentifier() - - /** - * Quote a string so it can be safely used as a table / column name - * - * Quoting style depends on which database driver is being used. - * - * @param string $str identifier name to be quoted - * - * @return string quoted identifier string - * - * @since 1.6.0 - * @access public - */ - function quoteIdentifier($str) - { - return '[' . str_replace(']', ']]', $str) . ']'; - } - - // }}} - -} - -/* - * Local variables: - * tab-width: 4 - * c-basic-offset: 4 - * End: - */ - -?> diff --git a/glmPEAR/Date.php b/glmPEAR/Date.php deleted file mode 100755 index 3546caf..0000000 --- a/glmPEAR/Date.php +++ /dev/null @@ -1,5863 +0,0 @@ - - * @author Pierre-Alain Joye - * @author Firman Wandayandi - * @author C.A. Woodcock - * @copyright 1997-2007 Baba Buehler, Pierre-Alain Joye, Firman Wandayandi, C.A. Woodcock - * @license http://www.opensource.org/licenses/bsd-license.php - * BSD License - * @version CVS: $Id: Date.php,v 1.1.1.1 2008/04/28 15:20:46 jamie Exp $ - * @link http://pear.php.net/package/Date - */ - - -// }}} -// {{{ Error constants - -define('DATE_ERROR_INVALIDDATE', 1); -define('DATE_ERROR_INVALIDTIME', 2); -define('DATE_ERROR_INVALIDTIMEZONE', 3); -define('DATE_ERROR_INVALIDDATEFORMAT', 4); -define('DATE_ERROR_INVALIDFORMATSTRING', 5); - - -// }}} -// {{{ Includes - -require_once 'PEAR.php'; - -/** - * Load Date_TimeZone - */ -require_once 'Date/TimeZone.php'; - -/** - * Load Date_Calc - */ -require_once 'Date/Calc.php'; - -/** - * Load Date_Span - */ -require_once 'Date/Span.php'; - - -// }}} -// {{{ General constants - -/** - * Whether to capture the micro-time (in microseconds) by default - * in calls to 'Date::setNow()'. Note that this makes a call to - * 'gettimeofday()', which may not work on all systems. - * - * @since Constant available since Release 1.5.0 - */ -define('DATE_CAPTURE_MICROTIME_BY_DEFAULT', false); - -/** - * Whether to correct, by adding the local Summer time offset, the - * specified time if it falls in the 'skipped hour' (encountered - * when the clocks go forward). - * - * N.B. if specified as 'false', and if a time zone that adjusts - * for Summer time is specified, then an object of this class will - * be set to a semi-invalid state if an invalid time is set. That - * is, an error will not be returned, unless the user then calls - * a function, directly or indirectly, that accesses the time - * part of the object. So, for example, if the user calls: - * - * $date_object->format2('HH.MI.SS') or: - * $date->object->addSeconds(30), - * - * an error will be returned if the time is invalid. However, - * if the user calls: - * - * $date->object->addDays(1), - * - * for example, such that the time is no longer invalid, then the - * object will no longer be in this invalid state. This behaviour - * is intended to minimize unexpected errors when a user uses the - * class to do addition with days only, and does not intend to - * access the time. - * - * Of course, this constant will be unused if the user chooses to - * work in UTC or a time zone without Summer time, in which case - * this situation will never arise. - * - * This constant is set to 'true' by default for backwards-compatibility - * reasons, however, you are recommended to set it to 'false'. Note that the - * behaviour is not intended to match that of previous versions of the class - * in terms of ignoring the Summer time offset when making calculations which - * involve dates in both standard and Summer time - this was recognized as a - * bug - but in terms of returning a PEAR error object when the user sets the - * object to an invalid date (i.e. a time in the hour which is skipped when - * the clocks go forwards, which in Europe would be a time such as 01.30). - * Backwards compatibility here means that the behaviour is the same as it - * used to be, less the bug. - * - * Note that this problem is not an issue for the user if: - * - * (a) the user uses a time zone that does not observe Summer time, e.g. UTC - * (b) the user never accesses the time, that is, he never makes a call to - * Date::getHour() or Date::format("%H"), for example, even if he sets - * the time to something invalid - * (c) the user sets DATE_CORRECTINVALIDTIME_DEFAULT to true - * - * @since Constant available since Release 1.5.0 - */ -define('DATE_CORRECTINVALIDTIME_DEFAULT', true); - -/** - * Whether to validate dates (i.e. day-month-year, ignoring the time) by - * disallowing invalid dates (e.g. 31st February) being set by the following - * functions: - * - * Date::setYear() - * Date::setMonth() - * Date::setDay() - * - * If the constant is set to 'true', then the date will be checked (by - * default), and if invalid, an error will be returned with the Date object - * left unmodified. - * - * This constant is set to 'false' by default for backwards-compatibility - * reasons, however, you are recommended to set it to 'true'. - * - * Note that setHour(), setMinute(), setSecond() and setPartSecond() - * allow an invalid date/time to be set regardless of the value of this - * constant. - * - * @since Constant available since Release 1.5.0 - */ -define('DATE_VALIDATE_DATE_BY_DEFAULT', false); - -/** - * Whether, by default, to accept times including leap seconds (i.e. '23.59.60') - * when setting the date/time, and whether to count leap seconds in the - * following functions: - * - * Date::addSeconds() - * Date::subtractSeconds() - * Date_Calc::addSeconds() - * Date::round() - * Date::roundSeconds() - * - * This constant is set to 'false' by default for backwards-compatibility - * reasons, however, you are recommended to set it to 'true'. - * - * Note that this constant does not affect Date::addSpan() and - * Date::subtractSpan() which will not count leap seconds in any case. - * - * @since Constant available since Release 1.5.0 - */ -define('DATE_COUNT_LEAP_SECONDS', false); - - -// }}} -// {{{ Output format constants (used in 'Date::getDate()') - -/** - * "YYYY-MM-DD HH:MM:SS" - */ -define('DATE_FORMAT_ISO', 1); - -/** - * "YYYYMMSSTHHMMSS(Z|(+/-)HHMM)?" - */ -define('DATE_FORMAT_ISO_BASIC', 2); - -/** - * "YYYY-MM-SSTHH:MM:SS(Z|(+/-)HH:MM)?" - */ -define('DATE_FORMAT_ISO_EXTENDED', 3); - -/** - * "YYYY-MM-SSTHH:MM:SS(.S*)?(Z|(+/-)HH:MM)?" - */ -define('DATE_FORMAT_ISO_EXTENDED_MICROTIME', 6); - -/** - * "YYYYMMDDHHMMSS" - */ -define('DATE_FORMAT_TIMESTAMP', 4); - -/** - * long int, seconds since the unix epoch - */ -define('DATE_FORMAT_UNIXTIME', 5); - - -// }}} -// {{{ Class: Date - -/** - * Generic date handling class for PEAR - * - * Supports time zones with the Date_TimeZone class. Supports several - * operations from Date_Calc on Date objects. - * - * Note to developers: the class stores the local time and date in the - * local standard time. That is, it does not store the time as the - * local Summer time when and if the time zone is in Summer time. It - * is much easier to store local standard time and remember to offset - * it when the user requests it. - * - * @category Date and Time - * @package Date - * @author Baba Buehler - * @author Pierre-Alain Joye - * @author Firman Wandayandi - * @author C.A. Woodcock - * @copyright 1997-2007 Baba Buehler, Pierre-Alain Joye, Firman Wandayandi, C.A. Woodcock - * @license http://www.opensource.org/licenses/bsd-license.php - * BSD License - * @version Release: 1.5.0a1 - * @link http://pear.php.net/package/Date - */ -class Date -{ - - // {{{ Properties - - /** - * The year - * - * @var int - * @access private - * @since Property available since Release 1.0 - */ - var $year; - - /** - * The month - * - * @var int - * @access private - * @since Property available since Release 1.0 - */ - var $month; - - /** - * The day - * - * @var int - * @access private - * @since Property available since Release 1.0 - */ - var $day; - - /** - * The hour - * - * @var int - * @access private - * @since Property available since Release 1.0 - */ - var $hour; - - /** - * The minute - * - * @var int - * @access private - * @since Property available since Release 1.0 - */ - var $minute; - - /** - * The second - * - * @var int - * @access private - * @since Property available since Release 1.0 - */ - var $second; - - /** - * The parts of a second - * - * @var float - * @access private - * @since Property available since Release 1.4.3 - */ - var $partsecond; - - /** - * The year in local standard time - * - * @var int - * @access private - * @since Property available since Release 1.5.0 - */ - var $on_standardyear; - - /** - * The month in local standard time - * - * @var int - * @access private - * @since Property available since Release 1.5.0 - */ - var $on_standardmonth; - - /** - * The day in local standard time - * - * @var int - * @access private - * @since Property available since Release 1.5.0 - */ - var $on_standardday; - - /** - * The hour in local standard time - * - * @var int - * @access private - * @since Property available since Release 1.5.0 - */ - var $on_standardhour; - - /** - * The minute in local standard time - * - * @var int - * @access private - * @since Property available since Release 1.5.0 - */ - var $on_standardminute; - - /** - * The second in local standard time - * - * @var int - * @access private - * @since Property available since Release 1.5.0 - */ - var $on_standardsecond; - - /** - * The part-second in local standard time - * - * @var float - * @access private - * @since Property available since Release 1.5.0 - */ - var $on_standardpartsecond; - - /** - * Whether the object should accept and count leap seconds - * - * @var bool - * @access private - * @since Property available since Release 1.5.0 - */ - var $ob_countleapseconds; - - /** - * Whether the time is valid as a local time (an invalid time - * is one that lies in the 'skipped hour' at the point that - * the clocks go forward) - * - * @var bool - * @access private - * @see Date::isTimeValid() - * @since Property available since Release 1.5.0 - */ - var $ob_invalidtime = null; - - /** - * Date_TimeZone object for this date - * - * @var object Date_TimeZone object - * @access private - * @since Property available since Release 1.0 - */ - var $tz; - - /** - * Defines the default weekday abbreviation length - * - * Formerly used by Date::format(), but now redundant - the abbreviation - * for the current locale of the machine is used. - * - * @var int - * @access private - * @since Property available since Release 1.4.4 - */ - var $getWeekdayAbbrnameLength = 3; - - - // }}} - // {{{ Constructor - - /** - * Constructor - * - * Creates a new Date Object initialized to the current date/time in the - * system-default timezone by default. A date optionally - * passed in may be in the ISO 8601, TIMESTAMP or UNIXTIME format, - * or another Date object. If no date is passed, the current date/time - * is used. - * - * If a date is passed and an exception is returned by 'setDate()' - * there is nothing that this function can do, so for this reason, it - * is advisable to pass no parameter and to make a separate call to - * 'setDate()'. A date/time should only be passed if known to be a - * valid ISO 8601 string or a valid Unix timestamp. - * - * @param mixed $date optional ISO 8601 date/time to initialize; - * or, a Unix time stamp - * @param bool $pb_countleapseconds whether to count leap seconds - * (defaults to DATE_COUNT_LEAP_SECONDS) - * - * @return void - * @access public - * @see Date::setDate() - */ - function Date($date = null, - $pb_countleapseconds = DATE_COUNT_LEAP_SECONDS) - { - $this->ob_countleapseconds = $pb_countleapseconds; - - if (is_a($date, 'Date')) { - $this->copy($date); - } else { - if (!is_null($date)) { - // 'setDate()' expects a time zone to be already set: - // - $this->_setTZToDefault(); - $this->setDate($date); - } else { - $this->setNow(); - } - } - } - - - // }}} - // {{{ copy() - - /** - * Copy values from another Date object - * - * Makes this Date a copy of another Date object. This is a - * PHP4-compatible implementation of '__clone()' in PHP5. - * - * @param object $date Date object to copy - * - * @return void - * @access public - */ - function copy($date) - { - $this->year = $date->year; - $this->month = $date->month; - $this->day = $date->day; - $this->hour = $date->hour; - $this->minute = $date->minute; - $this->second = $date->second; - $this->partsecond = $date->partsecond; - - $this->on_standardyear = $date->on_standardyear; - $this->on_standardmonth = $date->on_standardmonth; - $this->on_standardday = $date->on_standardday; - $this->on_standardhour = $date->on_standardhour; - $this->on_standardminute = $date->on_standardminute; - $this->on_standardsecond = $date->on_standardsecond; - $this->on_standardpartsecond = $date->on_standardpartsecond; - - $this->ob_countleapseconds = $date->ob_countleapseconds; - $this->ob_invalidtime = $date->ob_invalidtime; - - $this->tz = new Date_TimeZone($date->getTZID()); - - $this->getWeekdayAbbrnameLength = $date->getWeekdayAbbrnameLength; - } - - - // }}} - // {{{ __clone() - - /** - * Copy values from another Date object - * - * Makes this Date a copy of another Date object. For PHP5 - * only. - * - * @return void - * @access public - * @see Date::copy() - */ - function __clone() - { - // This line of code would be preferable, but will only - // compile in PHP5: - // - // $this->tz = clone $this->tz; - - $this->tz = new Date_TimeZone($this->getTZID()); - } - - - // }}} - // {{{ setDate() - - /** - * Sets the fields of a Date object based on the input date and format - * - * Format parameter should be one of the specified DATE_FORMAT_* constants: - * - * DATE_FORMAT_ISO - * - 'YYYY-MM-DD HH:MI:SS' - * DATE_FORMAT_ISO_BASIC - * - 'YYYYMMSSTHHMMSS(Z|(+/-)HHMM)?' - * DATE_FORMAT_ISO_EXTENDED - * - 'YYYY-MM-SSTHH:MM:SS(Z|(+/-)HH:MM)?' - * DATE_FORMAT_ISO_EXTENDED_MICROTIME - * - 'YYYY-MM-SSTHH:MM:SS(.S*)?(Z|(+/-)HH:MM)?' - * DATE_FORMAT_TIMESTAMP - * - 'YYYYMMDDHHMMSS' - * DATE_FORMAT_UNIXTIME' - * - long integer of the no of seconds since - * the Unix Epoch - * (1st January 1970 00.00.00 GMT) - * - * @param string $date input date - * @param int $format optional format constant - * (DATE_FORMAT_*) of the input date. - * This parameter is not needed, - * except to force the setting of the - * date from a Unix time-stamp - * (DATE_FORMAT_UNIXTIME). - * @param bool $pb_repeatedhourdefault value to return if repeated - * hour is specified (defaults - * to false) - * - * @return void - * @access public - */ - function setDate($date, - $format = DATE_FORMAT_ISO, - $pb_repeatedhourdefault = false) - { - - if (preg_match('/^([0-9]{4,4})-?(0[1-9]|1[0-2])-?(0[1-9]|[12][0-9]|3[01])' . - '([T\s]?([01][0-9]|2[0-3]):?' . // [hh] - '([0-5][0-9]):?([0-5][0-9]|60)(\.\d+)?' . // [mi]:[ss] - '(Z|[+\-][0-9]{2,2}(:?[0-5][0-9])?)?)?$/i', // offset - $date, $regs) && - $format != DATE_FORMAT_UNIXTIME - ) { - // DATE_FORMAT_ISO, ISO_BASIC, ISO_EXTENDED, and TIMESTAMP - // These formats are extremely close to each other. This regex - // is very loose and accepts almost any butchered format you could - // throw at it. e.g. 2003-10-07 19:45:15 and 2003-10071945:15 - // are the same thing in the eyes of this regex, even though the - // latter is not a valid ISO 8601 date. - - if (!Date_Calc::isValidDate($regs[3], $regs[2], $regs[1])) { - return PEAR::raiseError("'" . - Date_Calc::dateFormat($regs[1], - $regs[2], - $regs[3], - "%Y-%m-%d") . - "' is invalid calendar date", - DATE_ERROR_INVALIDDATE); - } - - if (isset($regs[9])) { - if ($regs[9] == "Z") { - $this->tz = new Date_TimeZone("UTC"); - } else { - $this->tz = new Date_TimeZone("UTC" . $regs[9]); - } - } - - $this->setLocalTime($regs[3], - $regs[2], - $regs[1], - isset($regs[5]) ? $regs[5] : 0, - isset($regs[6]) ? $regs[6] : 0, - isset($regs[7]) ? $regs[7] : 0, - isset($regs[8]) ? $regs[8] : 0.0, - $pb_repeatedhourdefault); - - } else if (is_numeric($date)) { - // Unix Time; N.B. Unix Time is defined relative to GMT, - // so it needs to be adjusted for the current time zone; - // however we do not know if it is in Summer time until - // we have converted it from Unix time: - // - - // Get current time zone details: - // - $hs_id = $this->getTZID(); - - // Input Unix time as UTC: - // - $this->tz = new Date_TimeZone("UTC"); - $this->setDate(gmdate("Y-m-d H:i:s", $date)); - - // Convert back to correct time zone: - // - $this->convertTZByID($hs_id); - } else { - return PEAR::raiseError("Date not in ISO 8601 format", - DATE_ERROR_INVALIDDATEFORMAT); - } - } - - - // }}} - // {{{ setNow() - - /** - * Sets to local current time and time zone - * - * @param bool $pb_setmicrotime whether to set micro-time (defaults to the - * value of the constant - * DATE_CAPTURE_MICROTIME_BY_DEFAULT) - * - * @return void - * @access public - * @since Method available since Release 1.5.0 - */ - function setNow($pb_setmicrotime = DATE_CAPTURE_MICROTIME_BY_DEFAULT) - { - $this->_setTZToDefault(); - - if ($pb_setmicrotime) { - $ha_unixtime = gettimeofday(); - } else { - $ha_unixtime = array("sec" => time()); - } - - $this->setDate(date("Y-m-d H:i:s", $ha_unixtime["sec"]) . - (isset($ha_unixtime["usec"]) ? - "." . sprintf("%06d", $ha_unixtime["usec"]) : - "")); - } - - - // }}} - // {{{ round() - - /** - * Rounds the date according to the specified precision (defaults - * to nearest day) - * - * The precision parameter must be one of the following constants: - * - * DATE_PRECISION_YEAR - * DATE_PRECISION_MONTH - * DATE_PRECISION_DAY - * DATE_PRECISION_HOUR - * DATE_PRECISION_10MINUTES - * DATE_PRECISION_MINUTE - * DATE_PRECISION_10SECONDS - * DATE_PRECISION_SECOND - * - * N.B. the default is DATE_PRECISION_DAY - * - * The precision can also be specified as an integral offset from - * one of these constants, where the offset reflects a precision - * of 10 to the power of the offset greater than the constant. - * For example: - * - * DATE_PRECISION_YEAR - 1 rounds the date to the nearest 10 - * years - * DATE_PRECISION_YEAR - 3 rounds the date to the nearest 1000 - * years - * DATE_PRECISION_SECOND + 1 rounds the date to 1 decimal - * point of a second - * DATE_PRECISION_SECOND + 3 rounds the date to 3 decimal - * points of a second - * DATE_PRECISION_SECOND - 1 rounds the date to the nearest 10 - * seconds (thus it is equivalent to - * DATE_PRECISION_10SECONDS) - * - * @param int $pn_precision a 'DATE_PRECISION_*' constant - * @param bool $pb_correctinvalidtime whether to correct, by adding the - * local Summer time offset, the rounded - * time if it falls in the skipped hour - * (defaults to - * DATE_CORRECTINVALIDTIME_DEFAULT) - * - * @return void - * @access public - * @since Method available since Release 1.5.0 - */ - function round($pn_precision = DATE_PRECISION_DAY, - $pb_correctinvalidtime = DATE_CORRECTINVALIDTIME_DEFAULT) - { - if ($pn_precision <= DATE_PRECISION_DAY) { - list($hn_year, - $hn_month, - $hn_day, - $hn_hour, - $hn_minute, - $hn_secondraw) = - Date_Calc::round($pn_precision, - $this->day, - $this->month, - $this->year, - $this->hour, - $this->minute, - $this->partsecond == 0.0 ? - $this->second : - $this->second + $this->partsecond, - $this->ob_countleapseconds); - if (is_float($hn_secondraw)) { - $hn_second = intval($hn_secondraw); - $hn_partsecond = $hn_secondraw - $hn_second; - } else { - $hn_second = $hn_secondraw; - $hn_partsecond = 0.0; - } - - $this->setLocalTime($hn_day, - $hn_month, - $hn_year, - $hn_hour, - $hn_minute, - $hn_second, - $hn_partsecond, - true, // This is unlikely anyway, but the - // day starts with the repeated hour - // the first time around - $pb_correctinvalidtime); - return; - } - - // ($pn_precision >= DATE_PRECISION_HOUR) - // - if ($this->tz->getDSTSavings() % 3600000 == 0 || - ($this->tz->getDSTSavings() % 60000 == 0 && - $pn_precision >= DATE_PRECISION_MINUTE) - ) { - list($hn_year, - $hn_month, - $hn_day, - $hn_hour, - $hn_minute, - $hn_secondraw) = - Date_Calc::round($pn_precision, - $this->on_standardday, - $this->on_standardmonth, - $this->on_standardyear, - $this->on_standardhour, - $this->on_standardminute, - $this->on_standardpartsecond == 0.0 ? - $this->on_standardsecond : - $this->on_standardsecond + - $this->on_standardpartsecond, - $this->ob_countleapseconds); - if (is_float($hn_secondraw)) { - $hn_second = intval($hn_secondraw); - $hn_partsecond = $hn_secondraw - $hn_second; - } else { - $hn_second = $hn_secondraw; - $hn_partsecond = 0.0; - } - - $this->setStandardTime($hn_day, - $hn_month, - $hn_year, - $hn_hour, - $hn_minute, - $hn_second, - $hn_partsecond); - return; - } - - // Very unlikely anyway (as I write, the only time zone like this - // is Lord Howe Island in Australia (offset of half an hour)): - // - // (This algorithm could be better) - // - list($hn_year, - $hn_month, - $hn_day, - $hn_hour, - $hn_minute, - $hn_secondraw) = - Date_Calc::round($pn_precision, - $this->day, - $this->month, - $this->year, - $this->hour, - $this->minute, - $this->partsecond == 0.0 ? - $this->second : - $this->second + $this->partsecond, - $this->ob_countleapseconds); - if (is_float($hn_secondraw)) { - $hn_second = intval($hn_secondraw); - $hn_partsecond = $hn_secondraw - $hn_second; - } else { - $hn_second = $hn_secondraw; - $hn_partsecond = 0.0; - } - - $this->setLocalTime($hn_day, - $hn_month, - $hn_year, - $hn_hour, - $hn_minute, - $hn_second, - $hn_partsecond, - false, // This will be right half the time - $pb_correctinvalidtime); // This will be right - // some of the time - // (depends on Summer - // time offset) - } - - - // }}} - // {{{ roundSeconds() - - /** - * Rounds seconds up or down to the nearest specified unit - * - * N.B. this function is equivalent to calling: - * 'round(DATE_PRECISION_SECOND + $pn_precision)' - * - * @param int $pn_precision number of digits after the decimal point - * @param bool $pb_correctinvalidtime whether to correct, by adding the - * local Summer time offset, the rounded - * time if it falls in the skipped hour - * (defaults to - * DATE_CORRECTINVALIDTIME_DEFAULT) - * - * @return void - * @access public - * @since Method available since Release 1.5.0 - */ - function roundSeconds($pn_precision = 0, - $pb_correctinvalidtime = DATE_CORRECTINVALIDTIME_DEFAULT) - { - $this->round(DATE_PRECISION_SECOND + $pn_precision, - $pb_correctinvalidtime); - } - - - // }}} - // {{{ trunc() - - /** - * Truncates the date according to the specified precision (by - * default, it truncates the time part of the date) - * - * The precision parameter must be one of the following constants: - * - * DATE_PRECISION_YEAR - * DATE_PRECISION_MONTH - * DATE_PRECISION_DAY - * DATE_PRECISION_HOUR - * DATE_PRECISION_10MINUTES - * DATE_PRECISION_MINUTE - * DATE_PRECISION_10SECONDS - * DATE_PRECISION_SECOND - * - * N.B. the default is DATE_PRECISION_DAY - * - * The precision can also be specified as an integral offset from - * one of these constants, where the offset reflects a precision - * of 10 to the power of the offset greater than the constant. - * For example: - * - * DATE_PRECISION_YEAR truncates the month, day and time - * part of the year - * DATE_PRECISION_YEAR - 1 truncates the unit part of the - * year, e.g. 1987 becomes 1980 - * DATE_PRECISION_YEAR - 3 truncates the hundreds part of the - * year, e.g. 1987 becomes 1000 - * DATE_PRECISION_SECOND + 1 truncates the part of the second - * less than 0.1 of a second, e.g. - * 3.26301 becomes 3.2 seconds - * DATE_PRECISION_SECOND + 3 truncates the part of the second - * less than 0.001 of a second, e.g. - * 3.26301 becomes 3.263 seconds - * DATE_PRECISION_SECOND - 1 truncates the unit part of the - * seconds (thus it is equivalent to - * DATE_PRECISION_10SECONDS) - * - * @param int $pn_precision a 'DATE_PRECISION_*' constant - * @param bool $pb_correctinvalidtime whether to correct, by adding the - * local Summer time offset, the - * truncated time if it falls in the - * skipped hour (defaults to - * DATE_CORRECTINVALIDTIME_DEFAULT) - * - * @return void - * @access public - * @since Method available since Release 1.5.0 - */ - function trunc($pn_precision = DATE_PRECISION_DAY, - $pb_correctinvalidtime = DATE_CORRECTINVALIDTIME_DEFAULT) - { - if ($pn_precision <= DATE_PRECISION_DAY) { - if ($pn_precision <= DATE_PRECISION_YEAR) { - $hn_month = 0; - $hn_day = 0; - $hn_hour = 0; - $hn_minute = 0; - $hn_second = 0; - $hn_partsecond = 0.0; - - $hn_invprecision = DATE_PRECISION_YEAR - $pn_precision; - if ($hn_invprecision > 0) { - $hn_year = intval($this->year / pow(10, $hn_invprecision)) * - pow(10, $hn_invprecision); - // - // (Conversion to int necessary for PHP <= 4.0.6) - } else { - $hn_year = $this->year; - } - } else if ($pn_precision == DATE_PRECISION_MONTH) { - $hn_year = $this->year; - $hn_month = $this->month; - $hn_day = 0; - $hn_hour = 0; - $hn_minute = 0; - $hn_second = 0; - $hn_partsecond = 0.0; - } else if ($pn_precision == DATE_PRECISION_DAY) { - $hn_year = $this->year; - $hn_month = $this->month; - $hn_day = $this->day; - $hn_hour = 0; - $hn_minute = 0; - $hn_second = 0; - $hn_partsecond = 0.0; - } - - $this->setLocalTime($hn_day, - $hn_month, - $hn_year, - $hn_hour, - $hn_minute, - $hn_second, - $hn_partsecond, - true, // This is unlikely anyway, but the - // day starts with the repeated - // hour the first time around - $pb_correctinvalidtime); - return; - } - - // Precision is at least equal to DATE_PRECISION_HOUR - // - if ($pn_precision == DATE_PRECISION_HOUR) { - $this->addSeconds($this->partsecond == 0.0 ? - -$this->second : - -$this->second - $this->partsecond); - // - // (leap seconds irrelevant) - - $this->addMinutes(-$this->minute); - } else if ($pn_precision <= DATE_PRECISION_MINUTE) { - if ($pn_precision == DATE_PRECISION_10MINUTES) { - $this->addMinutes(-$this->minute % 10); - } - - $this->addSeconds($this->partsecond == 0.0 ? - -$this->second : - -$this->second - $this->partsecond); - // - // (leap seconds irrelevant) - - } else if ($pn_precision == DATE_PRECISION_10SECONDS) { - $this->addSeconds($this->partsecond == 0.0 ? - -$this->second % 10 : - (-$this->second % 10) - $this->partsecond); - // - // (leap seconds irrelevant) - - } else { - // Assume Summer time offset cannot be composed of part-seconds: - // - $hn_precision = $pn_precision - DATE_PRECISION_SECOND; - $hn_partsecond = intval($this->on_standardpartsecond * - pow(10, $hn_precision)) / - pow(10, $hn_precision); - $this->setStandardTime($this->on_standardday, - $this->on_standardmonth, - $this->on_standardyear, - $this->on_standardhour, - $this->on_standardminute, - $this->on_standardsecond, - $hn_partsecond); - } - } - - - // }}} - // {{{ truncSeconds() - - /** - * Truncates seconds according to the specified precision - * - * N.B. this function is equivalent to calling: - * 'Date::trunc(DATE_PRECISION_SECOND + $pn_precision)' - * - * @param int $pn_precision number of digits after the decimal point - * @param bool $pb_correctinvalidtime whether to correct, by adding the - * local Summer time offset, the - * truncated time if it falls in the - * skipped hour (defaults to - * DATE_CORRECTINVALIDTIME_DEFAULT) - * - * @return void - * @access public - * @since Method available since Release 1.5.0 - */ - function truncSeconds($pn_precision = 0, - $pb_correctinvalidtime = DATE_CORRECTINVALIDTIME_DEFAULT) - { - $this->trunc(DATE_PRECISION_SECOND + $pn_precision, - $pb_correctinvalidtime); - } - - - // }}} - // {{{ getDate() - - /** - * Gets a string (or other) representation of this date - * - * Returns a date in the format specified by the DATE_FORMAT_* constants. - * - * @param int $format format constant (DATE_FORMAT_*) of the output date - * - * @return string the date in the requested format - * @access public - */ - function getDate($format = DATE_FORMAT_ISO) - { - switch ($format) { - case DATE_FORMAT_ISO: - return $this->format("%Y-%m-%d %T"); - break; - case DATE_FORMAT_ISO_BASIC: - $format = "%Y%m%dT%H%M%S"; - if ($this->getTZID() == 'UTC') { - $format .= "Z"; - } - return $this->format($format); - break; - case DATE_FORMAT_ISO_EXTENDED: - $format = "%Y-%m-%dT%H:%M:%S"; - if ($this->getTZID() == 'UTC') { - $format .= "Z"; - } - return $this->format($format); - break; - case DATE_FORMAT_ISO_EXTENDED_MICROTIME: - $format = "%Y-%m-%dT%H:%M:%s"; - if ($this->getTZID() == 'UTC') { - $format .= "Z"; - } - return $this->format($format); - break; - case DATE_FORMAT_TIMESTAMP: - return $this->format("%Y%m%d%H%M%S"); - break; - case DATE_FORMAT_UNIXTIME: - // Enter a time in UTC, so use 'gmmktime()' (the alternative - // is to offset additionally by the local time, but the object - // is not necessarily using local time): - // - if ($this->ob_invalidtime) - return $this->_getErrorInvalidTime(); - - return gmmktime($this->on_standardhour, - $this->on_standardminute, - $this->on_standardsecond, - $this->on_standardmonth, - $this->on_standardday, - $this->on_standardyear) - - $this->tz->getRawOffset() / 1000; // N.B. Unix-time excludes - // leap seconds by - // definition - break; - } - } - - - // }}} - // {{{ format() - - /** - * Date pretty printing, similar to strftime() - * - * Formats the date in the given format, much like - * strftime(). Most strftime() options are supported.

- * - * Formatting options:

- * - * %a abbreviated weekday name (Sun, Mon, Tue)
- * %A full weekday name (Sunday, Monday, Tuesday)
- * %b abbreviated month name (Jan, Feb, Mar)
- * %B full month name (January, February, March)
- * %C century number (the year divided by 100 and truncated - * to an integer, range 00 to 99)
- * %d day of month (range 00 to 31)
- * %D equivalent to "%m/%d/%y"
- * %e day of month without leading noughts (range 0 to 31)
- * %E Julian day - no of days since Monday, 24th November, - * 4714 B.C. (in the proleptic Gregorian calendar)
- * %g like %G, but without the century
- * %G the 4-digit year corresponding to the ISO week - * number (see %V). This has the same format and value - * as %Y, except that if the ISO week number belongs - * to the previous or next year, that year is used - * instead.
- * %h hour as decimal number without leading noughts (0 - * to 23)
- * %H hour as decimal number (00 to 23)
- * %i hour as decimal number on 12-hour clock without - * leading noughts (1 to 12)
- * %I hour as decimal number on 12-hour clock (01 to 12)
- * %j day of year (range 001 to 366)
- * %m month as decimal number (range 01 to 12)
- * %M minute as a decimal number (00 to 59)
- * %n newline character ("\n")
- * %o raw timezone offset expressed as '+/-HH:MM'
- * %O dst-corrected timezone offset expressed as '+/-HH:MM'
- * %p either 'am' or 'pm' depending on the time
- * %P either 'AM' or 'PM' depending on the time
- * %r time in am/pm notation; equivalent to "%I:%M:%S %p"
- * %R time in 24-hour notation; equivalent to "%H:%M"
- * %s seconds including the micro-time (the decimal - * representation less than one second to six decimal - * places
- * %S seconds as a decimal number (00 to 59)
- * %t tab character ("\t")
- * %T current time; equivalent to "%H:%M:%S"
- * %u day of week as decimal (1 to 7; where 1 = Monday)
- * %U week number of the current year as a decimal - * number, starting with the first Sunday as the first - * day of the first week (i.e. the first full week of - * the year, and the week that contains 7th January) - * (00 to 53)
- * %V the ISO 8601:1988 week number of the current year - * as a decimal number, range 01 to 53, where week 1 - * is the first week that has at least 4 days in the - * current year, and with Monday as the first day of - * the week. (Use %G or %g for the year component - * that corresponds to the week number for the - * specified timestamp.) - * %w day of week as decimal (0 to 6; where 0 = Sunday)
- * %W week number of the current year as a decimal - * number, starting with the first Monday as the first - * day of the first week (i.e. the first full week of - * the year, and the week that contains 7th January) - * (00 to 53)
- * %y year as decimal (range 00 to 99)
- * %Y year as decimal including century (range 0000 to - * 9999)
- * %Z Abbreviated form of time zone name, e.g. 'GMT', or - * the abbreviation for Summer time if the date falls - * in Summer time, e.g. 'BST'.
- * %% literal '%'
- *
- * - * The following codes render a different output to that of 'strftime()': - * - * %e in 'strftime()' a single digit is preceded by a space - * %h in 'strftime()' is equivalent to '%b' - * %U '%U' and '%W' are different in 'strftime()' in that - * if week 1 does not start on 1st January, '00' is - * returned, whereas this function returns '53', that is, - * the week is counted as the last of the previous year. - * %W - * - * @param string $format the format string for returned date/time - * - * @return string date/time in given format - * @access public - */ - function format($format) - { - $output = ""; - - $hn_isoyear = null; - $hn_isoweek = null; - $hn_isoday = null; - - for ($strpos = 0; $strpos < strlen($format); $strpos++) { - $char = substr($format, $strpos, 1); - if ($char == "%") { - $nextchar = substr($format, $strpos + 1, 1); - switch ($nextchar) { - case "a": - $output .= Date_Calc::getWeekdayAbbrname($this->day, - $this->month, $this->year, - $this->getWeekdayAbbrnameLength); - break; - case "A": - $output .= Date_Calc::getWeekdayFullname($this->day, - $this->month, $this->year); - break; - case "b": - $output .= Date_Calc::getMonthAbbrname($this->month); - break; - case "B": - $output .= Date_Calc::getMonthFullname($this->month); - break; - case "C": - $output .= sprintf("%02d", intval($this->year / 100)); - break; - case "d": - $output .= sprintf("%02d", $this->day); - break; - case "D": - $output .= sprintf("%02d/%02d/%02d", $this->month, - $this->day, $this->year); - break; - case "e": - $output .= $this->day; - break; - case "E": - $output .= Date_Calc::dateToDays($this->day, $this->month, - $this->year); - break; - case "g": - if (is_null($hn_isoyear)) - list($hn_isoyear, $hn_isoweek, $hn_isoday) = - Date_Calc::isoWeekDate($this->day, - $this->month, - $this->year); - - $output .= sprintf("%02d", $hn_isoyear % 100); - break; - case "G": - if (is_null($hn_isoyear)) - list($hn_isoyear, $hn_isoweek, $hn_isoday) = - Date_Calc::isoWeekDate($this->day, - $this->month, - $this->year); - - $output .= sprintf("%04d", $hn_isoyear); - break; - case 'h': - if ($this->ob_invalidtime) - return $this->_getErrorInvalidTime(); - $output .= sprintf("%d", $this->hour); - break; - case "H": - if ($this->ob_invalidtime) - return $this->_getErrorInvalidTime(); - $output .= sprintf("%02d", $this->hour); - break; - case "i": - case "I": - if ($this->ob_invalidtime) - return $this->_getErrorInvalidTime(); - $hour = $this->hour + 1 > 12 ? - $this->hour - 12 : - $this->hour; - $output .= $hour == 0 ? - 12 : - ($nextchar == "i" ? - $hour : - sprintf('%02d', $hour)); - break; - case "j": - $output .= sprintf("%03d", - Date_Calc::dayOfYear($this->day, - $this->month, - $this->year)); - break; - case "m": - $output .= sprintf("%02d", $this->month); - break; - case "M": - $output .= sprintf("%02d", $this->minute); - break; - case "n": - $output .= "\n"; - break; - case "O": - if ($this->ob_invalidtime) - return $this->_getErrorInvalidTime(); - $offms = $this->getTZOffset(); - $direction = $offms >= 0 ? "+" : "-"; - $offmins = abs($offms) / 1000 / 60; - $hours = $offmins / 60; - $minutes = $offmins % 60; - - $output .= sprintf("%s%02d:%02d", $direction, $hours, $minutes); - break; - case "o": - $offms = $this->tz->getRawOffset($this); - $direction = $offms >= 0 ? "+" : "-"; - $offmins = abs($offms) / 1000 / 60; - $hours = $offmins / 60; - $minutes = $offmins % 60; - - $output .= sprintf("%s%02d:%02d", $direction, $hours, $minutes); - break; - case "p": - if ($this->ob_invalidtime) - return $this->_getErrorInvalidTime(); - $output .= $this->hour >= 12 ? "pm" : "am"; - break; - case "P": - if ($this->ob_invalidtime) - return $this->_getErrorInvalidTime(); - $output .= $this->hour >= 12 ? "PM" : "AM"; - break; - case "r": - if ($this->ob_invalidtime) - return $this->_getErrorInvalidTime(); - $hour = $this->hour + 1 > 12 ? - $this->hour - 12 : - $this->hour; - $output .= sprintf("%02d:%02d:%02d %s", - $hour == 0 ? 12 : $hour, - $this->minute, - $this->second, - $this->hour >= 12 ? "PM" : "AM"); - break; - case "R": - if ($this->ob_invalidtime) - return $this->_getErrorInvalidTime(); - $output .= sprintf("%02d:%02d", $this->hour, $this->minute); - break; - case "s": - $output .= str_replace(',', - '.', - sprintf("%09f", - (float)((float) $this->second + - $this->partsecond))); - break; - case "S": - $output .= sprintf("%02d", $this->second); - break; - case "t": - $output .= "\t"; - break; - case "T": - if ($this->ob_invalidtime) - return $this->_getErrorInvalidTime(); - $output .= sprintf("%02d:%02d:%02d", - $this->hour, - $this->minute, - $this->second); - break; - case "u": - $hn_dayofweek = $this->getDayOfWeek(); - $output .= $hn_dayofweek == 0 ? 7 : $hn_dayofweek; - break; - case "U": - $ha_week = Date_Calc::weekOfYear7th($this->day, - $this->month, - $this->year, - 0); - $output .= sprintf("%02d", $ha_week[1]); - break; - case "V": - if (is_null($hn_isoyear)) - list($hn_isoyear, $hn_isoweek, $hn_isoday) = - Date_Calc::isoWeekDate($this->day, - $this->month, - $this->year); - - $output .= $hn_isoweek; - break; - case "w": - $output .= $this->getDayOfWeek(); - break; - case "W": - $ha_week = Date_Calc::weekOfYear7th($this->day, - $this->month, - $this->year, - 1); - $output .= sprintf("%02d", $ha_week[1]); - break; - case 'y': - $output .= sprintf('%0' . - ($this->year < 0 ? '3' : '2') . - 'd', - $this->year % 100); - break; - case "Y": - $output .= sprintf('%0' . - ($this->year < 0 ? '5' : '4') . - 'd', - $this->year); - break; - case "Z": - if ($this->ob_invalidtime) - return $this->_getErrorInvalidTime(); - $output .= $this->getTZShortName(); - break; - case "%": - $output .= "%"; - break; - default: - $output .= $char.$nextchar; - } - $strpos++; - } else { - $output .= $char; - } - } - return $output; - - } - - - // }}} - // {{{ _getOrdinalSuffix() - - /** - * Returns appropriate ordinal suffix (i.e. 'th', 'st', 'nd' or 'rd') - * - * @param int $pn_num number with which to determine suffix - * @param bool $pb_uppercase boolean specifying if the suffix should be - * capitalized - * - * @return string - * @access private - * @since Method available since Release 1.5.0 - */ - function _getOrdinalSuffix($pn_num, $pb_uppercase = true) - { - switch (($pn_numabs = abs($pn_num)) % 100) { - case 11: - case 12: - case 13: - $hs_suffix = "th"; - break; - default: - switch ($pn_numabs % 10) { - case 1: - $hs_suffix = "st"; - break; - case 2: - $hs_suffix = "nd"; - break; - case 3: - $hs_suffix = "rd"; - break; - default: - $hs_suffix = "th"; - } - } - - return $pb_uppercase ? strtoupper($hs_suffix) : $hs_suffix; - } - - - // }}} - // {{{ _spellNumber() - - /** - * Converts a number to its word representation - * - * Private helper function, particularly for 'format2()'. N.B. The - * second argument is the 'SP' code which can be specified in the - * format string for 'format2()' and is interpreted as follows: - * 'SP' - returns upper-case spelling, e.g. 'FOUR HUNDRED' - * 'Sp' - returns spelling with first character of each word - * capitalized, e.g. 'Four Hundred' - * 'sp' - returns lower-case spelling, e.g. 'four hundred' - * - * @param int $pn_num number to be converted to words - * @param bool $pb_ordinal boolean specifying if the number should - * be ordinal - * @param string $ps_capitalization string for specifying capitalization - * options - * @param string $ps_locale language name abbreviation used for - * formatting numbers as spelled-out words - * - * @return string - * @access private - * @since Method available since Release 1.5.0 - */ - function _spellNumber($pn_num, - $pb_ordinal = false, - $ps_capitalization = "SP", - $ps_locale = "en_GB") - { - include_once "Numbers/Words.php"; - $hs_words = Numbers_Words::toWords($pn_num, $ps_locale); - if (Pear::isError($hs_words)) { - return $hs_words; - } - - if ($pb_ordinal && substr($ps_locale, 0, 2) == "en") { - if (($pn_rem = ($pn_numabs = abs($pn_num)) % 100) == 12) { - $hs_words = substr($hs_words, 0, -2) . "fth"; - } else if ($pn_rem >= 11 && $pn_rem <= 15) { - $hs_words .= "th"; - } else { - switch ($pn_numabs % 10) { - case 1: - $hs_words = substr($hs_words, 0, -3) . "first"; - break; - case 2: - $hs_words = substr($hs_words, 0, -3) . "second"; - break; - case 3: - $hs_words = substr($hs_words, 0, -3) . "ird"; - break; - case 5: - $hs_words = substr($hs_words, 0, -2) . "fth"; - break; - default: - switch (substr($hs_words, -1)) { - case "e": - $hs_words = substr($hs_words, 0, -1) . "th"; - break; - case "t": - $hs_words .= "h"; - break; - case "y": - $hs_words = substr($hs_words, 0, -1) . "ieth"; - break; - default: - $hs_words .= "th"; - } - } - } - } - - if (($hs_char = substr($ps_capitalization, 0, 1)) == - strtolower($hs_char)) { - $hb_upper = false; - $hs_words = strtolower($hs_words); - } else if (($hs_char = substr($ps_capitalization, 1, 1)) == - strtolower($hs_char)) { - $hb_upper = false; - $hs_words = ucwords($hs_words); - } else { - $hb_upper = true; - $hs_words = strtoupper($hs_words); - } - - return $hs_words; - } - - - // }}} - // {{{ _formatNumber() - - /** - * Formats a number according to the specified format string - * - * Private helper function, for 'format2()', which interprets the - * codes 'SP' and 'TH' and the combination of the two as follows: - * - * TH Ordinal number - * SP Spelled cardinal number - * SPTH Spelled ordinal number (combination of 'SP' and 'TH' - * in any order) - * THSP - * - * Code 'SP' can have the following three variations (which can also be used - * in combination with 'TH'): - * - * SP returns upper-case spelling, e.g. 'FOUR HUNDRED' - * Sp returns spelling with first character of each word - * capitalized, e.g. 'Four Hundred' - * sp returns lower-case spelling, e.g. 'four hundred' - * - * Code 'TH' can have the following two variations (although in combination - * with code 'SP', the case specification of 'SP' takes precedence): - * - * TH returns upper-case ordinal suffix, e.g. 400TH - * th returns lower-case ordinal suffix, e.g. 400th - * - * N.B. The format string is passed by reference, in order to pass back - * the part of the format string that matches the valid codes 'SP' and - * 'TH'. If none of these are found, then it is set to an empty string; - * If both codes are found then a string is returned with code 'SP' - * preceding code 'TH' (i.e. 'SPTH', 'Spth' or 'spth'). - * - * @param int $pn_num integer to be converted to words - * @param string &$ps_format string of formatting codes (max. length 4) - * @param int $pn_numofdigits no of digits to display if displayed as - * numeral (i.e. not spelled out), not - * including the sign (if negative); to - * allow all digits specify 0 - * @param bool $pb_nopad boolean specifying whether to suppress - * padding with leading noughts (if displayed - * as numeral) - * @param bool $pb_nosign boolean specifying whether to suppress the - * display of the sign (if negative) - * @param string $ps_locale language name abbreviation used for - * formatting - * @param string $ps_thousandsep optional thousand-separator (e.g. a comma) - * numbers as spelled-out words - * @param int $pn_padtype optional integer to specify padding (if - * displayed as numeral) - can be - * STR_PAD_LEFT or STR_PAD_RIGHT - * - * @return string - * @access private - * @since Method available since Release 1.5.0 - */ - function _formatNumber($pn_num, - &$ps_format, - $pn_numofdigits, - $pb_nopad = false, - $pb_nosign = false, - $ps_locale = "en_GB", - $ps_thousandsep = null, - $pn_padtype = STR_PAD_LEFT) - { - $hs_code1 = substr($ps_format, 0, 2); - $hs_code2 = substr($ps_format, 2, 2); - - $hs_sp = null; - $hs_th = null; - if (strtoupper($hs_code1) == "SP") { - $hs_sp = $hs_code1; - if (strtoupper($hs_code2) == "TH") { - $hs_th = $hs_code2; - } - } else if (strtoupper($hs_code1) == "TH") { - $hs_th = $hs_code1; - if (strtoupper($hs_code2) == "SP") { - $hs_sp = $hs_code2; - } - } - - $hn_absnum = abs($pn_num); - if ($pn_numofdigits > 0 && strlen($hn_absnum) > $pn_numofdigits) { - $hn_absnum = intval(substr($hn_absnum, -$pn_numofdigits)); - } - $hs_num = $hn_absnum; - - if (!is_null($hs_sp)) { - // Spell out number: - // - $ps_format = $hs_sp . - (is_null($hs_th) ? "" : ($hs_sp == "SP" ? "TH" : "th")); - return $this->_spellNumber(!$pb_nosign && $pn_num < 0 ? - $hn_absnum * -1 : - $hn_absnum, - !is_null($hs_th), - $hs_sp, - $ps_locale); - } else { - // Display number as Arabic numeral: - // - if (!$pb_nopad) { - $hs_num = str_pad($hs_num, $pn_numofdigits, "0", $pn_padtype); - } - - if (!is_null($ps_thousandsep)) { - for ($i = strlen($hs_num) - 3; $i > 0; $i -= 3) { - $hs_num = substr($hs_num, 0, $i) . - $ps_thousandsep . - substr($hs_num, $i); - } - } - - if (!$pb_nosign) { - if ($pn_num < 0) - $hs_num = "-" . $hs_num; - else if (!$pb_nopad) - $hs_num = " " . $hs_num; - } - - if (!is_null($hs_th)) { - $ps_format = $hs_th; - return $hs_num . - $this->_getOrdinalSuffix($pn_num, - substr($hs_th, 0, 1) == "T"); - } else { - $ps_format = ""; - return $hs_num; - } - } - } - - - // }}} - // {{{ format2() - - /** - * Extended version of 'format()' with variable-length formatting codes - * - * Most codes reproduce the no of digits equal to the length of the code, - * for example, 'YYY' will return the last 3 digits of the year, and so - * the year 2007 will produce '007', and the year 89 will produce '089', - * unless the no-padding code is used as in 'NPYYY', which will return - * '89'. - * - * For negative values, the sign will be discarded, unless the 'S' code - * is used in combination, but note that for positive values the value - * will be padded with a leading space unless it is suppressed with - * the no-padding modifier, for example for 2007: - * - * YYYY returns '2007' - * SYYYY returns ' 2007' - * NPSYYYY returns '2007' - * - * The no-padding modifier 'NP' can be used with numeric codes to - * suppress leading (or trailing in the case of code 'F') noughts, and - * with character-returning codes such as 'DAY' to suppress trailing - * spaces, which will otherwise be padded to the maximum possible length - * of the return-value of the code; for example, for Monday: - * - * Day returns 'Monday ' because the maximum length of - * this code is 'Wednesday'; - * NPDay returns 'Monday' - * - * N.B. this code affects the code immediately following only, and - * without this code the default is always to apply padding. - * - * Most character-returning codes, such as 'MONTH', will - * set the capitalization according to the code, so for example: - * - * MONTH returns upper-case spelling, e.g. 'JANUARY' - * Month returns spelling with first character of each word - * capitalized, e.g. 'January' - * month returns lower-case spelling, e.g. 'january' - * - * Where it makes sense, numeric codes can be combined with a following - * 'SP' code which spells out the number, or with a 'TH' code, which - * renders the code as an ordinal ('TH' only works in English), for - * example, for 31st December: - * - * DD returns '31' - * DDTH returns '31ST' - * DDth returns '31st' - * DDSP returns 'THIRTY-ONE' - * DDSp returns 'Thirty-one' - * DDsp returns 'thirty-one' - * DDSPTH returns 'THIRTY-FIRST' - * DDSpth returns 'Thirty-first' - * DDspth returns 'thirty-first' - * - * - * All formatting options: - * - * - All punctuation and white-space is reproduced unchanged - * / - * , - * . - * ; - * : - * - * "text" Quoted text is reproduced unchanged (escape using - * '\') - * AD AD indicator with or without full stops; N.B. if you - * are using 'Astronomical' year numbering then 'A.D./B.C.' - * indicators will be out for negative years - * A.D. - * AM Meridian indicator with or without full stops - * A.M. - * BC BC indicator with or without full stops - * B.C. - * BCE BCE indicator with or without full stops - * B.C.E. - * CC Century, i.e. the year divided by 100, discarding the - * remainder; 'S' prefixes negative years with a minus sign - * SCC - * CE CE indicator with or without full stops - * C.E. - * D Day of week (0-6), where 0 represents Sunday - * DAY Name of day, padded with blanks to display width of the - * widest name of day in the locale of the machine - * DD Day of month (1-31) - * DDD Day of year (1-366) - * DY Abbreviated name of day - * FFF Fractional seconds; no radix character is printed. The - * no of 'F's determines the no of digits of the - * part-second to return; e.g. 'HH:MI:SS.FF' - * F[integer] The integer after 'F' specifies the number of - * digits of the part-second to return. This is an - * alternative to using F[integer], and 'F3' is thus - * equivalent to using 'FFF'. - * HH Hour of day (0-23) - * HH12 Hour of day (1-12) - * HH24 Hour of day (0-23) - * ID Day of week (1-7) based on the ISO standard - * IW Week of year (1-52 or 1-53) based on the ISO standard - * IYYY 4-digit year based on the ISO 8601 standard; 'S' - * prefixes negative years with a minus sign - * SIYYY - * IYY Last 3, 2, or 1 digit(s) of ISO year - * IY - * I - * J Julian day - the number of days since Monday, 24th - * November, 4714 B.C. (proleptic Gregorian calendar) - * MI Minute (0-59) - * MM Month (01-12; January = 01) - * MON Abbreviated name of month - * MONTH Name of month, padded with blanks to display width of - * the widest name of month in the date language used for - * PM Meridian indicator with or without full stops - * P.M. - * Q Quarter of year (1, 2, 3, 4; January - March = 1) - * RM Roman numeral month (I-XII; January = I); N.B. padded - * with leading spaces. - * SS Second (0-59) - * SSSSS Seconds past midnight (0-86399) - * TZC Abbreviated form of time zone name, e.g. 'GMT', or the - * abbreviation for Summer time if the date falls in Summer - * time, e.g. 'BST'. - * N.B. this is not a unique identifier - for this purpose - * use the time zone region (code 'TZR'). - * TZH Time zone hour; 'S' prefixes the hour with the correct - * sign, (+/-), which otherwise is not displayed. Note - * that the leading nought can be suppressed with the - * no-padding code 'NP'). Also note that if you combine - * with the 'SP' code, the sign will not be spelled out. - * (I.e. 'STZHSp' will produce '+One', for example, and - * not 'Plus One'. - * 'TZH:TZM' will produce, for example, '+05:30'. (Also - * see 'TZM' format code) - * STZH - * TZI Whether or not the date is in Summer time (daylight - * saving time). Returns '1' if Summer time, else '0'. - * TZM Time zone minute, without any +/- sign. (Also see - * 'TZH' format element) - * TZN Long form of time zone name, e.g. - * 'Greenwich Mean Time', or the name of the Summer time if - * the date falls in Summer time, e.g. - * 'British Summer Time'. N.B. this is not a unique - * identifier - for this purpose use the time zone region - * (code 'TZR'). - * TZO Time zone offset in ISO 8601 form - that is, 'Z' if - * UTC, else [+/-][hh]:[mm] (which would be equivalent - * to 'STZH:TZM'). Note that this result is right padded - * with spaces by default, (i.e. if 'Z'). - * TZS Time zone offset in seconds; 'S' prefixes negative - * sign with minus sign '-' if negative, and no sign if - * positive (i.e. -43200 to 50400). - * STZS - * TZR Time zone region, that is, the name or ID of the time - * zone e.g. 'Europe/London'. This value is unique for - * each time zone. - * U Seconds since the Unix Epoch - - * January 1 1970 00:00:00 GMT - * W 'Absolute' week of month (1-5), counting week 1 as - * 1st-7th of the year, regardless of the day - * W1 Week of year (1-54), counting week 1 as the week that - * contains 1st January - * W4 Week of year (1-53), counting week 1 as the week that - * contains 4th January (i.e. first week with at least 4 - * days) - * W7 Week of year (1-53), counting week 1 as the week that - * contains 7th January (i.e. first full week) - * WW 'Absolute' week of year (1-53), counting week 1 as - * 1st-7th of the year, regardless of the day - * YEAR Year, spelled out; 'S' prefixes negative years with - * 'MINUS'; N.B. 'YEAR' differs from 'YYYYSP' in that the - * first will render 1923, for example, as 'NINETEEN - * TWENTY-THREE, and the second as 'ONE THOUSAND NINE - * HUNDRED TWENTY-THREE' - * SYEAR - * YYYY 4-digit year; 'S' prefixes negative years with a minus - * sign - * SYYYY - * YYY Last 3, 2, or 1 digit(s) of year - * YY - * Y - * Y,YYY Year with thousands-separator in this position; five - * possible separators - * Y.YYY - * Y·YYY N.B. space-dot (mid-dot, interpunct) is valid only in - * ISO 8859-1 (so take care when using UTF-8 in - * particular) - * Y'YYY - * Y YYY - * - * In addition the following codes can be used in combination with other - * codes; - * Codes that modify the next code in the format string: - * - * NP 'No Padding' - Returns a value with no trailing blanks - * and no leading or trailing noughts; N.B. that the - * default is to include this padding in the return string. - * N.B. affects the code immediately following only. - * - * Codes that modify the previous code in the format string (can only - * be used with integral codes such as 'MM'): - * - * TH Ordinal number - * SP Spelled cardinal number - * SPTH Spelled ordinal number (combination of 'SP' and 'TH' - * in any order) - * THSP - * - * Code 'SP' can have the following three variations (which can also be used - * in combination with 'TH'): - * - * SP returns upper-case spelling, e.g. 'FOUR HUNDRED' - * Sp returns spelling with first character of each word - * capitalized, e.g. 'Four Hundred' - * sp returns lower-case spelling, e.g. 'four hundred' - * - * Code 'TH' can have the following two variations (although in combination - * with code 'SP', the case specification of 'SP' takes precedence): - * - * TH returns upper-case ordinal suffix, e.g. 400TH - * th returns lower-case ordinal suffix, e.g. 400th - * - * @param string $ps_format format string for returned date/time - * @param string $ps_locale language name abbreviation used for formatting - * numbers as spelled-out words - * - * @return string date/time in given format - * @access public - * @since Method available since Release 1.5.0 - */ - function format2($ps_format, $ps_locale = "en_GB") - { - if (!preg_match('/^("([^"\\\\]|\\\\\\\\|\\\\")*"|(D{1,3}|S?C+|' . - 'HH(12|24)?|I[DW]|S?IY*|J|M[IM]|Q|SS(SSS)?|S?TZ[HS]|' . - 'TZM|U|W[W147]?|S?Y{1,3}([,.·\' ]?YYY)*)(SP(TH)?|' . - 'TH(SP)?)?|AD|A\.D\.|AM|A\.M\.|BCE?|B\.C\.(E\.)?|CE|' . - 'C\.E\.|DAY|DY|F(F*|[1-9][0-9]*)|MON(TH)?|NP|PM|' . - 'P\.M\.|RM|TZ[CINOR]|S?YEAR|[^A-Z0-9"])*$/i', - $ps_format)) { - return PEAR::raiseError("Invalid date format '$ps_format'", - DATE_ERROR_INVALIDFORMATSTRING); - } - - $ret = ""; - $i = 0; - - $hb_nopadflag = false; - $hb_showsignflag = false; - - $hn_weekdaypad = null; - $hn_monthpad = null; - $hn_isoyear = null; - $hn_isoweek = null; - $hn_isoday = null; - $hn_tzoffset = null; - - while ($i < strlen($ps_format)) { - $hb_lower = false; - - if ($hb_nopadflag) { - $hb_nopad = true; - } else { - $hb_nopad = false; - } - if ($hb_showsignflag) { - $hb_nosign = false; - } else { - $hb_nosign = true; - } - $hb_nopadflag = false; - $hb_showsignflag = false; - - switch ($hs_char = substr($ps_format, $i, 1)) { - case "-": - case "/": - case ",": - case ".": - case ";": - case ":": - case " ": - $ret .= $hs_char; - $i += 1; - break; - case "\"": - preg_match('/(([^"\\\\]|\\\\\\\\|\\\\")*)"/', - $ps_format, - $ha_matches, - PREG_OFFSET_CAPTURE, - $i + 1); - $ret .= str_replace(array('\\\\', '\\"'), - array('\\', '"'), - $ha_matches[1][0]); - $i += strlen($ha_matches[0][0]) + 1; - break; - case "a": - $hb_lower = true; - case "A": - if (strtoupper(substr($ps_format, $i, 4)) == "A.D.") { - $ret .= $this->year >= 0 ? - ($hb_lower ? "a.d." : "A.D.") : - ($hb_lower ? "b.c." : "B.C."); - $i += 4; - } else if (strtoupper(substr($ps_format, $i, 2)) == "AD") { - $ret .= $this->year >= 0 ? - ($hb_lower ? "ad" : "AD") : - ($hb_lower ? "bc" : "BC"); - $i += 2; - } else { - if ($this->ob_invalidtime) - return $this->_getErrorInvalidTime(); - if (strtoupper(substr($ps_format, $i, 4)) == "A.M.") { - $ret .= $this->hour < 12 ? - ($hb_lower ? "a.m." : "A.M.") : - ($hb_lower ? "p.m." : "P.M."); - $i += 4; - } else if (strtoupper(substr($ps_format, $i, 2)) == "AM") { - $ret .= $this->hour < 12 ? - ($hb_lower ? "am" : "AM") : - ($hb_lower ? "pm" : "PM"); - $i += 2; - } - } - - break; - case "b": - $hb_lower = true; - case "B": - // Check for 'B.C.E.' first: - // - if (strtoupper(substr($ps_format, $i, 6)) == "B.C.E.") { - if ($this->year >= 0) { - $hs_era = $hb_lower ? "c.e." : "C.E."; - $ret .= $hb_nopad ? - $hs_era : - str_pad($hs_era, 6, " ", STR_PAD_RIGHT); - } else { - $ret .= $hb_lower ? "b.c.e." : "B.C.E."; - } - $i += 6; - } else if (strtoupper(substr($ps_format, $i, 3)) == "BCE") { - if ($this->year >= 0) { - $hs_era = $hb_lower ? "ce" : "CE"; - $ret .= $hb_nopad ? - $hs_era : - str_pad($hs_era, 3, " ", STR_PAD_RIGHT); - } else { - $ret .= $hb_lower ? "bce" : "BCE"; - } - $i += 3; - } else if (strtoupper(substr($ps_format, $i, 4)) == "B.C.") { - $ret .= $this->year >= 0 ? - ($hb_lower ? "a.d." : "A.D.") : - ($hb_lower ? "b.c." : "B.C."); - $i += 4; - } else if (strtoupper(substr($ps_format, $i, 2)) == "BC") { - $ret .= $this->year >= 0 ? - ($hb_lower ? "ad" : "AD") : - ($hb_lower ? "bc" : "BC"); - $i += 2; - } - - break; - case "c": - $hb_lower = true; - case "C": - if (strtoupper(substr($ps_format, $i, 4)) == "C.E.") { - if ($this->year >= 0) { - $hs_era = $hb_lower ? "c.e." : "C.E."; - $ret .= $hb_nopad ? - $hs_era : - str_pad($hs_era, 6, " ", STR_PAD_RIGHT); - } else { - $ret .= $hb_lower ? "b.c.e." : "B.C.E."; - } - $i += 4; - } else if (strtoupper(substr($ps_format, $i, 2)) == "CE") { - if ($this->year >= 0) { - $hs_era = $hb_lower ? "ce" : "CE"; - $ret .= $hb_nopad ? - $hs_era : - str_pad($hs_era, 3, " ", STR_PAD_RIGHT); - } else { - $ret .= $hb_lower ? "bce" : "BCE"; - } - $i += 2; - } else { - // Code C(CCC...): - // - $hn_codelen = 1; - while (strtoupper(substr($ps_format, - $i + $hn_codelen, - 1)) == "C") - ++$hn_codelen; - - // Check next code is not 'CE' or 'C.E.' - // - if ($hn_codelen > 1 && - (strtoupper(substr($ps_format, - $i + $hn_codelen - 1, - 4)) == "C.E." || - strtoupper(substr($ps_format, - $i + $hn_codelen - 1, - 2)) == "CE" - )) - --$hn_codelen; - - $hn_century = intval($this->year / 100); - $hs_numberformat = substr($ps_format, $i + $hn_codelen, 4); - $hs_century = $this->_formatNumber($hn_century, - $hs_numberformat, - $hn_codelen, - $hb_nopad, - $hb_nosign, - $ps_locale); - if (Pear::isError($hs_century)) - return $hs_century; - - $ret .= $hs_century; - $i += $hn_codelen + strlen($hs_numberformat); - } - - break; - case "d": - $hb_lower = true; - case "D": - if (strtoupper(substr($ps_format, $i, 3)) == "DAY") { - $hs_day = Date_Calc::getWeekdayFullname($this->day, - $this->month, - $this->year); - - if (!$hb_nopad) { - if (is_null($hn_weekdaypad)) { - // Set week-day padding variable: - // - $hn_weekdaypad = 0; - foreach (Date_Calc::getWeekDays() as $hs_weekday) - $hn_weekdaypad = max($hn_weekdaypad, - strlen($hs_weekday)); - } - $hs_day = str_pad($hs_day, - $hn_weekdaypad, - " ", - STR_PAD_RIGHT); - } - - $ret .= $hb_lower ? - strtolower($hs_day) : - (substr($ps_format, $i + 1, 1) == "A" ? - strtoupper($hs_day) : - $hs_day); - $i += 3; - } else if (strtoupper(substr($ps_format, $i, 2)) == "DY") { - $hs_day = Date_Calc::getWeekdayAbbrname($this->day, - $this->month, - $this->year); - $ret .= $hb_lower ? - strtolower($hs_day) : - (substr($ps_format, $i + 1, 1) == "Y" ? - strtoupper($hs_day) : - $hs_day); - $i += 2; - } else if (strtoupper(substr($ps_format, $i, 3)) == "DDD" && - strtoupper(substr($ps_format, $i + 2, 3)) != "DAY" && - strtoupper(substr($ps_format, $i + 2, 2)) != "DY" - ) { - $hn_day = Date_Calc::dayOfYear($this->day, - $this->month, - $this->year); - $hs_numberformat = substr($ps_format, $i + 3, 4); - $hs_day = $this->_formatNumber($hn_day, - $hs_numberformat, - 3, - $hb_nopad, - true, - $ps_locale); - if (Pear::isError($hs_day)) - return $hs_day; - - $ret .= $hs_day; - $i += 3 + strlen($hs_numberformat); - } else if (strtoupper(substr($ps_format, $i, 2)) == "DD" && - strtoupper(substr($ps_format, $i + 1, 3)) != "DAY" && - strtoupper(substr($ps_format, $i + 1, 2)) != "DY" - ) { - $hs_numberformat = substr($ps_format, $i + 2, 4); - $hs_day = $this->_formatNumber($this->day, - $hs_numberformat, - 2, - $hb_nopad, - true, - $ps_locale); - if (Pear::isError($hs_day)) - return $hs_day; - - $ret .= $hs_day; - $i += 2 + strlen($hs_numberformat); - } else { - // Code 'D': - // - $hn_day = Date_Calc::dayOfWeek($this->day, - $this->month, - $this->year); - $hs_numberformat = substr($ps_format, $i + 1, 4); - $hs_day = $this->_formatNumber($hn_day, - $hs_numberformat, - 1, - $hb_nopad, - true, - $ps_locale); - if (Pear::isError($hs_day)) - return $hs_day; - - $ret .= $hs_day; - $i += 1 + strlen($hs_numberformat); - } - - break; - case "f": - case "F": - if ($this->ob_invalidtime) - return $this->_getErrorInvalidTime(); - $hn_codelen = 1; - if (is_numeric(substr($ps_format, $i + $hn_codelen, 1))) { - ++$hn_codelen; - while (is_numeric(substr($ps_format, $i + $hn_codelen, 1))) - ++$hn_codelen; - - $hn_partsecdigits = substr($ps_format, $i + 1, $hn_codelen - 1); - } else { - while (strtoupper(substr($ps_format, - $i + $hn_codelen, - 1)) == "F") - ++$hn_codelen; - - // Check next code is not F[numeric]: - // - if ($hn_codelen > 1 && - is_numeric(substr($ps_format, $i + $hn_codelen, 1))) - --$hn_codelen; - - $hn_partsecdigits = $hn_codelen; - } - - $hs_partsec = (string) $this->partsecond; - if (preg_match('/^([0-9]+)(\.([0-9]+))?E-([0-9]+)$/i', - $hs_partsec, - $ha_matches)) { - $hs_partsec = - str_repeat("0", $ha_matches[4] - strlen($ha_matches[1])) . - $ha_matches[1] . - $ha_matches[3]; - } else { - $hs_partsec = substr($hs_partsec, 2); - } - $hs_partsec = substr($hs_partsec, 0, $hn_partsecdigits); - - // '_formatNumber() will not work for this because the - // part-second is an int, and we want it to behave like a float: - // - if ($hb_nopad) { - $hs_partsec = rtrim($hs_partsec, "0"); - if ($hs_partsec == "") - $hs_partsec = "0"; - } else { - $hs_partsec = str_pad($hs_partsec, - $hn_partsecdigits, - "0", - STR_PAD_RIGHT); - } - - $ret .= $hs_partsec; - $i += $hn_codelen; - break; - case "h": - case "H": - if ($this->ob_invalidtime) - return $this->_getErrorInvalidTime(); - if (strtoupper(substr($ps_format, $i, 4)) == "HH12") { - $hn_hour = $this->hour % 12; - if ($hn_hour == 0) - $hn_hour = 12; - - $hn_codelen = 4; - } else { - // Code 'HH' or 'HH24': - // - $hn_hour = $this->hour; - $hn_codelen = strtoupper(substr($ps_format, - $i, - 4)) == "HH24" ? 4 : 2; - } - - $hs_numberformat = substr($ps_format, $i + $hn_codelen, 4); - $hs_hour = $this->_formatNumber($hn_hour, - $hs_numberformat, - 2, - $hb_nopad, - true, - $ps_locale); - if (Pear::isError($hs_hour)) - return $hs_hour; - - $ret .= $hs_hour; - $i += $hn_codelen + strlen($hs_numberformat); - break; - case "i": - case "I": - if (is_null($hn_isoyear)) - list($hn_isoyear, $hn_isoweek, $hn_isoday) = - Date_Calc::isoWeekDate($this->day, - $this->month, - $this->year); - - if (strtoupper(substr($ps_format, $i, 2)) == "ID" && - strtoupper(substr($ps_format, $i + 1, 3)) != "DAY" - ) { - $hs_numberformat = substr($ps_format, $i + 2, 4); - $hs_isoday = $this->_formatNumber($hn_isoday, - $hs_numberformat, - 1, - $hb_nopad, - true, - $ps_locale); - if (Pear::isError($hs_isoday)) - return $hs_isoday; - - $ret .= $hs_isoday; - $i += 2 + strlen($hs_numberformat); - } else if (strtoupper(substr($ps_format, $i, 2)) == "IW") { - $hs_numberformat = substr($ps_format, $i + 2, 4); - $hs_isoweek = $this->_formatNumber($hn_isoweek, - $hs_numberformat, - 2, - $hb_nopad, - true, - $ps_locale); - if (Pear::isError($hs_isoweek)) - return $hs_isoweek; - - $ret .= $hs_isoweek; - $i += 2 + strlen($hs_numberformat); - } else { - // Code I(YYY...): - // - $hn_codelen = 1; - while (strtoupper(substr($ps_format, - $i + $hn_codelen, - 1)) == "Y") - ++$hn_codelen; - - $hs_numberformat = substr($ps_format, $i + $hn_codelen, 4); - $hs_isoyear = $this->_formatNumber($hn_isoyear, - $hs_numberformat, - $hn_codelen, - $hb_nopad, - $hb_nosign, - $ps_locale); - if (Pear::isError($hs_isoyear)) - return $hs_isoyear; - - $ret .= $hs_isoyear; - $i += $hn_codelen + strlen($hs_numberformat); - } - - break; - case "j": - case "J": - $hn_jd = Date_Calc::dateToDays($this->day, - $this->month, - $this->year); - $hs_numberformat = substr($ps_format, $i + 1, 4); - - // Allow sign if negative; allow all digits (specify nought); - // suppress padding: - // - $hs_jd = $this->_formatNumber($hn_jd, - $hs_numberformat, - 0, - true, - false, - $ps_locale); - if (Pear::isError($hs_jd)) - return $hs_jd; - - $ret .= $hs_jd; - $i += 1 + strlen($hs_numberformat); - break; - case "m": - $hb_lower = true; - case "M": - if (strtoupper(substr($ps_format, $i, 2)) == "MI") { - if ($this->ob_invalidtime) - return $this->_getErrorInvalidTime(); - $hs_numberformat = substr($ps_format, $i + 2, 4); - $hs_minute = $this->_formatNumber($this->minute, - $hs_numberformat, - 2, - $hb_nopad, - true, - $ps_locale); - if (Pear::isError($hs_minute)) - return $hs_minute; - - $ret .= $hs_minute; - $i += 2 + strlen($hs_numberformat); - } else if (strtoupper(substr($ps_format, $i, 2)) == "MM") { - $hs_numberformat = substr($ps_format, $i + 2, 4); - $hs_month = $this->_formatNumber($this->month, - $hs_numberformat, - 2, - $hb_nopad, - true, - $ps_locale); - if (Pear::isError($hs_month)) - return $hs_month; - - $ret .= $hs_month; - $i += 2 + strlen($hs_numberformat); - } else if (strtoupper(substr($ps_format, $i, 5)) == "MONTH") { - $hs_month = Date_Calc::getMonthFullname($this->month); - - if (!$hb_nopad) { - if (is_null($hn_monthpad)) { - // Set month padding variable: - // - $hn_monthpad = 0; - foreach (Date_Calc::getMonthNames() as $hs_monthofyear) - $hn_monthpad = max($hn_monthpad, - strlen($hs_monthofyear)); - } - $hs_month = str_pad($hs_month, - $hn_monthpad, - " ", - STR_PAD_RIGHT); - } - - $ret .= $hb_lower ? - strtolower($hs_month) : - (substr($ps_format, $i + 1, 1) == "O" ? - strtoupper($hs_month) : - $hs_month); - $i += 5; - } else if (strtoupper(substr($ps_format, $i, 3)) == "MON") { - $hs_month = Date_Calc::getMonthAbbrname($this->month); - $ret .= $hb_lower ? - strtolower($hs_month) : - (substr($ps_format, $i + 1, 1) == "O" ? - strtoupper($hs_month) : - $hs_month); - $i += 3; - } - - break; - case "n": - case "N": - // No-Padding rule 'NP' applies to the next code (either trailing - // spaces or leading/trailing noughts): - // - $hb_nopadflag = true; - $i += 2; - break; - case "p": - $hb_lower = true; - case "P": - if ($this->ob_invalidtime) - return $this->_getErrorInvalidTime(); - if (strtoupper(substr($ps_format, $i, 4)) == "P.M.") { - $ret .= $this->hour < 12 ? - ($hb_lower ? "a.m." : "A.M.") : - ($hb_lower ? "p.m." : "P.M."); - $i += 4; - } else if (strtoupper(substr($ps_format, $i, 2)) == "PM") { - $ret .= $this->hour < 12 ? - ($hb_lower ? "am" : "AM") : - ($hb_lower ? "pm" : "PM"); - $i += 2; - } - - break; - case "q": - case "Q": - // N.B. Current implementation ignores the day and year, but - // it is possible that a different implementation might be - // desired, so pass these parameters anyway: - // - $hn_quarter = Date_Calc::quarterOfYear($this->day, - $this->month, - $this->year); - $hs_numberformat = substr($ps_format, $i + 1, 4); - $hs_quarter = $this->_formatNumber($hn_quarter, - $hs_numberformat, - 1, - $hb_nopad, - true, - $ps_locale); - if (Pear::isError($hs_quarter)) - return $hs_quarter; - - $ret .= $hs_quarter; - $i += 1 + strlen($hs_numberformat); - break; - case "r": - $hb_lower = true; - case "R": - // Code 'RM': - // - switch ($this->month) { - case 1: - $hs_monthroman = "i"; - break; - case 2: - $hs_monthroman = "ii"; - break; - case 3: - $hs_monthroman = "iii"; - break; - case 4: - $hs_monthroman = "iv"; - break; - case 5: - $hs_monthroman = "v"; - break; - case 6: - $hs_monthroman = "vi"; - break; - case 7: - $hs_monthroman = "vii"; - break; - case 8: - $hs_monthroman = "viii"; - break; - case 9: - $hs_monthroman = "ix"; - break; - case 10: - $hs_monthroman = "x"; - break; - case 11: - $hs_monthroman = "xi"; - break; - case 12: - $hs_monthroman = "xii"; - break; - } - - $hs_monthroman = $hb_lower ? - $hs_monthroman : - strtoupper($hs_monthroman); - $ret .= $hb_nopad ? - $hs_monthroman : - str_pad($hs_monthroman, 4, " ", STR_PAD_LEFT); - $i += 2; - break; - case "s": - case "S": - // Check for 'SSSSS' before 'SS': - // - if (strtoupper(substr($ps_format, $i, 5)) == "SSSSS") { - if ($this->ob_invalidtime) - return $this->_getErrorInvalidTime(); - $hs_numberformat = substr($ps_format, $i + 5, 4); - $hn_second = Date_Calc::secondsPastMidnight($this->hour, - $this->minute, - $this->second); - $hs_second = $this->_formatNumber($hn_second, - $hs_numberformat, - 5, - $hb_nopad, - true, - $ps_locale); - if (Pear::isError($hs_second)) - return $hs_second; - - $ret .= $hs_second; - $i += 5 + strlen($hs_numberformat); - } else if (strtoupper(substr($ps_format, $i, 2)) == "SS") { - if ($this->ob_invalidtime) - return $this->_getErrorInvalidTime(); - $hs_numberformat = substr($ps_format, $i + 2, 4); - $hs_second = $this->_formatNumber($this->second, - $hs_numberformat, - 2, - $hb_nopad, - true, - $ps_locale); - if (Pear::isError($hs_second)) - return $hs_second; - - $ret .= $hs_second; - $i += 2 + strlen($hs_numberformat); - } else { - // One of the following codes: - // 'SC(CCC...)' - // 'SY(YYY...)' - // 'SIY(YYY...)' - // 'STZH' - // 'STZS' - // 'SYEAR' - // - $hb_showsignflag = true; - if ($hb_nopad) - $hb_nopadflag = true; - ++$i; - } - - break; - case "t": - case "T": - // Code TZ[...]: - // - - if (strtoupper(substr($ps_format, $i, 3)) == "TZR") { - // This time-zone-related code can be called when the time is - // invalid, but the others should return an error: - // - $ret .= $this->getTZID(); - $i += 3; - } else { - if ($this->ob_invalidtime) - return $this->_getErrorInvalidTime(); - - if (strtoupper(substr($ps_format, $i, 3)) == "TZC") { - $ret .= $this->getTZShortName(); - $i += 3; - } else if (strtoupper(substr($ps_format, $i, 3)) == "TZH") { - if (is_null($hn_tzoffset)) - $hn_tzoffset = $this->getTZOffset(); - - $hs_numberformat = substr($ps_format, $i + 3, 4); - $hn_tzh = intval($hn_tzoffset / 3600000); - - // Suppress sign here (it is added later): - // - $hs_tzh = $this->_formatNumber($hn_tzh, - $hs_numberformat, - 2, - $hb_nopad, - true, - $ps_locale); - if (Pear::isError($hs_tzh)) - return $hs_tzh; - - // Display sign, even if positive: - // - $ret .= ($hb_nosign ? "" : ($hn_tzh >= 0 ? '+' : '-')) . - $hs_tzh; - $i += 3 + strlen($hs_numberformat); - } else if (strtoupper(substr($ps_format, $i, 3)) == "TZI") { - $ret .= ($this->inDaylightTime() ? '1' : '0'); - $i += 3; - } else if (strtoupper(substr($ps_format, $i, 3)) == "TZM") { - if (is_null($hn_tzoffset)) - $hn_tzoffset = $this->getTZOffset(); - - $hs_numberformat = substr($ps_format, $i + 3, 4); - $hn_tzm = intval(($hn_tzoffset % 3600000) / 60000); - - // Suppress sign: - // - $hs_tzm = $this->_formatNumber($hn_tzm, - $hs_numberformat, - 2, - $hb_nopad, - true, - $ps_locale); - if (Pear::isError($hs_tzm)) - return $hs_tzm; - - $ret .= $hs_tzm; - $i += 3 + strlen($hs_numberformat); - } else if (strtoupper(substr($ps_format, $i, 3)) == "TZN") { - $ret .= $this->getTZLongName(); - $i += 3; - } else if (strtoupper(substr($ps_format, $i, 3)) == "TZO") { - if (is_null($hn_tzoffset)) - $hn_tzoffset = $this->getTZOffset(); - - $hn_tzh = intval(abs($hn_tzoffset) / 3600000); - $hn_tzm = intval((abs($hn_tzoffset) % 3600000) / 60000); - - if ($hn_tzoffset == 0) { - $ret .= $hb_nopad ? "Z" : "Z "; - } else { - // Display sign, even if positive: - // - $ret .= ($hn_tzoffset >= 0 ? '+' : '-') . - sprintf("%02d", $hn_tzh) . - ":" . - sprintf("%02d", $hn_tzm); - } - $i += 3; - } else if (strtoupper(substr($ps_format, $i, 3)) == "TZS") { - if (is_null($hn_tzoffset)) - $hn_tzoffset = $this->getTZOffset(); - - $hs_numberformat = substr($ps_format, $i + 3, 4); - $hn_tzs = intval($hn_tzoffset / 1000); - $hs_tzs = $this->_formatNumber($hn_tzs, - $hs_numberformat, - 5, - $hb_nopad, - $hb_nosign, - $ps_locale); - if (Pear::isError($hs_tzs)) - return $hs_tzs; - - $ret .= $hs_tzs; - $i += 3 + strlen($hs_numberformat); - } - } - - break; - case "u": - case "U": - if ($this->ob_invalidtime) - return $this->_getErrorInvalidTime(); - $hn_unixtime = $this->getTime(); - $hs_numberformat = substr($ps_format, $i + 1, 4); - - // Allow sign if negative; allow all digits (specify nought); - // suppress padding: - // - $hs_unixtime = $this->_formatNumber($hn_unixtime, - $hs_numberformat, - 0, - true, - false, - $ps_locale); - if (Pear::isError($hs_unixtime)) - return $hs_unixtime; - - $ret .= $hs_unixtime; - $i += 1 + strlen($hs_numberformat); - break; - case "w": - case "W": - // Check for 'WW' before 'W': - // - if (strtoupper(substr($ps_format, $i, 2)) == "WW") { - $hn_week = Date_Calc::weekOfYearAbsolute($this->day, - $this->month, - $this->year); - $hs_numberformat = substr($ps_format, $i + 2, 4); - $hs_week = $this->_formatNumber($hn_week, - $hs_numberformat, - 2, - $hb_nopad, - true, - $ps_locale); - if (Pear::isError($hs_week)) - return $hs_week; - - $ret .= $hs_week; - $i += 2 + strlen($hs_numberformat); - } else if (strtoupper(substr($ps_format, $i, 2)) == "W1") { - $hn_week = Date_Calc::weekOfYear1st($this->day, - $this->month, - $this->year); - $hs_numberformat = substr($ps_format, $i + 2, 4); - $hs_week = $this->_formatNumber($hn_week, - $hs_numberformat, - 2, - $hb_nopad, - true, - $ps_locale); - if (Pear::isError($hs_week)) - return $hs_week; - - $ret .= $hs_week; - $i += 2 + strlen($hs_numberformat); - } else if (strtoupper(substr($ps_format, $i, 2)) == "W4") { - $ha_week = Date_Calc::weekOfYear4th($this->day, - $this->month, - $this->year); - $hn_week = $ha_week[1]; - $hs_numberformat = substr($ps_format, $i + 2, 4); - $hs_week = $this->_formatNumber($hn_week, - $hs_numberformat, - 2, - $hb_nopad, - true, - $ps_locale); - if (Pear::isError($hs_week)) - return $hs_week; - - $ret .= $hs_week; - $i += 2 + strlen($hs_numberformat); - } else if (strtoupper(substr($ps_format, $i, 2)) == "W7") { - $ha_week = Date_Calc::weekOfYear7th($this->day, - $this->month, - $this->year); - $hn_week = $ha_week[1]; - $hs_numberformat = substr($ps_format, $i + 2, 4); - $hs_week = $this->_formatNumber($hn_week, - $hs_numberformat, - 2, - $hb_nopad, - true, - $ps_locale); - if (Pear::isError($hs_week)) - return $hs_week; - - $ret .= $hs_week; - $i += 2 + strlen($hs_numberformat); - } else { - // Code 'W': - // - $hn_week = Date_Calc::weekOfMonthAbsolute($this->day, - $this->month, - $this->year); - $hs_numberformat = substr($ps_format, $i + 1, 4); - $hs_week = $this->_formatNumber($hn_week, - $hs_numberformat, - 1, - $hb_nopad, - true, - $ps_locale); - if (Pear::isError($hs_week)) - return $hs_week; - - $ret .= $hs_week; - $i += 1 + strlen($hs_numberformat); - } - - break; - case "y": - case "Y": - // Check for 'YEAR' first: - // - if (strtoupper(substr($ps_format, $i, 4)) == "YEAR") { - switch (substr($ps_format, $i, 2)) { - case "YE": - $hs_spformat = "SP"; - break; - case "Ye": - $hs_spformat = "Sp"; - break; - default: - $hs_spformat = "sp"; - } - - if (($hn_yearabs = abs($this->year)) < 100 || - $hn_yearabs % 100 < 10) { - - $hs_numberformat = $hs_spformat; - - // Allow all digits (specify nought); padding irrelevant: - // - $hs_year = $this->_formatNumber($this->year, - $hs_numberformat, - 0, - true, - $hb_nosign, - $ps_locale); - if (Pear::isError($hs_year)) - return $hs_year; - - $ret .= $hs_year; - } else { - // Year is spelled 'Nineteen Twelve' rather than - // 'One thousand Nine Hundred Twelve': - // - $hn_century = intval($this->year / 100); - $hs_numberformat = $hs_spformat; - - // Allow all digits (specify nought); padding irrelevant: - // - $hs_century = $this->_formatNumber($hn_century, - $hs_numberformat, - 0, - true, - $hb_nosign, - $ps_locale); - if (Pear::isError($hs_century)) - return $hs_century; - - $ret .= $hs_century . " "; - - $hs_numberformat = $hs_spformat; - - // Discard sign; padding irrelevant: - // - $hs_year = $this->_formatNumber($this->year, - $hs_numberformat, - 2, - false, - true, - $ps_locale); - if (Pear::isError($hs_year)) - return $hs_year; - - $ret .= $hs_year; - } - - $i += 4; - } else { - // Code Y(YYY...): - // - $hn_codelen = 1; - while (strtoupper(substr($ps_format, - $i + $hn_codelen, - 1)) == "Y") - ++$hn_codelen; - - $hs_thousandsep = null; - $hn_thousandseps = 0; - if ($hn_codelen <= 3) { - while (preg_match('/([,.·\' ])YYY/i', - substr($ps_format, - $i + $hn_codelen, - 4), - $ha_matches)) { - $hn_codelen += 4; - $hs_thousandsep = $ha_matches[1]; - ++$hn_thousandseps; - } - } - - // Check next code is not 'YEAR' - // - if ($hn_codelen > 1 && - strtoupper(substr($ps_format, - $i + $hn_codelen - 1, - 4)) == "YEAR") - --$hn_codelen; - - $hs_numberformat = substr($ps_format, $i + $hn_codelen, 4); - $hs_year = $this->_formatNumber($this->year, - $hs_numberformat, - $hn_codelen - - $hn_thousandseps, - $hb_nopad, - $hb_nosign, - $ps_locale, - $hs_thousandsep); - if (Pear::isError($hs_year)) - return $hs_year; - - $ret .= $hs_year; - $i += $hn_codelen + strlen($hs_numberformat); - } - - break; - default: - $ret .= $hs_char; - ++$i; - break; - } - } - return $ret; - } - - - // }}} - // {{{ format3() - - /** - * Formats the date in the same way as 'format()', but using the - * formatting codes used by the PHP function 'date()' - * - * All 'date()' formatting options are supported except 'B'. This - * function also responds to the DATE_* constants, such as DATE_COOKIE, - * which are specified at: - * - * http://www.php.net/manual/en/ref.datetime.php#datetime.constants - * - * - * Formatting options: - * - * (Day) - * - * d Day of the month, 2 digits with leading zeros (01 to 31) - * D A textual representation of a day, three letters ('Mon' - * to 'Sun') - * j Day of the month without leading zeros (1 to 31) - * l [lowercase 'L'] A full textual representation of the day - * of the week ('Sunday' to 'Saturday') - * N ISO-8601 numeric representation of the day of the week - * (1 (for Monday) to 7 (for Sunday)) - * S English ordinal suffix for the day of the month, 2 - * characters ('st', 'nd', 'rd' or 'th') - * w Numeric representation of the day of the week (0 (for - * Sunday) to 6 (for Saturday)) - * z The day of the year, starting from 0 (0 to 365) - * - * (Week) - * - * W ISO-8601 week number of year, weeks starting on Monday - * (00 to 53) - * - * (Month) - * - * F A full textual representation of a month ('January' to - * 'December') - * m Numeric representation of a month, with leading zeros - * (01 to 12) - * M A short textual representation of a month, three letters - * ('Jan' to 'Dec') - * n Numeric representation of a month, without leading zeros - * (1 to 12) - * t Number of days in the given month (28 to 31) - * - * (Year) - * - * L Whether it is a leap year (1 if it is a leap year, 0 - * otherwise) - * o ISO-8601 year number. This has the same value as Y, - * except that if the ISO week number (W) belongs to the - * previous or next year, that year is used instead. - * Y A full numeric representation of a year, 4 digits (0000 - * to 9999) - * y A two digit representation of a year (00 to 99) - * - * (Time) - * - * a Lowercase Ante meridiem and Post meridiem ('am' or - * 'pm') - * A Uppercase Ante meridiem and Post meridiem ('AM' or - * 'PM') - * g 12-hour format of an hour without leading zeros (1 to 12) - * G 24-hour format of an hour without leading zeros (0 to 23) - * h 12-hour format of an hour with leading zeros (01 to 12) - * H 24-hour format of an hour with leading zeros (00 to 23) - * i Minutes with leading zeros (00 to 59) - * s Seconds, with leading zeros (00 to 59) - * u Milliseconds, e.g. '54321' - * - * (Time Zone) - * - * e Timezone identifier, e.g. Europe/London - * I Whether or not the date is in Summer time (1 if Summer - * time, 0 otherwise) - * O Difference to Greenwich time (GMT) in hours, e.g. '+0200' - * P Difference to Greenwich time (GMT) with colon between - * hours and minutes, e.g. '+02:00' - * T Timezone abbreviation, e.g. 'GMT', 'EST' - * Z Timezone offset in seconds. The offset for timezones west - * of UTC is always negative, and for those east of UTC is - * always positive. (-43200 to 50400) - * - * (Full Date/Time) - * - * c ISO 8601 date, e.g. '2004-02-12T15:19:21+00:00' - * r RFC 2822 formatted date, e.g. - * 'Thu, 21 Dec 2000 16:01:07 +0200' - * U Seconds since the Unix Epoch - * (January 1 1970 00:00:00 GMT) - * - * @param string $ps_format the format string for returned date/time - * - * @return string date/time in given format - * @access public - * @since Method available since Release 1.5.0 - */ - function format3($ps_format) - { - $hs_format2str = ""; - - for ($i = 0; $i < strlen($ps_format); ++$i) { - switch ($hs_char = substr($ps_format, $i, 1)) { - case 'd': - $hs_format2str .= 'DD'; - break; - case 'D': - $hs_format2str .= 'NPDy'; - break; - case 'j': - $hs_format2str .= 'NPDD'; - break; - case 'l': - $hs_format2str .= 'NPDay'; - break; - case 'N': - $hs_format2str .= 'ID'; - break; - case 'S': - $hs_format2str .= 'th'; - break; - case 'w': - $hs_format2str .= 'D'; - break; - case 'z': - $hs_format2str .= '"' . ($this->getDayOfYear() - 1) . '"'; - break; - case 'W': - $hs_format2str .= 'IW'; - break; - case 'F': - $hs_format2str .= 'NPMonth'; - break; - case 'm': - $hs_format2str .= 'MM'; - break; - case 'M': - $hs_format2str .= 'NPMon'; - break; - case 'n': - $hs_format2str .= 'NPMM'; - break; - case 't': - $hs_format2str .= '"' . $this->getDaysInMonth() . '"'; - break; - case 'L': - $hs_format2str .= '"' . ($this->isLeapYear() ? 1 : 0) . '"'; - break; - case 'o': - $hs_format2str .= 'IYYY'; - break; - case 'Y': - $hs_format2str .= 'YYYY'; - break; - case 'y': - $hs_format2str .= 'YY'; - break; - case 'a': - $hs_format2str .= 'am'; - break; - case 'A': - $hs_format2str .= 'AM'; - break; - case 'g': - $hs_format2str .= 'NPHH12'; - break; - case 'G': - $hs_format2str .= 'NPHH24'; - break; - case 'h': - $hs_format2str .= 'HH12'; - break; - case 'H': - $hs_format2str .= 'HH24'; - break; - case 'i': - $hs_format2str .= 'MI'; - break; - case 's': - $hs_format2str .= 'SS'; - break; - case 'u': - $hs_format2str .= 'SSFFF'; - break; - case 'e': - $hs_format2str .= 'TZR'; - break; - case 'I': - $hs_format2str .= 'TZI'; - break; - case 'O': - $hs_format2str .= 'STZHTZM'; - break; - case 'P': - $hs_format2str .= 'STZH:TZM'; - break; - case 'T': - $hs_format2str .= 'TZC'; - break; - case 'Z': - $hs_format2str .= 'TZS'; - break; - case 'c': - $hs_format2str .= 'YYYY-MM-DD"T"HH24:MI:SSSTZH:TZM'; - break; - case 'r': - $hs_format2str .= 'Dy, DD Mon YYYY HH24:MI:SS STZHTZM'; - break; - case 'U': - $hs_format2str .= 'U'; - break; - case '\\': - $hs_char = substr($ps_format, ++$i, 1); - $hs_format2str .= '"' . ($hs_char == '\\' ? '\\\\' : $hs_char) . '"'; - break; - case '"': - $hs_format2str .= '"\\""'; - break; - default: - $hs_format2str .= '"' . $hs_char . '"'; - } - } - - $ret = $this->format2($hs_format2str); - if (PEAR::isError($ret) && - $ret->getCode() == DATE_ERROR_INVALIDFORMATSTRING) { - return PEAR::raiseError("Invalid date format '$ps_format'", - DATE_ERROR_INVALIDFORMATSTRING); - } - - return $ret; - } - - - // }}} - // {{{ getTime() - - /** - * Returns the date/time in Unix time() format - * - * Returns a representation of this date in Unix time() format. This may - * only be valid for dates from 1970 to ~2038. - * - * @return int number of seconds since the unix epoch - * @access public - */ - function getTime() - { - return $this->getDate(DATE_FORMAT_UNIXTIME); - } - - - // }}} - // {{{ getTZID() - - /** - * Returns the unique ID of the time zone, e.g. 'America/Chicago' - * - * @return string the time zone ID - * @access public - * @since Method available since Release 1.5.0 - */ - function getTZID() - { - return $this->tz->getID(); - } - - - // }}} - // {{{ _setTZToDefault() - - /** - * sets time zone to the default time zone - * - * If PHP version >= 5.1.0, uses the php.ini configuration directive - * 'date.timezone' if set and valid, else the value returned by - * 'date("e")' if valid, else the default specified if the global - * constant '$GLOBALS["_DATE_TIMEZONE_DEFAULT"]', which if itself - * left unset, defaults to "UTC". - * - * N.B. this is a private method; to set the time zone to the - * default publicly you should call 'setTZByID()', that is, with no - * parameter (or a parameter of null). - * - * @return void - * @access private - * @since Method available since Release 1.5.0 - */ - function _setTZToDefault() - { - if (function_exists('version_compare') && - version_compare(phpversion(), "5.1.0", ">=") && - (Date_TimeZone::isValidID($hs_id = ini_get("date.timezone")) || - Date_TimeZone::isValidID($hs_id = date("e")) - ) - ) { - $this->tz = new Date_TimeZone($hs_id); - } else { - $this->tz = Date_TimeZone::getDefault(); - } - } - - - // }}} - // {{{ setTZ() - - /** - * Sets the time zone of this Date - * - * Sets the time zone of this date with the given - * Date_TimeZone object. Does not alter the date/time, - * only assigns a new time zone. For conversion, use - * convertTZ(). - * - * @param object $tz the Date_TimeZone object to use. If called with a - * parameter that is not a Date_TimeZone object, will - * fall through to setTZByID(). - * - * @return void - * @access public - * @see Date::setTZByID() - */ - function setTZ($tz) - { - if (is_a($tz, 'Date_Timezone')) { - $this->setTZByID($tz->getID()); - } else { - $res = $this->setTZByID($tz); - if (PEAR::isError($res)) - return $res; - } - } - - - // }}} - // {{{ setTZByID() - - /** - * Sets the time zone of this date with the given time zone ID - * - * The time zone IDs are drawn from the 'tz data-base' (see - * http://en.wikipedia.org/wiki/Zoneinfo), which is the de facto - * internet and IT standard. (There is no official standard, and - * the tz data-base is not intended to be a regulating body - * anyway.) Lists of valid IDs are maintained at: - * - * http://en.wikipedia.org/wiki/List_of_zoneinfo_timezones - * http://www.php.net/manual/en/timezones.php - * - * If no time-zone is specified and PHP version >= 5.1.0, the time - * zone is set automatically to the php.ini configuration directive - * 'date.timezone' if set and valid, else the value returned by - * 'date("e")' if valid, else the default specified if the global - * constant '$GLOBALS["_DATE_TIMEZONE_DEFAULT"]', which if itself - * left unset, defaults to "UTC". - * - * N.B. this function preserves the local date and time, that is, - * whether in local Summer time or local standard time. For example, - * if the time is set to 11.00 Summer time, and the time zone is then - * set to another time zone, using this function, in which the date - * falls in standard time, then the time will remain set to 11.00 UTC, - * and not 10.00. You can convert a date to another time zone by - * calling 'convertTZ()'. - * - * The ID can also be specified as a UTC offset in one of the following - * forms, i.e. an offset with no geographical or political base: - * - * UTC[+/-][h] - e.g. UTC-1 (the preferred form) - * UTC[+/-][hh] - e.g. UTC+03 - * UTC[+/-][hh][mm] - e.g. UTC-0530 - * UTC[+/-][hh]:[mm] - e.g. UTC+03:00 - * - * N.B. 'UTC' seems to be technically preferred over 'GMT'. GMT-based - * IDs still exist in the tz data-base, but beware of POSIX-style - * offsets which are the opposite way round to what people normally - * expect. - * - * @param string $ps_id a valid time zone id, e.g. 'Europe/London' - * - * @return void - * @access public - * @see Date::convertTZByID(), Date_TimeZone::isValidID(), - * Date_TimeZone::Date_TimeZone() - */ - function setTZByID($ps_id = null) - { - // Whether the date is in Summer time forms the default for - // the new time zone (if needed, which is very unlikely anyway). - // This is mainly to prevent unexpected (defaulting) behaviour - // if the user is in the repeated hour, and switches to a time - // zone that is also in the repeated hour (e.g. 'Europe/London' - // and 'Europe/Lisbon'). - // - $hb_insummertime = $this->inDaylightTime(); - if (PEAR::isError($hb_insummertime)) { - if ($hb_insummertime->getCode() == DATE_ERROR_INVALIDTIME) { - $hb_insummertime = false; - } else { - return $hb_insummertime; - } - } - - if (is_null($ps_id)) { - $this->_setTZToDefault(); - } else if (Date_TimeZone::isValidID($ps_id)) { - $this->tz = new Date_TimeZone($ps_id); - } else { - return PEAR::raiseError("Invalid time zone ID '$ps_id'", - DATE_ERROR_INVALIDTIMEZONE); - } - - $this->setLocalTime($this->day, - $this->month, - $this->year, - $this->hour, - $this->minute, - $this->second, - $this->partsecond, - $hb_insummertime); - } - - - // }}} - // {{{ getTZLongName() - - /** - * Returns the long name of the time zone - * - * Returns long form of time zone name, e.g. 'Greenwich Mean Time'. - * N.B. if the date falls in Summer time, the Summer time name will be - * returned instead, e.g. 'British Summer Time'. - * - * N.B. this is not a unique identifier for the time zone - for this - * purpose use the time zone ID. - * - * @return string the long name of the time zone - * @access public - * @since Method available since Release 1.5.0 - */ - function getTZLongName() - { - if ($this->ob_invalidtime) - return $this->_getErrorInvalidTime(); - - return $this->tz->getLongName($this->inDaylightTime()); - } - - - // }}} - // {{{ getTZShortName() - - /** - * Returns the short name of the time zone - * - * Returns abbreviated form of time zone name, e.g. 'GMT'. N.B. if the - * date falls in Summer time, the Summer time name will be returned - * instead, e.g. 'BST'. - * - * N.B. this is not a unique identifier - for this purpose use the - * time zone ID. - * - * @return string the short name of the time zone - * @access public - * @since Method available since Release 1.5.0 - */ - function getTZShortName() - { - if ($this->ob_invalidtime) - return $this->_getErrorInvalidTime(); - - return $this->tz->getShortName($this->inDaylightTime()); - } - - - // }}} - // {{{ getTZOffset() - - /** - * Returns the DST-corrected offset from UTC for the given date - * - * Gets the offset to UTC for a given date/time, taking into - * account daylight savings time, if the time zone observes it and if - * it is in effect. - * - * N.B. that the offset is calculated historically - * and in the future according to the current Summer time rules, - * and so this function is proleptically correct, but not necessarily - * historically correct. (Although if you want to be correct about - * times in the distant past, this class is probably not for you - * because the whole notion of time zones does not apply, and - * historically there are so many time zone changes, Summer time - * rule changes, name changes, calendar changes, that calculating - * this sort of information is beyond the scope of this package - * altogether.) - * - * @return int the corrected offset to UTC in milliseconds - * @access public - * @since Method available since Release 1.5.0 - */ - function getTZOffset() - { - if ($this->ob_invalidtime) - return $this->_getErrorInvalidTime(); - - return $this->tz->getOffset($this->inDaylightTime()); - } - - - // }}} - // {{{ inDaylightTime() - - /** - * Tests if this date/time is in DST - * - * Returns true if daylight savings time is in effect for - * this date in this date's time zone. - * - * @param bool $pb_repeatedhourdefault value to return if repeated hour is - * specified (defaults to false) - * - * @return boolean true if DST is in effect for this date - * @access public - */ - function inDaylightTime($pb_repeatedhourdefault = false) - { - if (!$this->tz->hasDaylightTime()) - return false; - if ($this->ob_invalidtime) - return $this->_getErrorInvalidTime(); - - // The return value is 'cached' whenever the date/time is set: - // - return $this->hour != $this->on_standardhour || - $this->minute != $this->on_standardminute || - $this->second != $this->on_standardsecond || - $this->partsecond != $this->on_standardpartsecond || - $this->day != $this->on_standardday || - $this->month != $this->on_standardmonth || - $this->year != $this->on_standardyear; - // - // (these last 3 conditions are theoretical - // possibilities but normally will never occur) - } - - - // }}} - // {{{ convertTZ() - - /** - * Converts this date to a new time zone - * - * Previously this might not have worked correctly if your system did - * not allow putenv() or if localtime() did not work in your - * environment, but this implementation is no longer used. - * - * @param object $tz Date_TimeZone object to convert to - * - * @return void - * @access public - * @see Date::convertTZByID() - */ - function convertTZ($tz) - { - if ($this->getTZID() == $tz->getID()) - return; - if ($this->ob_invalidtime) - return $this->_getErrorInvalidTime(); - - $hn_rawoffset = $tz->getRawOffset() - $this->tz->getRawOffset(); - $this->tz = new Date_TimeZone($tz->getID()); - - list($hn_standardyear, - $hn_standardmonth, - $hn_standardday, - $hn_standardhour, - $hn_standardminute, - $hn_standardsecond, - $hn_standardpartsecond) = - $this->_addOffset($hn_rawoffset, - $this->on_standardday, - $this->on_standardmonth, - $this->on_standardyear, - $this->on_standardhour, - $this->on_standardminute, - $this->on_standardsecond, - $this->on_standardpartsecond); - - $this->setStandardTime($hn_standardday, - $hn_standardmonth, - $hn_standardyear, - $hn_standardhour, - $hn_standardminute, - $hn_standardsecond, - $hn_standardpartsecond); - } - - - // }}} - // {{{ toUTC() - - /** - * Converts this date to UTC and sets this date's timezone to UTC - * - * @return void - * @access public - */ - function toUTC() - { - if ($this->getTZID() == "UTC") - return; - if ($this->ob_invalidtime) - return $this->_getErrorInvalidTime(); - - $res = $this->convertTZ(new Date_TimeZone("UTC")); - if (PEAR::isError($res)) - return $res; - } - - - // }}} - // {{{ convertTZByID() - - /** - * Converts this date to a new time zone, given a valid time zone ID - * - * Previously this might not have worked correctly if your system did - * not allow putenv() or if localtime() does not work in your - * environment, but this implementation is no longer used. - * - * @param string $ps_id a valid time zone id, e.g. 'Europe/London' - * - * @return void - * @access public - * @see Date::setTZByID(), Date_TimeZone::isValidID(), - * Date_TimeZone::Date_TimeZone() - */ - function convertTZByID($ps_id) - { - if (!Date_TimeZone::isValidID($ps_id)) { - return PEAR::raiseError("Invalid time zone ID '$ps_id'", - DATE_ERROR_INVALIDTIMEZONE); - } - - $res = $this->convertTZ(new Date_TimeZone($ps_id)); - - if (PEAR::isError($res)) - return $res; - } - - - // }}} - // {{{ toUTCbyOffset() - - /** - * Converts the date/time to UTC by the offset specified - * - * This function is no longer called from within the Date class - * itself because a time zone can be set using a pure offset - * (e.g. UTC+1), i.e. not a geographical time zone. However - * it is retained for backwards compaibility. - * - * @param string $ps_offset offset of the form '[+/-][hh]:[mm]', - * '[+/-][hh][mm]', or 'Z' - * - * @return bool - * @access private - */ - function toUTCbyOffset($ps_offset) - { - if ($ps_offset == "Z" || - preg_match('/^[+\-](00:?00|0{1,2})$/', $ps_offset)) { - $hs_tzid = "UTC"; - } else if (preg_match('/^[+\-]([0-9]{2,2}:?[0-5][0-9]|[0-9]{1,2})$/', - $ps_offset)) { - $hs_tzid = "UTC" . $ps_offset; - } else { - return PEAR::raiseError("Invalid offset '$ps_offset'"); - } - - // If the time is invalid, it does not matter here: - // - $this->setTZByID($hs_tzid); - - // Now the time will be valid because it is a time zone that - // does not observe Summer time: - // - $this->toUTC(); - } - - - // }}} - // {{{ addYears() - - /** - * Converts the date to the specified no of years from the given date - * - * To subtract years use a negative value for the '$pn_years' - * parameter - * - * @param int $pn_years years to add - * - * @return void - * @access public - * @since Method available since Release 1.5.0 - */ - function addYears($pn_years) - { - list($hs_year, $hs_month, $hs_day) = - explode(" ", Date_Calc::addYears($pn_years, - $this->day, - $this->month, - $this->year, - "%Y %m %d")); - $this->setLocalTime($hs_day, - $hs_month, - $hs_year, - $this->hour, - $this->minute, - $this->second, - $this->partsecond); - } - - - // }}} - // {{{ addMonths() - - /** - * Converts the date to the specified no of months from the given date - * - * To subtract months use a negative value for the '$pn_months' - * parameter - * - * @param int $pn_months months to add - * - * @return void - * @access public - * @since Method available since Release 1.5.0 - */ - function addMonths($pn_months) - { - list($hs_year, $hs_month, $hs_day) = - explode(" ", Date_Calc::addMonths($pn_months, - $this->day, - $this->month, - $this->year, - "%Y %m %d")); - $this->setLocalTime($hs_day, - $hs_month, - $hs_year, - $this->hour, - $this->minute, - $this->second, - $this->partsecond); - } - - - // }}} - // {{{ addDays() - - /** - * Converts the date to the specified no of days from the given date - * - * To subtract days use a negative value for the '$pn_days' parameter - * - * @param int $pn_days days to add - * - * @return void - * @access public - * @since Method available since Release 1.5.0 - */ - function addDays($pn_days) - { - list($hs_year, $hs_month, $hs_day) = - explode(" ", Date_Calc::addDays($pn_days, - $this->day, - $this->month, - $this->year, - "%Y %m %d")); - $this->setLocalTime($hs_day, - $hs_month, - $hs_year, - $this->hour, - $this->minute, - $this->second, - $this->partsecond); - } - - - // }}} - // {{{ addHours() - - /** - * Converts the date to the specified no of hours from the given date - * - * To subtract hours use a negative value for the '$pn_hours' parameter - * - * @param int $pn_hours hours to add - * - * @return void - * @access public - * @since Method available since Release 1.5.0 - */ - function addHours($pn_hours) - { - if ($this->ob_invalidtime) - return $this->_getErrorInvalidTime(); - - list($hn_standardyear, - $hn_standardmonth, - $hn_standardday, - $hn_standardhour) = - Date_Calc::addHours($pn_hours, - $this->on_standardday, - $this->on_standardmonth, - $this->on_standardyear, - $this->on_standardhour); - - $this->setStandardTime($hn_standardday, - $hn_standardmonth, - $hn_standardyear, - $hn_standardhour, - $this->on_standardminute, - $this->on_standardsecond, - $this->on_standardpartsecond); - } - - - // }}} - // {{{ addMinutes() - - /** - * Converts the date to the specified no of minutes from the given date - * - * To subtract minutes use a negative value for the '$pn_minutes' parameter - * - * @param int $pn_minutes minutes to add - * - * @return void - * @access public - * @since Method available since Release 1.5.0 - */ - function addMinutes($pn_minutes) - { - if ($this->ob_invalidtime) - return $this->_getErrorInvalidTime(); - - list($hn_standardyear, - $hn_standardmonth, - $hn_standardday, - $hn_standardhour, - $hn_standardminute) = - Date_Calc::addMinutes($pn_minutes, - $this->on_standardday, - $this->on_standardmonth, - $this->on_standardyear, - $this->on_standardhour, - $this->on_standardminute); - - $this->setStandardTime($hn_standardday, - $hn_standardmonth, - $hn_standardyear, - $hn_standardhour, - $hn_standardminute, - $this->on_standardsecond, - $this->on_standardpartsecond); - } - - - // }}} - // {{{ addSeconds() - - /** - * Adds a given number of seconds to the date - * - * @param mixed $sec the no of seconds to add as integer or float - * @param bool $pb_countleap whether to count leap seconds (defaults to - * value of count-leap-second object property) - * - * @return void - * @access public - */ - function addSeconds($sec, $pb_countleap = null) - { - if ($this->ob_invalidtime) - return $this->_getErrorInvalidTime(); - if (!is_int($sec) && !is_float($sec)) - settype($sec, 'int'); - if (!is_null($pb_countleap)) - $pb_countleap = $this->ob_countleapseconds; - - if ($pb_countleap) { - // Convert to UTC: - // - list($hn_standardyear, - $hn_standardmonth, - $hn_standardday, - $hn_standardhour, - $hn_standardminute, - $hn_standardsecond, - $hn_standardpartsecond) = - $this->_addOffset($this->tz->getRawOffset() * -1, - $this->on_standardday, - $this->on_standardmonth, - $this->on_standardyear, - $this->on_standardhour, - $this->on_standardminute, - $this->on_standardsecond, - $this->on_standardpartsecond); - list($hn_standardyear, - $hn_standardmonth, - $hn_standardday, - $hn_standardhour, - $hn_standardminute, - $hn_secondraw) = - Date_Calc::addSeconds($sec, - $hn_standardday, - $hn_standardmonth, - $hn_standardyear, - $hn_standardhour, - $hn_standardminute, - $hn_standardpartsecond == 0.0 ? - $hn_standardsecond : - $hn_standardsecond + - $hn_standardpartsecond, - $pb_countleap); - - if (is_float($hn_secondraw)) { - $hn_standardsecond = intval($hn_secondraw); - $hn_standardpartsecond = $hn_secondraw - $hn_standardsecond; - } else { - $hn_standardsecond = $hn_secondraw; - $hn_standardpartsecond = 0.0; - } - - list($hn_standardyear, - $hn_standardmonth, - $hn_standardday, - $hn_standardhour, - $hn_standardminute, - $hn_standardsecond, - $hn_standardpartsecond) = - $this->_addOffset($this->tz->getRawOffset(), - $hn_standardday, - $hn_standardmonth, - $hn_standardyear, - $hn_standardhour, - $hn_standardminute, - $hn_standardsecond, - $hn_standardpartsecond); - } else { - // Use local standard time: - // - list($hn_standardyear, - $hn_standardmonth, - $hn_standardday, - $hn_standardhour, - $hn_standardminute, - $hn_secondraw) = - Date_Calc::addSeconds($sec, - $this->on_standardday, - $this->on_standardmonth, - $this->on_standardyear, - $this->on_standardhour, - $this->on_standardminute, - $this->on_standardpartsecond == 0.0 ? - $this->on_standardsecond : - $this->on_standardsecond + - $this->on_standardpartsecond, - false); - - if (is_float($hn_secondraw)) { - $hn_standardsecond = intval($hn_secondraw); - $hn_standardpartsecond = $hn_secondraw - $hn_standardsecond; - } else { - $hn_standardsecond = $hn_secondraw; - $hn_standardpartsecond = 0.0; - } - } - - $this->setStandardTime($hn_standardday, - $hn_standardmonth, - $hn_standardyear, - $hn_standardhour, - $hn_standardminute, - $hn_standardsecond, - $hn_standardpartsecond); - } - - - // }}} - // {{{ subtractSeconds() - - /** - * Subtracts a given number of seconds from the date - * - * @param mixed $sec the no of seconds to subtract as integer or - * float - * @param bool $pb_countleap whether to count leap seconds (defaults to - * value of count-leap-second object property) - * - * @return void - * @access public - */ - function subtractSeconds($sec, $pb_countleap = null) - { - if (is_null($pb_countleap)) - $pb_countleap = $this->ob_countleapseconds; - - $res = $this->addSeconds(-$sec, $pb_countleap); - - if (PEAR::isError($res)) - return $res; - } - - - // }}} - // {{{ addSpan() - - /** - * Adds a time span to the date - * - * A time span is defined as a unsigned no of days, hours, minutes - * and seconds, where the no of minutes and seconds must be less than - * 60, and the no of hours must be less than 24. - * - * A span is added (and subtracted) according to the following logic: - * - * Hours, minutes and seconds are added such that if they fall over - * a leap second, the leap second is ignored, and not counted. - * For example, if a leap second occurred at 23.59.60, the - * following calculations: - * - * 23.59.59 + one second - * 23.59.00 + one minute - * 23.00.00 + one hour - * - * would all produce 00.00.00 the next day. - * - * A day is treated as equivalent to 24 hours, so if the clocks - * went backwards at 01.00, and one day was added to the time - * 00.30, the result would be 23.30 the same day. - * - * This is the implementation which is thought to yield the behaviour - * that the user is most likely to expect, or in another way of - * looking at it, it is the implementation that produces the least - * unexpected behaviour. It basically works in hours, that is, a day - * is treated as exactly equivalent to 24 hours, and minutes and - * seconds are treated as equivalent to 1/60th and 1/3600th of an - * hour. It should be obvious that working in days is impractical; - * working in seconds is problematic when it comes to adding days - * that fall over leap seconds, where it would appear to most users - * that the function adds only 23 hours, 59 minutes and 59 seconds. - * It is also problematic to work in any kind of mixture of days, - * hours, minutes, and seconds, because then the addition of a span - * would sometimes depend on which order you add the constituent - * parts, which undermines the concept of a span altogether. - * - * If you want alternative functionality, you must use a mixture of - * the following functions instead: - * - * addYears() - * addMonths() - * addDays() - * addHours() - * addMinutes() - * addSeconds() - * - * @param object $span the time span to add - * - * @return void - * @access public - */ - function addSpan($span) - { - if (!is_a($span, 'Date_Span')) { - return PEAR::raiseError("Invalid argument - not 'Date_Span' object"); - } else if ($this->ob_invalidtime) { - return $this->_getErrorInvalidTime(); - } - - $hn_days = $span->day; - $hn_standardhour = $this->on_standardhour + $span->hour; - $hn_standardminute = $this->on_standardminute + $span->minute; - $hn_standardsecond = $this->on_standardsecond + $span->second; - - if ($hn_standardsecond >= 60) { - ++$hn_standardminute; - $hn_standardsecond -= 60; - } - - if ($hn_standardminute >= 60) { - ++$hn_standardhour; - $hn_standardminute -= 60; - } - - if ($hn_standardhour >= 24) { - ++$hn_days; - $hn_standardhour -= 24; - } - - list($hn_standardyear, $hn_standardmonth, $hn_standardday) = - explode(" ", - Date_Calc::addDays($hn_days, - $this->on_standardday, - $this->on_standardmonth, - $this->on_standardyear, - "%Y %m %d")); - - $this->setStandardTime($hn_standardday, - $hn_standardmonth, - $hn_standardyear, - $hn_standardhour, - $hn_standardminute, - $hn_standardsecond, - $this->on_standardpartsecond); - } - - - // }}} - // {{{ subtractSpan() - - /** - * Subtracts a time span from the date - * - * N.B. it is impossible for this function to count leap seconds, - * because the result would be dependent on which order the consituent - * parts of the span are subtracted from the date. Therefore, leap - * seconds are ignored by this function. If you want to count leap - * seconds, use 'subtractSeconds()'. - * - * @param object $span the time span to subtract - * - * @return void - * @access public - */ - function subtractSpan($span) - { - if (!is_a($span, 'Date_Span')) { - return PEAR::raiseError("Invalid argument - not 'Date_Span' object"); - } else if ($this->ob_invalidtime) { - return $this->_getErrorInvalidTime(); - } - - $hn_days = -$span->day; - $hn_standardhour = $this->on_standardhour - $span->hour; - $hn_standardminute = $this->on_standardminute - $span->minute; - $hn_standardsecond = $this->on_standardsecond - $span->second; - - if ($hn_standardsecond < 0) { - --$hn_standardminute; - $hn_standardsecond += 60; - } - - if ($hn_standardminute < 0) { - --$hn_standardhour; - $hn_standardminute += 60; - } - - if ($hn_standardhour < 0) { - --$hn_days; - $hn_standardhour += 24; - } - - list($hn_standardyear, $hn_standardmonth, $hn_standardday) = - explode(" ", - Date_Calc::addDays($hn_days, - $this->on_standardday, - $this->on_standardmonth, - $this->on_standardyear, - "%Y %m %d")); - - $this->setStandardTime($hn_standardday, - $hn_standardmonth, - $hn_standardyear, - $hn_standardhour, - $hn_standardminute, - $hn_standardsecond, - $this->on_standardpartsecond); - } - - - // }}} - // {{{ dateDiff() - - /** - * Subtract supplied date and return answer in days - * - * If the second parameter '$pb_ignoretime' is specified as false, the time - * parts of the two dates will be ignored, and the integral no of days - * between the day-month-year parts of the two dates will be returned. If - * either of the two dates have an invalid time, the integral no of days - * will also be returned, else the returned value will be the no of days as - * a float, with each hour being treated as 1/24th of a day and so on. - * - * For example, - * 21/11/2007 13.00 minus 21/11/2007 01.00 - * returns 0.5 - * - * Note that if the passed date is in the past, a positive value will be - * returned, and if it is in the future, a negative value will be returned. - * - * @param object $po_date date to subtract - * @param bool $pb_ignoretime whether to ignore the time values of the two - * dates in subtraction (defaults to false) - * - * @return mixed days between two dates as int or float - * @access public - * @since Method available since Release 1.5.0 - */ - function dateDiff($po_date, $pb_ignoretime = false) - { - if ($pb_ignoretime || $this->ob_invalidtime) { - return Date_Calc::dateToDays($this->day, - $this->month, - $this->year) - - Date_Calc::dateToDays($po_date->getDay(), - $po_date->getMonth(), - $po_date->getYear()); - } - - $hn_secondscompare = $po_date->getStandardSecondsPastMidnight(); - if (PEAR::isError($hn_secondscompare)) { - if ($hn_secondscompare->getCode() != DATE_ERROR_INVALIDTIME) { - return $hn_secondscompare; - } - - return Date_Calc::dateToDays($this->day, - $this->month, - $this->year) - - Date_Calc::dateToDays($po_date->getDay(), - $po_date->getMonth(), - $po_date->getYear()); - } - - $hn_seconds = $this->getStandardSecondsPastMidnight(); - - // If time parts are equal, return int, else return float: - // - return Date_Calc::dateToDays($this->on_standardday, - $this->on_standardmonth, - $this->on_standardyear) - - Date_Calc::dateToDays($po_date->getStandardDay(), - $po_date->getStandardMonth(), - $po_date->getStandardYear()) + - ($hn_seconds == $hn_secondscompare ? 0 : - ($hn_seconds - $hn_secondscompare) / 86400); - } - - - // }}} - // {{{ inEquivalentTimeZones() - - /** - * Tests whether two dates are in equivalent time zones - * - * Equivalence in this context consists in the time zones of the two dates - * having: - * - * an equal offset from UTC in both standard and Summer time (if - * the time zones observe Summer time) - * the same Summer time start and end rules, that is, the two time zones - * must switch from standard time to Summer time, and vice versa, on the - * same day and at the same time - * - * An example of two equivalent time zones is 'Europe/London' and - * 'Europe/Lisbon', which in London is known as GMT/BST, and in Lisbon as - * WET/WEST. - * - * @param object $po_date1 the first Date object to compare - * @param object $po_date2 the second Date object to compare - * - * @return bool true if the time zones are equivalent - * @access public - * @static - * @since Method available since Release 1.5.0 - */ - function inEquivalentTimeZones($po_date1, $po_date2) - { - return $po_date1->tz->isEquivalent($po_date2->getTZID()); - } - - - // }}} - // {{{ compare() - - /** - * Compares two dates - * - * Suitable for use in sorting functions. - * - * @param object $od1 the first Date object to compare - * @param object $od2 the second Date object to compare - * - * @return int 0 if the dates are equal, -1 if '$od1' is - * before '$od2', 1 if '$od1' is after '$od2' - * @access public - * @static - */ - function compare($od1, $od2) - { - $d1 = new Date($od1); - $d2 = new Date($od2); - - // If the time zones are equivalent, do nothing: - // - if (!Date::inEquivalentTimeZones($d1, $d2)) { - // Only a time zone with a valid time can be converted: - // - if ($d2->isTimeValid()) { - $d2->convertTZByID($d1->getTZID()); - } else if ($d1->isTimeValid()) { - $d1->convertTZByID($d2->getTZID()); - } else { - // No comparison can be made without guessing the time: - // - return PEAR::raiseError("Both dates have invalid time", - DATE_ERROR_INVALIDTIME); - } - } - - $days1 = Date_Calc::dateToDays($d1->getDay(), - $d1->getMonth(), - $d1->getYear()); - $days2 = Date_Calc::dateToDays($d2->getDay(), - $d2->getMonth(), - $d2->getYear()); - if ($days1 < $days2) - return -1; - if ($days1 > $days2) - return 1; - - $hn_hour1 = $d1->getStandardHour(); - if (PEAR::isError($hn_hour1)) - return $hn_hour1; - $hn_hour2 = $d2->getStandardHour(); - if (PEAR::isError($hn_hour2)) - return $hn_hour2; - - if ($hn_hour1 < $hn_hour2) return -1; - if ($hn_hour1 > $hn_hour2) return 1; - if ($d1->getStandardMinute() < $d2->getStandardMinute()) return -1; - if ($d1->getStandardMinute() > $d2->getStandardMinute()) return 1; - if ($d1->getStandardSecond() < $d2->getStandardSecond()) return -1; - if ($d1->getStandardSecond() > $d2->getStandardSecond()) return 1; - if ($d1->getStandardPartSecond() < $d2->getStandardPartSecond()) return -1; - if ($d1->getStandardPartSecond() > $d2->getStandardPartSecond()) return 1; - return 0; - } - - - // }}} - // {{{ before() - - /** - * Test if this date/time is before a certain date/time - * - * @param object $when the Date object to test against - * - * @return boolean true if this date is before $when - * @access public - */ - function before($when) - { - $hn_compare = Date::compare($this, $when); - if (PEAR::isError($hn_compare)) - return $hn_compare; - - if ($hn_compare == -1) { - return true; - } else { - return false; - } - } - - - // }}} - // {{{ after() - - /** - * Test if this date/time is after a certain date/time - * - * @param object $when the Date object to test against - * - * @return boolean true if this date is after $when - * @access public - */ - function after($when) - { - $hn_compare = Date::compare($this, $when); - if (PEAR::isError($hn_compare)) - return $hn_compare; - - if ($hn_compare == 1) { - return true; - } else { - return false; - } - } - - - // }}} - // {{{ equals() - - /** - * Test if this date/time is exactly equal to a certain date/time - * - * @param object $when the Date object to test against - * - * @return boolean true if this date is exactly equal to $when - * @access public - */ - function equals($when) - { - $hn_compare = Date::compare($this, $when); - if (PEAR::isError($hn_compare)) - return $hn_compare; - - if ($hn_compare == 0) { - return true; - } else { - return false; - } - } - - - // }}} - // {{{ isFuture() - - /** - * Determine if this date is in the future - * - * @return boolean true if this date is in the future - * @access public - */ - function isFuture() - { - $now = new Date(); - return $this->after($now); - } - - - // }}} - // {{{ isPast() - - /** - * Determine if this date is in the past - * - * @return boolean true if this date is in the past - * @access public - */ - function isPast() - { - $now = new Date(); - return $this->before($now); - } - - - // }}} - // {{{ isLeapYear() - - /** - * Determine if the year in this date is a leap year - * - * @return boolean true if this year is a leap year - * @access public - */ - function isLeapYear() - { - return Date_Calc::isLeapYear($this->year); - } - - - // }}} - // {{{ getJulianDate() - - /** - * Returns the no of days (1-366) since 31st December of the previous year - * - * N.B. this function does not return (and never has returned) the 'Julian - * Date', as described, for example, at: - * - * http://en.wikipedia.org/wiki/Julian_day - * - * If you want the day of the year (0-366), use 'getDayOfYear()' instead. - * If you want the true Julian Day, call one of the following: - * - * format("%E") - * format2("J") - * - * There currently is no function that calls the Julian Date (as opposed - * to the 'Julian Day'), although the Julian Day is an approximation. - * - * @return int the Julian date - * @access public - * @see Date::getDayOfYear() - * @deprecated Method deprecated in Release 1.5.0 - */ - function getJulianDate() - { - return Date_Calc::julianDate($this->day, $this->month, $this->year); - } - - - // }}} - // {{{ getDayOfYear() - - /** - * Returns the no of days (1-366) since 31st December of the previous year - * - * @return int an integer between 1 and 366 - * @access public - * @since Method available since Release 1.5.0 - */ - function getDayOfYear() - { - return Date_Calc::dayOfYear($this->day, $this->month, $this->year); - } - - - // }}} - // {{{ getDayOfWeek() - - /** - * Gets the day of the week for this date (0 = Sunday) - * - * @return int the day of the week (0 = Sunday) - * @access public - */ - function getDayOfWeek() - { - return Date_Calc::dayOfWeek($this->day, $this->month, $this->year); - } - - - // }}} - // {{{ getWeekOfYear() - - /** - * Gets the week of the year for this date - * - * @return int the week of the year - * @access public - */ - function getWeekOfYear() - { - return Date_Calc::weekOfYear($this->day, $this->month, $this->year); - } - - - // }}} - // {{{ getQuarterOfYear() - - /** - * Gets the quarter of the year for this date - * - * @return int the quarter of the year (1-4) - * @access public - */ - function getQuarterOfYear() - { - return Date_Calc::quarterOfYear($this->day, $this->month, $this->year); - } - - - // }}} - // {{{ getDaysInMonth() - - /** - * Gets number of days in the month for this date - * - * @return int number of days in this month - * @access public - */ - function getDaysInMonth() - { - return Date_Calc::daysInMonth($this->month, $this->year); - } - - - // }}} - // {{{ getWeeksInMonth() - - /** - * Gets the number of weeks in the month for this date - * - * @return int number of weeks in this month - * @access public - */ - function getWeeksInMonth() - { - return Date_Calc::weeksInMonth($this->month, $this->year); - } - - - // }}} - // {{{ getDayName() - - /** - * Gets the full name or abbreviated name of this weekday - * - * @param bool $abbr abbreviate the name - * @param int $length length of abbreviation - * - * @return string name of this day - * @access public - */ - function getDayName($abbr = false, $length = 3) - { - if ($abbr) { - return Date_Calc::getWeekdayAbbrname($this->day, - $this->month, - $this->year, - $length); - } else { - return Date_Calc::getWeekdayFullname($this->day, - $this->month, - $this->year); - } - } - - - // }}} - // {{{ getMonthName() - - /** - * Gets the full name or abbreviated name of this month - * - * @param boolean $abbr abbreviate the name - * - * @return string name of this month - * @access public - */ - function getMonthName($abbr = false) - { - if ($abbr) { - return Date_Calc::getMonthAbbrname($this->month); - } else { - return Date_Calc::getMonthFullname($this->month); - } - } - - - // }}} - // {{{ getNextDay() - - /** - * Get a Date object for the day after this one - * - * The time of the returned Date object is the same as this time. - * - * @return object Date object representing the next day - * @access public - */ - function getNextDay() - { - $ret = new Date($this); - $ret->addDays(1); - return $ret; - } - - - // }}} - // {{{ getPrevDay() - - /** - * Get a Date object for the day before this one - * - * The time of the returned Date object is the same as this time. - * - * @return object Date object representing the previous day - * @access public - */ - function getPrevDay() - { - $ret = new Date($this); - $ret->addDays(-1); - return $ret; - } - - - // }}} - // {{{ getNextWeekday() - - /** - * Get a Date object for the weekday after this one - * - * The time of the returned Date object is the same as this time. - * - * @return object Date object representing the next week-day - * @access public - */ - function getNextWeekday() - { - $ret = new Date($this); - list($hs_year, $hs_month, $hs_day) = - explode(" ", Date_Calc::nextWeekday($this->day, - $this->month, - $this->year, - "%Y %m %d")); - $ret->setDayMonthYear($hs_day, $hs_month, $hs_year); - return $ret; - } - - - // }}} - // {{{ getPrevWeekday() - - /** - * Get a Date object for the weekday before this one - * - * The time of the returned Date object is the same as this time. - * - * @return object Date object representing the previous week-day - * @access public - */ - function getPrevWeekday() - { - $ret = new Date($this); - list($hs_year, $hs_month, $hs_day) = - explode(" ", Date_Calc::prevWeekday($this->day, - $this->month, - $this->year, - "%Y %m %d")); - $ret->setDayMonthYear($hs_day, $hs_month, $hs_year); - return $ret; - } - - - // }}} - // {{{ getYear() - - /** - * Returns the year field of the date object - * - * @return int the year - * @access public - */ - function getYear() - { - return $this->year; - } - - - // }}} - // {{{ getMonth() - - /** - * Returns the month field of the date object - * - * @return int the minute - * @access public - */ - function getMonth() - { - return $this->month; - } - - - // }}} - // {{{ getDay() - - /** - * Returns the day field of the date object - * - * @return int the day - * @access public - */ - function getDay() - { - return $this->day; - } - - - // }}} - // {{{ _getErrorInvalidTime() - - /** - * Returns invalid time PEAR Error - * - * @return object - * @access private - * @since Method available since Release 1.5.0 - */ - function _getErrorInvalidTime() - { - return PEAR::raiseError("Invalid time '" . - sprintf("%02d.%02d.%02d", - $this->hour, - $this->minute, - $this->second) . - "' specified for date '" . - Date_Calc::dateFormat($this->day, - $this->month, - $this->year, - "%Y-%m-%d") . - "' and in this timezone", - DATE_ERROR_INVALIDTIME); - } - - - // }}} - // {{{ _secondsInDayIsValid() - - /** - * If leap seconds are observed, checks if the seconds in the day is valid - * - * Note that only the local standard time is accessed. - * - * @return bool - * @access private - * @since Method available since Release 1.5.0 - */ - function _secondsInDayIsValid() - { - if ($this->ob_countleapseconds) { - // Convert to UTC: - // - list($hn_year, - $hn_month, - $hn_day, - $hn_hour, - $hn_minute, - $hn_second, - $hn_partsecond) = - $this->_addOffset($this->tz->getRawOffset() * -1, - $this->on_standardday, - $this->on_standardmonth, - $this->on_standardyear, - $this->on_standardhour, - $this->on_standardminute, - $this->on_standardsecond, - $this->on_standardpartsecond); - return Date_Calc::secondsPastMidnight($hn_hour, - $hn_minute, - $hn_second + - $hn_partsecond) < - Date_Calc::getSecondsInDay($hn_day, $hn_month, $hn_year); - } else { - return $this->getStandardSecondsPastMidnight() < 86400; - } - } - - - // }}} - // {{{ isTimeValid() - - /** - * Whether the stored time is valid as a local time - * - * An invalid time is one that lies in the 'skipped hour' at the point - * that the clocks go forward. Note that the stored date (i.e. - * the day/month/year, is always valid). - * - * The object is able to store an invalid time because a user might - * unwittingly and correctly store a valid time, and then add one day so - * as to put the object in the 'skipped' hour (when the clocks go forward). - * This could be corrected by a conversion to Summer time (by adding one - * hour); however, if the user then added another day, and had no need for - * or interest in the time anyway, the behaviour may be rather unexpected. - * And anyway in this situation, the time originally specified would now, - * two days on, be valid again. - * - * So this class allows an invalid time like this so long as the user does - * not in any way make use of or request the time while it is in this - * semi-invalid state, in order to allow for for the fact that he might be - * only interested in the date, and not the time, and in order not to behave - * in an unexpected way, especially without throwing an exception to tell - * the user about it. - * - * @return bool - * @access public - * @since Method available since Release 1.5.0 - */ - function isTimeValid() - { - return !$this->ob_invalidtime; - } - - - // }}} - // {{{ getHour() - - /** - * Returns the hour field of the date object - * - * @return int the hour - * @access public - */ - function getHour() - { - if ($this->ob_invalidtime) - return $this->_getErrorInvalidTime(); - - return $this->hour; - } - - - // }}} - // {{{ getMinute() - - /** - * Returns the minute field of the date object - * - * @return int the minute - * @access public - */ - function getMinute() - { - if ($this->ob_invalidtime) - return $this->_getErrorInvalidTime(); - - return $this->minute; - } - - - // }}} - // {{{ getSecond() - - /** - * Returns the second field of the date object - * - * @return int the second - * @access public - */ - function getSecond() - { - if ($this->ob_invalidtime) - return $this->_getErrorInvalidTime(); - - return $this->second; - } - - - // }}} - // {{{ getSecondsPastMidnight() - - /** - * Returns the no of seconds since midnight (0-86400) as float - * - * @return float float which is at least 0 and less than 86400 - * @access public - * @since Method available since Release 1.5.0 - */ - function getSecondsPastMidnight() - { - if ($this->ob_invalidtime) - return $this->_getErrorInvalidTime(); - - return Date_Calc::secondsPastMidnight($this->hour, - $this->minute, - $this->second) + - $this->partsecond; - } - - - // }}} - // {{{ getPartSecond() - - /** - * Returns the part-second field of the date object - * - * @return float the part-second - * @access protected - * @since Method available since Release 1.5.0 - */ - function getPartSecond() - { - if ($this->ob_invalidtime) - return $this->_getErrorInvalidTime(); - - return $this->partsecond; - } - - - // }}} - // {{{ getStandardYear() - - /** - * Returns the year field of the local standard time - * - * @return int the year - * @access public - * @since Method available since Release 1.5.0 - */ - function getStandardYear() - { - if ($this->ob_invalidtime) - return $this->_getErrorInvalidTime(); - - return $this->on_standardyear; - } - - - // }}} - // {{{ getStandardMonth() - - /** - * Returns the month field of the local standard time - * - * @return int the minute - * @access public - * @since Method available since Release 1.5.0 - */ - function getStandardMonth() - { - if ($this->ob_invalidtime) - return $this->_getErrorInvalidTime(); - - return $this->on_standardmonth; - } - - - // }}} - // {{{ getStandardDay() - - /** - * Returns the day field of the local standard time - * - * @return int the day - * @access public - * @since Method available since Release 1.5.0 - */ - function getStandardDay() - { - if ($this->ob_invalidtime) - return $this->_getErrorInvalidTime(); - - return $this->on_standardday; - } - - - // }}} - // {{{ getStandardHour() - - /** - * Returns the hour field of the local standard time - * - * @return int the hour - * @access public - * @since Method available since Release 1.5.0 - */ - function getStandardHour() - { - if ($this->ob_invalidtime) - return $this->_getErrorInvalidTime(); - - return $this->on_standardhour; - } - - - // }}} - // {{{ getStandardMinute() - - /** - * Returns the minute field of the local standard time - * - * @return int the minute - * @access public - * @since Method available since Release 1.5.0 - */ - function getStandardMinute() - { - if ($this->ob_invalidtime) - return $this->_getErrorInvalidTime(); - - return $this->on_standardminute; - } - - - // }}} - // {{{ getStandardSecond() - - /** - * Returns the second field of the local standard time - * - * @return int the second - * @access public - * @since Method available since Release 1.5.0 - */ - function getStandardSecond() - { - if ($this->ob_invalidtime) - return $this->_getErrorInvalidTime(); - - return $this->on_standardsecond; - } - - - // }}} - // {{{ getStandardSecondsPastMidnight() - - /** - * Returns the no of seconds since midnight (0-86400) of the - * local standard time as float - * - * @return float float which is at least 0 and less than 86400 - * @access public - * @since Method available since Release 1.5.0 - */ - function getStandardSecondsPastMidnight() - { - if ($this->ob_invalidtime) - return $this->_getErrorInvalidTime(); - - return Date_Calc::secondsPastMidnight($this->on_standardhour, - $this->on_standardminute, - $this->on_standardsecond) + - $this->on_standardpartsecond; - } - - - // }}} - // {{{ getStandardPartSecond() - - /** - * Returns the part-second field of the local standard time - * - * @return float the part-second - * @access protected - * @since Method available since Release 1.5.0 - */ - function getStandardPartSecond() - { - if ($this->ob_invalidtime) - return $this->_getErrorInvalidTime(); - - return $this->on_standardpartsecond; - } - - - // }}} - // {{{ _addOffset() - - /** - * Add a time zone offset to the passed date/time - * - * @param int $pn_offset the offset to add in milliseconds - * @param int $pn_day the day - * @param int $pn_month the month - * @param int $pn_year the year - * @param int $pn_hour the hour - * @param int $pn_minute the minute - * @param int $pn_second the second - * @param float $pn_partsecond the part-second - * - * @return array array of year, month, day, hour, minute, second, - * and part-second - * @access private - * @static - * @since Method available since Release 1.5.0 - */ - function _addOffset($pn_offset, - $pn_day, - $pn_month, - $pn_year, - $pn_hour, - $pn_minute, - $pn_second, - $pn_partsecond) - { - if ($pn_offset == 0) { - return array((int) $pn_year, - (int) $pn_month, - (int) $pn_day, - (int) $pn_hour, - (int) $pn_minute, - (int) $pn_second, - (float) $pn_partsecond); - } - - if ($pn_offset % 3600000 == 0) { - list($hn_year, - $hn_month, - $hn_day, - $hn_hour) = - Date_Calc::addHours($pn_offset / 3600000, - $pn_day, - $pn_month, - $pn_year, - $pn_hour); - - $hn_minute = (int) $pn_minute; - $hn_second = (int) $pn_second; - $hn_partsecond = (float) $pn_partsecond; - } else if ($pn_offset % 60000 == 0) { - list($hn_year, - $hn_month, - $hn_day, - $hn_hour, - $hn_minute) = - Date_Calc::addMinutes($pn_offset / 60000, - $pn_day, - $pn_month, - $pn_year, - $pn_hour, - $pn_minute); - - $hn_second = (int) $pn_second; - $hn_partsecond = (float) $pn_partsecond; - } else { - list($hn_year, - $hn_month, - $hn_day, - $hn_hour, - $hn_minute, - $hn_secondraw) = - Date_Calc::addSeconds($pn_offset / 1000, - $pn_day, - $pn_month, - $pn_year, - $pn_hour, - $pn_partsecond == 0.0 ? - $pn_second : - $pn_second + $pn_partsecond, - false); // N.B. do not count - // leap seconds - - if (is_float($hn_secondraw)) { - $hn_second = intval($hn_secondraw); - $hn_partsecond = $hn_secondraw - $hn_second; - } else { - $hn_second = $hn_secondraw; - $hn_partsecond = 0.0; - } - } - - return array($hn_year, - $hn_month, - $hn_day, - $hn_hour, - $hn_minute, - $hn_second, - $hn_partsecond); - } - - - // }}} - // {{{ setLocalTime() - - /** - * Sets local time (Summer-time-adjusted) and then calculates local - * standard time - * - * @param int $pn_day the day - * @param int $pn_month the month - * @param int $pn_year the year - * @param int $pn_hour the hour - * @param int $pn_minute the minute - * @param int $pn_second the second - * @param float $pn_partsecond the part-second - * @param bool $pb_repeatedhourdefault whether to assume Summer time if a - * repeated hour is specified (defaults - * to false) - * @param bool $pb_correctinvalidtime whether to correct, by adding the - * local Summer time offset, the - * specified time if it falls in the - * skipped hour (defaults to - * DATE_CORRECTINVALIDTIME_DEFAULT) - * - * @return void - * @access protected - * @see Date::setStandardTime() - * @since Method available since Release 1.5.0 - */ - function setLocalTime($pn_day, - $pn_month, - $pn_year, - $pn_hour, - $pn_minute, - $pn_second, - $pn_partsecond, - $pb_repeatedhourdefault = false, - $pb_correctinvalidtime = DATE_CORRECTINVALIDTIME_DEFAULT) - { - settype($pn_day, "int"); - settype($pn_month, "int"); - settype($pn_year, "int"); - settype($pn_hour, "int"); - settype($pn_minute, "int"); - settype($pn_second, "int"); - settype($pn_partsecond, "float"); - - $hb_insummertime = - $this->tz->inDaylightTime(array($pn_day, - $pn_month, $pn_year, Date_Calc::secondsPastMidnight($pn_hour, - $pn_minute, $pn_second) + $pn_partsecond), - $pb_repeatedhourdefault); - if (PEAR::isError($hb_insummertime)) { - if ($hb_insummertime->getCode() != DATE_ERROR_INVALIDTIME) { - return $hb_insummertime; - } else if ($pb_correctinvalidtime) { - // Store passed time as local standard time: - // - $this->on_standardday = $pn_day; - $this->on_standardmonth = $pn_month; - $this->on_standardyear = $pn_year; - $this->on_standardhour = $pn_hour; - $this->on_standardminute = $pn_minute; - $this->on_standardsecond = $pn_second; - $this->on_standardpartsecond = $pn_partsecond; - - // Add Summer time offset to passed time: - // - list($this->year, - $this->month, - $this->day, - $this->hour, - $this->minute, - $this->second, - $this->partsecond) = - $this->_addOffset($this->tz->getDSTSavings(), - $pn_day, - $pn_month, - $pn_year, - $pn_hour, - $pn_minute, - $pn_second, - $pn_partsecond); - - $this->ob_invalidtime = !$this->_secondsInDayIsValid(); - } else { - // Hedge bets - if the user adds/subtracts a day, then the time - // will be uncorrupted, and if the user does - // addition/subtraction with the time, or requests the time, - // then return an error at that point: - // - $this->day = $pn_day; - $this->month = $pn_month; - $this->year = $pn_year; - $this->hour = $pn_hour; - $this->minute = $pn_minute; - $this->second = $pn_second; - $this->partsecond = $pn_partsecond; - - $this->ob_invalidtime = true; - } - - return; - } else { - // Passed time is valid as local time: - // - $this->day = $pn_day; - $this->month = $pn_month; - $this->year = $pn_year; - $this->hour = $pn_hour; - $this->minute = $pn_minute; - $this->second = $pn_second; - $this->partsecond = $pn_partsecond; - } - - $this->ob_invalidtime = !$this->_secondsInDayIsValid(); - - if ($hb_insummertime) { - // Calculate local standard time: - // - list($this->on_standardyear, - $this->on_standardmonth, - $this->on_standardday, - $this->on_standardhour, - $this->on_standardminute, - $this->on_standardsecond, - $this->on_standardpartsecond) = - $this->_addOffset($this->tz->getDSTSavings() * -1, - $pn_day, - $pn_month, - $pn_year, - $pn_hour, - $pn_minute, - $pn_second, - $pn_partsecond); - } else { - // Time is already local standard time: - // - $this->on_standardday = $pn_day; - $this->on_standardmonth = $pn_month; - $this->on_standardyear = $pn_year; - $this->on_standardhour = $pn_hour; - $this->on_standardminute = $pn_minute; - $this->on_standardsecond = $pn_second; - $this->on_standardpartsecond = $pn_partsecond; - } - } - - - // }}} - // {{{ setStandardTime() - - /** - * Sets local standard time and then calculates local time (i.e. - * Summer-time-adjusted) - * - * @param int $pn_day the day - * @param int $pn_month the month - * @param int $pn_year the year - * @param int $pn_hour the hour - * @param int $pn_minute the minute - * @param int $pn_second the second - * @param float $pn_partsecond the part-second - * - * @return void - * @access protected - * @see Date::setLocalTime() - * @since Method available since Release 1.5.0 - */ - function setStandardTime($pn_day, - $pn_month, - $pn_year, - $pn_hour, - $pn_minute, - $pn_second, - $pn_partsecond) - { - settype($pn_day, "int"); - settype($pn_month, "int"); - settype($pn_year, "int"); - settype($pn_hour, "int"); - settype($pn_minute, "int"); - settype($pn_second, "int"); - settype($pn_partsecond, "float"); - - $this->on_standardday = $pn_day; - $this->on_standardmonth = $pn_month; - $this->on_standardyear = $pn_year; - $this->on_standardhour = $pn_hour; - $this->on_standardminute = $pn_minute; - $this->on_standardsecond = $pn_second; - $this->on_standardpartsecond = $pn_partsecond; - - $this->ob_invalidtime = !$this->_secondsInDayIsValid(); - - if ($this->tz->inDaylightTimeStandard(array($pn_day, $pn_month, - $pn_year, Date_Calc::secondsPastMidnight($pn_hour, $pn_minute, - $pn_second) + $pn_partsecond))) { - - // Calculate local time: - // - list($this->year, - $this->month, - $this->day, - $this->hour, - $this->minute, - $this->second, - $this->partsecond) = - $this->_addOffset($this->tz->getDSTSavings(), - $pn_day, - $pn_month, - $pn_year, - $pn_hour, - $pn_minute, - $pn_second, - $pn_partsecond); - } else { - // Time is already local time: - // - $this->day = $pn_day; - $this->month = $pn_month; - $this->year = $pn_year; - $this->hour = $pn_hour; - $this->minute = $pn_minute; - $this->second = $pn_second; - $this->partsecond = $pn_partsecond; - } - } - - - // }}} - // {{{ setYear() - - /** - * Sets the year field of the date object - * - * If specified year forms an invalid date, then PEAR error will be - * returned, unless the validation is over-ridden using the second - * parameter. - * - * @param int $y the year - * @param bool $pb_validate whether to check that the new date is valid - * - * @return void - * @access public - * @see Date::setDayMonthYear(), Date::setDateTime() - */ - function setYear($y, $pb_validate = DATE_VALIDATE_DATE_BY_DEFAULT) - { - if ($pb_validate && !Date_Calc::isValidDate($this->day, $this->month, $y)) { - return PEAR::raiseError("'" . - Date_Calc::dateFormat($this->day, - $this->month, - $y, - "%Y-%m-%d") . - "' is invalid calendar date", - DATE_ERROR_INVALIDDATE); - } else { - $this->setLocalTime($this->day, - $this->month, - $y, - $this->hour, - $this->minute, - $this->second, - $this->partsecond); - } - } - - - // }}} - // {{{ setMonth() - - /** - * Sets the month field of the date object - * - * If specified year forms an invalid date, then PEAR error will be - * returned, unless the validation is over-ridden using the second - * parameter. - * - * @param int $m the month - * @param bool $pb_validate whether to check that the new date is valid - * - * @return void - * @access public - * @see Date::setDayMonthYear(), Date::setDateTime() - */ - function setMonth($m, $pb_validate = DATE_VALIDATE_DATE_BY_DEFAULT) - { - if ($pb_validate && !Date_Calc::isValidDate($this->day, $m, $this->year)) { - return PEAR::raiseError("'" . - Date_Calc::dateFormat($this->day, - $m, - $this->year, - "%Y-%m-%d") . - "' is invalid calendar date", - DATE_ERROR_INVALIDDATE); - } else { - $this->setLocalTime($this->day, - $m, - $this->year, - $this->hour, - $this->minute, - $this->second, - $this->partsecond); - } - } - - - // }}} - // {{{ setDay() - - /** - * Sets the day field of the date object - * - * If specified year forms an invalid date, then PEAR error will be - * returned, unless the validation is over-ridden using the second - * parameter. - * - * @param int $d the day - * @param bool $pb_validate whether to check that the new date is valid - * - * @return void - * @access public - * @see Date::setDayMonthYear(), Date::setDateTime() - */ - function setDay($d, $pb_validate = DATE_VALIDATE_DATE_BY_DEFAULT) - { - if ($pb_validate && !Date_Calc::isValidDate($d, $this->month, $this->year)) { - return PEAR::raiseError("'" . - Date_Calc::dateFormat($d, - $this->month, - $this->year, - "%Y-%m-%d") . - "' is invalid calendar date", - DATE_ERROR_INVALIDDATE); - } else { - $this->setLocalTime($d, - $this->month, - $this->year, - $this->hour, - $this->minute, - $this->second, - $this->partsecond); - } - } - - - // }}} - // {{{ setDayMonthYear() - - /** - * Sets the day, month and year fields of the date object - * - * If specified year forms an invalid date, then PEAR error will be - * returned. Note that setting each of these fields separately - * may unintentionally return a PEAR error if a transitory date is - * invalid between setting these fields. - * - * @param int $d the day - * @param int $m the month - * @param int $y the year - * - * @return void - * @access public - * @see Date::setDateTime() - * @since Method available since Release 1.5.0 - */ - function setDayMonthYear($d, $m, $y) - { - if (!Date_Calc::isValidDate($d, $m, $y)) { - return PEAR::raiseError("'" . - Date_Calc::dateFormat($d, - $m, - $y, - "%Y-%m-%d") . - "' is invalid calendar date", - DATE_ERROR_INVALIDDATE); - } else { - $this->setLocalTime($d, - $m, - $y, - $this->hour, - $this->minute, - $this->second, - $this->partsecond); - } - } - - - // }}} - // {{{ setHour() - - /** - * Sets the hour field of the date object - * - * Expects an hour in 24-hour format. - * - * @param int $h the hour - * @param bool $pb_repeatedhourdefault whether to assume Summer time if a - * repeated hour is specified (defaults - * to false) - * - * @return void - * @access public - * @see Date::setHourMinuteSecond(), Date::setDateTime() - */ - function setHour($h, $pb_repeatedhourdefault = false) - { - if ($h > 23 || $h < 0) { - return PEAR::raiseError("Invalid hour value '$h'"); - } else { - $ret = $this->setHourMinuteSecond($h, - $this->minute, - $this->partsecond == 0.0 ? - $this->second : - $this->second + $this->partsecond, - $pb_repeatedhourdefault); - - if (PEAR::isError($ret)) - return $ret; - } - } - - - // }}} - // {{{ setMinute() - - /** - * Sets the minute field of the date object - * - * @param int $m the minute - * @param bool $pb_repeatedhourdefault whether to assume Summer time if a - * repeated hour is specified (defaults - * to false) - * - * @return void - * @access public - * @see Date::setHourMinuteSecond(), Date::setDateTime() - */ - function setMinute($m, $pb_repeatedhourdefault = false) - { - if ($m > 59 || $m < 0) { - return PEAR::raiseError("Invalid minute value '$m'"); - } else { - $ret = $this->setHourMinuteSecond($this->hour, - $m, - $this->partsecond == 0.0 ? - $this->second : - $this->second + $this->partsecond, - $pb_repeatedhourdefault); - - if (PEAR::isError($ret)) - return $ret; - } - } - - - // }}} - // {{{ setSecond() - - /** - * Sets the second field of the date object - * - * @param mixed $s the second as integer or float - * @param bool $pb_repeatedhourdefault whether to assume Summer time if a - * repeated hour is specified - * (defaults to false) - * - * @return void - * @access public - * @see Date::setHourMinuteSecond(), Date::setDateTime() - */ - function setSecond($s, $pb_repeatedhourdefault = false) - { - if ($s > 60 || // Leap seconds possible - $s < 0) { - return PEAR::raiseError("Invalid second value '$s'"); - } else { - $ret = $this->setHourMinuteSecond($this->hour, - $this->minute, - $s, - $pb_repeatedhourdefault); - - if (PEAR::isError($ret)) - return $ret; - } - } - - - // }}} - // {{{ setPartSecond() - - /** - * Sets the part-second field of the date object - * - * @param float $pn_ps the part-second - * @param bool $pb_repeatedhourdefault whether to assume Summer time if a - * repeated hour is specified (defaults - * to false) - * - * @return void - * @access protected - * @see Date::setHourMinuteSecond(), Date::setDateTime() - * @since Method available since Release 1.5.0 - */ - function setPartSecond($pn_ps, $pb_repeatedhourdefault = false) - { - if ($pn_ps >= 1 || $pn_ps < 0) { - return PEAR::raiseError("Invalid part-second value '$pn_ps'"); - } else { - $ret = $this->setHourMinuteSecond($this->hour, - $this->minute, - $this->second + $pn_ps, - $pb_repeatedhourdefault); - - if (PEAR::isError($ret)) - return $ret; - } - } - - - // }}} - // {{{ setHourMinuteSecond() - - /** - * Sets the hour, minute, second and part-second fields of the date object - * - * N.B. if the repeated hour, due to the clocks going back, is specified, - * the default is to assume local standard time. - * - * @param int $h the hour - * @param int $m the minute - * @param mixed $s the second as integer or float - * @param bool $pb_repeatedhourdefault whether to assume Summer time if a - * repeated hour is specified - * (defaults to false) - * - * @return void - * @access public - * @see Date::setDateTime() - * @since Method available since Release 1.5.0 - */ - function setHourMinuteSecond($h, $m, $s, $pb_repeatedhourdefault = false) - { - // Split second into integer and part-second: - // - if (is_float($s)) { - $hn_second = intval($s); - $hn_partsecond = $s - $hn_second; - } else { - $hn_second = (int) $s; - $hn_partsecond = 0.0; - } - - $this->setLocalTime($this->day, - $this->month, - $this->year, - $h, - $m, - $hn_second, - $hn_partsecond, - $pb_repeatedhourdefault); - } - - - // }}} - // {{{ setDateTime() - - /** - * Sets all the fields of the date object (day, month, year, hour, minute - * and second) - * - * If specified year forms an invalid date, then PEAR error will be - * returned. Note that setting each of these fields separately - * may unintentionally return a PEAR error if a transitory date is - * invalid between setting these fields. - * - * N.B. if the repeated hour, due to the clocks going back, is specified, - * the default is to assume local standard time. - * - * @param int $pn_day the day - * @param int $pn_month the month - * @param int $pn_year the year - * @param int $pn_hour the hour - * @param int $pn_minute the minute - * @param mixed $pm_second the second as integer or float - * @param bool $pb_repeatedhourdefault whether to assume Summer time if a - * repeated hour is specified - * (defaults to false) - * - * @return void - * @access public - * @see Date::setDayMonthYear(), Date::setHourMinuteSecond() - * @since Method available since Release 1.5.0 - */ - function setDateTime($pn_day, - $pn_month, - $pn_year, - $pn_hour, - $pn_minute, - $pm_second, - $pb_repeatedhourdefault = false) - { - if (!Date_Calc::isValidDate($d, $m, $y)) { - return PEAR::raiseError("'" . - Date_Calc::dateFormat($d, - $m, - $y, - "%Y-%m-%d") . - "' is invalid calendar date", - DATE_ERROR_INVALIDDATE); - } else { - // Split second into integer and part-second: - // - if (is_float($pm_second)) { - $hn_second = intval($pm_second); - $hn_partsecond = $pm_second - $hn_second; - } else { - $hn_second = (int) $pm_second; - $hn_partsecond = 0.0; - } - - $this->setLocalTime($d, - $m, - $y, - $h, - $m, - $hn_second, - $hn_partsecond, - $pb_repeatedhourdefault); - } - } - - - // }}} - -} - -// }}} - -/* - * Local variables: - * mode: php - * tab-width: 4 - * c-basic-offset: 4 - * c-hanging-comment-ender-p: nil - * End: - */ -?> \ No newline at end of file diff --git a/glmPEAR/Date/Calc.php b/glmPEAR/Date/Calc.php deleted file mode 100755 index 5da8055..0000000 --- a/glmPEAR/Date/Calc.php +++ /dev/null @@ -1,4363 +0,0 @@ - - * @author Pierre-Alain Joye - * @author Daniel Convissor - * @author C.A. Woodcock - * @copyright 1999-2007 Monte Ohrt, Pierre-Alain Joye, Daniel Convissor, C.A. Woodcock - * @license http://www.opensource.org/licenses/bsd-license.php - * BSD License - * @version CVS: $Id: Calc.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ - * @link http://pear.php.net/package/Date - * @since File available since Release 1.2 - */ - - -// }}} -// {{{ General constants: - -if (!defined('DATE_CALC_BEGIN_WEEKDAY')) { - /** - * Defines what day starts the week - * - * Monday (1) is the international standard. - * Redefine this to 0 if you want weeks to begin on Sunday. - */ - define('DATE_CALC_BEGIN_WEEKDAY', 1); -} - -if (!defined('DATE_CALC_FORMAT')) { - /** - * The default value for each method's $format parameter - * - * The default is '%Y%m%d'. To override this default, define - * this constant before including Calc.php. - * - * @since Constant available since Release 1.4.4 - */ - define('DATE_CALC_FORMAT', '%Y%m%d'); -} - - -// {{{ Date precision constants (used in 'round()' and 'trunc()'): - -define('DATE_PRECISION_YEAR', -2); -define('DATE_PRECISION_MONTH', -1); -define('DATE_PRECISION_DAY', 0); -define('DATE_PRECISION_HOUR', 1); -define('DATE_PRECISION_10MINUTES', 2); -define('DATE_PRECISION_MINUTE', 3); -define('DATE_PRECISION_10SECONDS', 4); -define('DATE_PRECISION_SECOND', 5); - - -// }}} -// {{{ Class: Date_Calc - -/** - * Calculates, manipulates and retrieves dates - * - * It does not rely on 32-bit system time stamps, so it works dates - * before 1970 and after 2038. - * - * @category Date and Time - * @package Date - * @author Monte Ohrt - * @author Daniel Convissor - * @author C.A. Woodcock - * @copyright 1999-2007 Monte Ohrt, Pierre-Alain Joye, Daniel Convissor, C.A. Woodcock - * @license http://www.opensource.org/licenses/bsd-license.php - * BSD License - * @version Release: 1.5.0a1 - * @link http://pear.php.net/package/Date - * @since Class available since Release 1.2 - */ -class Date_Calc -{ - - // {{{ dateFormat() - - /** - * Formats the date in the given format, much like strfmt() - * - * This function is used to alleviate the problem with 32-bit numbers for - * dates pre 1970 or post 2038, as strfmt() has on most systems. - * Most of the formatting options are compatible. - * - * Formatting options: - *
-     * %a   abbreviated weekday name (Sun, Mon, Tue)
-     * %A   full weekday name (Sunday, Monday, Tuesday)
-     * %b   abbreviated month name (Jan, Feb, Mar)
-     * %B   full month name (January, February, March)
-     * %d   day of month (range 00 to 31)
-     * %e   day of month, single digit (range 0 to 31)
-     * %E   number of days since unspecified epoch (integer)
-     *        (%E is useful for passing a date in a URL as
-     *        an integer value. Then simply use
-     *        daysToDate() to convert back to a date.)
-     * %j   day of year (range 001 to 366)
-     * %m   month as decimal number (range 1 to 12)
-     * %n   newline character (\n)
-     * %t   tab character (\t)
-     * %w   weekday as decimal (0 = Sunday)
-     * %U   week number of current year, first sunday as first week
-     * %y   year as decimal (range 00 to 99)
-     * %Y   year as decimal including century (range 0000 to 9999)
-     * %%   literal '%'
-     * 
- * - * @param int $day the day of the month - * @param int $month the month - * @param int $year the year. Use the complete year instead of the - * abbreviated version. E.g. use 2005, not 05. - * @param string $format the format string - * - * @return string the date in the desired format - * @access public - * @static - */ - function dateFormat($day, $month, $year, $format) - { - if (!Date_Calc::isValidDate($day, $month, $year)) { - $year = Date_Calc::dateNow('%Y'); - $month = Date_Calc::dateNow('%m'); - $day = Date_Calc::dateNow('%d'); - } - - $output = ''; - - for ($strpos = 0; $strpos < strlen($format); $strpos++) { - $char = substr($format, $strpos, 1); - if ($char == '%') { - $nextchar = substr($format, $strpos + 1, 1); - switch($nextchar) { - case 'a': - $output .= Date_Calc::getWeekdayAbbrname($day, $month, $year); - break; - case 'A': - $output .= Date_Calc::getWeekdayFullname($day, $month, $year); - break; - case 'b': - $output .= Date_Calc::getMonthAbbrname($month); - break; - case 'B': - $output .= Date_Calc::getMonthFullname($month); - break; - case 'd': - $output .= sprintf('%02d', $day); - break; - case 'e': - $output .= $day; - break; - case 'E': - $output .= Date_Calc::dateToDays($day, $month, $year); - break; - case 'j': - $output .= Date_Calc::dayOfYear($day, $month, $year); - break; - case 'm': - $output .= sprintf('%02d', $month); - break; - case 'n': - $output .= "\n"; - break; - case 't': - $output .= "\t"; - break; - case 'w': - $output .= Date_Calc::dayOfWeek($day, $month, $year); - break; - case 'U': - $output .= Date_Calc::weekOfYear($day, $month, $year); - break; - case 'y': - $output .= sprintf('%0' . - ($year < 0 ? '3' : '2') . - 'd', - $year % 100); - break; - case "Y": - $output .= sprintf('%0' . - ($year < 0 ? '5' : '4') . - 'd', - $year); - break; - case '%': - $output .= '%'; - break; - default: - $output .= $char.$nextchar; - } - $strpos++; - } else { - $output .= $char; - } - } - return $output; - } - - - // }}} - // {{{ dateNow() - - /** - * Returns the current local date - * - * NOTE: This function retrieves the local date using strftime(), - * which may or may not be 32-bit safe on your system. - * - * @param string $format the string indicating how to format the output - * - * @return string the current date in the specified format - * @access public - * @static - */ - function dateNow($format = DATE_CALC_FORMAT) - { - return strftime($format, time()); - } - - - // }}} - // {{{ getYear() - - /** - * Returns the current local year in format CCYY - * - * @return string the current year in four digit format - * @access public - * @static - */ - function getYear() - { - return Date_Calc::dateNow('%Y'); - } - - - // }}} - // {{{ getMonth() - - /** - * Returns the current local month in format MM - * - * @return string the current month in two digit format - * @access public - * @static - */ - function getMonth() - { - return Date_Calc::dateNow('%m'); - } - - - // }}} - // {{{ getDay() - - /** - * Returns the current local day in format DD - * - * @return string the current day of the month in two digit format - * @access public - * @static - */ - function getDay() - { - return Date_Calc::dateNow('%d'); - } - - - // }}} - // {{{ defaultCentury() - - /** - * Turns a two digit year into a four digit year - * - * Return value depends on current year; the century chosen - * will be the one which forms the year that is closest - * to the current year. If the two possibilities are - * equidistant to the current year (i.e. 50 years in the past - * and 50 years in the future), then the past year is chosen. - * - * For example, if the current year is 2007: - * 03 - returns 2003 - * 09 - returns 2009 - * 56 - returns 2056 (closer to 2007 than 1956) - * 57 - returns 1957 (1957 and 2007 are equidistant, so previous century - * chosen) - * 58 - returns 1958 - * - * @param int $year the 2 digit year - * - * @return int the 4 digit year - * @access public - * @static - */ - function defaultCentury($year) - { - $hn_century = intval(($hn_currentyear = date("Y")) / 100); - $hn_currentyear = $hn_currentyear % 100; - - if ($year < 0 || $year >= 100) - $year = $year % 100; - - if ($year - $hn_currentyear < -50) - return ($hn_century + 1) * 100 + $year; - else if ($year - $hn_currentyear < 50) - return $hn_century * 100 + $year; - else - return ($hn_century - 1) * 100 + $year; - } - - - // }}} - // {{{ getSecondsInYear() - - /** - * Returns the total number of seconds in the given year - * - * This takes into account leap seconds. - * - * @param int $pn_year the year in four digit format - * - * @return int - * @access public - * @static - * @since Method available since Release 1.5.0 - */ - function getSecondsInYear($pn_year) - { - $pn_year = intval($pn_year); - - static $ha_leapseconds; - if (!isset($ha_leapseconds)) { - $ha_leapseconds = array(1972 => 2, - 1973 => 1, - 1974 => 1, - 1975 => 1, - 1976 => 1, - 1977 => 1, - 1978 => 1, - 1979 => 1, - 1981 => 1, - 1982 => 1, - 1983 => 1, - 1985 => 1, - 1987 => 1, - 1989 => 1, - 1990 => 1, - 1992 => 1, - 1993 => 1, - 1994 => 1, - 1995 => 1, - 1997 => 1, - 1998 => 1, - 2005 => 1); - } - - $ret = Date_Calc::daysInYear($pn_year) * 86400; - - if (isset($ha_leapseconds[$pn_year])) { - return $ret + $ha_leapseconds[$pn_year]; - } else { - return $ret; - } - } - - - // }}} - // {{{ getSecondsInMonth() - - /** - * Returns the total number of seconds in the given month - * - * This takes into account leap seconds. - * - * @param int $pn_month the month - * @param int $pn_year the year in four digit format - * - * @return int - * @access public - * @static - * @since Method available since Release 1.5.0 - */ - function getSecondsInMonth($pn_month, $pn_year) - { - $pn_month = intval($pn_month); - $pn_year = intval($pn_year); - - static $ha_leapseconds; - if (!isset($ha_leapseconds)) { - $ha_leapseconds = array(1972 => array(6 => 1, - 12 => 1), - 1973 => array(12 => 1), - 1974 => array(12 => 1), - 1975 => array(12 => 1), - 1976 => array(12 => 1), - 1977 => array(12 => 1), - 1978 => array(12 => 1), - 1979 => array(12 => 1), - 1981 => array(6 => 1), - 1982 => array(6 => 1), - 1983 => array(6 => 1), - 1985 => array(6 => 1), - 1987 => array(12 => 1), - 1989 => array(12 => 1), - 1990 => array(12 => 1), - 1992 => array(6 => 1), - 1993 => array(6 => 1), - 1994 => array(6 => 1), - 1995 => array(12 => 1), - 1997 => array(6 => 1), - 1998 => array(12 => 1), - 2005 => array(12 => 1)); - } - - $ret = Date_Calc::daysInMonth($pn_month, $pn_year) * 86400; - - if (isset($ha_leapseconds[$pn_year][$pn_month])) { - return $ret + $ha_leapseconds[$pn_year][$pn_month]; - } else { - return $ret; - } - } - - - // }}} - // {{{ getSecondsInDay() - - /** - * Returns the total number of seconds in the day of the given date - * - * This takes into account leap seconds. - * - * @param int $pn_day the day of the month - * @param int $pn_month the month - * @param int $pn_year the year in four digit format - * - * @return int - * @access public - * @static - * @since Method available since Release 1.5.0 - */ - function getSecondsInDay($pn_day, $pn_month, $pn_year) - { - // Note to developers: - // - // The leap seconds listed here are a matter of historical fact, - // that is, it is known on which exact day they occurred. - // However, the implementation of the class as a whole depends - // on the fact that they always occur at the end of the month - // (although it is assumed that they could occur in any month, - // even though practically they only occur in June or December). - // - // Do not define a leap second on a day of the month other than - // the last day without altering the implementation of the - // functions that depend on this one. - // - // It is possible, though, to define an un-leap second (i.e. a skipped - // second (I do not know what they are called), or a number of - // consecutive leap seconds). - - $pn_day = intval($pn_day); - $pn_month = intval($pn_month); - $pn_year = intval($pn_year); - - static $ha_leapseconds; - if (!isset($ha_leapseconds)) { - $ha_leapseconds = array(1972 => array(6 => array(30 => 1), - 12 => array(31 => 1)), - 1973 => array(12 => array(31 => 1)), - 1974 => array(12 => array(31 => 1)), - 1975 => array(12 => array(31 => 1)), - 1976 => array(12 => array(31 => 1)), - 1977 => array(12 => array(31 => 1)), - 1978 => array(12 => array(31 => 1)), - 1979 => array(12 => array(31 => 1)), - 1981 => array(6 => array(30 => 1)), - 1982 => array(6 => array(30 => 1)), - 1983 => array(6 => array(30 => 1)), - 1985 => array(6 => array(30 => 1)), - 1987 => array(12 => array(31 => 1)), - 1989 => array(12 => array(31 => 1)), - 1990 => array(12 => array(31 => 1)), - 1992 => array(6 => array(30 => 1)), - 1993 => array(6 => array(30 => 1)), - 1994 => array(6 => array(30 => 1)), - 1995 => array(12 => array(31 => 1)), - 1997 => array(6 => array(30 => 1)), - 1998 => array(12 => array(31 => 1)), - 2005 => array(12 => array(31 => 1))); - } - - if (isset($ha_leapseconds[$pn_year][$pn_month][$pn_day])) { - return 86400 + $ha_leapseconds[$pn_year][$pn_month][$pn_day]; - } else { - return 86400; - } - } - - - // }}} - // {{{ getSecondsInHour() - - /** - * Returns the total number of seconds in the hour of the given date - * - * This takes into account leap seconds. - * - * @param int $pn_day the day of the month - * @param int $pn_month the month - * @param int $pn_year the year in four digit format - * @param int $pn_hour the hour - * - * @return int - * @access public - * @static - */ - function getSecondsInHour($pn_day, $pn_month, $pn_year, $pn_hour) - { - if ($pn_hour < 23) - return 3600; - else - return Date_Calc::getSecondsInDay($pn_day, $pn_month, $pn_year) - - 82800; - } - - - // }}} - // {{{ getSecondsInMinute() - - /** - * Returns the total number of seconds in the minute of the given hour - * - * This takes into account leap seconds. - * - * @param int $pn_day the day of the month - * @param int $pn_month the month - * @param int $pn_year the year in four digit format - * @param int $pn_hour the hour - * @param int $pn_minute the minute - * - * @return int - * @access public - * @static - * @since Method available since Release 1.5.0 - */ - function getSecondsInMinute($pn_day, - $pn_month, - $pn_year, - $pn_hour, - $pn_minute) - { - if ($pn_hour < 23 || $pn_minute < 59) - return 60; - else - return Date_Calc::getSecondsInDay($pn_day, $pn_month, $pn_year) - - 86340; - } - - - // }}} - // {{{ secondsPastMidnight() - - /** - * Returns the no of seconds since midnight (0-86399) - * - * @param int $pn_hour the hour of the day - * @param int $pn_minute the minute - * @param mixed $pn_second the second as integer or float - * - * @return mixed integer or float from 0-86399 - * @access public - * @static - * @since Method available since Release 1.5.0 - */ - function secondsPastMidnight($pn_hour, $pn_minute, $pn_second) - { - return 3600 * $pn_hour + 60 * $pn_minute + $pn_second; - } - - - // }}} - // {{{ secondsPastMidnightToTime() - - /** - * Returns the time as an array (i.e. hour, minute, second) - * - * @param mixed $pn_seconds the no of seconds since midnight (0-86399) - * - * @return mixed array of hour, minute (both as integers), second (as - * integer or float, depending on parameter) - * @access public - * @static - * @since Method available since Release 1.5.0 - */ - function secondsPastMidnightToTime($pn_seconds) - { - if ($pn_seconds >= 86400) { - return array(23, 59, $pn_seconds - 86340); - } - - $hn_hour = intval($pn_seconds / 3600); - $hn_minute = intval(($pn_seconds - $hn_hour * 3600) / 60); - $hn_second = is_float($pn_seconds) ? - fmod($pn_seconds, 60) : - $pn_seconds % 60; - - return array($hn_hour, $hn_minute, $hn_second); - } - - - // }}} - // {{{ secondsPastTheHour() - - /** - * Returns the no of seconds since the last hour o'clock (0-3599) - * - * @param int $pn_minute the minute - * @param mixed $pn_second the second as integer or float - * - * @return mixed integer or float from 0-3599 - * @access public - * @static - * @since Method available since Release 1.5.0 - */ - function secondsPastTheHour($pn_minute, $pn_second) - { - return 60 * $pn_minute + $pn_second; - } - - - // }}} - // {{{ addHours() - - /** - * Returns the date the specified no of hours from the given date - * - * To subtract hours use a negative value for the '$pn_hours' parameter - * - * @param int $pn_hours hours to add - * @param int $pn_day the day of the month - * @param int $pn_month the month - * @param int $pn_year the year - * @param int $pn_hour the hour - * - * @return array array of year, month, day, hour - * @access public - * @static - * @since Method available since Release 1.5.0 - */ - function addHours($pn_hours, $pn_day, $pn_month, $pn_year, $pn_hour) - { - if ($pn_hours == 0) - return array((int) $pn_year, - (int) $pn_month, - (int) $pn_day, - (int) $pn_hour); - - $hn_days = intval($pn_hours / 24); - $hn_hour = $pn_hour + $pn_hours % 24; - - if ($hn_hour >= 24) { - ++$hn_days; - $hn_hour -= 24; - } else if ($hn_hour < 0) { - --$hn_days; - $hn_hour += 24; - } - - if ($hn_days == 0) { - $hn_year = $pn_year; - $hn_month = $pn_month; - $hn_day = $pn_day; - } else { - list($hn_year, $hn_month, $hn_day) = - explode(" ", - Date_Calc::addDays($hn_days, - $pn_day, - $pn_month, - $pn_year, - "%Y %m %d")); - } - - return array((int) $hn_year, (int) $hn_month, (int) $hn_day, $hn_hour); - } - - - // }}} - // {{{ addMinutes() - - /** - * Returns the date the specified no of minutes from the given date - * - * To subtract minutes use a negative value for the '$pn_minutes' parameter - * - * @param int $pn_minutes minutes to add - * @param int $pn_day the day of the month - * @param int $pn_month the month - * @param int $pn_year the year - * @param int $pn_hour the hour - * @param int $pn_minute the minute - * - * @return array array of year, month, day, hour, minute - * @access public - * @static - * @since Method available since Release 1.5.0 - */ - function addMinutes($pn_minutes, - $pn_day, - $pn_month, - $pn_year, - $pn_hour, - $pn_minute) - { - if ($pn_minutes == 0) - return array((int) $pn_year, - (int) $pn_month, - (int) $pn_day, - (int) $pn_hour, - (int) $pn_minute); - - $hn_hours = intval($pn_minutes / 60); - $hn_minute = $pn_minute + $pn_minutes % 60; - - if ($hn_minute >= 60) { - ++$hn_hours; - $hn_minute -= 60; - } else if ($hn_minute < 0) { - --$hn_hours; - $hn_minute += 60; - } - - if ($hn_hours == 0) { - $hn_year = $pn_year; - $hn_month = $pn_month; - $hn_day = $pn_day; - $hn_hour = $pn_hour; - } else { - list($hn_year, $hn_month, $hn_day, $hn_hour) = - Date_Calc::addHours($hn_hours, - $pn_day, - $pn_month, - $pn_year, - $pn_hour); - } - - return array($hn_year, $hn_month, $hn_day, $hn_hour, $hn_minute); - } - - - // }}} - // {{{ addSeconds() - - /** - * Returns the date the specified no of seconds from the given date - * - * If leap seconds are specified to be counted, the passed time must be UTC. - * To subtract seconds use a negative value for the '$pn_seconds' parameter. - * - * N.B. the return type of the second part of the date is float if - * either '$pn_seconds' or '$pn_second' is a float; otherwise, it - * is integer. - * - * @param mixed $pn_seconds seconds to add as integer or float - * @param int $pn_day the day of the month - * @param int $pn_month the month - * @param int $pn_year the year - * @param int $pn_hour the hour - * @param int $pn_minute the minute - * @param mixed $pn_second the second as integer or float - * @param bool $pb_countleap whether to count leap seconds (defaults to - * DATE_COUNT_LEAP_SECONDS) - * - * @return array array of year, month, day, hour, minute, second - * @access public - * @static - * @since Method available since Release 1.5.0 - */ - function addSeconds($pn_seconds, - $pn_day, - $pn_month, - $pn_year, - $pn_hour, - $pn_minute, - $pn_second, - $pb_countleap = DATE_COUNT_LEAP_SECONDS) - { - if ($pn_seconds == 0) - return array((int) $pn_year, - (int) $pn_month, - (int) $pn_day, - (int) $pn_hour, - (int) $pn_minute, - $pn_second); - - if ($pb_countleap) { - $hn_seconds = $pn_seconds; - - $hn_day = (int) $pn_day; - $hn_month = (int) $pn_month; - $hn_year = (int) $pn_year; - $hn_hour = (int) $pn_hour; - $hn_minute = (int) $pn_minute; - $hn_second = $pn_second; - - $hn_days = Date_Calc::dateToDays($pn_day, - $pn_month, - $pn_year); - $hn_secondsofmonth = 86400 * ($hn_days - - Date_Calc::firstDayOfMonth($pn_month, - $pn_year)) + - Date_Calc::secondsPastMidnight($pn_hour, - $pn_minute, - $pn_second); - - if ($hn_seconds > 0) { - // Advance to end of month: - // - if ($hn_secondsofmonth != 0 && - $hn_secondsofmonth + $hn_seconds >= - ($hn_secondsinmonth = - Date_Calc::getSecondsInMonth($hn_month, $hn_year))) { - - $hn_seconds -= $hn_secondsinmonth - $hn_secondsofmonth; - $hn_secondsofmonth = 0; - list($hn_year, $hn_month) = - Date_Calc::nextMonth($hn_month, $hn_year); - $hn_day = Date_Calc::getFirstDayOfMonth($hn_month, - $hn_year); - $hn_hour = $hn_minute = $hn_second = 0; - } - - // Advance to end of year: - // - if ($hn_secondsofmonth == 0 && - $hn_month != Date_Calc::getFirstMonthOfYear($hn_year)) { - - while ($hn_year == $pn_year && - $hn_seconds >= ($hn_secondsinmonth = - Date_Calc::getSecondsInMonth($hn_month, - $hn_year))) { - $hn_seconds -= $hn_secondsinmonth; - list($hn_year, $hn_month) = - Date_Calc::nextMonth($hn_month, $hn_year); - $hn_day = Date_Calc::getFirstDayOfMonth($hn_month, - $hn_year); - } - } - - if ($hn_secondsofmonth == 0) { - // Add years: - // - if ($hn_month == Date_Calc::getFirstMonthOfYear($hn_year)) { - while ($hn_seconds >= ($hn_secondsinyear = - Date_Calc::getSecondsInYear($hn_year))) { - $hn_seconds -= $hn_secondsinyear; - $hn_month = Date_Calc::getFirstMonthOfYear(++$hn_year); - $hn_day = Date_Calc::getFirstDayOfMonth($hn_month, - $hn_year); - } - } - - // Add months: - // - while ($hn_seconds >= ($hn_secondsinmonth = - Date_Calc::getSecondsInMonth($hn_month, $hn_year))) { - $hn_seconds -= $hn_secondsinmonth; - list($hn_year, $hn_month) = - Date_Calc::nextMonth($hn_month, $hn_year); - $hn_day = Date_Calc::getFirstDayOfMonth($hn_month, $hn_year); - } - } - } else { - // - // (if $hn_seconds < 0) - - // Go back to start of month: - // - if ($hn_secondsofmonth != 0 && - -$hn_seconds >= $hn_secondsofmonth) { - - $hn_seconds += $hn_secondsofmonth; - $hn_secondsofmonth = 0; - $hn_day = Date_Calc::getFirstDayOfMonth($hn_month, - $hn_year); - $hn_hour = $hn_minute = $hn_second = 0; - } - - // Go back to start of year: - // - if ($hn_secondsofmonth == 0) { - while ($hn_month != - Date_Calc::getFirstMonthOfYear($hn_year)) { - - list($hn_year, $hn_prevmonth) = - Date_Calc::prevMonth($hn_month, $hn_year); - - if (-$hn_seconds >= ($hn_secondsinmonth = - Date_Calc::getSecondsInMonth($hn_prevmonth, - $hn_year))) { - $hn_seconds += $hn_secondsinmonth; - $hn_month = $hn_prevmonth; - $hn_day = Date_Calc::getFirstDayOfMonth($hn_month, - $hn_year); - } else { - break; - } - } - } - - if ($hn_secondsofmonth == 0) { - // Subtract years: - // - if ($hn_month == Date_Calc::getFirstMonthOfYear($hn_year)) { - while (-$hn_seconds >= ($hn_secondsinyear = - Date_Calc::getSecondsInYear($hn_year - 1))) { - $hn_seconds += $hn_secondsinyear; - $hn_month = Date_Calc::getFirstMonthOfYear(--$hn_year); - $hn_day = Date_Calc::getFirstDayOfMonth($hn_month, - $hn_year); - } - } - - // Subtract months: - // - list($hn_pmyear, $hn_prevmonth) = - Date_Calc::prevMonth($hn_month, $hn_year); - while (-$hn_seconds >= ($hn_secondsinmonth = - Date_Calc::getSecondsInMonth($hn_prevmonth, - $hn_pmyear))) { - $hn_seconds += $hn_secondsinmonth; - $hn_year = $hn_pmyear; - $hn_month = $hn_prevmonth; - $hn_day = Date_Calc::getFirstDayOfMonth($hn_month, - $hn_year); - list($hn_pmyear, $hn_prevmonth) = - Date_Calc::prevMonth($hn_month, $hn_year); - } - } - } - - if ($hn_seconds < 0 && $hn_secondsofmonth == 0) { - list($hn_year, $hn_month) = - Date_Calc::prevMonth($hn_month, $hn_year); - $hn_day = Date_Calc::getFirstDayOfMonth($hn_month, $hn_year); - $hn_seconds += Date_Calc::getSecondsInMonth($hn_month, $hn_year); - } - - $hn_seconds += Date_Calc::secondsPastMidnight($hn_hour, - $hn_minute, - $hn_second); - if ($hn_seconds < 0) { - $hn_daysadd = intval($hn_seconds / 86400) - 1; - } else if ($hn_seconds < 86400) { - $hn_daysadd = 0; - } else { - $hn_daysadd = intval($hn_seconds / 86400) - 1; - } - - if ($hn_daysadd != 0) { - list($hn_year, $hn_month, $hn_day) = - explode(" ", - Date_Calc::addDays($hn_daysadd, - $hn_day, - $hn_month, - $hn_year, - "%Y %m %d")); - $hn_seconds -= $hn_daysadd * 86400; - } - - $hn_secondsinday = Date_Calc::getSecondsInDay($hn_day, - $hn_month, - $hn_year); - if ($hn_seconds >= $hn_secondsinday) { - list($hn_year, $hn_month, $hn_day) = - explode(" ", - Date_Calc::addDays(1, - $hn_day, - $hn_month, - $hn_year, - "%Y %m %d")); - $hn_seconds -= $hn_secondsinday; - } - - list($hn_hour, $hn_minute, $hn_second) = - Date_Calc::secondsPastMidnightToTime($hn_seconds); - - return array((int) $hn_year, - (int) $hn_month, - (int) $hn_day, - $hn_hour, - $hn_minute, - $hn_second); - } else { - // Assume every day has 86400 seconds exactly (ignore leap seconds): - // - $hn_minutes = intval($pn_seconds / 60); - - if (is_float($pn_seconds)) { - $hn_second = $pn_second + fmod($pn_seconds, 60); - } else { - $hn_second = $pn_second + $pn_seconds % 60; - } - - if ($hn_second >= 60) { - ++$hn_minutes; - $hn_second -= 60; - } else if ($hn_second < 0) { - --$hn_minutes; - $hn_second += 60; - } - - if ($hn_minutes == 0) { - $hn_year = $pn_year; - $hn_month = $pn_month; - $hn_day = $pn_day; - $hn_hour = $pn_hour; - $hn_minute = $pn_minute; - } else { - list($hn_year, $hn_month, $hn_day, $hn_hour, $hn_minute) = - Date_Calc::addMinutes($hn_minutes, - $pn_day, - $pn_month, - $pn_year, - $pn_hour, - $pn_minute); - } - - return array($hn_year, - $hn_month, - $hn_day, - $hn_hour, - $hn_minute, - $hn_second); - } - } - - - // }}} - // {{{ dateToDays() - - /** - * Converts a date in the proleptic Gregorian calendar to the no of days - * since 24th November, 4714 B.C. - * - * Returns the no of days since Monday, 24th November, 4714 B.C. in the - * proleptic Gregorian calendar (which is 24th November, -4713 using - * 'Astronomical' year numbering, and 1st January, 4713 B.C. in the - * proleptic Julian calendar). This is also the first day of the 'Julian - * Period' proposed by Joseph Scaliger in 1583, and the number of days - * since this date is known as the 'Julian Day'. (It is not directly - * to do with the Julian calendar, although this is where the name - * is derived from.) - * - * The algorithm is valid for all years (positive and negative), and - * also for years preceding 4714 B.C. - * - * @param int $day the day of the month - * @param int $month the month - * @param int $year the year (using 'Astronomical' year numbering) - * - * @return int the number of days since 24th November, 4714 B.C. - * @access public - * @static - */ - function dateToDays($day, $month, $year) - { - if ($month > 2) { - // March = 0, April = 1, ..., December = 9, - // January = 10, February = 11 - $month -= 3; - } else { - $month += 9; - --$year; - } - - $hb_negativeyear = $year < 0; - $century = intval($year / 100); - $year = $year % 100; - - if ($hb_negativeyear) { - // Subtract 1 because year 0 is a leap year; - // And N.B. that we must treat the leap years as occurring - // one year earlier than they do, because for the purposes - // of calculation, the year starts on 1st March: - // - return intval((14609700 * $century + ($year == 0 ? 1 : 0)) / 400) + - intval((1461 * $year + 1) / 4) + - intval((153 * $month + 2) / 5) + - $day + 1721118; - } else { - return intval(146097 * $century / 4) + - intval(1461 * $year / 4) + - intval((153 * $month + 2) / 5) + - $day + 1721119; - } - } - - - // }}} - // {{{ daysToDate() - - /** - * Converts no of days since 24th November, 4714 B.C. (in the proleptic - * Gregorian calendar, which is year -4713 using 'Astronomical' year - * numbering) to Gregorian calendar date - * - * Returned date belongs to the proleptic Gregorian calendar, using - * 'Astronomical' year numbering. - * - * The algorithm is valid for all years (positive and negative), and - * also for years preceding 4714 B.C. (i.e. for negative 'Julian Days'), - * and so the only limitation is platform-dependent (for 32-bit systems - * the maximum year would be something like about 1,465,190 A.D.). - * - * N.B. Monday, 24th November, 4714 B.C. is Julian Day '0'. - * - * @param int $days the number of days since 24th November, 4714 B.C. - * @param string $format the string indicating how to format the output - * - * @return string the date in the desired format - * @access public - * @static - */ - function daysToDate($days, $format = DATE_CALC_FORMAT) - { - $days = intval($days); - - $days -= 1721119; - $century = floor((4 * $days - 1) / 146097); - $days = floor(4 * $days - 1 - 146097 * $century); - $day = floor($days / 4); - - $year = floor((4 * $day + 3) / 1461); - $day = floor(4 * $day + 3 - 1461 * $year); - $day = floor(($day + 4) / 4); - - $month = floor((5 * $day - 3) / 153); - $day = floor(5 * $day - 3 - 153 * $month); - $day = floor(($day + 5) / 5); - - $year = $century * 100 + $year; - if ($month < 10) { - $month +=3; - } else { - $month -=9; - ++$year; - } - - return Date_Calc::dateFormat($day, $month, $year, $format); - } - - - // }}} - // {{{ getMonths() - - /** - * Returns array of the month numbers, in order, for the given year - * - * @param int $pn_year the year (using 'Astronomical' year numbering) - * - * @return array array of integer month numbers, in order - * @access public - * @static - * @since Method available since Release 1.5.0 - */ - function getMonths($pn_year) - { - // N.B. Month numbers can be skipped but not duplicated: - // - return array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12); - } - - - // }}} - // {{{ getMonthNames() - - /** - * Returns an array of month names - * - * Used to take advantage of the setlocale function to return - * language specific month names. - * - * TODO: cache values to some global array to avoid performance - * hits when called more than once. - * - * @param int $pb_abbreviated whether to return the abbreviated form of the - * months - * - * @return array associative array of integer month numbers, in - * order, to month names - * @access public - * @static - */ - function getMonthNames($pb_abbreviated = false) - { - $ret = array(); - foreach (Date_Calc::getMonths(2001) as $i) { - $ret[$i] = strftime($pb_abbreviated ? '%b' : '%B', - mktime(0, 0, 0, $i, 1, 2001)); - } - return $ret; - } - - - // }}} - // {{{ prevMonth() - - /** - * Returns month and year of previous month - * - * @param int $pn_month the month - * @param int $pn_year the year (using 'Astronomical' year numbering) - * - * @return array array of year, month as integers - * @access public - * @static - * @since Method available since Release 1.5.0 - */ - function prevMonth($pn_month, $pn_year) - { - $ha_months = Date_Calc::getMonths($pn_year); - $hn_monthkey = array_search($pn_month, $ha_months); - if (array_key_exists($hn_monthkey - 1, $ha_months)) { - return array((int) $pn_year, $ha_months[$hn_monthkey - 1]); - } else { - $ha_months = Date_Calc::getMonths($pn_year - 1); - return array($pn_year - 1, end($ha_months)); - } - } - - - // }}} - // {{{ nextMonth() - - /** - * Returns month and year of next month - * - * @param int $pn_month the month - * @param int $pn_year the year (using 'Astronomical' year numbering) - * - * @return array array of year, month as integers - * @access public - * @static - * @since Method available since Release 1.5.0 - */ - function nextMonth($pn_month, $pn_year) - { - $ha_months = Date_Calc::getMonths($pn_year); - $hn_monthkey = array_search($pn_month, $ha_months); - if (array_key_exists($hn_monthkey + 1, $ha_months)) { - return array((int) $pn_year, $ha_months[$hn_monthkey + 1]); - } else { - $ha_months = Date_Calc::getMonths($pn_year + 1); - return array($pn_year + 1, $ha_months[0]); - } - } - - - // }}} - // {{{ addMonthsToDays() - - /** - * Returns 'Julian Day' of the date the specified no of months - * from the given date - * - * To subtract months use a negative value for the '$pn_months' - * parameter - * - * @param int $pn_months months to add - * @param int $pn_days 'Julian Day', i.e. the no of days since 1st - * January, 4713 B.C. - * - * @return int 'Julian Day', i.e. the no of days since 1st January, - * 4713 B.C. - * @access public - * @static - * @since Method available since Release 1.5.0 - */ - function addMonthsToDays($pn_months, $pn_days) - { - if ($pn_months == 0) - return (int) $pn_days; - - list($hn_year, $hn_month, $hn_day) = - explode(" ", Date_Calc::daysToDate($pn_days, "%Y %m %d")); - - $hn_retmonth = $hn_month + $pn_months % 12; - $hn_retyear = $hn_year + intval($pn_months / 12); - if ($hn_retmonth < 1) { - $hn_retmonth += 12; - --$hn_retyear; - } else if ($hn_retmonth > 12) { - $hn_retmonth -= 12; - ++$hn_retyear; - } - - if (Date_Calc::isValidDate($hn_day, $hn_retmonth, $hn_retyear)) - return Date_Calc::dateToDays($hn_day, $hn_retmonth, $hn_retyear); - - // Calculate days since first of month: - // - $hn_dayoffset = $pn_days - - Date_Calc::firstDayOfMonth($hn_month, $hn_year); - - $hn_retmonthfirstday = Date_Calc::firstDayOfMonth($hn_retmonth, - $hn_retyear); - $hn_retmonthlastday = Date_Calc::lastDayOfMonth($hn_retmonth, - $hn_retyear); - - if ($hn_dayoffset > $hn_retmonthlastday - $hn_retmonthfirstday) { - return $hn_retmonthlastday; - } else { - return $hn_retmonthfirstday + $hn_dayoffset; - } - } - - - // }}} - // {{{ addMonths() - - /** - * Returns the date the specified no of months from the given date - * - * To subtract months use a negative value for the '$pn_months' - * parameter - * - * @param int $pn_months months to add - * @param int $pn_day the day of the month, default is current local - * day - * @param int $pn_month the month, default is current local month - * @param int $pn_year the year in four digit format, default is - * current local year - * @param string $ps_format string specifying how to format the output - * - * @return string the date in the desired format - * @access public - * @static - * @since Method available since Release 1.5.0 - */ - function addMonths($pn_months, - $pn_day, - $pn_month, - $pn_year, - $ps_format = DATE_CALC_FORMAT) - { - if (is_null($pn_year)) { - $pn_year = Date_Calc::dateNow('%Y'); - } - if (empty($pn_month)) { - $pn_month = Date_Calc::dateNow('%m'); - } - if (empty($pn_day)) { - $pn_day = Date_Calc::dateNow('%d'); - } - - if ($pn_months == 0) - return Date_Calc::dateFormat($pn_day, - $pn_month, - $pn_year, - $ps_format); - - $hn_days = Date_Calc::dateToDays($pn_day, $pn_month, $pn_year); - return Date_Calc::daysToDate(Date_Calc::addMonthsToDays($pn_months, - $hn_days), - $ps_format); - } - - - // }}} - // {{{ addYearsToDays() - - /** - * Returns 'Julian Day' of the date the specified no of years - * from the given date - * - * To subtract years use a negative value for the '$pn_years' - * parameter - * - * @param int $pn_years years to add - * @param int $pn_days 'Julian Day', i.e. the no of days since 1st January, - * 4713 B.C. - * - * @return int 'Julian Day', i.e. the no of days since 1st January, - * 4713 B.C. - * @access public - * @static - * @since Method available since Release 1.5.0 - */ - function addYearsToDays($pn_years, $pn_days) - { - if ($pn_years == 0) - return (int) $pn_days; - - list($hn_year, $hn_month, $hn_day) = - explode(" ", Date_Calc::daysToDate($pn_days, "%Y %m %d")); - - $hn_retyear = $hn_year + $pn_years; - if (Date_Calc::isValidDate($hn_day, $hn_month, $hn_retyear)) - return Date_Calc::dateToDays($hn_day, $hn_month, $hn_retyear); - - $ha_months = Date_Calc::getMonths($hn_retyear); - if (in_array($hn_month, $ha_months)) { - $hn_retmonth = $hn_month; - - // Calculate days since first of month: - // - $hn_dayoffset = $pn_days - Date_Calc::firstDayOfMonth($hn_month, - $hn_year); - - $hn_retmonthfirstday = Date_Calc::firstDayOfMonth($hn_retmonth, - $hn_retyear); - $hn_retmonthlastday = Date_Calc::lastDayOfMonth($hn_retmonth, - $hn_retyear); - - if ($hn_dayoffset > $hn_retmonthlastday - $hn_retmonthfirstday) { - return $hn_retmonthlastday; - } else { - return $hn_retmonthfirstday + $hn_dayoffset; - } - } else { - // Calculate days since first of year: - // - $hn_dayoffset = $pn_days - Date_Calc::firstDayOfYear($hn_year); - - $hn_retyearfirstday = Date_Calc::firstDayOfYear($hn_retyear); - $hn_retyearlastday = Date_Calc::lastDayOfYear($hn_retyear); - - if ($hn_dayoffset > $hn_retyearlastday - $hn_retyearfirstday) { - return $hn_retyearlastday; - } else { - return $hn_retyearfirstday + $hn_dayoffset; - } - } - } - - - // }}} - // {{{ addYears() - - /** - * Returns the date the specified no of years from the given date - * - * To subtract years use a negative value for the '$pn_years' - * parameter - * - * @param int $pn_years years to add - * @param int $pn_day the day of the month, default is current local - * day - * @param int $pn_month the month, default is current local month - * @param int $pn_year the year in four digit format, default is - * current local year - * @param string $ps_format string specifying how to format the output - * - * @return string the date in the desired format - * @access public - * @static - * @since Method available since Release 1.5.0 - */ - function addYears($pn_years, - $pn_day, - $pn_month, - $pn_year, - $ps_format = DATE_CALC_FORMAT) - { - if (is_null($pn_year)) { - $pn_year = Date_Calc::dateNow('%Y'); - } - if (empty($pn_month)) { - $pn_month = Date_Calc::dateNow('%m'); - } - if (empty($pn_day)) { - $pn_day = Date_Calc::dateNow('%d'); - } - - if ($pn_years == 0) - return Date_Calc::dateFormat($pn_day, - $pn_month, - $pn_year, - $ps_format); - - $hn_days = Date_Calc::dateToDays($pn_day, $pn_month, $pn_year); - return Date_Calc::daysToDate(Date_Calc::addYearsToDays($pn_years, - $hn_days), - $ps_format); - } - - - // }}} - // {{{ addDays() - - /** - * Returns the date the specified no of days from the given date - * - * To subtract days use a negative value for the '$pn_days' parameter - * - * @param int $pn_days days to add - * @param int $pn_day the day of the month, default is current local - * day - * @param int $pn_month the month, default is current local month - * @param int $pn_year the year in four digit format, default is - * current local year - * @param string $ps_format string specifying how to format the output - * - * @return string the date in the desired format - * @access public - * @static - * @since Method available since Release 1.5.0 - */ - function addDays($pn_days, - $pn_day, - $pn_month, - $pn_year, - $ps_format = DATE_CALC_FORMAT) - { - if (is_null($pn_year)) { - $pn_year = Date_Calc::dateNow('%Y'); - } - if (empty($pn_month)) { - $pn_month = Date_Calc::dateNow('%m'); - } - if (empty($pn_day)) { - $pn_day = Date_Calc::dateNow('%d'); - } - - if ($pn_days == 0) - return Date_Calc::dateFormat($pn_day, - $pn_month, - $pn_year, - $ps_format); - - return Date_Calc::daysToDate(Date_Calc::dateToDays($pn_day, - $pn_month, - $pn_year) + - $pn_days, - $ps_format); - } - - - // }}} - // {{{ getFirstDayOfMonth() - - /** - * Returns first day of the specified month of specified year as integer - * - * @param int $pn_month the month - * @param int $pn_year the year (using 'Astronomical' year numbering) - * - * @return int number of first day of month - * @access public - * @static - * @since Method available since Release 1.5.0 - */ - function getFirstDayOfMonth($pn_month, $pn_year) - { - return 1; - } - - - // }}} - // {{{ getLastDayOfMonth() - - /** - * Returns last day of the specified month of specified year as integer - * - * @param int $pn_month the month - * @param int $pn_year the year (using 'Astronomical' year numbering) - * - * @return int number of last day of month - * @access public - * @static - * @since Method available since Release 1.5.0 - */ - function getLastDayOfMonth($pn_month, $pn_year) - { - return Date_Calc::daysInMonth($pn_month, $pn_year); - } - - - // }}} - // {{{ firstDayOfMonth() - - /** - * Returns the Julian Day of the first day of the month of the specified - * year (i.e. the no of days since 24th November, 4714 B.C.) - * - * @param int $pn_month the month - * @param int $pn_year the year (using 'Astronomical' year numbering) - * - * @return integer the number of days since 24th November, 4714 B.C. - * @access public - * @static - * @since Method available since Release 1.5.0 - */ - function firstDayOfMonth($pn_month, $pn_year) - { - return Date_Calc::dateToDays(Date_Calc::getFirstDayOfMonth($pn_month, - $pn_year), - $pn_month, - $pn_year); - } - - - // }}} - // {{{ lastDayOfMonth() - - /** - * Returns the Julian Day of the last day of the month of the specified - * year (i.e. the no of days since 24th November, 4714 B.C.) - * - * @param int $pn_month the month - * @param int $pn_year the year (using 'Astronomical' year numbering) - * - * @return integer the number of days since 24th November, 4714 B.C. - * @access public - * @static - * @since Method available since Release 1.5.0 - */ - function lastDayOfMonth($pn_month, $pn_year) - { - list($hn_nmyear, $hn_nextmonth) = Date_Calc::nextMonth($pn_month, - $pn_year); - return Date_Calc::firstDayOfMonth($hn_nextmonth, $hn_nmyear) - 1; - } - - - // }}} - // {{{ getFirstMonthOfYear() - - /** - * Returns first month of specified year as integer - * - * @param int $pn_year the year (using 'Astronomical' year numbering) - * - * @return int number of first month of year - * @access public - * @static - * @since Method available since Release 1.5.0 - */ - function getFirstMonthOfYear($pn_year) - { - $ha_months = Date_Calc::getMonths($pn_year); - return $ha_months[0]; - } - - - // }}} - // {{{ firstDayOfYear() - - /** - * Returns the Julian Day of the first day of the year (i.e. the no of - * days since 24th November, 4714 B.C.) - * - * @param int $pn_year the year (using 'Astronomical' year numbering) - * - * @return integer the number of days since 24th November, 4714 B.C. - * @access public - * @static - * @since Method available since Release 1.5.0 - */ - function firstDayOfYear($pn_year) - { - return Date_Calc::firstDayOfMonth(Date_Calc::getFirstMonthOfYear($pn_year), - $pn_year); - } - - - // }}} - // {{{ lastDayOfYear() - - /** - * Returns the Julian Day of the last day of the year (i.e. the no of - * days since 24th November, 4714 B.C.) - * - * @param int $pn_year the year (using 'Astronomical' year numbering) - * - * @return integer the number of days since 24th November, 4714 B.C. - * @access public - * @static - * @since Method available since Release 1.5.0 - */ - function lastDayOfYear($pn_year) - { - return Date_Calc::firstDayOfYear($pn_year + 1) - 1; - } - - - // }}} - // {{{ dateToDaysJulian() - - /** - * Converts a date in the proleptic Julian calendar to the no of days - * since 1st January, 4713 B.C. - * - * Returns the no of days since Monday, 1st January, 4713 B.C. in the - * proleptic Julian calendar (which is 1st January, -4712 using - * 'Astronomical' year numbering, and 24th November, 4713 B.C. in the - * proleptic Gregorian calendar). This is also the first day of the 'Julian - * Period' proposed by Joseph Scaliger in 1583, and the number of days - * since this date is known as the 'Julian Day'. (It is not directly - * to do with the Julian calendar, although this is where the name - * is derived from.) - * - * The algorithm is valid for all years (positive and negative), and - * also for years preceding 4713 B.C. - * - * @param int $day the day of the month - * @param int $month the month - * @param int $year the year (using 'Astronomical' year numbering) - * - * @return int the number of days since 1st January, 4713 B.C. - * @access public - * @static - * @since Method available since Release 1.5.0 - */ - function dateToDaysJulian($day, $month, $year) - { - if ($month > 2) { - // March = 0, April = 1, ..., December = 9, - // January = 10, February = 11 - $month -= 3; - } else { - $month += 9; - --$year; - } - - $hb_negativeyear = $year < 0; - - if ($hb_negativeyear) { - // Subtract 1 because year 0 is a leap year; - // And N.B. that we must treat the leap years as occurring - // one year earlier than they do, because for the purposes - // of calculation, the year starts on 1st March: - // - return intval((1461 * $year + 1) / 4) + - intval((153 * $month + 2) / 5) + - $day + 1721116; - } else { - return intval(1461 * $year / 4) + - floor((153 * $month + 2) / 5) + - $day + 1721117; - } - } - - - // }}} - // {{{ daysToDateJulian() - - /** - * Converts no of days since 1st January, 4713 B.C. (in the proleptic - * Julian calendar, which is year -4712 using 'Astronomical' year - * numbering) to Julian calendar date - * - * Returned date belongs to the proleptic Julian calendar, using - * 'Astronomical' year numbering. - * - * @param int $days the number of days since 1st January, 4713 B.C. - * @param string $format the string indicating how to format the output - * - * @return string the date in the desired format - * @access public - * @static - * @since Method available since Release 1.5.0 - */ - function daysToDateJulian($days, $format = DATE_CALC_FORMAT) - { - $days = intval($days); - - $days -= 1721117; - $days = floor(4 * $days - 1); - $day = floor($days / 4); - - $year = floor((4 * $day + 3) / 1461); - $day = floor(4 * $day + 3 - 1461 * $year); - $day = floor(($day + 4) / 4); - - $month = floor((5 * $day - 3) / 153); - $day = floor(5 * $day - 3 - 153 * $month); - $day = floor(($day + 5) / 5); - - if ($month < 10) { - $month +=3; - } else { - $month -=9; - ++$year; - } - - return Date_Calc::dateFormat($day, $month, $year, $format); - } - - - // }}} - // {{{ isoWeekDate() - - /** - * Returns array defining the 'ISO Week Date' as defined in ISO 8601 - * - * Expects a date in the proleptic Gregorian calendar using 'Astronomical' - * year numbering, that is, with a year 0. Algorithm is valid for all - * years (positive and negative). - * - * N.B. the ISO week day no for Sunday is defined as 7, whereas this - * class and its related functions defines Sunday as 0. - * - * @param int $pn_day the day of the month - * @param int $pn_month the month - * @param int $pn_year the year - * - * @return array array of ISO Year, ISO Week No, ISO Day No as - * integers - * @access public - * @static - * @since Method available since Release 1.5.0 - */ - function isoWeekDate($pn_day = 0, $pn_month = 0, $pn_year = null) - { - if (is_null($pn_year)) { - $pn_year = Date_Calc::dateNow('%Y'); - } - if (empty($pn_month)) { - $pn_month = Date_Calc::dateNow('%m'); - } - if (empty($pn_day)) { - $pn_day = Date_Calc::dateNow('%d'); - } - - $hn_jd = Date_Calc::dateToDays($pn_day, $pn_month, $pn_year); - $hn_wd = Date_Calc::daysToDayOfWeek($hn_jd); - if ($hn_wd == 0) - $hn_wd = 7; - - $hn_jd1 = Date_Calc::firstDayOfYear($pn_year); - $hn_day = $hn_jd - $hn_jd1 + 1; - - if ($hn_wd <= $hn_jd - Date_Calc::lastDayOfYear($pn_year) + 3) { - // ISO week is the first week of the next ISO year: - // - $hn_year = $pn_year + 1; - $hn_isoweek = 1; - } else { - switch ($hn_wd1 = Date_Calc::daysToDayOfWeek($hn_jd1)) { - case 1: - case 2: - case 3: - case 4: - // Monday - Thursday: - // - $hn_year = $pn_year; - $hn_isoweek = floor(($hn_day + $hn_wd1 - 2) / 7) + 1; - break; - case 0: - $hn_wd1 = 7; - case 5: - case 6: - // Friday - Sunday: - // - if ($hn_day <= 8 - $hn_wd1) { - // ISO week is the last week of the previous ISO year: - // - list($hn_year, $hn_lastmonth, $hn_lastday) = - explode(" ", - Date_Calc::daysToDate($hn_jd1 - 1, "%Y %m %d")); - list($hn_year, $hn_isoweek, $hn_pisoday) = - Date_Calc::isoWeekDate($hn_lastday, - $hn_lastmonth, - $hn_year); - } else { - $hn_year = $pn_year; - $hn_isoweek = floor(($hn_day + $hn_wd1 - 9) / 7) + 1; - } - - break; - } - } - - return array((int) $hn_year, (int) $hn_isoweek, (int) $hn_wd); - } - - - // }}} - // {{{ gregorianToISO() - - /** - * Converts from Gregorian Year-Month-Day to ISO Year-WeekNumber-WeekDay - * - * Uses ISO 8601 definitions. - * - * @param int $day the day of the month - * @param int $month the month - * @param int $year the year. Use the complete year instead of the - * abbreviated version. E.g. use 2005, not 05. - * - * @return string the date in ISO Year-WeekNumber-WeekDay format - * @access public - * @static - */ - function gregorianToISO($day, $month, $year) - { - list($yearnumber, $weeknumber, $weekday) = - Date_Calc::isoWeekDate($day, $month, $year); - return sprintf("%04d", $yearnumber) . - '-' . - sprintf("%02d", $weeknumber) . - '-' . - $weekday; - } - - - // }}} - // {{{ weekOfYear4th() - - /** - * Returns week of the year counting week 1 as the week that contains 4th - * January - * - * Week 1 is determined to be the week that includes the 4th January, and - * therefore can be defined as the first week of the year that has at least - * 4 days. The previous week is counted as week 52 or 53 of the previous - * year. Note that this definition depends on which day is the first day of - * the week, and that if this is not passed as the '$pn_firstdayofweek' - * parameter, the default is assumed. - * - * Note also that the last day week of the year is likely to extend into - * the following year, except in the case that the last day of the week - * falls on 31st December. - * - * Also note that this is very similar to the ISO week returned by - * 'isoWeekDate()', the difference being that the ISO week always has - * 7 days, and if the 4th of January is a Friday, for example, - * ISO week 1 would start on Monday, 31st December in the previous year, - * whereas the week defined by this function would start on 1st January, - * but would be only 6 days long. Of course you can also set the day - * of the week, whereas the ISO week starts on a Monday by definition. - * - * Returned week is an integer from 1 to 53. - * - * @param int $pn_day the day of the month, default is current - * local day - * @param int $pn_month the month, default is current local month - * @param int $pn_year the year in four digit format, default is - * current local year - * @param int $pn_firstdayofweek optional integer specifying the first day - * of the week - * - * @return array array of year, week no as integers - * @access public - * @static - * @since Method available since Release 1.5.0 - */ - function weekOfYear4th($pn_day = 0, - $pn_month = 0, - $pn_year = null, - $pn_firstdayofweek = DATE_CALC_BEGIN_WEEKDAY) - { - if (is_null($pn_year)) { - $pn_year = Date_Calc::dateNow('%Y'); - } - if (empty($pn_month)) { - $pn_month = Date_Calc::dateNow('%m'); - } - if (empty($pn_day)) { - $pn_day = Date_Calc::dateNow('%d'); - } - - $hn_wd1 = Date_Calc::daysToDayOfWeek(Date_Calc::firstDayOfYear($pn_year)); - $hn_day = Date_Calc::dayOfYear($pn_day, $pn_month, $pn_year); - $hn_week = floor(($hn_day + - (10 + $hn_wd1 - $pn_firstdayofweek) % 7 + - 3) / 7); - - if ($hn_week > 0) { - $hn_year = $pn_year; - } else { - // Week number is the last week of the previous year: - // - list($hn_year, $hn_lastmonth, $hn_lastday) = - explode(" ", - Date_Calc::daysToDate(Date_Calc::lastDayOfYear($pn_year - 1), - "%Y %m %d")); - list($hn_year, $hn_week) = - Date_Calc::weekOfYear4th($hn_lastday, - $hn_lastmonth, - $hn_year, - $pn_firstdayofweek); - } - - return array((int) $hn_year, (int) $hn_week); - } - - - // }}} - // {{{ weekOfYear7th() - - /** - * Returns week of the year counting week 1 as the week that contains 7th - * January - * - * Week 1 is determined to be the week that includes the 7th January, and - * therefore can be defined as the first full week of the year. The - * previous week is counted as week 52 or 53 of the previous year. Note - * that this definition depends on which day is the first day of the week, - * and that if this is not passed as the '$pn_firstdayofweek' parameter, the - * default is assumed. - * - * Note also that the last day week of the year is likely to extend into - * the following year, except in the case that the last day of the week - * falls on 31st December. - * - * Returned week is an integer from 1 to 53. - * - * @param int $pn_day the day of the month, default is current - * local day - * @param int $pn_month the month, default is current local month - * @param int $pn_year the year in four digit format, default is - * current local year - * @param int $pn_firstdayofweek optional integer specifying the first day - * of the week - * - * @return array array of year, week no as integers - * @access public - * @static - * @since Method available since Release 1.5.0 - */ - function weekOfYear7th($pn_day = 0, - $pn_month = 0, - $pn_year = null, - $pn_firstdayofweek = DATE_CALC_BEGIN_WEEKDAY) - { - if (is_null($pn_year)) { - $pn_year = Date_Calc::dateNow('%Y'); - } - if (empty($pn_month)) { - $pn_month = Date_Calc::dateNow('%m'); - } - if (empty($pn_day)) { - $pn_day = Date_Calc::dateNow('%d'); - } - - $hn_wd1 = Date_Calc::daysToDayOfWeek(Date_Calc::firstDayOfYear($pn_year)); - $hn_day = Date_Calc::dayOfYear($pn_day, $pn_month, $pn_year); - $hn_week = floor(($hn_day + (6 + $hn_wd1 - $pn_firstdayofweek) % 7) / 7); - - if ($hn_week > 0) { - $hn_year = $pn_year; - } else { - // Week number is the last week of the previous ISO year: - // - list($hn_year, $hn_lastmonth, $hn_lastday) = explode(" ", Date_Calc::daysToDate(Date_Calc::lastDayOfYear($pn_year - 1), "%Y %m %d")); - list($hn_year, $hn_week) = Date_Calc::weekOfYear7th($hn_lastday, $hn_lastmonth, $hn_year, $pn_firstdayofweek); - } - - return array((int) $hn_year, (int) $hn_week); - } - - - // }}} - // {{{ dateSeason() - - /** - * Determines julian date of the given season - * - * Adapted from previous work in Java by James Mark Hamilton. - * - * @param string $season the season to get the date for: VERNALEQUINOX, - * SUMMERSOLSTICE, AUTUMNALEQUINOX, - * or WINTERSOLSTICE - * @param string $year the year in four digit format. Must be between - * -1000 B.C. and 3000 A.D. - * - * @return float the julian date the season starts on - * @access public - * @static - */ - function dateSeason($season, $year = 0) - { - if ($year == '') { - $year = Date_Calc::dateNow('%Y'); - } - if (($year >= -1000) && ($year <= 1000)) { - $y = $year / 1000.0; - switch ($season) { - case 'VERNALEQUINOX': - $juliandate = (((((((-0.00071 * $y) - 0.00111) * $y) + 0.06134) * $y) + 365242.1374) * $y) + 1721139.29189; - break; - case 'SUMMERSOLSTICE': - $juliandate = (((((((0.00025 * $y) + 0.00907) * $y) - 0.05323) * $y) + 365241.72562) * $y) + 1721233.25401; - break; - case 'AUTUMNALEQUINOX': - $juliandate = (((((((0.00074 * $y) - 0.00297) * $y) - 0.11677) * $y) + 365242.49558) * $y) + 1721325.70455; - break; - case 'WINTERSOLSTICE': - default: - $juliandate = (((((((-0.00006 * $y) - 0.00933) * $y) - 0.00769) * $y) + 365242.88257) * $y) + 1721414.39987; - } - } elseif (($year > 1000) && ($year <= 3000)) { - $y = ($year - 2000) / 1000; - switch ($season) { - case 'VERNALEQUINOX': - $juliandate = (((((((-0.00057 * $y) - 0.00411) * $y) + 0.05169) * $y) + 365242.37404) * $y) + 2451623.80984; - break; - case 'SUMMERSOLSTICE': - $juliandate = (((((((-0.0003 * $y) + 0.00888) * $y) + 0.00325) * $y) + 365241.62603) * $y) + 2451716.56767; - break; - case 'AUTUMNALEQUINOX': - $juliandate = (((((((0.00078 * $y) + 0.00337) * $y) - 0.11575) * $y) + 365242.01767) * $y) + 2451810.21715; - break; - case 'WINTERSOLSTICE': - default: - $juliandate = (((((((0.00032 * $y) - 0.00823) * $y) - 0.06223) * $y) + 365242.74049) * $y) + 2451900.05952; - } - } - return $juliandate; - } - - - // }}} - // {{{ dayOfYear() - - /** - * Returns number of days since 31 December of year before given date - * - * @param int $pn_day the day of the month, default is current local day - * @param int $pn_month the month, default is current local month - * @param int $pn_year the year in four digit format, default is current - * local year - * - * @return int - * @access public - * @static - * @since Method available since Release 1.5.0 - */ - function dayOfYear($pn_day = 0, $pn_month = 0, $pn_year = null) - { - if (is_null($pn_year)) { - $pn_year = Date_Calc::dateNow('%Y'); - } - if (empty($pn_month)) { - $pn_month = Date_Calc::dateNow('%m'); - } - if (empty($pn_day)) { - $pn_day = Date_Calc::dateNow('%d'); - } - - $hn_jd = Date_Calc::dateToDays($pn_day, $pn_month, $pn_year); - $hn_jd1 = Date_Calc::firstDayOfYear($pn_year); - return $hn_jd - $hn_jd1 + 1; - } - - - // }}} - // {{{ julianDate() - - /** - * Returns number of days since 31 December of year before given date - * - * @param int $pn_day the day of the month, default is current local day - * @param int $pn_month the month, default is current local month - * @param int $pn_year the year in four digit format, default is current - * local year - * - * @return int - * @access public - * @static - * @deprecated Method deprecated in Release 1.5.0 - */ - function julianDate($pn_day = 0, $pn_month = 0, $pn_year = null) - { - return Date_Calc::dayOfYear($pn_day, $pn_month, $pn_year); - } - - - // }}} - // {{{ getWeekdayFullname() - - /** - * Returns the full weekday name for the given date - * - * @param int $pn_day the day of the month, default is current local day - * @param int $pn_month the month, default is current local month - * @param int $pn_year the year in four digit format, default is current - * local year - * - * @return string the full name of the day of the week - * @access public - * @static - */ - function getWeekdayFullname($pn_day = 0, $pn_month = 0, $pn_year = null) - { - if (is_null($pn_year)) { - $pn_year = Date_Calc::dateNow('%Y'); - } - if (empty($pn_month)) { - $pn_month = Date_Calc::dateNow('%m'); - } - if (empty($pn_day)) { - $pn_day = Date_Calc::dateNow('%d'); - } - - $weekday_names = Date_Calc::getWeekDays(); - $weekday = Date_Calc::dayOfWeek($pn_day, $pn_month, $pn_year); - return $weekday_names[$weekday]; - } - - - // }}} - // {{{ getWeekdayAbbrname() - - /** - * Returns the abbreviated weekday name for the given date - * - * @param int $pn_day the day of the month, default is current local day - * @param int $pn_month the month, default is current local month - * @param int $pn_year the year in four digit format, default is current - * local year - * @param int $length the length of abbreviation - * - * @return string the abbreviated name of the day of the week - * @access public - * @static - * @see Date_Calc::getWeekdayFullname() - */ - function getWeekdayAbbrname($pn_day = 0, - $pn_month = 0, - $pn_year = null, - $length = 3) - { - if (is_null($pn_year)) { - $pn_year = Date_Calc::dateNow('%Y'); - } - if (empty($pn_month)) { - $pn_month = Date_Calc::dateNow('%m'); - } - if (empty($pn_day)) { - $pn_day = Date_Calc::dateNow('%d'); - } - - $weekday_names = Date_Calc::getWeekDays(true); - $weekday = Date_Calc::dayOfWeek($pn_day, $pn_month, $pn_year); - return $weekday_names[$weekday]; - } - - - // }}} - // {{{ getMonthFullname() - - /** - * Returns the full month name for the given month - * - * @param int $month the month - * - * @return string the full name of the month - * @access public - * @static - */ - function getMonthFullname($month) - { - $month = (int)$month; - if (empty($month)) { - $month = (int)Date_Calc::dateNow('%m'); - } - - $month_names = Date_Calc::getMonthNames(); - return $month_names[$month]; - } - - - // }}} - // {{{ getMonthAbbrname() - - /** - * Returns the abbreviated month name for the given month - * - * @param int $month the month - * @param int $length the length of abbreviation - * - * @return string the abbreviated name of the month - * @access public - * @static - * @see Date_Calc::getMonthFullname - */ - function getMonthAbbrname($month, $length = 3) - { - $month = (int)$month; - if (empty($month)) { - $month = Date_Calc::dateNow('%m'); - } - - $month_names = Date_Calc::getMonthNames(true); - return $month_names[$month]; - } - - - // }}} - // {{{ getMonthFromFullname() - - /** - * Returns the numeric month from the month name or an abreviation - * - * Both August and Aug would return 8. - * - * @param string $month the name of the month to examine. - * Case insensitive. - * - * @return int the month's number - * @access public - * @static - */ - function getMonthFromFullName($month) - { - $month = strtolower($month); - $months = Date_Calc::getMonthNames(); - while (list($id, $name) = each($months)) { - if (ereg($month, strtolower($name))) { - return $id; - } - } - return 0; - } - - - // }}} - // {{{ getWeekDays() - - /** - * Returns an array of week day names - * - * Used to take advantage of the setlocale function to return language - * specific week days. - * - * @param int $pb_abbreviated whether to return the abbreviated form of the - * days - * - * @return array an array of week-day names - * @access public - * @static - */ - function getWeekDays($pb_abbreviated = false) - { - for ($i = 0; $i < 7; $i++) { - $weekdays[$i] = strftime($pb_abbreviated ? '%a' : '%A', - mktime(0, 0, 0, 1, $i, 2001)); - } - return $weekdays; - } - - - // }}} - // {{{ daysToDayOfWeek() - - /** - * Returns day of week for specified 'Julian Day' - * - * The algorithm is valid for all years (positive and negative), and - * also for years preceding 4714 B.C. (i.e. for negative 'Julian Days'), - * and so the only limitation is platform-dependent (for 32-bit systems - * the maximum year would be something like about 1,465,190 A.D.). - * - * N.B. Monday, 24th November, 4714 B.C. is Julian Day '0'. - * - * @param int $pn_days the number of days since 24th November, 4714 B.C. - * - * @return int integer from 0 to 7 where 0 represents Sunday - * @access public - * @static - * @since Method available since Release 1.5.0 - */ - function daysToDayOfWeek($pn_days) - { - // On Julian day 0 the day is Monday (PHP day 1): - // - $ret = ($pn_days + 1) % 7; - return $ret < 0 ? $ret + 7 : $ret; - } - - - // }}} - // {{{ dayOfWeek() - - /** - * Returns day of week for given date (0 = Sunday) - * - * The algorithm is valid for all years (positive and negative). - * - * @param int $day the day of the month, default is current local day - * @param int $month the month, default is current local month - * @param int $year the year in four digit format, default is current - * local year - * - * @return int the number of the day in the week - * @access public - * @static - */ - function dayOfWeek($day = null, $month = null, $year = null) - { - if (is_null($year)) { - $year = Date_Calc::dateNow('%Y'); - } - if (empty($month)) { - $month = Date_Calc::dateNow('%m'); - } - if (empty($day)) { - $day = Date_Calc::dateNow('%d'); - } - - // if ($month <= 2) { - // $month += 12; - // --$year; - // } - - // $wd = ($day + - // intval((13 * $month + 3) / 5) + - // $year + - // floor($year / 4) - - // floor($year / 100) + - // floor($year / 400) + - // 1) % 7; - - // return (int) ($wd < 0 ? $wd + 7 : $wd); - - return Date_Calc::daysToDayOfWeek(Date_Calc::dateToDays($day, - $month, - $year)); - } - - - // }}} - // {{{ weekOfYearAbsolute() - - /** - * Returns week of the year counting week 1 as 1st-7th January, - * regardless of what day 1st January falls on - * - * Returned value is an integer from 1 to 53. Week 53 will start on - * 31st December and have only one day, except in a leap year, in - * which it will start a day earlier and contain two days. - * - * @param int $pn_day the day of the month, default is current local day - * @param int $pn_month the month, default is current local month - * @param int $pn_year the year in four digit format, default is current - * local year - * - * @return int integer from 1 to 53 - * @access public - * @static - * @since Method available since Release 1.5.0 - */ - function weekOfYearAbsolute($pn_day = 0, $pn_month = 0, $pn_year = null) - { - if (is_null($pn_year)) { - $pn_year = Date_Calc::dateNow('%Y'); - } - if (empty($pn_month)) { - $pn_month = Date_Calc::dateNow('%m'); - } - if (empty($pn_day)) { - $pn_day = Date_Calc::dateNow('%d'); - } - - $hn_day = Date_Calc::dayOfYear($pn_day, $pn_month, $pn_year); - return intval(($hn_day + 6) / 7); - } - - - // }}} - // {{{ weekOfYear1st() - - /** - * Returns week of the year counting week 1 as the week that contains 1st - * January - * - * Week 1 is determined to be the week that includes the 1st January, even - * if this week extends into the previous year, in which case the week will - * only contain between 1 and 6 days of the current year. Note that this - * definition depends on which day is the first day of the week, and that if - * this is not passed as the '$pn_firstdayofweek' parameter, the default is - * assumed. - * - * Note also that the last day week of the year is also likely to contain - * less than seven days, except in the case that the last day of the week - * falls on 31st December. - * - * Returned value is an integer from 1 to 54. The year will only contain - * 54 weeks in the case of a leap year in which 1st January is the last day - * of the week, and 31st December is the first day of the week. In this - * case, both weeks 1 and 54 will contain one day only. - * - * @param int $pn_day the day of the month, default is current - * local day - * @param int $pn_month the month, default is current local month - * @param int $pn_year the year in four digit format, default is - * current local year - * @param int $pn_firstdayofweek optional integer specifying the first day - * of the week - * - * @return int integer from 1 to 54 - * @access public - * @static - * @since Method available since Release 1.5.0 - */ - function weekOfYear1st($pn_day = 0, - $pn_month = 0, - $pn_year = null, - $pn_firstdayofweek = DATE_CALC_BEGIN_WEEKDAY) - { - if (is_null($pn_year)) { - $pn_year = Date_Calc::dateNow('%Y'); - } - if (empty($pn_month)) { - $pn_month = Date_Calc::dateNow('%m'); - } - if (empty($pn_day)) { - $pn_day = Date_Calc::dateNow('%d'); - } - - $hn_wd1 = Date_Calc::daysToDayOfWeek(Date_Calc::firstDayOfYear($pn_year)); - $hn_day = Date_Calc::dayOfYear($pn_day, $pn_month, $pn_year); - return floor(($hn_day + (7 + $hn_wd1 - $pn_firstdayofweek) % 7 + 6) / 7); - } - - - // }}} - // {{{ weekOfYear() - - /** - * Returns week of the year, where first Sunday is first day of first week - * - * N.B. this function is equivalent to calling: - * - * Date_Calc::weekOfYear7th($day, $month, $year, 0) - * - * Returned week is an integer from 1 to 53. - * - * @param int $pn_day the day of the month, default is current local day - * @param int $pn_month the month, default is current local month - * @param int $pn_year the year in four digit format, default is current - * local year - * - * @return int integer from 1 to 53 - * @access public - * @static - * @see Date_Calc::weekOfYear7th - * @deprecated Method deprecated in Release 1.5.0 - */ - function weekOfYear($pn_day = 0, $pn_month = 0, $pn_year = null) - { - $ha_week = Date_Calc::weekOfYear7th($pn_day, $pn_month, $pn_year, 0); - return $ha_week[1]; - } - - - // }}} - // {{{ weekOfMonthAbsolute() - - /** - * Returns week of the month counting week 1 as 1st-7th of the month, - * regardless of what day the 1st falls on - * - * Returned value is an integer from 1 to 5. Week 5 will start on - * the 29th of the month and have between 1 and 3 days, except - * in February in a non-leap year, when there will be 4 weeks only. - * - * @param int $pn_day the day of the month, default is current local day - * - * @return int integer from 1 to 5 - * @access public - * @static - * @since Method available since Release 1.5.0 - */ - function weekOfMonthAbsolute($pn_day = 0) - { - if (empty($pn_day)) { - $pn_day = Date_Calc::dateNow('%d'); - } - return intval(($pn_day + 6) / 7); - } - - - // }}} - // {{{ weekOfMonth() - - /** - * Alias for 'weekOfMonthAbsolute()' - * - * @param int $pn_day the day of the month, default is current local day - * - * @return int integer from 1 to 5 - * @access public - * @static - * @since Method available since Release 1.5.0 - */ - function weekOfMonth($pn_day = 0) - { - return Date_Calc::weekOfMonthAbsolute($pn_day); - } - - - // }}} - // {{{ quarterOfYear() - - /** - * Returns quarter of the year for given date - * - * @param int $day the day of the month, default is current local day - * @param int $month the month, default is current local month - * @param int $year the year in four digit format, default is current - * local year - * - * @return int the number of the quarter in the year - * @access public - * @static - */ - function quarterOfYear($day = 0, $month = 0, $year = null) - { - if (empty($month)) { - $month = Date_Calc::dateNow('%m'); - } - return intval(($month - 1) / 3 + 1); - } - - - // }}} - // {{{ daysInMonth() - - /** - * Returns the number of days in the given month - * - * @param int $month the month, default is current local month - * @param int $year the year in four digit format, default is current - * local year - * - * @return int the number of days the month has - * @access public - * @static - */ - function daysInMonth($month = 0, $year = null) - { - if (is_null($year)) { - $year = Date_Calc::dateNow('%Y'); - } - if (empty($month)) { - $month = Date_Calc::dateNow('%m'); - } - - return Date_Calc::lastDayOfMonth($month, $year) - - Date_Calc::firstDayOfMonth($month, $year) + - 1; - } - - - // }}} - // {{{ daysInYear() - - /** - * Returns the number of days in the given year - * - * @param int $year the year in four digit format, default is current local - * year - * - * @return int the number of days the year has - * @access public - * @static - */ - function daysInYear($year = null) - { - if (is_null($year)) { - $year = Date_Calc::dateNow('%Y'); - } - - return Date_Calc::firstDayOfYear($year + 1) - - Date_Calc::firstDayOfYear($year); - } - - - // }}} - // {{{ weeksInMonth() - - /** - * Returns the number of rows on a calendar month - * - * Useful for determining the number of rows when displaying a typical - * month calendar. - * - * @param int $month the month, default is current local month - * @param int $year the year in four digit format, default is current - * local year - * - * @return int the number of weeks the month has - * @access public - * @static - */ - function weeksInMonth($month = 0, $year = null) - { - if (is_null($year)) { - $year = Date_Calc::dateNow('%Y'); - } - if (empty($month)) { - $month = Date_Calc::dateNow('%m'); - } - $FDOM = Date_Calc::firstOfMonthWeekday($month, $year); - if (DATE_CALC_BEGIN_WEEKDAY==1 && $FDOM==0) { - $first_week_days = 7 - $FDOM + DATE_CALC_BEGIN_WEEKDAY; - $weeks = 1; - } elseif (DATE_CALC_BEGIN_WEEKDAY==0 && $FDOM == 6) { - $first_week_days = 7 - $FDOM + DATE_CALC_BEGIN_WEEKDAY; - $weeks = 1; - } else { - $first_week_days = DATE_CALC_BEGIN_WEEKDAY - $FDOM; - $weeks = 0; - } - $first_week_days %= 7; - return ceil((Date_Calc::daysInMonth($month, $year) - - $first_week_days) / 7) + $weeks; - } - - - // }}} - // {{{ getCalendarWeek() - - /** - * Return an array with days in week - * - * @param int $day the day of the month, default is current local day - * @param int $month the month, default is current local month - * @param int $year the year in four digit format, default is current - * local year - * @param string $format the string indicating how to format the output - * - * @return array $week[$weekday] - * @access public - * @static - */ - function getCalendarWeek($day = 0, $month = 0, $year = null, - $format = DATE_CALC_FORMAT) - { - if (is_null($year)) { - $year = Date_Calc::dateNow('%Y'); - } - if (empty($month)) { - $month = Date_Calc::dateNow('%m'); - } - if (empty($day)) { - $day = Date_Calc::dateNow('%d'); - } - - $week_array = array(); - - // date for the column of week - - $curr_day = Date_Calc::beginOfWeek($day, $month, $year, '%E'); - - for ($counter = 0; $counter <= 6; $counter++) { - $week_array[$counter] = Date_Calc::daysToDate($curr_day, $format); - $curr_day++; - } - return $week_array; - } - - - // }}} - // {{{ getCalendarMonth() - - /** - * Return a set of arrays to construct a calendar month for the given date - * - * @param int $month the month, default is current local month - * @param int $year the year in four digit format, default is current - * local year - * @param string $format the string indicating how to format the output - * - * @return array $month[$row][$col] - * @access public - * @static - */ - function getCalendarMonth($month = 0, $year = null, - $format = DATE_CALC_FORMAT) - { - if (is_null($year)) { - $year = Date_Calc::dateNow('%Y'); - } - if (empty($month)) { - $month = Date_Calc::dateNow('%m'); - } - - $month_array = array(); - - // date for the first row, first column of calendar month - if (DATE_CALC_BEGIN_WEEKDAY == 1) { - if (Date_Calc::firstOfMonthWeekday($month, $year) == 0) { - $curr_day = Date_Calc::firstDayOfMonth($month, $year) - 6; - } else { - $curr_day = Date_Calc::firstDayOfMonth($month, $year) - - Date_Calc::firstOfMonthWeekday($month, $year) + 1; - } - } else { - $curr_day = (Date_Calc::firstDayOfMonth($month, $year) - - Date_Calc::firstOfMonthWeekday($month, $year)); - } - - // number of days in this month - $daysInMonth = Date_Calc::daysInMonth($month, $year); - - $weeksInMonth = Date_Calc::weeksInMonth($month, $year); - for ($row_counter = 0; $row_counter < $weeksInMonth; $row_counter++) { - for ($column_counter = 0; $column_counter <= 6; $column_counter++) { - $month_array[$row_counter][$column_counter] = - Date_Calc::daysToDate($curr_day, $format); - $curr_day++; - } - } - - return $month_array; - } - - - // }}} - // {{{ getCalendarYear() - - /** - * Return a set of arrays to construct a calendar year for the given date - * - * @param int $year the year in four digit format, default current - * local year - * @param string $format the string indicating how to format the output - * - * @return array $year[$month][$row][$col] - * @access public - * @static - */ - function getCalendarYear($year = null, $format = DATE_CALC_FORMAT) - { - if (is_null($year)) { - $year = Date_Calc::dateNow('%Y'); - } - - $year_array = array(); - - for ($curr_month = 0; $curr_month <= 11; $curr_month++) { - $year_array[$curr_month] = - Date_Calc::getCalendarMonth($curr_month + 1, - $year, $format); - } - - return $year_array; - } - - - // }}} - // {{{ prevDay() - - /** - * Returns date of day before given date - * - * @param int $day the day of the month, default is current local day - * @param int $month the month, default is current local month - * @param int $year the year in four digit format, default is current - * local year - * @param string $format the string indicating how to format the output - * - * @return string the date in the desired format - * @access public - * @static - */ - function prevDay($day = 0, $month = 0, $year = null, - $format = DATE_CALC_FORMAT) - { - if (is_null($year)) { - $year = Date_Calc::dateNow('%Y'); - } - if (empty($month)) { - $month = Date_Calc::dateNow('%m'); - } - if (empty($day)) { - $day = Date_Calc::dateNow('%d'); - } - - return Date_Calc::addDays(-1, $day, $month, $year, $format); - } - - - // }}} - // {{{ nextDay() - - /** - * Returns date of day after given date - * - * @param int $day the day of the month, default is current local day - * @param int $month the month, default is current local month - * @param int $year the year in four digit format, default is current - * local year - * @param string $format the string indicating how to format the output - * - * @return string the date in the desired format - * @access public - * @static - */ - function nextDay($day = 0, - $month = 0, - $year = null, - $format = DATE_CALC_FORMAT) - { - if (is_null($year)) { - $year = Date_Calc::dateNow('%Y'); - } - if (empty($month)) { - $month = Date_Calc::dateNow('%m'); - } - if (empty($day)) { - $day = Date_Calc::dateNow('%d'); - } - - return Date_Calc::addDays(1, $day, $month, $year, $format); - } - - - // }}} - // {{{ prevWeekday() - - /** - * Returns date of the previous weekday, skipping from Monday to Friday - * - * @param int $day the day of the month, default is current local day - * @param int $month the month, default is current local month - * @param int $year the year in four digit format, default is current - * local year - * @param string $format the string indicating how to format the output - * - * @return string the date in the desired format - * @access public - * @static - */ - function prevWeekday($day = 0, $month = 0, $year = null, - $format = DATE_CALC_FORMAT) - { - if (is_null($year)) { - $year = Date_Calc::dateNow('%Y'); - } - if (empty($month)) { - $month = Date_Calc::dateNow('%m'); - } - if (empty($day)) { - $day = Date_Calc::dateNow('%d'); - } - - $days = Date_Calc::dateToDays($day, $month, $year); - if (Date_Calc::dayOfWeek($day, $month, $year) == 1) { - $days -= 3; - } elseif (Date_Calc::dayOfWeek($day, $month, $year) == 0) { - $days -= 2; - } else { - $days -= 1; - } - - return Date_Calc::daysToDate($days, $format); - } - - - // }}} - // {{{ nextWeekday() - - /** - * Returns date of the next weekday of given date, skipping from - * Friday to Monday - * - * @param int $day the day of the month, default is current local day - * @param int $month the month, default is current local month - * @param int $year the year in four digit format, default is current - * local year - * @param string $format the string indicating how to format the output - * - * @return string the date in the desired format - * @access public - * @static - */ - function nextWeekday($day = 0, $month = 0, $year = null, - $format = DATE_CALC_FORMAT) - { - if (is_null($year)) { - $year = Date_Calc::dateNow('%Y'); - } - if (empty($month)) { - $month = Date_Calc::dateNow('%m'); - } - if (empty($day)) { - $day = Date_Calc::dateNow('%d'); - } - - $days = Date_Calc::dateToDays($day, $month, $year); - if (Date_Calc::dayOfWeek($day, $month, $year) == 5) { - $days += 3; - } elseif (Date_Calc::dayOfWeek($day, $month, $year) == 6) { - $days += 2; - } else { - $days += 1; - } - - return Date_Calc::daysToDate($days, $format); - } - - - // }}} - // {{{ daysToPrevDayOfWeek() - - /** - * Returns 'Julian Day' of the previous specific day of the week - * from the given date. - * - * @param int $dow the day of the week (0 = Sunday) - * @param int $days 'Julian Day', i.e. the no of days since 1st - * January, 4713 B.C. - * @param bool $onorbefore if true and days are same, returns current day - * - * @return int 'Julian Day', i.e. the no of days since 1st January, - * 4713 B.C. - * @access public - * @static - * @since Method available since Release 1.5.0 - */ - function daysToPrevDayOfWeek($dow, $days, $onorbefore = false) - { - $curr_weekday = Date_Calc::daysToDayOfWeek($days); - if ($curr_weekday == $dow) { - if ($onorbefore) { - return $days; - } else { - return $days - 7; - } - } else if ($curr_weekday < $dow) { - return $days - 7 + $dow - $curr_weekday; - } else { - return $days - $curr_weekday + $dow; - } - } - - - // }}} - // {{{ prevDayOfWeek() - - /** - * Returns date of the previous specific day of the week - * from the given date - * - * @param int $dow the day of the week (0 = Sunday) - * @param int $day the day of the month, default is current local - * day - * @param int $month the month, default is current local month - * @param int $year the year in four digit format, default is - * current local year - * @param string $format the string indicating how to format the output - * @param bool $onorbefore if true and days are same, returns current day - * - * @return string the date in the desired format - * @access public - * @static - */ - function prevDayOfWeek($dow, - $day = 0, - $month = 0, - $year = null, - $format = DATE_CALC_FORMAT, - $onorbefore = false) - { - if (is_null($year)) { - $year = Date_Calc::dateNow('%Y'); - } - if (empty($month)) { - $month = Date_Calc::dateNow('%m'); - } - if (empty($day)) { - $day = Date_Calc::dateNow('%d'); - } - - $days = Date_Calc::dateToDays($day, $month, $year); - $days = Date_Calc::daysToPrevDayOfWeek($dow, $days, $onorbefore); - return Date_Calc::daysToDate($days, $format); - } - - - // }}} - // {{{ daysToNextDayOfWeek() - - /** - * Returns 'Julian Day' of the next specific day of the week - * from the given date. - * - * @param int $dow the day of the week (0 = Sunday) - * @param int $days 'Julian Day', i.e. the no of days since 1st - * January, 4713 B.C. - * @param bool $onorafter if true and days are same, returns current day - * - * @return int 'Julian Day', i.e. the no of days since 1st January, - * 4713 B.C. - * @access public - * @static - * @since Method available since Release 1.5.0 - */ - function daysToNextDayOfWeek($dow, $days, $onorafter = false) - { - $curr_weekday = Date_Calc::daysToDayOfWeek($days); - if ($curr_weekday == $dow) { - if ($onorafter) { - return $days; - } else { - return $days + 7; - } - } else if ($curr_weekday > $dow) { - return $days + 7 - $curr_weekday + $dow; - } else { - return $days + $dow - $curr_weekday; - } - } - - - // }}} - // {{{ nextDayOfWeek() - - /** - * Returns date of the next specific day of the week - * from the given date - * - * @param int $dow the day of the week (0 = Sunday) - * @param int $day the day of the month, default is current local - * day - * @param int $month the month, default is current local month - * @param int $year the year in four digit format, default is - * current local year - * @param string $format the string indicating how to format the output - * @param bool $onorafter if true and days are same, returns current day - * - * @return string the date in the desired format - * @access public - * @static - */ - function nextDayOfWeek($dow, - $day = 0, - $month = 0, - $year = null, - $format = DATE_CALC_FORMAT, - $onorafter = false) - { - if (is_null($year)) { - $year = Date_Calc::dateNow('%Y'); - } - if (empty($month)) { - $month = Date_Calc::dateNow('%m'); - } - if (empty($day)) { - $day = Date_Calc::dateNow('%d'); - } - - $days = Date_Calc::dateToDays($day, $month, $year); - $days = Date_Calc::daysToNextDayOfWeek($dow, $days, $onorafter); - return Date_Calc::daysToDate($days, $format); - } - - - // }}} - // {{{ prevDayOfWeekOnOrBefore() - - /** - * Returns date of the previous specific day of the week - * on or before the given date - * - * @param int $dow the day of the week (0 = Sunday) - * @param int $day the day of the month, default is current local day - * @param int $month the month, default is current local month - * @param int $year the year in four digit format, default is current - * local year - * @param string $format the string indicating how to format the output - * - * @return string the date in the desired format - * @access public - * @static - */ - function prevDayOfWeekOnOrBefore($dow, - $day = 0, - $month = 0, - $year = null, - $format = DATE_CALC_FORMAT) - { - return Date_Calc::prevDayOfWeek($dow, - $day, - $month, - $year, - $format, - true); - } - - - // }}} - // {{{ nextDayOfWeekOnOrAfter() - - /** - * Returns date of the next specific day of the week - * on or after the given date - * - * @param int $dow the day of the week (0 = Sunday) - * @param int $day the day of the month, default is current local day - * @param int $month the month, default is current local month - * @param int $year the year in four digit format, default is current - * local year - * @param string $format the string indicating how to format the output - * - * @return string the date in the desired format - * @access public - * @static - */ - function nextDayOfWeekOnOrAfter($dow, - $day = 0, - $month = 0, - $year = null, - $format = DATE_CALC_FORMAT) - { - return Date_Calc::nextDayOfWeek($dow, - $day, - $month, - $year, - $format, - true); - } - - - // }}} - // {{{ beginOfWeek() - - /** - * Find the month day of the beginning of week for given date, - * using DATE_CALC_BEGIN_WEEKDAY - * - * Can return weekday of prev month. - * - * @param int $day the day of the month, default is current local day - * @param int $month the month, default is current local month - * @param int $year the year in four digit format, default is current - * local year - * @param string $format the string indicating how to format the output - * - * @return string the date in the desired format - * @access public - * @static - */ - function beginOfWeek($day = 0, $month = 0, $year = null, - $format = DATE_CALC_FORMAT) - { - if (is_null($year)) { - $year = Date_Calc::dateNow('%Y'); - } - if (empty($month)) { - $month = Date_Calc::dateNow('%m'); - } - if (empty($day)) { - $day = Date_Calc::dateNow('%d'); - } - - $hn_days = Date_Calc::dateToDays($day, $month, $year); - $this_weekday = Date_Calc::daysToDayOfWeek($hn_days); - $interval = (7 - DATE_CALC_BEGIN_WEEKDAY + $this_weekday) % 7; - return Date_Calc::daysToDate($hn_days - $interval, $format); - } - - - // }}} - // {{{ endOfWeek() - - /** - * Find the month day of the end of week for given date, - * using DATE_CALC_BEGIN_WEEKDAY - * - * Can return weekday of following month. - * - * @param int $day the day of the month, default is current local day - * @param int $month the month, default is current local month - * @param int $year the year in four digit format, default is current - * local year - * @param string $format the string indicating how to format the output - * - * @return string the date in the desired format - * @access public - * @static - */ - function endOfWeek($day = 0, $month = 0, $year = null, - $format = DATE_CALC_FORMAT) - { - if (is_null($year)) { - $year = Date_Calc::dateNow('%Y'); - } - if (empty($month)) { - $month = Date_Calc::dateNow('%m'); - } - if (empty($day)) { - $day = Date_Calc::dateNow('%d'); - } - - $hn_days = Date_Calc::dateToDays($day, $month, $year); - $this_weekday = Date_Calc::daysToDayOfWeek($hn_days); - $interval = (6 + DATE_CALC_BEGIN_WEEKDAY - $this_weekday) % 7; - return Date_Calc::daysToDate($hn_days + $interval, $format); - } - - - // }}} - // {{{ beginOfPrevWeek() - - /** - * Find the month day of the beginning of week before given date, - * using DATE_CALC_BEGIN_WEEKDAY - * - * Can return weekday of prev month. - * - * @param int $day the day of the month, default is current local day - * @param int $month the month, default is current local month - * @param int $year the year in four digit format, default is current - * local year - * @param string $format the string indicating how to format the output - * - * @return string the date in the desired format - * @access public - * @static - */ - function beginOfPrevWeek($day = 0, $month = 0, $year = null, - $format = DATE_CALC_FORMAT) - { - if (is_null($year)) { - $year = Date_Calc::dateNow('%Y'); - } - if (empty($month)) { - $month = Date_Calc::dateNow('%m'); - } - if (empty($day)) { - $day = Date_Calc::dateNow('%d'); - } - - list($hn_pwyear, $hn_pwmonth, $hn_pwday) = - explode(" ", Date_Calc::daysToDate(Date_Calc::dateToDays($day, - $month, - $year) - 7, - '%Y %m %d')); - return Date_Calc::beginOfWeek($hn_pwday, - $hn_pwmonth, - $hn_pwyear, - $format); - } - - - // }}} - // {{{ beginOfNextWeek() - - /** - * Find the month day of the beginning of week after given date, - * using DATE_CALC_BEGIN_WEEKDAY - * - * Can return weekday of prev month. - * - * @param int $day the day of the month, default is current local day - * @param int $month the month, default is current local month - * @param int $year the year in four digit format, default is current - * local year - * @param string $format the string indicating how to format the output - * - * @return string the date in the desired format - * @access public - * @static - */ - function beginOfNextWeek($day = 0, $month = 0, $year = null, - $format = DATE_CALC_FORMAT) - { - if (is_null($year)) { - $year = Date_Calc::dateNow('%Y'); - } - if (empty($month)) { - $month = Date_Calc::dateNow('%m'); - } - if (empty($day)) { - $day = Date_Calc::dateNow('%d'); - } - - list($hn_pwyear, $hn_pwmonth, $hn_pwday) = - explode(" ", - Date_Calc::daysToDate(Date_Calc::dateToDays($day, - $month, - $year) + 7, - '%Y %m %d')); - return Date_Calc::beginOfWeek($hn_pwday, - $hn_pwmonth, - $hn_pwyear, - $format); - } - - - // }}} - // {{{ beginOfMonth() - - /** - * Return date of first day of month of given date - * - * @param int $month the month, default is current local month - * @param int $year the year in four digit format, default is current - * local year - * @param string $format the string indicating how to format the output - * - * @return string the date in the desired format - * @access public - * @static - * @see Date_Calc::beginOfMonthBySpan() - * @deprecated Method deprecated in Release 1.4.4 - */ - function beginOfMonth($month = 0, $year = null, $format = DATE_CALC_FORMAT) - { - if (is_null($year)) { - $year = Date_Calc::dateNow('%Y'); - } - if (empty($month)) { - $month = Date_Calc::dateNow('%m'); - } - - return Date_Calc::dateFormat(Date_Calc::getFirstDayOfMonth($month, - $year), - $month, - $year, - $format); - } - - - // }}} - // {{{ endOfMonth() - - /** - * Return date of last day of month of given date - * - * @param int $month the month, default is current local month - * @param int $year the year in four digit format, default is current - * local year - * @param string $format the string indicating how to format the output - * - * @return string the date in the desired format - * @access public - * @static - * @see Date_Calc::beginOfMonthBySpan() - * @since Method available since Release 1.5.0 - * @deprecated Method deprecated in Release 1.5.0 - */ - function endOfMonth($month = 0, $year = null, $format = DATE_CALC_FORMAT) - { - if (is_null($year)) { - $year = Date_Calc::dateNow('%Y'); - } - if (empty($month)) { - $month = Date_Calc::dateNow('%m'); - } - - return Date_Calc::daysToDate(Date_Calc::lastDayOfMonth($month, $year), - $format); - } - - - // }}} - // {{{ beginOfPrevMonth() - - /** - * Returns date of the first day of previous month of given date - * - * @param mixed $dummy irrelevant parameter - * @param int $month the month, default is current local month - * @param int $year the year in four digit format, default is current - * local year - * @param string $format the string indicating how to format the output - * - * @return string the date in the desired format - * @access public - * @static - * @see Date_Calc::beginOfMonthBySpan() - * @deprecated Method deprecated in Release 1.4.4 - */ - function beginOfPrevMonth($dummy = null, - $month = 0, - $year = null, - $format = DATE_CALC_FORMAT) - { - if (is_null($year)) { - $year = Date_Calc::dateNow('%Y'); - } - if (empty($month)) { - $month = Date_Calc::dateNow('%m'); - } - - list($hn_pmyear, $hn_prevmonth) = Date_Calc::prevMonth($month, $year); - return Date_Calc::dateFormat(Date_Calc::getFirstDayOfMonth($hn_prevmonth, - $hn_pmyear), - $hn_prevmonth, - $hn_pmyear, - $format); - } - - - // }}} - // {{{ endOfPrevMonth() - - /** - * Returns date of the last day of previous month for given date - * - * @param mixed $dummy irrelevant parameter - * @param int $month the month, default is current local month - * @param int $year the year in four digit format, default is current - * local year - * @param string $format the string indicating how to format the output - * - * @return string the date in the desired format - * @access public - * @static - * @see Date_Calc::endOfMonthBySpan() - * @deprecated Method deprecated in Release 1.4.4 - */ - function endOfPrevMonth($dummy = null, - $month = 0, - $year = null, - $format = DATE_CALC_FORMAT) - { - if (is_null($year)) { - $year = Date_Calc::dateNow('%Y'); - } - if (empty($month)) { - $month = Date_Calc::dateNow('%m'); - } - - return Date_Calc::daysToDate(Date_Calc::firstDayOfMonth($month, - $year) - 1, - $format); - } - - - // }}} - // {{{ beginOfNextMonth() - - /** - * Returns date of begin of next month of given date - * - * @param mixed $dummy irrelevant parameter - * @param int $month the month, default is current local month - * @param int $year the year in four digit format, default is current - * local year - * @param string $format the string indicating how to format the output - * - * @return string the date in the desired format - * @access public - * @static - * @see Date_Calc::beginOfMonthBySpan() - * @deprecated Method deprecated in Release 1.4.4 - */ - function beginOfNextMonth($dummy = null, - $month = 0, - $year = null, - $format = DATE_CALC_FORMAT) - { - if (is_null($year)) { - $year = Date_Calc::dateNow('%Y'); - } - if (empty($month)) { - $month = Date_Calc::dateNow('%m'); - } - - list($hn_nmyear, $hn_nextmonth) = Date_Calc::nextMonth($month, $year); - return Date_Calc::dateFormat(Date_Calc::getFirstDayOfMonth($hn_nextmonth, - $hn_nmyear), - $hn_nextmonth, - $hn_nmyear, - $format); - } - - - // }}} - // {{{ endOfNextMonth() - - /** - * Returns date of the last day of next month of given date - * - * @param mixed $dummy irrelevant parameter - * @param int $month the month, default is current local month - * @param int $year the year in four digit format, default is current - * local year - * @param string $format the string indicating how to format the output - * - * @return string the date in the desired format - * @access public - * @static - * @see Date_Calc::endOfMonthBySpan() - * @deprecated Method deprecated in Release 1.4.4 - */ - function endOfNextMonth($dummy = null, - $month = 0, - $year = null, - $format = DATE_CALC_FORMAT) - { - if (is_null($year)) { - $year = Date_Calc::dateNow('%Y'); - } - if (empty($month)) { - $month = Date_Calc::dateNow('%m'); - } - - list($hn_nmyear, $hn_nextmonth) = Date_Calc::nextMonth($month, $year); - return Date_Calc::daysToDate(Date_Calc::lastDayOfMonth($hn_nextmonth, - $hn_nmyear), - $format); - } - - - // }}} - // {{{ beginOfMonthBySpan() - - /** - * Returns date of the first day of the month in the number of months - * from the given date - * - * @param int $months the number of months from the date provided. - * Positive numbers go into the future. - * Negative numbers go into the past. - * 0 is the month presented in $month. - * @param string $month the month, default is current local month - * @param string $year the year in four digit format, default is the - * current local year - * @param string $format the string indicating how to format the output - * - * @return string the date in the desired format - * @access public - * @static - * @since Method available since Release 1.4.4 - */ - function beginOfMonthBySpan($months = 0, - $month = 0, - $year = null, - $format = DATE_CALC_FORMAT) - { - if (is_null($year)) { - $year = Date_Calc::dateNow('%Y'); - } - if (empty($month)) { - $month = Date_Calc::dateNow('%m'); - } - - return Date_Calc::addMonths($months, - Date_Calc::getFirstDayOfMonth($month, $year), - $month, - $year, - $format); - } - - - // }}} - // {{{ endOfMonthBySpan() - - /** - * Returns date of the last day of the month in the number of months - * from the given date - * - * @param int $months the number of months from the date provided. - * Positive numbers go into the future. - * Negative numbers go into the past. - * 0 is the month presented in $month. - * @param string $month the month, default is current local month - * @param string $year the year in four digit format, default is the - * current local year - * @param string $format the string indicating how to format the output - * - * @return string the date in the desired format - * @access public - * @static - * @since Method available since Release 1.4.4 - */ - function endOfMonthBySpan($months = 0, - $month = 0, - $year = null, - $format = DATE_CALC_FORMAT) - { - if (is_null($year)) { - $year = Date_Calc::dateNow('%Y'); - } - if (empty($month)) { - $month = Date_Calc::dateNow('%m'); - } - - $hn_days = Date_Calc::addMonthsToDays($months + 1, - Date_Calc::firstDayOfMonth($month, $year)) - 1; - return Date_Calc::daysToDate($hn_days, $format); - } - - - // }}} - // {{{ firstOfMonthWeekday() - - /** - * Find the day of the week for the first of the month of given date - * - * @param int $month the month, default is current local month - * @param int $year the year in four digit format, default is current - * local year - * - * @return int number of weekday for the first day, 0=Sunday - * @access public - * @static - */ - function firstOfMonthWeekday($month = 0, $year = null) - { - if (is_null($year)) { - $year = Date_Calc::dateNow('%Y'); - } - if (empty($month)) { - $month = Date_Calc::dateNow('%m'); - } - return Date_Calc::daysToDayOfWeek(Date_Calc::firstDayOfMonth($month, - $year)); - } - - - // }}} - // {{{ nWeekdayOfMonth() - - /** - * Calculates the date of the Nth weekday of the month, - * such as the second Saturday of January 2000 - * - * @param int $week the number of the week to get - * (1 = first, etc. Also can be 'last'.) - * @param int $dow the day of the week (0 = Sunday) - * @param int $month the month - * @param int $year the year. Use the complete year instead of the - * abbreviated version. E.g. use 2005, not 05. - * @param string $format the string indicating how to format the output - * - * @return string the date in the desired format - * @access public - * @static - */ - function nWeekdayOfMonth($week, $dow, $month, $year, - $format = DATE_CALC_FORMAT) - { - if (is_numeric($week)) { - $DOW1day = ($week - 1) * 7 + 1; - $DOW1 = Date_Calc::dayOfWeek($DOW1day, $month, $year); - $wdate = ($week - 1) * 7 + 1 + (7 + $dow - $DOW1) % 7; - if ($wdate > Date_Calc::daysInMonth($month, $year)) { - return -1; - } else { - return Date_Calc::dateFormat($wdate, $month, $year, $format); - } - } elseif ($week == 'last' && $dow < 7) { - $lastday = Date_Calc::daysInMonth($month, $year); - $lastdow = Date_Calc::dayOfWeek($lastday, $month, $year); - $diff = $dow - $lastdow; - if ($diff > 0) { - return Date_Calc::dateFormat($lastday - (7 - $diff), $month, - $year, $format); - } else { - return Date_Calc::dateFormat($lastday + $diff, $month, - $year, $format); - } - } else { - return -1; - } - } - - - // }}} - // {{{ isValidDate() - - /** - * Returns true for valid date, false for invalid date - * - * Uses the proleptic Gregorian calendar, with the year 0 (1 B.C.) - * assumed to be valid and also assumed to be a leap year. - * - * @param int $day the day of the month - * @param int $month the month - * @param int $year the year. Use the complete year instead of the - * abbreviated version. E.g. use 2005, not 05. - * - * @return bool - * @access public - * @static - */ - function isValidDate($day, $month, $year) - { - if ($day < 1 || $month < 1 || $month > 12) - return false; - if ($month == 2) { - if (Date_Calc::isLeapYearGregorian($year)) { - return $day <= 29; - } else { - return $day <= 28; - } - } elseif ($month == 4 || $month == 6 || $month == 9 || $month == 11) { - return $day <= 30; - } else { - return $day <= 31; - } - } - - - // }}} - // {{{ isLeapYearGregorian() - - /** - * Returns true for a leap year, else false - * - * Uses the proleptic Gregorian calendar. The year 0 (1 B.C.) is - * assumed in this algorithm to be a leap year. The function is - * valid for all years, positive and negative. - * - * @param int $year the year. Use the complete year instead of the - * abbreviated version. E.g. use 2005, not 05. - * - * @return bool - * @access public - * @static - * @since Method available since Release 1.5.0 - */ - function isLeapYearGregorian($year = null) - { - if (is_null($year)) { - $year = Date_Calc::dateNow('%Y'); - } - return (($year % 4 == 0) && - ($year % 100 != 0)) || - ($year % 400 == 0); - } - - - // }}} - // {{{ isLeapYearJulian() - - /** - * Returns true for a leap year, else false - * - * Uses the proleptic Julian calendar. The year 0 (1 B.C.) is - * assumed in this algorithm to be a leap year. The function is - * valid for all years, positive and negative. - * - * @param int $year the year. Use the complete year instead of the - * abbreviated version. E.g. use 2005, not 05. - * - * @return boolean - * @access public - * @static - * @since Method available since Release 1.5.0 - */ - function isLeapYearJulian($year = null) - { - if (is_null($year)) { - $year = Date_Calc::dateNow('%Y'); - } - return $year % 4 == 0; - } - - - // }}} - // {{{ isLeapYear() - - /** - * Returns true for a leap year, else false - * - * @param int $year the year. Use the complete year instead of the - * abbreviated version. E.g. use 2005, not 05. - * - * @return boolean - * @access public - * @static - */ - function isLeapYear($year = null) - { - if (is_null($year)) { - $year = Date_Calc::dateNow('%Y'); - } - if ($year < 1582) { - // pre Gregorio XIII - 1582 - return Date_Calc::isLeapYearJulian($year); - } else { - // post Gregorio XIII - 1582 - return Date_Calc::isLeapYearGregorian($year); - } - } - - - // }}} - // {{{ isFutureDate() - - /** - * Determines if given date is a future date from now - * - * @param int $day the day of the month - * @param int $month the month - * @param int $year the year. Use the complete year instead of the - * abbreviated version. E.g. use 2005, not 05. - * - * @return bool - * @access public - * @static - */ - function isFutureDate($day, $month, $year) - { - $this_year = Date_Calc::dateNow('%Y'); - $this_month = Date_Calc::dateNow('%m'); - $this_day = Date_Calc::dateNow('%d'); - - if ($year > $this_year) { - return true; - } elseif ($year == $this_year) { - if ($month > $this_month) { - return true; - } elseif ($month == $this_month) { - if ($day > $this_day) { - return true; - } - } - } - return false; - } - - - // }}} - // {{{ isPastDate() - - /** - * Determines if given date is a past date from now - * - * @param int $day the day of the month - * @param int $month the month - * @param int $year the year. Use the complete year instead of the - * abbreviated version. E.g. use 2005, not 05. - * - * @return boolean - * @access public - * @static - */ - function isPastDate($day, $month, $year) - { - $this_year = Date_Calc::dateNow('%Y'); - $this_month = Date_Calc::dateNow('%m'); - $this_day = Date_Calc::dateNow('%d'); - - if ($year < $this_year) { - return true; - } elseif ($year == $this_year) { - if ($month < $this_month) { - return true; - } elseif ($month == $this_month) { - if ($day < $this_day) { - return true; - } - } - } - return false; - } - - - // }}} - // {{{ dateDiff() - - /** - * Returns number of days between two given dates - * - * @param int $day1 the day of the month - * @param int $month1 the month - * @param int $year1 the year. Use the complete year instead of the - * abbreviated version. E.g. use 2005, not 05. - * @param int $day2 the day of the month - * @param int $month2 the month - * @param int $year2 the year. Use the complete year instead of the - * abbreviated version. E.g. use 2005, not 05. - * - * @return int the absolute number of days between the two dates. - * If an error occurs, -1 is returned. - * @access public - * @static - */ - function dateDiff($day1, $month1, $year1, $day2, $month2, $year2) - { - if (!Date_Calc::isValidDate($day1, $month1, $year1)) { - return -1; - } - if (!Date_Calc::isValidDate($day2, $month2, $year2)) { - return -1; - } - return abs(Date_Calc::dateToDays($day1, $month1, $year1) - - Date_Calc::dateToDays($day2, $month2, $year2)); - } - - - // }}} - // {{{ compareDates() - - /** - * Compares two dates - * - * @param int $day1 the day of the month - * @param int $month1 the month - * @param int $year1 the year. Use the complete year instead of the - * abbreviated version. E.g. use 2005, not 05. - * @param int $day2 the day of the month - * @param int $month2 the month - * @param int $year2 the year. Use the complete year instead of the - * abbreviated version. E.g. use 2005, not 05. - * - * @return int 0 if the dates are equal. 1 if date 1 is later, -1 - * if date 1 is earlier. - * @access public - * @static - */ - function compareDates($day1, $month1, $year1, $day2, $month2, $year2) - { - $ndays1 = Date_Calc::dateToDays($day1, $month1, $year1); - $ndays2 = Date_Calc::dateToDays($day2, $month2, $year2); - if ($ndays1 == $ndays2) { - return 0; - } - return ($ndays1 > $ndays2) ? 1 : -1; - } - - - // }}} - // {{{ round() - - /** - * Rounds the date according to the specified precision - * - * The precision parameter must be one of the following constants: - * - * DATE_PRECISION_YEAR - * DATE_PRECISION_MONTH - * DATE_PRECISION_DAY - * DATE_PRECISION_HOUR - * DATE_PRECISION_10MINUTES - * DATE_PRECISION_MINUTE - * DATE_PRECISION_10SECONDS - * DATE_PRECISION_SECOND - * - * The precision can also be specified as an integral offset from - * one of these constants, where the offset reflects a precision - * of 10 to the power of the offset greater than the constant. - * For example: - * - * DATE_PRECISION_YEAR - 1 rounds the date to the nearest 10 - * years - * DATE_PRECISION_YEAR - 3 rounds the date to the nearest 1000 - * years - * DATE_PRECISION_SECOND + 1 rounds the date to 1 decimal - * point of a second - * DATE_PRECISION_SECOND + 1 rounds the date to 3 decimal - * points of a second - * DATE_PRECISION_SECOND + 1 rounds the date to the nearest 10 - * seconds (thus it is equivalent to - * DATE_PRECISION_10SECONDS) - * - * N.B. This function requires a time in UTC if both the precision is at - * least DATE_PRECISION_SECOND and leap seconds are being counted, otherwise - * any local time is acceptable. - * - * @param int $pn_precision a 'DATE_PRECISION_*' constant - * @param int $pn_day the day of the month - * @param int $pn_month the month - * @param int $pn_year the year - * @param int $pn_hour the hour - * @param int $pn_minute the minute - * @param mixed $pn_second the second as integer or float - * @param bool $pb_countleap whether to count leap seconds (defaults to - * DATE_COUNT_LEAP_SECONDS) - * - * @return array array of year, month, day, hour, minute, second - * @access public - * @static - * @since Method available since Release 1.5.0 - */ - function round($pn_precision, - $pn_day, - $pn_month, - $pn_year, - $pn_hour = 0, - $pn_minute = 0, - $pn_second = 0, - $pb_countleap = DATE_COUNT_LEAP_SECONDS) - { - if ($pn_precision <= DATE_PRECISION_YEAR) { - $hn_month = 0; - $hn_day = 0; - $hn_hour = 0; - $hn_minute = 0; - $hn_second = 0; - - if ($pn_precision < DATE_PRECISION_YEAR) { - $hn_year = round($pn_year, $pn_precision - DATE_PRECISION_YEAR); - } else { - // Check part-year: - // - $hn_midyear = (Date_Calc::firstDayOfYear($pn_year + 1) - - Date_Calc::firstDayOfYear($pn_year)) / 2; - if (($hn_days = Date_Calc::dayOfYear($pn_day, - $pn_month, - $pn_year)) <= - $hn_midyear - 1) { - $hn_year = $pn_year; - } else if ($hn_days >= $hn_midyear) { - // Round up: - // - $hn_year = $pn_year + 1; - } else { - // Take time into account: - // - $hn_partday = Date_Calc::secondsPastMidnight($pn_hour, - $pn_minute, - $pn_second) / - 86400; - if ($hn_partday >= $hn_midyear - $hn_days) { - // Round up: - // - $hn_year = $pn_year + 1; - } else { - $hn_year = $pn_year; - } - } - } - } else if ($pn_precision == DATE_PRECISION_MONTH) { - $hn_year = $pn_year; - $hn_day = 0; - $hn_hour = 0; - $hn_minute = 0; - $hn_second = 0; - - $hn_firstofmonth = Date_Calc::firstDayOfMonth($pn_month, $pn_year); - $hn_midmonth = (Date_Calc::lastDayOfMonth($pn_month, $pn_year) + - 1 - - $hn_firstofmonth) / 2; - if (($hn_days = Date_Calc::dateToDays($pn_day, - $pn_month, - $pn_year) - - $hn_firstofmonth) <= $hn_midmonth - 1) { - $hn_month = $pn_month; - } else if ($hn_days >= $hn_midmonth) { - // Round up: - // - list($hn_year, $hn_month) = Date_Calc::nextMonth($pn_month, - $pn_year); - } else { - // Take time into account: - // - $hn_partday = Date_Calc::secondsPastMidnight($pn_hour, - $pn_minute, - $pn_second) / - 86400; - if ($hn_partday >= $hn_midmonth - $hn_days) { - // Round up: - // - list($hn_year, $hn_month) = Date_Calc::nextMonth($pn_month, - $pn_year); - } else { - $hn_month = $pn_month; - } - } - } else if ($pn_precision == DATE_PRECISION_DAY) { - $hn_year = $pn_year; - $hn_month = $pn_month; - $hn_hour = 0; - $hn_minute = 0; - $hn_second = 0; - - if (Date_Calc::secondsPastMidnight($pn_hour, - $pn_minute, - $pn_second) >= 43200) { - // Round up: - // - list($hn_year, $hn_month, $hn_day) = - explode(" ", Date_Calc::nextDay($pn_day, - $pn_month, - $pn_year, - "%Y %m %d")); - } else { - $hn_day = $pn_day; - } - } else if ($pn_precision == DATE_PRECISION_HOUR) { - $hn_year = $pn_year; - $hn_month = $pn_month; - $hn_day = $pn_day; - $hn_minute = 0; - $hn_second = 0; - - if (Date_Calc::secondsPastTheHour($pn_minute, $pn_second) >= 1800) { - // Round up: - // - list($hn_year, $hn_month, $hn_day, $hn_hour) = - Date_Calc::addHours(1, - $pn_day, - $pn_month, - $pn_year, - $pn_hour); - } else { - $hn_hour = $pn_hour; - } - } else if ($pn_precision <= DATE_PRECISION_MINUTE) { - $hn_year = $pn_year; - $hn_month = $pn_month; - $hn_day = $pn_day; - $hn_hour = $pn_hour; - $hn_second = 0; - - if ($pn_precision < DATE_PRECISION_MINUTE) { - $hn_minute = round($pn_minute, - $pn_precision - DATE_PRECISION_MINUTE); - } else { - // Check seconds: - // - if ($pn_second >= 30) { - // Round up: - // - list($hn_year, - $hn_month, - $hn_day, - $hn_hour, - $hn_minute) = - Date_Calc::addMinutes(1, - $pn_day, - $pn_month, - $pn_year, - $pn_hour, - $pn_minute); - } else { - $hn_minute = $pn_minute; - } - } - } else { - // Precision is at least (DATE_PRECISION_SECOND - 1): - // - $hn_year = $pn_year; - $hn_month = $pn_month; - $hn_day = $pn_day; - $hn_hour = $pn_hour; - $hn_minute = $pn_minute; - - $hn_second = round($pn_second, - $pn_precision - DATE_PRECISION_SECOND); - - if (fmod($hn_second, 1) == 0.0) { - $hn_second = (int) $hn_second; - - if ($hn_second != intval($pn_second)) { - list($hn_year, - $hn_month, - $hn_day, - $hn_hour, - $hn_minute, - $hn_second) = - Date_Calc::addSeconds($hn_second - intval($pn_second), - $pn_day, - $pn_month, - $pn_year, - $pn_hour, - $pn_minute, - intval($pn_second), - $pn_precision >= - DATE_PRECISION_SECOND && - $pb_countleap); - // - // (N.B. if rounded to nearest 10 seconds, - // user does not expect seconds to be '60') - } - } - } - - return array((int) $hn_year, - (int) $hn_month, - (int) $hn_day, - (int) $hn_hour, - (int) $hn_minute, - $hn_second); - } - - - // }}} - // {{{ roundSeconds() - - /** - * Rounds seconds up or down to the nearest specified unit - * - * @param int $pn_precision number of digits after the decimal point - * @param int $pn_day the day of the month - * @param int $pn_month the month - * @param int $pn_year the year - * @param int $pn_hour the hour - * @param int $pn_minute the minute - * @param mixed $pn_second the second as integer or float - * @param bool $pb_countleap whether to count leap seconds (defaults to - * DATE_COUNT_LEAP_SECONDS) - * - * @return array array of year, month, day, hour, minute, second - * @access public - * @static - * @since Method available since Release 1.5.0 - */ - function roundSeconds($pn_precision, - $pn_day, - $pn_month, - $pn_year, - $pn_hour, - $pn_minute, - $pn_second, - $pb_countleap = DATE_COUNT_LEAP_SECONDS) - { - return Date_Calc::round(DATE_PRECISION_SECOND + $pn_precision, - $pn_day, - $pn_month, - $pn_year, - $pn_hour, - $pn_minute, - $pn_second); - } - - - // }}} - -} - -// }}} - - -/* - * Local variables: - * mode: php - * tab-width: 4 - * c-basic-offset: 4 - * c-hanging-comment-ender-p: nil - * End: - */ -?> \ No newline at end of file diff --git a/glmPEAR/Date/Human.php b/glmPEAR/Date/Human.php deleted file mode 100755 index a3dea88..0000000 --- a/glmPEAR/Date/Human.php +++ /dev/null @@ -1,243 +0,0 @@ - - * @copyright 1997-2006 Allan Kent - * @license http://www.opensource.org/licenses/bsd-license.php - * BSD License - * @version CVS: $Id: Human.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ - * @link http://pear.php.net/package/Date - * @since File available since Release 1.3 - */ - -// }}} -// {{{ Class: Date_Human - -/** - * Class to convert date strings between Gregorian and Human calendar formats - * - * The Human Calendar format has been proposed by Scott Flansburg and can be - * explained as follows: - * The year is made up of 13 months - * Each month has 28 days - * Counting of months starts from 0 (zero) so the months will run from 0 to 12 - * New Years day (00) is a monthless day - * Note: Leap Years are not yet accounted for in the Human Calendar system - * - * @category Date and Time - * @package Date - * @author Allan Kent - * @copyright 1997-2005 Allan Kent - * @license http://www.opensource.org/licenses/bsd-license.php - * BSD License - * @version Release: 1.5.0a1 - * @link http://pear.php.net/package/Date - * @since Class available since Release 1.3 - */ -class Date_Human -{ - // {{{ gregorianToHuman() - - /** - * Returns an associative array containing the converted date information - * in 'Human Calendar' format. - * - * If the day is New Years Day, the function will return - * "hdom" => 0 - * "hdow" => 0 - * "hwom" => 0 - * "hwoy" => 0 - * "hmoy" => -1 - * Since 0 is a valid month number under the Human Calendar, I have left - * the month as -1 for New Years Day. - * - * @param int $day in DD format, default current local day - * @param int $month in MM format, default current local month - * @param int $year in CCYY format, default to current local year - * - * @return associative array( - * hdom, // Human Day Of Month, starting at 1 - * hdow, // Human Day Of Week, starting at 1 - * hwom, // Human Week of Month, starting at 1 - * hwoy, // Human Week of Year, starting at 1 - * hmoy, // Human Month of Year, starting at 0 - * ) - * @access public - * @static - */ - function gregorianToHuman($day = 0, $month = 0, $year = 0) - { - /* - * Check to see if any of the arguments are empty - * If they are then populate the $dateinfo array - * Then check to see which arguments are empty and fill - * those with the current date info - */ - if ((empty($day) || (empty($month)) || empty($year))) { - $dateinfo = getdate(time()); - } - if (empty($day)) { - $day = $dateinfo["mday"]; - } - if (empty($month)) { - $month = $dateinfo["mon"]; - } - if (empty($year)) { - $year = $dateinfo["year"]; - } - /* - * We need to know how many days into the year we are - */ - $dateinfo = getdate(mktime(0, 0, 0, $month, $day, $year)); - $dayofyear = $dateinfo["yday"]; - /* - * Human Calendar starts at 0 for months and the first day of the year - * is designated 00, so we need to start our day of the year at 0 for - * these calculations. - * Also, the day of the month is calculated with a modulus of 28. - * Because a day is 28 days, the last day of the month would have a - * remainder of 0 and not 28 as it should be. Decrementing $dayofyear - * gets around this. - */ - $dayofyear--; - /* - * 28 days in a month... - */ - $humanMonthOfYear = floor($dayofyear / 28); - /* - * If we are in the first month then the day of the month is $dayofyear - * else we need to find the modulus of 28. - */ - if ($humanMonthOfYear == 0) { - $humanDayOfMonth = $dayofyear; - } else { - $humanDayOfMonth = ($dayofyear) % 28; - } - /* - * Day of the week is modulus 7 - */ - $humanDayOfWeek = $dayofyear % 7; - /* - * We can now increment $dayofyear back to it's correct value for - * the remainder of the calculations - */ - $dayofyear++; - /* - * $humanDayOfMonth needs to be incremented now - recall that we fudged - * it a bit by decrementing $dayofyear earlier - * Same goes for $humanDayOfWeek - */ - $humanDayOfMonth++; - $humanDayOfWeek++; - /* - * Week of the month is day of the month divided by 7, rounded up - * Same for week of the year, but use $dayofyear instead $humanDayOfMonth - */ - $humanWeekOfMonth = ceil($humanDayOfMonth / 7); - $humanWeekOfYear = ceil($dayofyear / 7); - /* - * Return an associative array of the values - */ - return array("hdom" => $humanDayOfMonth, - "hdow" => $humanDayOfWeek, - "hwom" => $humanWeekOfMonth, - "hwoy" => $humanWeekOfYear, - "hmoy" => $humanMonthOfYear ); - } - - // }}} - // {{{ humanToGregorian() - - /** - * Returns unix timestamp for a given Human Calendar date - * - * @param int $day in DD format - * @param int $month in MM format - * @param int $year in CCYY format, default to current local year - * - * @return int unix timestamp of date - * @access public - * @static - */ - function humanToGregorian($day, $month, $year = 0) - { - /* - * Check to see if the year has been passed through. - * If not get current year - */ - if (empty($year)) { - $dateinfo = getdate(time()); - $year = $dateinfo["year"]; - } - /* - * We need to get the day of the year that we are currently at so that - * we can work out the Gregorian Month and day - */ - $DayOfYear = $month * 28; - $DayOfYear += $day; - /* - * Human Calendar starts at 0, so we need to increment $DayOfYear - * to take into account the day 00 - */ - $DayOfYear++; - /* - * the mktime() function will correctly calculate the date for out of - * range values, so putting $DayOfYear instead of the day of the month - * will work fine. - */ - $GregorianTimeStamp = mktime(0, 0, 0, 1, $DayOfYear, $year); - return $GregorianTimeStamp; - } - - // }}} -} - -// }}} - -/* - * Local variables: - * mode: php - * tab-width: 4 - * c-basic-offset: 4 - * c-hanging-comment-ender-p: nil - * End: - */ -?> \ No newline at end of file diff --git a/glmPEAR/Date/Span.php b/glmPEAR/Date/Span.php deleted file mode 100755 index 3cddadd..0000000 --- a/glmPEAR/Date/Span.php +++ /dev/null @@ -1,1104 +0,0 @@ - - * @author Pierre-Alain Joye - * @copyright 1997-2006 Leandro Lucarella, Pierre-Alain Joye - * @license http://www.opensource.org/licenses/bsd-license.php - * BSD License - * @version CVS: $Id: Span.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ - * @link http://pear.php.net/package/Date - * @since File available since Release 1.4 - */ - -// }}} -// {{{ Includes - -/** - * Get the Date class - */ -require_once 'Date.php'; - -/** - * Get the Date_Calc class - */ -require_once 'Date/Calc.php'; - -// }}} -// {{{ Constants - -/** - * Non Numeric Separated Values (NNSV) Input Format - * - * Input format guessed from something like this: - * dayshoursminutesseconds - * Where is any quantity of non numeric chars. If no values are - * given, time span is set to zero, if one value is given, it's used for - * hours, if two values are given it's used for hours and minutes and if - * three values are given, it's used for hours, minutes and seconds.
- * Examples:
- * '' -> 0, 0, 0, 0 (days, hours, minutes, seconds)
- * '12' -> 0, 12, 0, 0 - * '12.30' -> 0, 12, 30, 0
- * '12:30:18' -> 0, 12, 30, 18
- * '3-12-30-18' -> 3, 12, 30, 18
- * '3 days, 12-30-18' -> 3, 12, 30, 18
- * '12:30 with 18 secs' -> 0, 12, 30, 18
- * - * @const int - */ -define('DATE_SPAN_INPUT_FORMAT_NNSV', 1); - -// }}} -// {{{ Global Variables - -/** - * Default time format when converting to a string - * - * @global string - */ -$GLOBALS['_DATE_SPAN_FORMAT'] = '%C'; - -/** - * Default time format when converting from a string - * - * @global mixed - */ -$GLOBALS['_DATE_SPAN_INPUT_FORMAT'] = DATE_SPAN_INPUT_FORMAT_NNSV; - -// }}} -// {{{ Class: Date_Span - -/** - * Generic time span handling class for PEAR - * - * @category Date and Time - * @package Date - * @author Leandro Lucarella - * @author Pierre-Alain Joye - * @copyright 1997-2006 Leandro Lucarella, Pierre-Alain Joye - * @license http://www.opensource.org/licenses/bsd-license.php - * BSD License - * @version Release: 1.5.0a1 - * @link http://pear.php.net/package/Date - * @since Class available since Release 1.4 - */ -class Date_Span -{ - - // {{{ Properties - - /** - * The no of days - * - * @var int - * @access private - * @since Property available since Release 1.0 - */ - var $day; - - /** - * The no of hours (0 to 23) - * - * @var int - * @access private - * @since Property available since Release 1.0 - */ - var $hour; - - /** - * The no of minutes (0 to 59) - * - * @var int - * @access private - * @since Property available since Release 1.0 - */ - var $minute; - - /** - * The no of seconds (0 to 59) - * - * @var int - * @access private - * @since Property available since Release 1.0 - */ - var $second; - - - // }}} - // {{{ Constructor - - /** - * Constructor - * - * Creates the time span object calling the set() method. - * - * @param mixed $time time span expression - * @param mixed $format format string to set it from a string or the - * second date set it from a date diff - * - * @access public - * @see set() - */ - function Date_Span($time = 0, $format = null) - { - $this->set($time, $format); - } - - - // }}} - // {{{ set() - - /** - * Set the time span to a new value in a 'smart' way - * - * Sets the time span depending on the argument types, calling - * to the appropriate setFromXxx() method. - * - * @param mixed $time time span expression - * @param mixed $format format string to set it from a string or the - * second date set it from a date diff - * - * @return bool true on success - * @access public - * @see setFromObject(), setFromArray(), setFromString(), - * setFromSeconds(), setFromDateDiff() - */ - function set($time = 0, $format = null) - { - if (is_a($time, 'date_span')) { - return $this->copy($time); - } elseif (is_a($time, 'date') and is_a($format, 'date')) { - return $this->setFromDateDiff($time, $format); - } elseif (is_array($time)) { - return $this->setFromArray($time); - } elseif (is_string($time)) { - return $this->setFromString($time, $format); - } elseif (is_int($time)) { - return $this->setFromSeconds($time); - } else { - return $this->setFromSeconds(0); - } - } - - - // }}} - // {{{ setFromArray() - - /** - * Set the time span from an array - * - * Any value can be a float (but it has no sense in seconds), for example: - * - * array(23.5, 20, 0) - * - * is interpreted as 23 hours, .5*60 + 20 = 50 minutes and 0 seconds. - * - * @param array $time items are counted from right to left. First - * item is for seconds, second for minutes, third - * for hours and fourth for days. If there are - * less items than 4, zero (0) is assumed for the - * absent values. - * - * @return bool true on success - * @access public - */ - function setFromArray($time) - { - if (!is_array($time)) { - return false; - } - $tmp1 = new Date_Span; - if (!$tmp1->setFromSeconds(@array_pop($time))) { - return false; - } - $tmp2 = new Date_Span; - if (!$tmp2->setFromMinutes(@array_pop($time))) { - return false; - } - $tmp1->add($tmp2); - if (!$tmp2->setFromHours(@array_pop($time))) { - return false; - } - $tmp1->add($tmp2); - if (!$tmp2->setFromDays(@array_pop($time))) { - return false; - } - $tmp1->add($tmp2); - return $this->copy($tmp1); - } - - - // }}} - // {{{ setFromString() - - /** - * Set the time span from a string based on an input format - * - * This is some like a mix of format() method and sscanf() PHP function. - * The error checking and validation of this function is very primitive, - * so you should be carefull when using it with unknown $time strings. - * With this method you are assigning day, hour, minute and second - * values, and the last values are used. This means that if you use - * something like setFromString('10, 20', '%H, %h') your time span - * would be 20 hours long. Allways remember that this method sets - * all the values, so if you had a $time span 30 minutes long - * and you make $time->setFromString('20 hours', '%H hours'), $time - * span would be 20 hours long (and not 20 hours and 30 minutes). - * Input format options:
- * %C Days with time, same as "%D, %H:%M:%S"
- * %d Total days as a float number - * (2 days, 12 hours = 2.5 days)
- * %D Days as a decimal number
- * %e Total hours as a float number - * (1 day, 2 hours, 30 minutes = 26.5 hours)
- * %f Total minutes as a float number - * (2 minutes, 30 seconds = 2.5 minutes)
- * %g Total seconds as a decimal number - * (2 minutes, 30 seconds = 90 seconds)
- * %h Hours as decimal number
- * %H Hours as decimal number limited to 2 digits
- * %m Minutes as a decimal number
- * %M Minutes as a decimal number limited to 2 digits
- * %n Newline character (\n)
- * %p Either 'am' or 'pm' depending on the time. If 'pm' - * is detected it adds 12 hours to the resulting time - * span (without any checks). This is case - * insensitive.
- * %r Time in am/pm notation, same as "%H:%M:%S %p"
- * %R Time in 24-hour notation, same as "%H:%M"
- * %s Seconds as a decimal number
- * %S Seconds as a decimal number limited to 2 digits
- * %t Tab character (\t)
- * %T Current time equivalent, same as "%H:%M:%S"
- * %% Literal '%'
- * - * @param string $time string from where to get the time span - * information - * @param string $format format string - * - * @return bool true on success - * @access public - */ - function setFromString($time, $format = null) - { - if (is_null($format)) { - $format = $GLOBALS['_DATE_SPAN_INPUT_FORMAT']; - } - // If format is a string, it parses the string format. - if (is_string($format)) { - $str = ''; - $vars = array(); - $pm = 'am'; - $day = $hour = $minute = $second = 0; - for ($i = 0; $i < strlen($format); $i++) { - $char = $format{$i}; - if ($char == '%') { - $nextchar = $format{++$i}; - switch ($nextchar) { - case 'c': - $str .= '%d, %d:%d:%d'; - array_push($vars, - 'day', - 'hour', - 'minute', - 'second'); - break; - case 'C': - $str .= '%d, %2d:%2d:%2d'; - array_push($vars, - 'day', - 'hour', - 'minute', - 'second'); - break; - case 'd': - $str .= '%f'; - array_push($vars, 'day'); - break; - case 'D': - $str .= '%d'; - array_push($vars, 'day'); - break; - case 'e': - $str .= '%f'; - array_push($vars, 'hour'); - break; - case 'f': - $str .= '%f'; - array_push($vars, 'minute'); - break; - case 'g': - $str .= '%f'; - array_push($vars, 'second'); - break; - case 'h': - $str .= '%d'; - array_push($vars, 'hour'); - break; - case 'H': - $str .= '%2d'; - array_push($vars, 'hour'); - break; - case 'm': - $str .= '%d'; - array_push($vars, 'minute'); - break; - case 'M': - $str .= '%2d'; - array_push($vars, 'minute'); - break; - case 'n': - $str .= "\n"; - break; - case 'p': - $str .= '%2s'; - array_push($vars, 'pm'); - break; - case 'r': - $str .= '%2d:%2d:%2d %2s'; - array_push($vars, - 'hour', - 'minute', - 'second', - 'pm'); - break; - case 'R': - $str .= '%2d:%2d'; - array_push($vars, 'hour', 'minute'); - break; - case 's': - $str .= '%d'; - array_push($vars, 'second'); - break; - case 'S': - $str .= '%2d'; - array_push($vars, 'second'); - break; - case 't': - $str .= "\t"; - break; - case 'T': - $str .= '%2d:%2d:%2d'; - array_push($vars, 'hour', 'minute', 'second'); - break; - case '%': - $str .= "%"; - break; - default: - $str .= $char . $nextchar; - } - } else { - $str .= $char; - } - } - $vals = sscanf($time, $str); - foreach ($vals as $i => $val) { - if (is_null($val)) { - return false; - } - $$vars[$i] = $val; - } - if (strcasecmp($pm, 'pm') == 0) { - $hour += 12; - } elseif (strcasecmp($pm, 'am') != 0) { - return false; - } - $this->setFromArray(array($day, $hour, $minute, $second)); - } elseif (is_integer($format)) { - // If format is a integer, it uses a predefined format - // detection method. - switch ($format) { - case DATE_SPAN_INPUT_FORMAT_NNSV: - $time = preg_split('/\D+/', $time); - switch (count($time)) { - case 0: - return $this->setFromArray(array(0, - 0, - 0, - 0)); - case 1: - return $this->setFromArray(array(0, - $time[0], - 0, - 0)); - case 2: - return $this->setFromArray(array(0, - $time[0], - $time[1], - 0)); - case 3: - return $this->setFromArray(array(0, - $time[0], - $time[1], - $time[2])); - default: - return $this->setFromArray($time); - } - break; - } - } - return false; - } - - - // }}} - // {{{ setFromSeconds() - - /** - * Set the time span from a total number of seconds - * - * @param int $seconds total number of seconds - * - * @return bool true on success - * @access public - */ - function setFromSeconds($seconds) - { - if ($seconds < 0) { - return false; - } - $sec = intval($seconds); - $min = floor($sec / 60); - $hour = floor($min / 60); - $day = intval(floor($hour / 24)); - - $this->second = $sec % 60; - $this->minute = $min % 60; - $this->hour = $hour % 24; - $this->day = $day; - return true; - } - - - // }}} - // {{{ setFromMinutes() - - /** - * Set the time span from a total number of minutes - * - * @param float $minutes total number of minutes - * - * @return bool true on success - * @access public - */ - function setFromMinutes($minutes) - { - return $this->setFromSeconds(round($minutes * 60)); - } - - - // }}} - // {{{ setFromHours() - - /** - * Set the time span from a total number of hours - * - * @param float $hours total number of hours - * - * @return bool true on success - * @access public - */ - function setFromHours($hours) - { - return $this->setFromSeconds(round($hours * 3600)); - } - - - // }}} - // {{{ setFromDays() - - /** - * Set the time span from a total number of days - * - * @param float $days total number of days - * - * @return bool true on success - * @access public - */ - function setFromDays($days) - { - return $this->setFromSeconds(round($days * 86400)); - } - - - // }}} - // {{{ setFromDateDiff() - - /** - * Set the span from the elapsed time between two dates - * - * The time span is unsigned, so the date's order is not important. - * - * @param object $date1 first Date - * @param object $date2 second Date - * - * @return bool true on success - * @access public - */ - function setFromDateDiff($date1, $date2) - { - if (!is_a($date1, 'date') or !is_a($date2, 'date')) { - return false; - } - $date1->toUTC(); - $date2->toUTC(); - if ($date1->after($date2)) { - list($date1, $date2) = array($date2, $date1); - } - $days = Date_Calc::dateDiff($date1->getDay(), - $date1->getMonth(), - $date1->getYear(), - $date2->getDay(), - $date2->getMonth(), - $date2->getYear()); - $hours = $date2->getHour() - $date1->getHour(); - $mins = $date2->getMinute() - $date1->getMinute(); - $secs = $date2->getSecond() - $date1->getSecond(); - $this->setFromSeconds($days * 86400 + - $hours * 3600 + - $mins * 60 + $secs); - return true; - } - - - // }}} - // {{{ copy() - - /** - * Set the time span from another time object - * - * @param object $time source time span object - * - * @return bool true on success - * @access public - */ - function copy($time) - { - if (is_a($time, 'date_span')) { - $this->second = $time->second; - $this->minute = $time->minute; - $this->hour = $time->hour; - $this->day = $time->day; - return true; - } else { - return false; - } - } - - - // }}} - // {{{ format() - - /** - * Time span pretty printing (similar to Date::format()) - * - * Formats the time span in the given format, similar to - * strftime() and Date::format().
- *
- * Formatting options:
- * %C Days with time, same as "%D, %H:%M:%S"
- * %d Total days as a float number - * (2 days, 12 hours = 2.5 days)
- * %D Days as a decimal number
- * %e Total hours as a float number - * (1 day, 2 hours, 30 minutes = 26.5 hours)
- * %E Total hours as a decimal number - * (1 day, 2 hours, 40 minutes = 26 hours)
- * %f Total minutes as a float number - * (2 minutes, 30 seconds = 2.5 minutes)
- * %F Total minutes as a decimal number - * (1 hour, 2 minutes, 40 seconds = 62 minutes)
- * %g Total seconds as a decimal number - * (2 minutes, 30 seconds = 90 seconds)
- * %h Hours as decimal number (0 to 23)
- * %H Hours as decimal number (00 to 23)
- * %i Hours as decimal number on 12-hour clock - * (1 to 12)
- * %I Hours as decimal number on 12-hour clock - * (01 to 12)
- * %m Minutes as a decimal number (0 to 59)
- * %M Minutes as a decimal number (00 to 59)
- * %n Newline character (\n)
- * %p Either 'am' or 'pm' depending on the time
- * %P Either 'AM' or 'PM' depending on the time
- * %r Time in am/pm notation, same as "%I:%M:%S %p"
- * %R Time in 24-hour notation, same as "%H:%M"
- * %s Seconds as a decimal number (0 to 59)
- * %S Seconds as a decimal number (00 to 59)
- * %t Tab character (\t)
- * %T Current time equivalent, same as "%H:%M:%S"
- * %% Literal '%'
- * - * @param string $format the format string for returned time span - * - * @return string the time span in specified format - * @access public - */ - function format($format = null) - { - if (is_null($format)) { - $format = $GLOBALS['_DATE_SPAN_FORMAT']; - } - $output = ''; - for ($i = 0; $i < strlen($format); $i++) { - $char = $format{$i}; - if ($char == '%') { - $nextchar = $format{++$i}; - switch ($nextchar) { - case 'C': - $output .= sprintf('%d, %02d:%02d:%02d', - $this->day, - $this->hour, - $this->minute, - $this->second); - break; - case 'd': - $output .= $this->toDays(); - break; - case 'D': - $output .= $this->day; - break; - case 'e': - $output .= $this->toHours(); - break; - case 'E': - $output .= floor($this->toHours()); - break; - case 'f': - $output .= $this->toMinutes(); - break; - case 'F': - $output .= floor($this->toMinutes()); - break; - case 'g': - $output .= $this->toSeconds(); - break; - case 'h': - $output .= $this->hour; - break; - case 'H': - $output .= sprintf('%02d', $this->hour); - break; - case 'i': - case 'I': - $hour = $this->hour + 1 > 12 ? - $this->hour - 12 : - $this->hour; - $output .= $hour == 0 ? - 12 : - ($nextchar == "i" ? - $hour : - sprintf('%02d', $hour)); - break; - case 'm': - $output .= $this->minute; - break; - case 'M': - $output .= sprintf('%02d', $this->minute); - break; - case 'n': - $output .= "\n"; - break; - case 'p': - $output .= $this->hour >= 12 ? 'pm' : 'am'; - break; - case 'P': - $output .= $this->hour >= 12 ? 'PM' : 'AM'; - break; - case 'r': - $hour = $this->hour + 1 > 12 ? - $this->hour - 12 : - $this->hour; - $output .= sprintf('%02d:%02d:%02d %s', - $hour == 0 ? 12 : $hour, - $this->minute, - $this->second, - $this->hour >= 12 ? 'pm' : 'am'); - break; - case 'R': - $output .= sprintf('%02d:%02d', - $this->hour, - $this->minute); - break; - case 's': - $output .= $this->second; - break; - case 'S': - $output .= sprintf('%02d', $this->second); - break; - case 't': - $output .= "\t"; - break; - case 'T': - $output .= sprintf('%02d:%02d:%02d', - $this->hour, - $this->minute, - $this->second); - break; - case '%': - $output .= "%"; - break; - default: - $output .= $char . $nextchar; - } - } else { - $output .= $char; - } - } - return $output; - } - - - // }}} - // {{{ toSeconds() - - /** - * Convert time span to seconds - * - * @return int time span as an integer number of seconds - * @access public - */ - function toSeconds() - { - return $this->day * 86400 + $this->hour * 3600 + - $this->minute * 60 + $this->second; - } - - - // }}} - // {{{ toMinutes() - - /** - * Convert time span to minutes - * - * @return float time span as a decimal number of minutes - * @access public - */ - function toMinutes() - { - return $this->day * 1440 + $this->hour * 60 + $this->minute + - $this->second / 60; - } - - - // }}} - // {{{ toHours() - - /** - * Convert time span to hours - * - * @return float time span as a decimal number of hours - * @access public - */ - function toHours() - { - return $this->day * 24 + $this->hour + $this->minute / 60 + - $this->second / 3600; - } - - - // }}} - // {{{ toDays() - - /** - * Convert time span to days - * - * @return float time span as a decimal number of days - * @access public - */ - function toDays() - { - return $this->day + $this->hour / 24 + $this->minute / 1440 + - $this->second / 86400; - } - - - // }}} - // {{{ add() - - /** - * Adds a time span - * - * @param object $time time span to add - * - * @return void - * @access public - */ - function add($time) - { - return $this->setFromSeconds($this->toSeconds() + - $time->toSeconds()); - } - - - // }}} - // {{{ subtract() - - /** - * Subtracts a time span - * - * If the time span to subtract is larger than the original, the result - * is zero (there's no sense in negative time spans). - * - * @param object $time time span to subtract - * - * @return void - * @access public - */ - function subtract($time) - { - $sub = $this->toSeconds() - $time->toSeconds(); - if ($sub < 0) { - $this->setFromSeconds(0); - } else { - $this->setFromSeconds($sub); - } - } - - - // }}} - // {{{ equal() - - /** - * Tells if time span is equal to $time - * - * @param object $time time span to compare to - * - * @return bool true if the time spans are equal - * @access public - */ - function equal($time) - { - return $this->toSeconds() == $time->toSeconds(); - } - - - // }}} - // {{{ greaterEqual() - - /** - * Tells if this time span is greater or equal than $time - * - * @param object $time time span to compare to - * - * @return bool true if this time span is greater or equal than $time - * @access public - */ - function greaterEqual($time) - { - return $this->toSeconds() >= $time->toSeconds(); - } - - - // }}} - // {{{ lowerEqual() - - /** - * Tells if this time span is lower or equal than $time - * - * @param object $time time span to compare to - * - * @return bool true if this time span is lower or equal than $time - * @access public - */ - function lowerEqual($time) - { - return $this->toSeconds() <= $time->toSeconds(); - } - - - // }}} - // {{{ greater() - - /** - * Tells if this time span is greater than $time - * - * @param object $time time span to compare to - * - * @return bool true if this time span is greater than $time - * @access public - */ - function greater($time) - { - return $this->toSeconds() > $time->toSeconds(); - } - - - // }}} - // {{{ lower() - - /** - * Tells if this time span is lower than $time - * - * @param object $time time span to compare to - * - * @return bool true if this time span is lower than $time - * @access public - */ - function lower($time) - { - return $this->toSeconds() < $time->toSeconds(); - } - - - // }}} - // {{{ compare() - - /** - * Compares two time spans - * - * Suitable for use in sorting functions. - * - * @param object $time1 the first time span - * @param object $time2 the second time span - * - * @return int 0 if the time spans are equal, -1 if time1 is lower - * than time2, 1 if time1 is greater than time2 - * @access public - * @static - */ - function compare($time1, $time2) - { - if ($time1->equal($time2)) { - return 0; - } elseif ($time1->lower($time2)) { - return -1; - } else { - return 1; - } - } - - - // }}} - // {{{ isEmpty() - - /** - * Tells if the time span is empty (zero length) - * - * @return bool true if empty - * @access public - */ - function isEmpty() - { - return !$this->day && !$this->hour && !$this->minute && !$this->second; - } - - - // }}} - // {{{ setDefaultInputFormat() - - /** - * Set the default input format - * - * @param mixed $format new default input format - * - * @return mixed previous default input format - * @access public - * @static - */ - function setDefaultInputFormat($format) - { - $old = $GLOBALS['_DATE_SPAN_INPUT_FORMAT']; - $GLOBALS['_DATE_SPAN_INPUT_FORMAT'] = $format; - return $old; - } - - - // }}} - // {{{ getDefaultInputFormat() - - /** - * Get the default input format - * - * @return mixed default input format - * @access public - * @static - */ - function getDefaultInputFormat() - { - return $GLOBALS['_DATE_SPAN_INPUT_FORMAT']; - } - - - // }}} - // {{{ setDefaultFormat() - - /** - * Set the default format - * - * @param mixed $format new default format - * - * @return mixed previous default format - * @access public - * @static - */ - function setDefaultFormat($format) - { - $old = $GLOBALS['_DATE_SPAN_FORMAT']; - $GLOBALS['_DATE_SPAN_FORMAT'] = $format; - return $old; - } - - - // }}} - // {{{ getDefaultFormat() - - /** - * Get the default format - * - * @return mixed default format - * @access public - * @static - */ - function getDefaultFormat() - { - return $GLOBALS['_DATE_SPAN_FORMAT']; - } - - - // }}} - -} - -// }}} - -/* - * Local variables: - * mode: php - * tab-width: 4 - * c-basic-offset: 4 - * c-hanging-comment-ender-p: nil - * End: - */ -?> \ No newline at end of file diff --git a/glmPEAR/Date/TimeZone.php b/glmPEAR/Date/TimeZone.php deleted file mode 100755 index 6e6cf8e..0000000 --- a/glmPEAR/Date/TimeZone.php +++ /dev/null @@ -1,7247 +0,0 @@ - - * @author Pierre-Alain Joye - * @author C.A. Woodcock - * @copyright 1997-2007 Baba Buehler, Pierre-Alain Joye, C.A. Woodcock - * @license http://www.opensource.org/licenses/bsd-license.php - * BSD License - * @version CVS: $Id: TimeZone.php,v 1.1.1.1 2008/04/28 15:20:48 jamie Exp $ - * @link http://pear.php.net/package/Date - */ - - -// }}} -// {{{ Class Date_TimeZone - -/** - * TimeZone representation class, along with time zone information data - * - * The default timezone is set from the first valid timezone id found - * in one of the following places, in this order: - * + global $_DATE_TIMEZONE_DEFAULT - * + system environment variable PHP_TZ - * + system environment variable TZ - * + the result of date('T') - * - * If no valid timezone id is found, the default timezone is set to 'UTC'. - * You may also manually set the default timezone by passing a valid id to - * Date_TimeZone::setDefault(). - * - * This class includes time zone data (from zoneinfo) in the form of a - * global array, $_DATE_TIMEZONE_DATA. - * - * @category Date and Time - * @package Date - * @author Baba Buehler - * @author C.A. Woodcock - * @copyright 1997-2007 Baba Buehler, Pierre-Alain Joye, C.A. Woodcock - * @license http://www.opensource.org/licenses/bsd-license.php - * BSD License - * @version Release: 1.5.0a1 - * @link http://pear.php.net/package/Date - */ -class Date_TimeZone -{ - - // {{{ Properties - - /** - * Unique time Zone ID of this time zone - * - * @var string - * @access private - * @since Property available since Release 1.0 - */ - var $id; - - /** - * Offset, in milliseconds, of this timezone - * - * @var int - * @access private - * @since Property available since Release 1.0 - */ - var $offset; - - /** - * Short name of this time zone (e.g. "CST") - * - * @var string - * @access private - * @since Property available since Release 1.0 - */ - var $shortname; - - /** - * DST short name of this timezone (e.g. 'BST') - * - * @var string - * @access private - * @since Property available since Release 1.0 - */ - var $dstshortname; - - /** - * Long name of this time zone (e.g. "Central Standard Time") - * - * N.B. this is not necessarily unique - * - * @since 1.0 - * @access private - * @since Property available since Release 1.0 - */ - var $longname; - - /** - * DST long name of this time zone (e.g. 'British Summer Time') - * - * @var string - * @access private - * @since Property available since Release 1.0 - */ - var $dstlongname; - - /** - * Whether this time zone observes daylight savings time - * - * @var bool - * @access private - * @since Property available since Release 1.0 - */ - var $hasdst; - - /** - * Additional offset of Summer time from the standard time of the - * time zone in milli-seconds - * - * The value is usually 3600000, i.e. one hour, and always positive - * - * @var int - * @access private - * @since Property available since Release 1.5.0 - */ - var $on_summertimeoffset; - - /** - * Month no (1-12) in which Summer time starts (the clocks go forward) - * - * @var int - * @access private - * @since Property available since Release 1.5.0 - */ - var $on_summertimestartmonth; - - /** - * Definition of when Summer time starts in the specified month - * - * Can take one of the following forms: - * - * 5 the fifth of the month - * lastSun the last Sunday in the month - * lastMon the last Monday in the month - * Sun>=8 first Sunday on or after the 8th - * Sun<=25 last Sunday on or before the 25th - * - * @var string - * @access private - * @since Property available since Release 1.5.0 - */ - var $os_summertimestartday; - - /** - * Time in milli-seconds relative to midnight UTC when - * Summer time starts (the clocks go forward) - * - * @var int - * @access private - * @since Property available since Release 1.5.0 - */ - var $on_summertimestarttime; - - /** - * Month no (1-12) in which Summer time ends (the clocks go back) - * - * @var int - * @access private - * @since Property available since Release 1.5.0 - */ - var $on_summertimeendmonth; - - /** - * Definition of when Summer time ends in the specified month - * - * @var string - * @access private - * @see Date_TimeZone::$os_summertimestartday - * @since Property available since Release 1.5.0 - */ - var $os_summertimeendday; - - /** - * Time in milli-seconds relative to midnight UTC when - * Summer time ends (the clocks go back) - * - * @var int - * @access private - * @since Property available since Release 1.5.0 - */ - var $on_summertimeendtime; - - - // }}} - // {{{ Constructor - - /** - * Constructor - * - * Creates a new Date::TimeZone object, representing the time zone - * specified in $id. - * - * If the supplied ID is invalid, the created time zone is "UTC". - * - * A note about time zones of the form 'Etc/*' (quoted from the public - * domain 'tz' data-base (see ftp://elsie.nci.nih.gov/pub/tzdata2007i.tar.gz - * [file 'etcetera']): - * - * These entries are mostly present for historical reasons, so that - * people in areas not otherwise covered by the tz files could use - * a time zone that was right for their area. These days, the - * tz files cover almost all the inhabited world, and the only practical - * need now for the entries that are not on UTC are for ships at sea - * that cannot use POSIX TZ settings. - * - * Etc/GMT (GMT) - * Etc/UTC (UTC) - * Etc/UCT (UCT) - * - * The following link uses older naming conventions, but it belongs here. - * We want this to work even on installations that omit the other older - * names. - * - * Etc/GMT (equivalent to GMT) - * - * Etc/UTC (equivalent to Etc/Universal) - * Etc/UTC (equivalent to Etc/Zulu) - * - * Etc/GMT (equivalent to Etc/Greenwich) - * Etc/GMT (equivalent to Etc/GMT-0) - * Etc/GMT (equivalent to Etc/GMT+0) - * Etc/GMT (equivalent to Etc/GMT0) - * - * We use POSIX-style signs in the Zone names and the output abbreviations, - * even though this is the opposite of what many people expect. - * POSIX has positive signs west of Greenwich, but many people expect - * positive signs east of Greenwich. For example, TZ='Etc/GMT+4' uses - * the abbreviation "GMT+4" and corresponds to 4 hours behind UTC - * (i.e. west of Greenwich) even though many people would expect it to - * mean 4 hours ahead of UTC (i.e. east of Greenwich). - * - * In the draft 5 of POSIX 1003.1-200x, the angle bracket notation - * (which is not yet supported by the tz code) allows for - * TZ='+4'; if you want time zone abbreviations conforming to - * ISO 8601 you can use TZ='<-0400>+4'. Thus the commonly-expected - * offset is kept within the angle bracket (and is used for display) - * while the POSIX sign is kept outside the angle bracket (and is used - * for calculation). - * - * Do not use a TZ setting like TZ='GMT+4', which is four hours behind - * GMT but uses the completely misleading abbreviation "GMT". - * - * Earlier incarnations of this package were not POSIX-compliant, and - * we did not want things to change quietly if someone accustomed to the - * old way uses the codes from previous versions so we moved the names - * into the Etc subdirectory. - * - * Etc/GMT-14 (14 hours ahead of Greenwich) - * Etc/GMT-13 (13) - * Etc/GMT-12 (12) - * Etc/GMT-11 (11) - * Etc/GMT-10 (10) - * Etc/GMT-9 (9) - * Etc/GMT-8 (8) - * Etc/GMT-7 (7) - * Etc/GMT-6 (6) - * Etc/GMT-5 (5) - * Etc/GMT-4 (4) - * Etc/GMT-3 (3) - * Etc/GMT-2 (2) - * Etc/GMT-1 (1) - * Etc/GMT+1 (1 hour behind Greenwich) - * Etc/GMT+2 (2) - * Etc/GMT+3 (3) - * Etc/GMT+4 (4) - * Etc/GMT+5 (5) - * Etc/GMT+6 (6) - * Etc/GMT+7 (7) - * Etc/GMT+8 (8) - * Etc/GMT+9 (9) - * Etc/GMT+10 (10) - * Etc/GMT+11 (11) - * Etc/GMT+12 (12) - * - * @param string $ps_id the time zone ID - * - * @return void - * @access public - * @see Date::setTZByID(), Date_TimeZone::isValidID() - */ - function Date_TimeZone($ps_id) - { - $_DATE_TIMEZONE_DATA =& $GLOBALS['_DATE_TIMEZONE_DATA']; - - if (isset($GLOBALS['_DATE_TIMEZONE_DATA'][$ps_id])) { - $this->id = $ps_id; - - $this->shortname = $_DATE_TIMEZONE_DATA[$ps_id]['shortname']; - $this->longname = $_DATE_TIMEZONE_DATA[$ps_id]['longname']; - $this->offset = $_DATE_TIMEZONE_DATA[$ps_id]['offset']; - $this->dstshortname = - array_key_exists("dstshortname", - $_DATE_TIMEZONE_DATA[$ps_id]) ? - $_DATE_TIMEZONE_DATA[$ps_id]['dstshortname'] : - null; - if ($this->hasdst = !is_null($this->dstshortname)) { - $this->dstlongname = - array_key_exists("dstlongname", - $_DATE_TIMEZONE_DATA[$ps_id]) ? - $_DATE_TIMEZONE_DATA[$ps_id]['dstlongname'] : - null; - if (isset($_DATE_TIMEZONE_DATA[$ps_id]["summertimeoffset"])) { - $this->on_summertimeoffset = $_DATE_TIMEZONE_DATA[$ps_id]["summertimeoffset"]; - $this->on_summertimestartmonth = $_DATE_TIMEZONE_DATA[$ps_id]["summertimestartmonth"]; - $this->os_summertimestartday = $_DATE_TIMEZONE_DATA[$ps_id]["summertimestartday"]; - $this->on_summertimestarttime = $_DATE_TIMEZONE_DATA[$ps_id]["summertimestarttime"]; - $this->on_summertimeendmonth = $_DATE_TIMEZONE_DATA[$ps_id]["summertimeendmonth"]; - $this->os_summertimeendday = $_DATE_TIMEZONE_DATA[$ps_id]["summertimeendday"]; - $this->on_summertimeendtime = $_DATE_TIMEZONE_DATA[$ps_id]["summertimeendtime"]; - } else { - $this->on_summertimeoffset = null; - } - } - } else { - $this->hasdst = false; - - if (preg_match('/^UTC([+\-])([0-9]{2,2}):?([0-5][0-9])$/', - $ps_id, - $ha_matches)) { - $this->id = $ps_id; - $this->offset = ($ha_matches[1] . - ($ha_matches[2] * 3600 + - $ha_matches[3] * 60)) * 1000; - - if (!($hb_isutc = $this->offset == 0)) { - $this->id = $ps_id; - $this->shortname = "UTC" . - $ha_matches[1] . - ($ha_matches[3] == "00" ? - ltrim($ha_matches[2], "0") : - $ha_matches[2] . $ha_matches[3]); - $this->longname = "UTC" . - $ha_matches[1] . - $ha_matches[2] . - ":" . - $ha_matches[3]; - } - } else if (preg_match('/^UTC([+\-])([0-9]{1,2})$/', - $ps_id, - $ha_matches)) { - $this->id = $ps_id; - $this->offset = ($ha_matches[1] . - ($ha_matches[2] * 3600)) * 1000; - - if (!($hb_isutc = $this->offset == 0)) { - $this->shortname = "UTC" . - $ha_matches[1] . - ltrim($ha_matches[2], "0"); - $this->longname = "UTC" . - $ha_matches[1] . - sprintf("%02d", $ha_matches[2]) . - ":00"; - } - } else { - $this->id = "UTC"; - $hb_isutc = true; - } - - if ($hb_isutc) { - $this->shortname = $_DATE_TIMEZONE_DATA["UTC"]['shortname']; - $this->longname = $_DATE_TIMEZONE_DATA["UTC"]['longname']; - $this->offset = $_DATE_TIMEZONE_DATA["UTC"]['offset']; - } - } - } - - - // }}} - // {{{ getDefault() - - /** - * Returns a TimeZone object representing the system default time zone - * - * The system default time zone is initialized during the loading of - * this file. - * - * @return object Date_TimeZone object of the default time zone - * @access public - */ - function getDefault() - { - return new Date_TimeZone($GLOBALS['_DATE_TIMEZONE_DEFAULT']); - } - - - // }}} - // {{{ setDefault() - - /** - * Sets the system default time zone to the time zone in $id - * - * @param string $id the time zone id to use - * - * @return void - * @access public - */ - function setDefault($id) - { - if (Date_TimeZone::isValidID($id)) { - $GLOBALS['_DATE_TIMEZONE_DEFAULT'] = $id; - } else { - return PEAR::raiseError("Invalid time zone ID '$id'"); - } - } - - - // }}} - // {{{ isValidID() - - /** - * Tests if given time zone ID (e.g. 'London/Europe') is valid and unique - * - * Checks if given ID is either represented in the $_DATE_TIMEZONE_DATA - * time zone data, or is a UTC offset in one of the following forms, - * i.e. an offset with no geographical or political base: - * - * UTC[+/-][hh]:[mm] - e.g. UTC+03:00 - * UTC[+/-][hh][mm] - e.g. UTC-0530 - * UTC[+/-][hh] - e.g. UTC+03 - * UTC[+/-][h] - e.g. UTC-1 (the last is not ISO 8601 - * standard but is the preferred - * form) - * - * N.B. these are not sanctioned by any ISO standard, but the form of - * the offset itself, i.e. the part after the characters 'UTC', is the - * ISO 8601 standard form for representing this part. - * - * The form '[+/-][h]' is not ISO conformant, but ISO 8601 only - * defines the form of the time zone offset of a particular time, that - * is, it actually defines the form '