Location: PHPKode > scripts > SPL and Iterators > spl-and-iterators/users/class.oUser.php
<?php
/**
 * oUser package
 * @author Johan Barbier <hide@address.com>
 * @version 20061124
 */
if (!class_exists ('RecursiveArrayIterator')) { // PHP5 < 5.1
	/**
	 * class RecursiveArrayIterator
	 * @author php.net
	 * implementation for PHP5 < 5.1
	 */
	class RecursiveArrayIterator extends ArrayIterator implements RecursiveIterator {

		private $ref;

		function hasChildren () {
			return is_array ($this -> current ());
		}

		function getChildren () {
			if ($this -> current () instanceof self) {
				return $this -> current ();
			}
			if (empty ($this -> ref)) {
				$this -> ref = new ReflectionClass ($this);
			}
			return $this -> ref -> newInstance ($this -> current ());
		}
	}
}

/**
 * class oUserException extends Exception
 * personalized Exception class for this package
 * @author Johan Barbier <hide@address.com>
 * @version 20061124
 */
class oUserException extends Exception {

	const ERROR_GEN_NOT_SETABLE = '{__PROP__} is not a setable property';
	const ERROR_GEN_NOT_GETABLE = '{__PROP__} is not a getable property';

	const ERROR_USER_PROP_NOT_EXISTS = '{__PROP__} property does not exist';
	const ERROR_USER_PROP_HAS_NO_VALUE = '{__PROP__} property has no value';
	const ERROR_USER_XML_KEY_NOT_COMPLETE = '{__KEY__} has no children';
	const ERROR_USER_XML_FILE_NOT_EXISTS = '{__FILE__} has not been found';
	const ERROR_USER_XML_LOADING_FAILED = 'Failed to load {__FILE__}';
	const ERROR_USER_CHECKIDENT_BAD_VALUES_COUNT = 'Values given in arguments and Authentication fields do not match';
	const ERROR_USER_MANDATORY_FIELD_MISSING = 'The mandatory field {__FIELD__} is missing';
	const ERROR_USER_ID_NOT_INTEGER = 'User ID must be an integer';

	public function __construct($sMsg, $iCode = 0) {
		parent::__construct($sMsg, $iCode);
	}
}

/**
 * class myFilter extends FilterIterator
 * filter Iterator class dedicated to oUser class
 * @author Johan Barbier <hide@address.com>
 * @version 20061124
 */
class myFilter extends FilterIterator  {

	/**
	 * private oIt
	 * Iterator object
	 * @var Iterator
	 */
	private $oIt = null;

	/**
	 * private mFilter
	 * main filter
	 * @var string
	 */
	private $mFilter = null;

	/**
	 * public function __construct
	 * constructor
	 *
	 * @param (RecursiveIteratorIterator) oIt
	 * @param (string) mFilter
	 */
    public function __construct (RecursiveIteratorIterator $oIt, $mFilter = null) {
        parent::__construct ($oIt);
        $this -> oIt = $oIt;
        $this -> mFilter = $mFilter;
    }

    /**
     * public function accept
     *
     * @return (boolean)
     */
    public function accept () {
        if (!is_null ($this -> mFilter)) {
        	if ($this -> oIt -> key () === $this -> mFilter && $this -> oIt -> getDepth () === 0) {
        		return true;
        	}
        	if ($this -> oIt -> key () === $this -> mFilter && $this -> oIt -> getDepth () === 1) {
				return true;
        	}
        	if ($this -> oIt -> getDepth () > 0 && $this -> oIt -> getSubIterator (0) -> key () === $this -> mFilter) {
				return true;
        	}
        	return false;
        }
        return true;
    }

}

/**
 * abstract class abstractUser
 * abstraction class defining oUser
 * @author Johan Barbier <hide@address.com>
 * @version 20061124
 */
abstract class abstractUser {

	/**
	 * protected aCanBeGet
	 * array of properties that can be get
	 * @var array
	 */
	protected $aCanBeGet = array (
	'FILTER',
	'SUBFILTER',
	'ITMODE'
	);

	/**
	 * protected aCanBeSet
	 * array of properties that can be set
	 * @var array
	 */
	protected $aCanBeSet = array (
	'FILTER',
	'SUBFILTER',
	'ITMODE'
	);

	/**
	 * protected cItMode
	 * RecursiveIteratorIterator mode
	 * @var RecursiveIteratorIterator constant
	 */
	protected $cItMode = true;

	/**
	 * protected mFilter
	 * main filter
	 * @var string
	 */
	protected $mFilter = null;

	/**
	 * protected aProps
	 * array of properties
	 * @var array
	 */
	protected $aProps = array ();

	/**
	 * public oSession
	 * oSession object
	 * @var oSession
	 */
	public $oSession = null;

	/**
	 * protected oXml
	 * simpleXML object
	 * @var simpleXML
	 */
	protected $oXml = null;

	/**
	 * public function __construct
	 * constructor
	 * @param (string) $fXml : xml config filename
	 */
	public function __construct ($fXml) {
		if (!file_exists ($fXml)) {
			throw new oUserException (str_replace ('{__FILE__}', $fXml, oUserException::ERROR_USER_XML_FILE_NOT_EXISTS));
		}
		if (!($this -> oXml = @simplexml_load_file ($fXml)) instanceof SimpleXMLElement) {
			throw new oUserException (str_replace ('{__FILE__}', $fXml, oUserException::ERROR_USER_XML_LOADING_FAILED));
		}
		$this -> oSession = new oSession ($this -> oXml);
		$this -> aPropsFill ();
	}

	/**
	 * private function aPropsFill
	 * fills the array of properties aProps from oXml
	 */
	private function aPropsFill () {
		foreach ($this -> oXml -> USER -> children () as $oNode) {
			$aTmp = array ();
			foreach ($oNode -> children() as $oChild) {
				$aTmp[(string)dom_import_simplexml($oChild) -> tagName] = (string)$oChild['value'];
			}
			if (empty ($aTmp)) {
				throw new oUserException (str_replace ('{__KEY__}', (string)dom_import_simplexml($oNode) -> tagName, self::ERROR_XML_KEY_NOT_COMPLETE));
			}
			$this -> aProps[(string)dom_import_simplexml($oNode) -> tagName] = $aTmp;
		}
	}

	/**
	 * public function __get
	 * getter
	 * @param (string) sProp
	 * @return sProp value
	 */
	public function __get ($sProp) {
		if (!in_array ($sProp, $this -> aCanBeGet) && !array_key_exists ($sProp, $this -> aProps)) {
			throw new oUserException (str_replace ('{__PROP__}', $sProp, oUserException::ERROR_GEN_NOT_GETABLE));
		}
		switch ($sProp) {
			case 'FILTER' :
				return $this -> mFilter;
				break;
			case 'SUBFILTER' :
				return $this -> mSubFilter;
				break;
			case 'ITMODE' :
				return $this -> cItMode;
				break;
			default :
				if (!isset ($this -> aProps[$sProp])) {
					throw new oUserException (str_replace ('{__PROP__}', $sProp, oUserException::ERROR_USER_NOT_EXISTS));
				}
				if (!is_null ($this -> mFilter)) {
					if (isset ($this -> aProps[$sProp][$this -> mFilter])) {
						return $this -> aProps[$sProp][$this -> mFilter];
					}
				}
				if (!isset ($this -> aProps[$sProp]['VALUE'])) {
					//throw new oUserException (str_replace ('{__PROP__}', $sProp, oUserException::ERROR_USER_PROP_HAS_NO_VALUE));
					return null;
				}
				return $this -> aProps[$sProp]['VALUE'];
				break;
		}
	}

	/**
	 * public function __set
	 * setter
	 * @param (string) sProp
	 * @param (mixed) mVal
	 * @return void
	 */
	public function __set ($sProp, $mVal) {
		if (!array_key_exists ($sProp, $this -> aProps) && !in_array ($sProp, $this -> aCanBeSet)) {
			throw new oUserException (str_replace ('{__PROP__}', $sProp, oUserException::ERROR_GEN_NOT_SETABLE));
		}
		switch ($sProp) {
			case 'FILTER' :
				$this -> mFilter = $mVal;
				break;
			case 'ITMODE' :
				$this -> cItMode = $mVal;
				break;
			default :
				$this -> aProps[$sProp]['VALUE'] = $mVal;
				break;
		}
	}

	/**
	 * public function getProps
	 * get the aProps array of properties
	 * @return RecursiveIteratorIterator or myFilter Iterator
	 */
	public function getProps () {
		if (!is_null ($this -> mFilter)) {
			if (is_string ($this -> mFilter)) {
				return new myFilter (new RecursiveIteratorIterator (new RecursiveArrayIterator ($this -> aProps), $this -> cItMode), $this -> mFilter);
			}
		}
		return new RecursiveIteratorIterator (new RecursiveArrayIterator ($this -> aProps), $this -> cItMode);
	}

	/**
	 * abstract public function checkIdent
	 * check if a user exists in the database, given IDENT fields in the xml config file
	 * @param (string) sTable : users DB table name
	 * @param (array) aValues : array of fields to be checked, each key being the key of the config file, and the value being the input value
	 */
	abstract public function checkIdent ($sTable, $aValues);

	/**
	 * abstract public function createUser
	 * create a user if values are correct
	 * @param (string) sTable : users db table name
	 * @param (array) aValues : array of fields to be created, each key being the key of the config file, and the value being the input value
	 */
	abstract public function createUser ($sTable, $aValues);

	/**
	 * abstract public function getUser
	 * get a user from DB
	 * @param (mixed) iUserId : existing user ID in the DB
	 * @param (string) sTable : users db table name
	 * @param (boolean) bSession : true if get values must fill the session (if config file defines these fields for the session), false if not
	 */
	abstract public function getUser ($iUserId, $sTable, $bSession = true);

	/**
	 * abstract public function modUser
	 * modify a user in DB
	 * @param (mixed) iUserId : existing user ID in the DB
	 * @param (string) sTable : users db table name
	 * @param (array) aValues : array of fields to be modified, each key being the key of the config file, and the value being the input value
	 * @param (boolean) bSession : true if get values must fill the session (if config file defines these fields for the session), false if not
	 */
	abstract public function modUser ($iUserId, $sTable, $aValues, $bSession = true);

}

/**
 * class oSession
 * session class
 * @author Johan Barbier <hide@address.com>
 * @version 20061124
 *
 * see abstractUser for info about the methods and properties of this class, same definitions apply here
 */
class oSession {

	private $aProps = array ();
	private $oXml;

	public function __construct (simpleXMLElement $oXml) {
		$sSessionId = session_id ();
		if (empty ($sSessionId)) {
			session_start ();
		}
		$this -> oXml = $oXml;
		$this -> aPropsFill ();
	}

	private function aPropsFill () {
		foreach ($this -> oXml -> SESSION -> children () as $oNode) {
			$this -> aProps[(string)dom_import_simplexml($oNode) -> tagName] = null;
		}
	}

	public function __get ($sProp) {
		if (!array_key_exists ($sProp, $this -> aProps)) {
			throw new oUserException (str_replace ('{__PROP__}', $sProp, oUserException::ERROR_GEN_NOT_SETABLE));
		}
		return $this -> aProps[$sProp];
	}

	public function __set ($sProp, $mVal) {
		if (!array_key_exists ($sProp, $this -> aProps)) {
			throw new oUserException (str_replace ('{__PROP__}', $sProp, oUserException::ERROR_GEN_NOT_GETABLE));
		}
		$this -> aProps[$sProp] = $mVal;
		$_SESSION['USER'][$sProp] = $mVal;
	}

	public function __isset ($sProp) {
		if (!array_key_exists ($sProp, $this -> aProps)) {
			return false;
		}
		return true;
	}
}

/**
 * class oUser extends abstractUser
 * user class
 * @author Johan Barbier <hide@address.com>
 * @version 20061124
 *
 * see abstractUser for info about the methods and properties of this class, same definitions apply here
 */
class oUser extends abstractUser {

	private $oDB;

	public function __construct ($sXml, $oDB) {
		parent::__construct ($sXml);
		$this -> oDB = $oDB;
	}

	public function checkIdent ($sTable, $aValues) {
		$sTmp = $this -> mFilter;
		$this -> mFilter = 'IDENT';
		$aProps = $this -> getProps ();
		foreach ($aProps as $sV) {
			$sKeyName = $aProps -> getInnerIterator () -> getSubIterator (0) -> key ();
			$sCurrentDbName = $this -> aProps [$sKeyName]['BDD_NAME'];
			if (empty ($aValues[$sKeyName])) {
				throw new oUserException (oUserException::ERROR_USER_CHECKIDENT_BAD_VALUES_COUNT);
			}
			if ($this -> aProps[$sKeyName]['TYPE'] === 'string') {
				if (isset ($this -> aProps[$sKeyName]['DEDOUBLE'])) {
					$aDedoub[] = $sCurrentDbName.' = \''.$aValues[$sKeyName].'\'';
				}
				$aIdent[] = $sCurrentDbName.' = \''.$aValues[$sKeyName].'\'';
			} else {
				if (isset ($this -> aProps[$sKeyName]['DEDOUBLE'])) {
					$aDedoub[] = $sCurrentDbName.' = '.$aValues[$sKeyName];
				}
				$aIdent[] = $sCurrentDbName.' = '.$aValues[$sKeyName];
			}
		}
		$this -> mFilter = $sTmp;
		if (count ($aValues) !== count ($aIdent)) {
			throw new oUserException (oUserException::ERROR_USER_CHECKIDENT_BAD_VALUES_COUNT);
		}
		$sWhereClause = implode (' AND ', $aIdent);
		$sQuery = 'SELECT '.$this -> aProps['ID']['BDD_NAME'].' FROM '.$sTable.' WHERE '.$sWhereClause;
		$this -> oDB -> query ($sQuery);
		$aRes = $this -> oDB -> fetch_assoc ();
		if (!empty ($aRes[$this -> aProps['ID']['BDD_NAME']])) {
			$this -> oSession -> ID = $aRes[$this -> aProps['ID']['BDD_NAME']];
			return true;
		} else {
			if (!empty ($aDedoub)) {
				$sWhereDedoubClause = implode (' AND ', $aDedoub);
				$sQuery = 'SELECT '.$this -> aProps['ID']['BDD_NAME'].' FROM '.$sTable.' WHERE '.$sWhereDedoubClause;
				$this -> oDB -> query ($sQuery);
				$aRes = $this -> oDB -> fetch_assoc ();
				if (!empty ($aRes[$this -> aProps['ID']['BDD_NAME']])) {
					return -1;
				}
			}
			return false;
		}
	}

	public function createUser ($sTable, $aValues) {
		$sTmp = $this -> mFilter;
		$this -> mFilter = 'MANDATORY';
		$aProps = $this -> getProps ();
		foreach ($aProps as $sK => $sV) {
			$sMandatory = $aProps -> getInnerIterator () -> getSubIterator (0) -> key ();
			if (empty ($aValues[$sMandatory])) {
				throw new oUserException (str_replace ('{__FIELD__}', $sMandatory, oUserException::ERROR_USER_MANDATORY_FIELD_MISSING));
			}
		}
		$this -> mFilter = 'BDD_NAME';
		$aProps = $this -> getProps ();
		foreach ($aProps as $sV) {
			$sKeyName = $aProps -> getInnerIterator () -> getSubIterator (0) -> key ();
			if (!empty ($aValues[$sKeyName])) {
				$aFields[] = $sV;
				if ($this -> aProps [$aProps -> getInnerIterator () -> getSubIterator (0) -> key ()]['TYPE'] === 'string') {
					$aVals[] = '\''.$aValues[$sKeyName].'\'';
				} else {
					$aVals[] = $aValues[$sKeyName];
				}
			}
		}
		$this -> mFilter = $sTmp;
		$sFields = implode (',', $aFields);
		$sVals = implode (',', $aVals);
		$sQuery = 'INSERT INTO '.$sTable.' ('.$sFields.') VALUES ('.$sVals.')' ;
		if ($this -> oDB -> query ($sQuery)) {
			$this -> oSession -> ID = $this -> oDB -> insert_id ();
			return true;
		}
		return false;
	}

	public function getUser ($iUserId, $sTable, $bSession = true) {
		$sTmp = $this -> mFilter;
		$this -> mFilter = 'BDD_NAME';
		$aProps = $this -> getProps ();
		foreach ($aProps as $sV) {
			$aFields[] = $sV;
		}
		$sFields = implode (',', $aFields);
		$sQuery = 'SELECT '.$sFields.' FROM '.$sTable.' WHERE '.$this -> aProps['ID']['BDD_NAME'].' = '.$iUserId;
		$this -> oDB -> query ($sQuery);
		$aRes = $this -> oDB -> fetch_assoc ();
		if (empty ($aRes)) {
			return false;
		}
		foreach ($aProps as $sV) {
			$sKeyName = $aProps -> getInnerIterator () -> getSubIterator (0) -> key ();
			$this -> aProps[$sKeyName]['VALUE'] = $aRes[$sV];
			// PHP5 < 5.1
			if (true === $bSession && true === $this -> oSession -> __isset ($sKeyName)) {
				$this -> oSession -> $sKeyName = $aRes[$sV];
			}
			/*PHP5 >= 5.1
			if (true === $bSession && true === isset ($this -> oSession -> $sKeyName)) {
				$this -> oSession -> $sKeyName = $aRes[$sV];
			}
			*/
		}
		$this -> mFilter = $sTmp;
		return true;
	}

	public function modUser ($iUserId, $sTable, $aValues, $bSession = true) {
		$sTmp = $this -> mFilter;
		$this -> mFilter = 'BDD_NAME';
		$aProps = $this -> getProps ();
		foreach ($aProps as $sV) {
			$sKeyName = $aProps -> getInnerIterator () -> getSubIterator (0) -> key ();
			if (!empty ($aValues[$sKeyName])) {
				if ($this -> aProps [$aProps -> getInnerIterator () -> getSubIterator (0) -> key ()]['TYPE'] === 'string') {
					$aVals[] = $sV.'= \''.$aValues[$sKeyName].'\'';
				} else {
					$aVals[] = $sV.'='.$aValues[$sKeyName];
				}
				// PHP5 < 5.1
				if (true === $bSession && true === $this -> oSession -> __isset ($sKeyName)) {
					$this -> oSession -> $sKeyName = $aValues[$sKeyName];
				}
			}
		}
		$this -> mFilter = $sTmp;
		if (empty ($aVals)) {
			return false;
		}
		$sVals = implode (',', $aVals);
		$sQuery = 'UPDATE '.$sTable.' SET '.$sVals.' WHERE '.$this -> aProps['ID']['BDD_NAME'].' = '.$iUserId;
		if ($this -> oDB -> query ($sQuery)) {
			return true;
		}
		return false;
	}
}
?>
Return current item: SPL and Iterators