From: Erin S. <ebu...@us...> - 2003-10-24 07:53:42
|
Update of /cvsroot/squirrelmail/smdoc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv13312/lib Added Files: lib.php env.template.php env.foowd.php env.database.php db.mysql.php class.user.php class.text.plain.php class.text.html.php class.object.php class.anonuser.php Log Message: import of FOOWD classes. Some of these are tweaked (marked if so) Trying to keep the changes in these parts minor (use subclasses for more substantial changes so this is easier to keep in sync with the separate project..) --- NEW FILE --- <?php /* Copyright 2003, Paul James This file is part of the Framework for Object Orientated Web Development (Foowd). This file contains some methods from the Smarty templating engine version 2.5.0 by Monte Ohrt <mo...@is...> and Andrei Zmievski <an...@ph...>. Foowd is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Foowd is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Foowd; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* env.template.php Foowd template class */ /** * The Foowd template class. * * Basic template class for capturing values and pluging them into a template. * This class uses a similar API to Smarty. * * @author Paul James * @author Monte Ohrt <mo...@is...> * @author Andrei Zmievski <an...@ph...> * @package Foowd */ class foowd_template { /** * The templates values array * * @var array */ var $values = array(); /** * The template directory to use * * @var str */ var $template_dir = 'templates\default'; /** * Assigns values to template variables * * @param array|string $tpl_var the template variable name(s) * @param mixed $value the value to assign */ function assign($tpl_var, $value = NULL) { if (is_array($tpl_var)){ foreach ($tpl_var as $key => $val) { if ($key != '') { $this->values[$key] = $val; } } } else { if ($tpl_var != '') { $this->values[$tpl_var] = $value; } } } /** * Assigns values to template variables by reference * * @param string $tpl_var the template variable name * @param mixed $value the referenced value to assign */ function assign_by_ref($tpl_var, &$value) { if ($tpl_var != '') { $this->values[$tpl_var] = &$value; } } /** * Appends values to template variables * * @param array|string $tpl_var the template variable name(s) * @param mixed $value the value to append */ function append($tpl_var, $value = NULL, $merge = FALSE) { if (is_array($tpl_var)) { foreach ($tpl_var as $_key => $_val) { if ($_key != '') { if(isset($this->values[$_key]) && !@is_array($this->values[$_key])) { settype($this->values[$_key],'array'); } if($merge && is_array($_val)) { foreach($_val as $_mkey => $_mval) { $this->values[$_key][$_mkey] = $_mval; } } else { $this->values[$_key][] = $_val; } } } } else { if ($tpl_var != '' && isset($value)) { if(isset($this->values[$tpl_var]) && !@is_array($this->values[$tpl_var])) { settype($this->values[$tpl_var],'array'); } if($merge && is_array($value)) { foreach($value as $_mkey => $_mval) { $this->values[$tpl_var][$_mkey] = $_mval; } } else { $this->values[$tpl_var][] = $value; } } } } /** * Appends values to template variables by reference * * @param string $tpl_var the template variable name * @param mixed $value the referenced value to append */ function append_by_ref($tpl_var, &$value, $merge = FALSE) { if ($tpl_var != '' && isset($value)) { if(!@is_array($this->values[$tpl_var])) { settype($this->values[$tpl_var],'array'); } if ($merge && is_array($value)) { foreach($value as $_key => $_val) { $this->values[$tpl_var][$_key] = &$value[$_key]; } } else { $this->values[$tpl_var][] = &$value; } } } /** * Display the template * * @param string $file The template file to use */ function display($file) { $t = &$this->values; // place values array directly in scope include($this->template_dir.$file); } /** * Return the results of applying a template. * * @param string $file The template file to use * @return string A string of the results */ function fetch($file) { ob_start(); $t = &$this->values; // place values array directly in scope include($this->template_dir.$file); $contents = ob_get_contents(); ob_end_clean(); return $contents; } } ?> --- NEW FILE --- <?php /* Copyright 2003, Paul James This file is part of the Framework for Object Orientated Web Development (Foowd). Foowd is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Foowd is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Foowd; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* * Modified by SquirrelMail Development * $Id: env.foowd.php,v 1.1 2003/10/23 05:18:06 ebullient Exp $ */ /* env.foowd.php Foowd environment class */ // check PHP version if (version_compare(phpversion(), '4.2.0', '<')) trigger_error('You need PHP version 4.2.0 or greater to run FOOWD, please upgrade', E_USER_ERROR); // include foowd lib require_once(SM_PATH.'lib.php'); // FOOWD lib // define regex constants setConst('REGEX_ID', '/^[0-9-]{1,11}$/'); setConst('REGEX_TITLE', '/^[a-zA-Z0-9-_ ]{1,32}$/'); setConst('REGEX_PASSWORD', '/^[A-Za-z0-9]{4,32}$/'); setConst('REGEX_DATETIME', '/^[0-9-]{1,10}$/'); setConst('REGEX_EMAIL', '/^[A-Za-z0-9._-]+@[A-Za-z0-9._-]+\.[A-Za-z]{1,4}$/'); setConst('REGEX_GROUP', '/^[a-zA-Z0-9-]{0,32}$/'); /** * The Foowd environment class. * * Sets up the Foowd environment, including database connection, user group * management and user initialisation, and provides methods for accessing * objects within the system. * * @author Paul James * @package Foowd * @version 0.8.4 */ class foowd { /* configuration vars */ /** * Array of foowd configuration settings * * @var array * @access public */ var $config_settings; /* additional settings vars */ /** * The version of this Foowd environment class * * @var str * @access public */ var $version = '0.8.4'; /* foowd object vars */ /** * The database object used in this Foowd environment. * * @var object * @access private */ var $database = FALSE; /** * The user object loaded for this execution cycle. * * @var object * @access private */ var $user = FALSE; /** * The debug object loaded for this Foowd environment. * * @var object * @access private */ var $debug = FALSE; /** * Template object * * @var object * @access private */ var $template = FALSE; /** * Constructs a new environment object. * * @param array $settings Array of settings for this Foowd environment. */ function foowd($settings = NULL) { // store config settings $this->config_settings =& $settings; // create debug object $this->debug = FALSE; if ( $settings['debug']['debug_enabled'] ) { require_once($settings['debug']['debug_path']); $debugClass = $settings['debug']['debug_class']; if ( class_exists($debugClass) ) $this->debug = new $debugClass($this); } $this->track('foowd->constructor'); // create database object require_once($settings['database']['db_path']); $dbClass = $settings['database']['db_class']; if ( !class_exists($dbClass) ) { trigger_error('Can not find database class: ' . $dbClass, E_USER_ERROR); } $this->database = new $dbClass($this); // create template object require_once($settings['template']['template_path']); $tplClass = $settings['template']['template_class']; if ( !class_exists($tplClass) ) { trigger_error('Can not find template class: ' . $tplClass, E_USER_ERROR); } $this->template =& new $tplClass($this); $this->template->template_dir = $settings['template']['template_dir']; $this->template->assign_by_ref('foowd', $this); // load base Foowd class require(FOOWD_DIR.'class.object.php'); // set default user groups if (!isset($this->groups['Everyone'])) $this->groups['Everyone'] = 'Everyone'; if (!isset($this->groups['Author'])) $this->groups['Author'] = 'Author'; if (!isset($this->groups['Gods'])) $this->groups['Gods'] = 'Gods'; if (!isset($this->groups['Nobody'])) $this->groups['Nobody'] = 'Nobody'; if (!isset($this->groups['Registered'])) $this->groups['Registered'] = 'Registered'; // load user require_once($settings['user']['user_path']); require_once($settings['user']['anon_user_path']); $userClass = $settings['user']['user_class']; $anonUserClass = $settings['user']['anon_user_class']; if ( !class_exists($anonUserClass) ) { trigger_error('Can not find anonymous user class: ' . $anonUserClass, E_USER_ERROR); } if ( class_exists($userClass) ) $this->user = call_user_func(array($userClass,'factory'), &$this); else $this->user = new $anonUserClass; $this->track(); } /** * Class destructor. * * Destroys the environment object outputting debugging information and * closing the database connection. */ function destroy() { // destructor, must be called explicitly $this->track('foowd->destructor'); if ($this->database) { // close DB and do database end execution stuff $this->database->destroy($this); } $this->track(); if ($this->debug) { // display debug data $this->debug->display(); } unset($this); // unset object } /** * Debug tracking wrapper. * * Wrapper function to <code>foowd_debug::track</code> * * @param str functionName Name of the function execution is * entering. */ function track($functionName = NULL) { // function call track debug wrapper if ($this->debug) { if (func_num_args() > 1) { $args = func_get_args(); array_shift($args); // shift off $function } else { $args = NULL; } $this->debug->track($functionName, $args); } } /** * Debugging wrapper. * * Wrapper function to <code>foowd_debug::debug</code> * * @param str function Name of the debugging function in <code>foowd_debug</code> to call. */ function debug($function) { // generic debug wrapper if ($this->debug) { if (func_num_args() > 1) { $args = func_get_args(); array_shift($args); // shift off $function } else { $args = NULL; } call_user_func_array(array(&$this->debug, $function), $args); } } /** * Get name of template for the given class and method. If a template does * not exist for the particular class and method, we look for a template for * the classes parent class until we either find a template or reach the base * class. In which case we use load default template "default.tpl". * * @param str className Name of the class. * @param str methodName Name of the method. */ function getTemplateName($className, $methodName) { $templateFilename = $className.'.'.$methodName.'.tpl'; while (!file_exists($this->template->template_dir.$templateFilename)) { if ($className == FALSE) { trigger_error('Could not load template "'.$this->template_dir.$templateFilename.'"', E_USER_ERROR); return; } elseif ($className == 'foowd_object') { $className = FALSE; $templateFilename = 'default.tpl'; } else { $className = get_parent_class($className); $templateFilename = $className.'.'.$methodName.'.tpl'; } } return $templateFilename; } /** * Get the current user from the database. * * Given the array of user details, fetch the corrisponding user object from * the database, unserialise and return it. * * @access private * @param str class The name of the user class being used. * @param str username The name of the user to fetch. * @param str password The password of the user to fetch * @return mixed The selected user object or FALSE on failure. */ function fetchUser($class = NULL, $username = NULL, $password = NULL) { // fetches a user into $this->user, should only be used by Foowd constructor, fetch users as objects using fetchObject() if required $this->track('foowd->fetchUser', $class, $username, $password); if (isset($username) && $username != NULL) { $userid = crc32(strtolower($username)); // generate user ID from given username $classid = crc32(strtolower($class)); // generate class ID of user class } if (isset($userid) && isset($classid)) { // load user from DB if ($user = &$this->getObj(array('objectid' => $userid, 'classid' => $classid))) { if (isset($password) && $password != NULL && $user->passwordCheck($password) && $user->hostmaskCheck()) { // password and hostmask match, user is valid $this->user = &$user; if ($user->updated < time() - $this->session_length) { // session start $this->debug('msg', 'Starting new user session'); if (function_exists('foowd_session_start')) { // call session start foowd_session_start($this); } if (method_exists($this->user, 'session_start')) { // call user session start $this->user->session_start(); } $this->user->update(); // update user } else { $this->debug('msg', $this->session_length - (time() - $user->updated).' seconds left in current user session'); } $this->track(); return TRUE; } else { $this->debug('msg', 'Password incorrect for user'); } } else { $this->debug('msg', 'Could not find user in database'); } } else { // create anonymous user object if (class_exists($this->anonuser_class)) { $this->user = &new $this->anonuser_class($this); } else { trigger_error('Could not find anonymous user class "'.$this->anonuser_class.'".', E_USER_ERROR); } } $this->track(); return FALSE; } /** * Fetch one version of an object. * * @param array indexes Array of indexes and values to match * @param str source Source to get object from * @return object The selected object or NULL on failure. * @see foowd_db::getObj */ function &getObj($indexes, $joins = NULL, $source = NULL) { $this->track('foowd->getObj', $indexes); if ($object = &$this->database->getObj($indexes, $joins, $source)) { // get object $this->track(); return $object; } elseif (isset($indexes['workspaceid']) && $indexes['workspaceid'] != 0) { // if not already looking in main workspace $indexes['workspaceid'] = 0; $this->track(); return $this->getObj($indexes); // WARNING: recursion in action } else { $this->track(); return NULL; } } /** * Get all versions of an object. * * @param array indexes Array of indexes and values to match * @param str source Source to get object from * @return array The array of selected objects or NULL on failure. * @see foowd::getObjHistory */ function &getObjHistory($indexes, $source = NULL) { $this->track('foowd->getObjHistory', $indexes); if ($objects = &$this->database->getObjHistory($indexes, $source)) { // get object history $this->track(); return $objects; } elseif (isset($indexes['workspaceid']) && $indexes['workspaceid'] != 0) { // if not already looking in main workspace $indexes['workspaceid'] = 0; $this->track(); return $this->getObjHistory($indexes); // WARNING: recursion in action } else { $this->track(); return NULL; } } /** * Get a list of objects. * * @param array indexes Array of indexes and values to match * @param str source Source to get object from * @param str order The index to sort the list on * @param bool reverse Display the list in reverse order * @param int offset Offset the list by this many items * @param int number The length of the list to return * @param bool returnObjects Return the actual objects not just the object meta data * @return array The array of selected objects or NULL on failure. * @see foowd::getObjList */ function &getObjList($indexes, $source = NULL, $order = NULL, $reverse = NULL, $offset = NULL, $number = NULL, $returnObjects = FALSE) { $this->track('foowd->getObjList', $indexes); if ($objects = &$this->database->getObjList($indexes, $source, $order, $reverse, $offset, $number, $returnObjects)) { $this->track(); return $objects; } else { $this->track(); return NULL; } } /** * Call class/object method. * * Wrapper function for <code>foowd_object::method</code> and * <code>foowd_object::classMethod</code>. Checks if parameter is a class * name or an object * * @param mixed classNameOrObject The name of the class or object to call the method upon. * @param str methodName The method to call upon the object. * @return mixed The array results of the method call or an error string. */ function method(&$classNameOrObject, $methodName = NULL) { $this->track('foowd->method', $methodName); if (is_string($classNameOrObject)) { if (class_exists($classNameOrObject) || $this->loadClass(crc32(strtolower($classNameOrObject)))) { // check class exists (if it doesn't, try to load it from DB) $this->track(); return call_user_func(array($classNameOrObject, 'classMethod'), &$this, $classNameOrObject, $methodName); // call method } else { trigger_error('Class "'.$classNameOrObject.'" does not exist'); $this->track(); return FALSE; } } elseif (is_object($classNameOrObject)) { $this->track(); return $classNameOrObject->method($methodName); } else { trigger_error('Class/object not specified'); $this->track(); return FALSE; } } /** * Get user groups. * * Return an array of all user groups the current user has access to. * * @param bool includeSpecialGroups Return special groups as well? * @return array An array of user groups. */ function getUserGroups($includeSpecialGroups = TRUE) { $items = array(); // add custom groups foreach ($this->groups as $group => $name) { if ($this->user->inGroup($group)) { $items[$group] = $name; } } // add foowd_group groups if (class_exists($this->group_class)) { $userGroups = $this->getObjList( array('classid' => crc32(strtolower($this->group_class))), NULL, array('title'), NULL, 0, NULL, TRUE ); if ($userGroups) { foreach ($userGroups as $userGroup) { if ($this->user->inGroup($userGroup->objectid)) { $items[$userGroup->objectid] = $userGroup->getTitle(); } } } } if (!$includeSpecialGroups) { // remove special groups unset($items['Everyone']); unset($items['Nobody']); unset($items['Registered']); } ksort($items); return $items; } /** * Unserialise object. * * Unserialise a serialised object loading any classes that are required. * * @param str serializedObj Serialised object to unserialise. * @param int classid Classid of the object to be unserialised. * @return object The unserialised object. */ function unserialize($serializedObj, $classid = NULL) { $this->track('foowd->unserialize', $classid); if (!classLoaded($classid)) { // class definition not found, load $this->loadClass($classid); } $this->track(); return unserialize($serializedObj); } /** * Load dynamic class. * * Load a class definition from an object within the database. * * @access private * @param int classid Classid of the class to be loaded. * @return bool Success or failure. */ function loadClass($classid) { $this->track('foowd->loadClass', $classid); if ( isset($this->config_settings['site']['definition_class']) && class_exists($this->config_settings['site']['definition_class']) ) { $class = $this->getObj(array('objectid' => $classid, 'classid' => crc32(strtolower($this->definition_class)))); if (is_object($class)) { // if it inherits from another class, find out and load it now if (preg_match_all('|class ([-_a-zA-Z0-9]*) extends ([-_a-zA-Z0-9]*) ?{|', $class->body, $pregMatches)) { // i'd rather do this with catching errors on the eval, but that can't be done if ($pregMatches[1] != $pregMatches[2]) { foreach($pregMatches[2] as $className) { if ($className != $class->title && !class_exists($className)) { $this->loadClass(crc32(strtolower($className))); // WARNING: recursion in action } } } } // define class setClassMeta($class->title, $class->description); if (eval($class->body) === FALSE) { $this->track(); return FALSE; } else { $this->track(); return TRUE; } } } else { $this->debug('msg', 'Unknown object type found, dynamic classes not active, failing to load class definition for object'); } $this->track(); } /** * Load default class. * * Create a child of foowd_object for the given class name so that objects of * that type can be loaded without their original class definition. * * @static * @param str className Name of the class to load. */ function loadDefaultClass($className) { // load an incomplete class, it is just a foowd_object clone to enable loading of objects whose class definitions can not be found. setClassMeta($className, _("Unknown Foowd Class")); eval('class '.$className.' extends foowd_object {}'); } } // set unserialize callback function ini_set('unserialize_callback_func', 'unserializeCallback'); function unserializeCallback($className) { foowd::loadDefaultClass($className); } ?> --- NEW FILE --- <?php /* Copyright 2003, Paul James This file is part of the Framework for Object Orientated Web Development (Foowd). Foowd is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Foowd is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Foowd; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* * Modified by SquirrelMail Development * $Id: env.database.php,v 1.1 2003/10/23 05:18:06 ebullient Exp $ */ /* env.database.php Foowd database base object */ /** * The Foowd abstract database class. * * Abstract class for storage abstraction layer, handles storage connection * and querying in a non-implementation specific way. * * @author Paul James * @abstract * @package Foowd/DB */ class foowd_db { /** * The database connect resource. * * @var resource */ var $conn; /** * The date/time format used by this storage medium. This string should be * a PHP date function compatible date/time formatting string. * * @var str */ var $dateTimeFormat = 'Y-m-d H:i:s'; /** * An array of references to all objects loaded from this database. * * @var array */ var $objects = array(); /** * Reference to the Foowd object. * * @var object */ var $foowd; /** * Constructs a new storage object. * * @abstract * @param object foowd The foowd environment object. */ function foowd_db(&$foowd) { trigger_error('This is an abstract class and can not be instanciated.', E_USER_ERROR); } /** * Destructs the storage object. */ function destroy() { $this->foowd->track('foowd_db->destructor'); foreach ($this->objects as $object) { //show($object); if (isset($object->foowd_changed) && $object->foowd_changed) { if ($object->objectid == 0) { $this->foowd->debug('msg', 'Deleting object '.$object->objectid); $result = $object->delete(); if ($result == 0) { trigger_error('Could not delete object '.$object->objectid); } } else { $this->foowd->debug('msg', 'Saving object '.$object->objectid); $result = $object->save(); if ($result == 0) { trigger_error('Could not save object '.$object->objectid); } } } } $this->foowd->track(); } /** * Execute query * * @abstract * @access protected * @param str query The query to execute * @return resource The resulting query resource */ function query($query) { return FALSE; } /** * Escape a string for use in SQL string * * @abstract * @access protected * @param str str String to escape * @return str The escaped string */ function escape($str) { return FALSE; } /** * Add an object reference to the loaded objects array. * * @access protected * @param array indexes Array of indexes and values to find object by * @param object object Reference of the object to add */ function addToLoadedReference(&$object) { $this->objects[$object->objectid.'_'.$object->classid.'_'.$object->version.'_'.$object->workspaceid] = &$object; } /** * Check if an object is referenced in the object reference array. * * @access protected * @param array indexes Array of indexes and values to find object by */ function &checkLoadedReference($indexes) { $hash = $this->createHashFromIndexes($indexes); if (isset($this->objects[$hash])) { $this->foowd->debug('msg', 'Using exising loaded reference'); return $this->objects[$hash]; } else { return FALSE; } } /** * Create a unique hash to store the object reference under. * * @access protected * @param array indexes Array of indexes and values to find object by */ function createHashFromIndexes($indexes) { if ( isset($indexes['objectid']) && isset($indexes['classid']) && isset($indexes['version']) && isset($indexes['workspaceid']) ) { return $indexes['objectid'].'_'.$indexes['classid'].'_'.$indexes['version'].'_'.$indexes['workspaceid']; } return FALSE; } /** * Build where clause from indexes array. * * @access protected * @param array indexes Array of indexes and values to find object by * @param str conjuction Operand to use to join the elements of the clause * @return str The generated where clause. */ function buildWhere($indexes, $conjuction = 'AND') { $where = ''; foreach ($indexes as $key => $index) { if ($conjuction === 'OR') { $where .= ' OR'; } else { $where .= 'AND'; } if (!is_array($index)) { if (isset($index)) { if (is_numeric($index)) { $where .= ' '.$key.' = '.$index.' '; } else { $where .= ' '.$key.' = \''.$index.'\' '; } } else { $where = substr($where, 0, -3); } } elseif (!isset($index['index'])) { $where .= $this->buildWhere($index, $key); } else { if (!isset($index['op'])) { $index['op'] = '='; } elseif ($index['op'] == '!=') { $index['op'] = '<>'; } if (!isset($index['value'])) { trigger_error('No value given for index "'.$index['index'].'".'); $index['value'] = ''; } if (is_numeric($index['value'])) { $where .= ' '.$index['index'].' '.$index['op'].' '.$index['value'].' '; } else { $where .= ' '.$index['index'].' '.$index['op'].' \''.$index['value'].'\' '; } } } return ' ('.substr($where, 3).') '; } /** * Add workspaceid index to index array if one does not exist at the top level. * * @access protected * @param array indexes Array of indexes and values to find object by */ function setWorkspace(&$indexes) { $found = FALSE; if (is_array($indexes)) { foreach($indexes as $key => $index) { if (is_array($index) && isset($index['index']) && $index['index'] == 'workspaceid') { $found = TRUE; } elseif ($key == 'workspaceid') { $found = TRUE; } } } if (!$found) { $workspaceid['index'] = 'workspaceid'; $workspaceid['op'] = '='; if (isset($this->foowd->user->workspaceid)) { $workspaceid['value'] = $this->foowd->user->workspaceid; } else { $workspaceid['value'] = 0; } $indexes[] = $workspaceid; } } /** * Get lastest version of an object. * * @param array indexes Array of indexes and values to find object by * @param array joins Array of sources and indexes of objects to also fetch based upon indexes of first object * @param str source The source to fetch the object from * @return mixed The retrieved object or an array containing the retrieved object and the joined objects. */ function &getObj($indexes, $joins = NULL, $source = NULL) { $this->foowd->track('foowd_db->getObj'); // set workspace $this->setWorkspace($indexes); // check previously loaded object reference if ($object = &$this->checkLoadedReference($indexes)) { return $object; } // set source if (!isset($source)) { $source = $this->foowd->config_settings['database']['db_table']; } // build joins $join = ''; $fields = ''; $orderby = ''; if (is_array($joins)) { $foo = 0; $table = array(); foreach ($joins as $table => $index) { if (is_numeric($table)) { $table[$foo] = $source; } $join .= ' LEFT JOIN '.$table[$foo].' AS join'.$foo.' ON '.$source.'.'.$index[0].' = join'.$foo.'.'.$index[1]; $fields .= ', join'.$foo.'.object AS object'.$foo.', join'.$foo.'.classid AS classid'.$foo; $orderby .= ', join'.$foo.'.version DESC'; $foo++; } } if (isset($indexes['version']) && $indexes['version'] == 0) { unset($indexes['version']); } // build where $where = ' WHERE'.$this->buildWhere($indexes); // build query $select = 'SELECT '.$source.'.object AS object, '.$source.'.classid AS classid'.$fields.' FROM '.$source.$join.$where.' ORDER BY '.$source.'.version DESC'.$orderby.' LIMIT 1'; if ($query = $this->query($select)) { if ($result = $this->fetch($query)) { if (is_array($joins)) { $return = array(); $return['object'] = $this->foowd->unserialize($result['object'], $result['classid']); $max = count($joins); for($foo = 0; $foo < $max; $foo++) { if (isset($result['object'.$foo])) { $return['join'.$foo] = $this->foowd->unserialize($result['object'.$foo], $result['classid'.$foo]); $return['join'.$foo]->foowd_source = $table[$foo]; } else { $return['join'.$foo] = FALSE; } } $this->foowd->track(); return $return; } else { $object = $this->foowd->unserialize($result['object'], $result['classid']); $object->foowd = &$this->foowd; // create Foowd reference $object->foowd_source = $source; // set source for object $this->addToLoadedReference($object); $this->foowd->track(); return $object; } } else { $this->foowd->track(); return FALSE; } } else { $this->foowd->track(); return FALSE; } } /** * Get an object. * * @param array indexes Array of indexes and values to find object by * @param str source The source to fetch the object from * @return array An array of the retrieved object versions indexed by version number. */ function &getObjHistory($indexes, $source = NULL) { $this->foowd->track('foowd_db->getObjHistory'); // set source if (!isset($source)) { $source = $this->foowd->config_settings['database']['db_table']; } // set workspace $this->setWorkspace($indexes); // build where $where = ' WHERE'.$this->buildWhere($indexes); // build select $select = 'SELECT '.$source.'.object AS object, '.$source.'.classid AS classid, '.$source.'.version AS version FROM '.$source.$where.' ORDER BY '.$source.'.version'; if ($query = $this->query($select)) { if ($this->num_rows($query) > 0) { $return = array(); $latest = 0; while ($record = $this->fetch($query)) { $return[$record['version']] = $this->foowd->unserialize($record['object']. $record['classid']); $return[$record['version']]->foowd = &$this->foowd; // create Foowd reference $return[$record['version']]->foowd_source = $source; $this->addToLoadedReference($return[$record['version']]); if ($record['version'] > $latest) { $latest = $record['version']; } } $return[0] = &$return[$latest]; // set reference on index zero to latest version $this->foowd->track(); return $return; } else { $this->foowd->track(); return FALSE; } } else { $this->foowd->track(); return FALSE; } } /** * Get a list of objects. * * @param array indexes Array of indexes and values to find object by * @param str source The source to fetch the object from * @param array order The index to sort the list on * @param bool reverse Display the list in reverse order * @param int offset Offset the list by this many items * @param int number The length of the list to return * @param bool returnObjects Return the actual objects not just the object meta data * @return array An array of object meta data or of objects. */ function &getObjList($indexes, $source = NULL, $order = NULL, $reverse = NULL, $offset = NULL, $number = NULL, $returnObjects = FALSE) { $this->foowd->track('foowd_db->getObjList'); // set source if (!isset($source)) { $source = $this->foowd->config_settings['database']['db_table']; } // set workspace $this->setWorkspace($indexes); // build where $where = ' WHERE'.$this->buildWhere($indexes); // build order if (isset($order)) { if (is_array($order)) { $order = ' ORDER BY '.join(', ', $order); } else { $order = ' ORDER BY '.$order; } if (isset($reverse) && !$reverse) { $order .= ' DESC'; } } else { $order = ''; } // build limit if (isset($number)) { $limit = ' LIMIT '; if (isset($offset)) { $limit .= $offset.', '; } $limit .= $number; } else { $limit = ''; } $select = 'SELECT '.$source.'.objectid AS objectid, '.$source.'.classid AS classid, '.$source.'.version AS version, '.$source.'.workspaceid AS workspaceid, '.$source.'.title AS title, '.$source.'.object AS object FROM '.$source.$where.$order.$limit; if ($query = $this->query($select)) { if ($this->num_rows($query) > 0) { $return = array(); while ($record = $this->fetch($query)) { if (!isset($return[$record['objectid']]) || $record['version'] > $return[$record['objectid']]['version']) { if ($returnObjects) { $return[$record['objectid']] = $this->foowd->unserialize($record['object']. $record['classid']); $return[$record['objectid']]->foowd = &$this->foowd; // create Foowd reference $return[$record['objectid']]->source = $source; $this->addToLoadedReference($return[$record['objectid']]); } else { $return[$record['objectid']] = array( 'objectid' => $record['objectid'], 'classid' => $record['classid'], 'version' => $record['version'], 'workspaceid' => $record['workspaceid'], 'title' => $record['title'] ); } } } $this->foowd->track(); return $return; } else { $this->foowd->track(); return FALSE; } } else { $this->foowd->track(); return FALSE; } } /** * Save an object. * * @param object object The object to save * @return bool Success or failure. */ function save(&$object) { $this->foowd->track('foowd_db->save'); if (!isset($object->foowd_update) || $object->foowd_update) { $object->update(); // update object meta data } $serializedObj = serialize($object); if (isset($object->foowd_source)) { $source = $object->foowd_source; } else { $source = $this->foowd->config_settings['database']['db_table']; } // build field array from object indexes $fieldArray['object'] = $serializedObj; foreach ($object->foowd_indexes as $index => $definition) { if (isset($object->$index)) { if ($object->$index == FALSE) { $fieldArray[$index] = 0; } else { $fieldArray[$index] = $object->$index; } } } // build where $where = ' WHERE objectid = '.$object->foowd_original_access_vars['objectid'] .' AND version = '.$object->foowd_original_access_vars['version'] .' AND classid = '.$object->foowd_original_access_vars['classid'] .' AND workspaceid = '.$object->foowd_original_access_vars['workspaceid']; // build update query $update = 'UPDATE '.$source.' SET '; $foo = FALSE; foreach($fieldArray as $field => $value) { if ($foo) { $update .= ', '; } if (isset($object->foowd_indexes[$field]['type']) && $object->foowd_indexes[$field]['type'] == 'INT') { $update .= $field.' = '.$value; } elseif (isset($object->foowd_indexes[$field]['type']) && $object->foowd_indexes[$field]['type'] == 'DATETIME') { $update .= $field.' = \''.date($this->dateTimeFormat, $value).'\''; } else { $update .= $field.' = \''.$this->escape($value).'\''; } $foo = TRUE; } $update .= $where; // build insert query $insert = 'INSERT INTO '.$source.' ('; $values = ''; $foo = FALSE; foreach($fieldArray as $field => $value) { if ($foo) { $insert .= ', '; $values .= ', '; } $insert .= $field; if (isset($object->foowd_indexes[$field]['type']) && $object->foowd_indexes[$field]['type'] == 'INT') { $values .= $value; } elseif (isset($object->foowd_indexes[$field]['type']) && $object->foowd_indexes[$field]['type'] == 'DATETIME') { $values .= '\''.date($this->dateTimeFormat, $value).'\''; } else { $values .= '\''.$this->escape($value).'\''; } $foo = TRUE; } $insert .= ') VALUES ('.$values.')'; $saveResult = 0; // try to update existing record $result = $this->query($update); if ($this->query_success($result)) { $saveResult = 1; } else { // if fail, write new record $result = $this->query($insert); if ($this->query_success($result)) { $saveResult = 2; } else { // if fail, modify table to include indexes from class definition if ($this->alterTable($source, $fieldArray)) { $result = $this->query($update); if ($this->query_success($result)) { $saveResult = 3; } else { $result = $this->query($insert); if ($this->query_success($result)) { $saveResult = 4; } } } } } // tidy old archived versions if ($saveResult && $object->updated < time() - $this->foowd->tidy_delay) { $this->tidy($object); } $this->foowd->track(); return $saveResult; } /** * Delete an object (and all archive versions). * * @param object object The object to delete * @return bool Success or failure. */ function delete(&$object) { $this->foowd->track('foowd_db->delete'); if (isset($object->foowd_source)) { $source = $object->foowd_source; } else { $source = $this->foowd->config_settings['database']['db_table']; } // build delete $delete = 'DELETE FROM '.$source .' WHERE objectid = '.$object->foowd_original_access_vars['objectid'] .' AND classid = '.$object->foowd_original_access_vars['classid'] .' AND workspaceid = '.$object->foowd_original_access_vars['workspaceid']; if ($this->query($delete)) { $this->foowd->track(); return TRUE; } else { $this->foowd->track(); return FALSE; } } /** * Tidy an objects archived versions. * * @param object object The object to delete * @return bool Success or failure. */ function tidy(&$object) { $this->foowd->track('foowd_db->tidy'); if (isset($object->foowd_source)) { $source = $object->foowd_source; } else { $source = $this->foowd->config_settings['database']['db_table']; } // build delete $delete = 'DELETE FROM '.$source .' WHERE objectid = '.$object->foowd_original_access_vars['objectid'] .' AND classid = '.$object->foowd_original_access_vars['classid'] .' AND workspaceid = '.$object->foowd_original_access_vars['workspaceid'] .' AND version < '.($object->foowd_original_access_vars['version'] - $this->foowd->minimum_number_of_archived_versions) .' AND updated < \''.date($this->foowd->database->dateTimeFormat, strtotime($this->foowd->destroy_older_than)).'\''; if ($this->query($delete)) { $this->foowd->track(); return TRUE; } else { $this->foowd->track(); return FALSE; } } /** * Get the fields for this table. If it fails, this method presumes that that * is because the table does not exist, so tries to create it. * * @access protected * @return array Array of field names */ function getFields($table) { if ($query = $this->query('SELECT * FROM '.$table.' LIMIT 1')) { $return = array(); if ($record = $this->fetch($query)) { foreach ($record as $field => $value) { if (!is_numeric($field)) { $return[] = $field; } } return $return; } } else { // failed to get current table structure, so maybe it doesn't exist so try and make it $this->query('CREATE TABLE '.$table.' ( \'objectid\' int(11) NOT NULL default \'0\', \'version\' int(10) unsigned NOT NULL default \'1\', \'classid\' int(11) NOT NULL default \'0\', \'workspaceid\' int(11) NOT NULL default \'0\', \'object\' longblob, \'title\' varchar(255) NOT NULL default \'\', \'updated\' datetime NOT NULL default \'0000-00-00 00:00:00\', PRIMARY KEY (\'objectid\',\'version\',\'classid\',\'workspaceid\'), KEY \'idxtblObjectTitle\'(\'title\'), KEY \'idxtblObjectupdated\'(\'updated\'), KEY \'idxtblObjectObjectid\'(\'objectid\'), KEY \'idxtblObjectClassid\'(\'classid\'), KEY \'idxtblObjectVersion\'(\'version\'), KEY \'idxtblObjectWorkspaceid\'(\'workspaceid\') )'); } return array( 'objectid' => NULL, 'version' => NULL, 'classid' => NULL, 'workspaceid' => NULL, 'object' => NULL, 'title' => NULL, 'updated' => NULL ); } /** * Do a SQL ALTER TABLE statement. * * @access protected * @param str table The source table to alter * @param array fieldArray An array of column clause elements. * @return bool TRUE on success. */ function alterTable($table, $fieldArray) { if ($fields = $this->getFields($table)) { $missingFields = array(); foreach ($fieldArray as $field => $value) { if (!in_array($field, $fields) && $field != 'object') { $missingFields[] = $object->foowd_indexes[$field]; } } if (isset($missingFields) && is_array($missingFields)) { $SQLString = 'ALTER TABLE '.$table.' ADD COLUMN ('; $PrimaryKeyString = ''; $indexes = array(); foreach($missingFields as $column) { if ($column['name'] != '' && $column['type'] != '') { $SQLString .= $column['name'].' '.$this->dataTypes[$column['type']]; if (isset($column['length']) && is_numeric($column['length'])) $SQLString .= '('.$column['length'].')'; if (isset($column['notnull']) && $column['notnull']) { $SQLString .= ' '.$this->keywords['notnull']; } if (isset($column['default']) && is_numeric($column['default'])) { $SQLString .= ' '.$this->keywords['default'].' '.$column['default']; } elseif (isset($column['default'])) { $SQLString .= ' '.$this->keywords['default'].' "'.$column['default'].'"'; } if (isset($column['identity']) && $column['identity']) { $SQLString .= ' '.$this->keywords['identity']; } if (isset($column['primary']) && $column['primary']) { $PrimaryKeyString .= $column['name'].', '; if (!isset($column['notnull'])) { $SQLString .= ' '.$this->keywords['notnull']; } } if (isset($column['index'])) { $indexes[] = $column['index']; } $SQLString .= ', '; } } if ($PrimaryKeyString != '') { $PrimaryKeyString = 'PRIMARY KEY ('.substr($PrimaryKeyString, 0, -2).'), '; $SQLString .= $PrimaryKeyString; } $SQLString = substr($SQLString, 0, -2); $SQLString .= ')'; if ($this->query($SQLString)) { if (count($indexes) > 0) { // there are indexes to create foreach ($indexes as $column) { $this->createIndex($table, $column); } } return TRUE; } } } return FALSE; } /** * Do a SQL CREATE INDEX statement. * * @access protected * @param str table The source table to create * @param str column The column to add the index on. * @return bool TRUE on success. */ function createIndex($table, $column) { if ($this->query('CREATE INDEX idx'.$table.$column.' ON '.$table.' ('.$column.')')) { return TRUE; } else { return FALSE; } } } ?> --- NEW FILE --- <?php /* * Modified by SquirrelMail Development * $Id: class.anonuser.php,v 1.1 2003/10/23 05:18:06 ebullient Exp $ */ /** * Anonymous user class. * * Used to instanciate bogus user for anoymous access where only basic user * data is required and it would be a waste to pull a user from the database. * This is here rather than in class.user.php since it is possible to use * foowd without class.user.php and just with the anonymous user if you don't * need users. * * @author Paul James */ class foowd_anonuser extends foowd_object { /** * Constructs a new anonymous user. * * @param object foowd The foowd environment object. */ function foowd_anonuser(&$foowd) { $foowd->track('foowd_anonuser->constructor'); $this->title = $foowd->config_settings['user']['anon_user_name']; $this->objectid = NULL; $this->version = 1; $this->classid = -1063205124; $this->workspaceid = 0; $this->created = time(); $this->creatorid = 0; $this->creatorName = 'System'; $this->updated = time(); $this->updatorid = 0; $this->updatorName = 'System'; $this->email = NULL; $this->permissions = NULL; $this->foowd = &$foowd; $foowd->track(); } /** * Whether the anonymous user is in a user group. * * @param str groupName Name of the group to check. * @return bool TRUE or FALSE. */ function inGroup($groupName, $creatorid = NULL) { if ($groupName == 'Everyone') { return TRUE; } elseif ($this->foowd->config_settings['user']['anon_user_god']) { return TRUE; } else { return FALSE; } } /** * Returns true if user has permission * * @param str className Name of the class the method belongs to. * @param str methodName Name of the method. * @param string type class/object method * @param object objectReference to current object being checked (may be NULL) * @return bool TRUE if user has access to method */ function hasPermission($className,$methodName,$type,&$object) { $creatorid = NULL; if ( isset($object) ) { if ( isset($object->permissions[$methodName]) ) $methodPermission = $object->permissions[$methodName]; } if ( !isset($methodPermission) ) $methodPermission = getPermission($className, $methodName, $type); return $this->inGroup($methodPermission, $creatorid); } /** * Check the string is the users password. * * @param str password The password to check. * @param bool plainText The password is in plain text rather than an md5 hash. * @return bool Always returns TRUE. */ function passwordCheck($password, $plainText = FALSE) { // there is no password for the anonymous user, so it must always match return TRUE; } /** * Check if the user is the anonymous user. * * @return bool Always returns TRUE. */ function isAnonymous() { // yes this is the anonymous user, so we must be anonymous return TRUE; } /** * Override {@link foowd_object#save} to stop this object from being saved. * * @return bool Always returns FALSE. */ function save() { // override save function since it should never be written to the database and is just instanciated as needed. return FALSE; } } ?> |