Location: PHPKode > scripts > AJAX Login Module > Driver/MDB2.php
<?php
require_once('Driver.php');
require_once('MDB2.php');

/**
 * A driver that use MDB2 as data store
 */
class AJAX_Locking_Driver_MDB2 extends AJAX_Locking_Driver
{
    /**
     * Instance of a MDB2 connection
     *
     * @var MBD2 connection
     */
	var $mdb2;

	/**
	 * Default table and columns names
	 *
	 * @var array
	 */
	var $names = array(
	   'table' => 'ajax_locks',
	   'columns' => array(
	       'type' => 'type',
	       'id' => 'id',
	       'user' => '[user]',
	       'time' => '[time]'
	   )
	);

	/**
	 * Constructor
	 *
	 * @param mixed $dsn DSN for MDB2 connection
	 * @param array $names names of table and its columns where store data
	 * @param int $timeout session timeout
	 * @return AJAX_Locking_Driver
	 */
	function AJAX_Locking_Driver_MDB2($dsn = false, $names = false, $timeout = false)
	{
		parent::AJAX_Locking_Driver($timeout);

		$this->mdb2 =& MDB2::factory($dsn);
		if (PEAR::isError($this->mdb2)) {
		    die($this->mdb2->getMessage());
        }

        // eventually override default names of table and columns
        if ($names && is_array($names)) {
            $names['columns'] = array_merge($this->names['columns'], $names['columns']);
            $this->names = array_merge($this->names, $names);
        }
	}

	/**
	 * Locks an object
	 *
	 * @param mixed $user	id of the user who wants to lock
	 * @param string $type	type/classname of the object
	 * @param mixed $id		id of the object
	 * @return boolean true if the unlock was successfull, false otherwise
	 */
	function lock($user, $type, $id)
	{
	    $result = false;
	    $this->mdb2->beginTransaction();

	    $sql = $this->_getStatusSQL($type, $id);
	    $rs = $this->mdb2->query($sql);
	    if (PEAR::isError($rs)) {
		    die($rs->getMessage());
        }
	    $row = $rs->fetchRow();
	    if (!$row) {
			// object is unlocked: lock it
			$sql = $this->_getLockSQL($user, $type, $id);
			$affected =& $this->mdb2->exec($sql);
			if (PEAR::isError($affected)) {
               die($affected->getMessage());
            }
			$result = true;
		} else {
			// object is locked: check if lock expired
			$time = $row[3];
			if (time() - $time > $this->timeout) {
				// lock expired: remove it and lock
				$sql = $this->_getUnlockSQL($type, $id);
				$this->mdb2->exec($sql);
				$sql = $this->_getLockSQL($user, $type, $id);
				$this->mdb2->exec($sql);
				$result = true;
			} else {
				// object properly locked by (another?) user
				$result = ($owner == $user);
			}
		}

		$this->mdb2->commit();

		return $result;
	}

	/**
	 * Unlocks an object
	 *
	 * @param mixed $user	id of the user who wants to unlock
	 * @param string $type	type/classname of the object
	 * @param mixed $id		id of the object
	 * @return boolean true if the unlock was successfull, false otherwise
	 */
	function unlock($user, $type, $id)
	{
	    $result = false;
	    $this->mdb2->beginTransaction();

	    $sql = $this->_getStatusSQL($type, $id);
	    $rs = $this->mdb2->query($sql);
	    if (PEAR::isError($rs)) {
		    die($rs->getMessage());
        }
	    $row = $rs->fetchRow();
	    if (!$row) {
			// object was not locked
			$result = false;
		} else {
			// check if user is owner of the lock
			$owner = $row[2];
			if ($user == $owner) {
				// unlock it
				$sql = $this->_getUnlockSQL($type, $id);
				$this->mdb2->exec($sql);
				$result = true;
			} else {
				// user cannot unlock it
				$result = false;
			}
		}

		$this->mdb2->commit();
		return $result;
	}

	/**
	 * Returns the status of the object (lock or unlocked)
	 *
	 * @param mixed $user	id of the user who wants to know the object's status
	 * @param string $type	type/classname of the object
	 * @param mixed $id		id of the object
	 * @return string the status and the owner of the object
	 */
	function status($user, $type, $id)
	{
	    $result = "~";
	    $this->mdb2->beginTransaction();

	    $sql = $this->_getStatusSQL($type, $id);
	    $rs = $this->mdb2->query($sql);
	    if (PEAR::isError($rs)) {
		    die($rs->getMessage());
        }
	    $row = $rs->fetchRow();
	    if (!$row) {
			// object is unlocked
			$result =  AJAX_LOCKING_UNLOCKED . '~' . 'noboby';
		} else {
			// object is locked:
			// 1. check if current user is owner of the lock
			// 2. check if lock expired
			$owner = $row[2]; $time = $row[3];
			$timeout = (time() - $time > $this->timeout);
			if ($owner == $user) {
				if ($timeout) {
					// lock expired: remove it and inform it's ower
					$sql = $this->_getUnlockSQL($type, $id);
					$this->mdb2->exec($sql);
					$result = AJAX_LOCKING_TIMEOUT . '~' . $owner;
				} else {
				    $result = AJAX_LOCKING_OWNED . '~' . $owner;
				}
			} else {
				if ($timeout) {
					// lock expired: remove it
					$sql = $this->_getUnlockSQL($type, $id);
					$this->mdb2->exec($sql);
					$result = AJAX_LOCKING_UNLOCKED . '~' . 'nobody';
				} else {
					$result = AJAX_LOCKING_LOCKED . '~' . $owner;
				}
			}
		}

		$this->mdb2->commit();
		return $result;
	}

	/**
	 * Returns the list of all active locks for administration purpose
	 *
	 * @return array of locks (owner, type, id), false if not implemented
	 */
	function getLocks()
	{
	    $locks = array();

	    $sql = $this->_getListSQL($type, $id);
	    $rs = $this->mdb2->query($sql);
	    if (PEAR::isError($rs)) {
		    die($rs->getMessage());
        }
        while (($row = $rs->fetchRow())) {
            list($owner, $type, $id, $time) = $row;
            $timeout = (time() - $time > $this->timeout);
            if (!$timeout) {
                $locks[] = array(
                    'owner' => $owner,
                    'type' => $type,
                    'id' => $id
                );
            }
        }

        return $locks;
	}

	/**
	 * Administrately delete lock
	 *
	 * @param string $type
	 * @param mixed $id
	 *
	 * @return true if the lock is deleted successfully, false otherwise
	 */
    function deleteLock($type, $id)
    {
        $sql = $this->_getUnlockSQL($type, $id);
        return $this->mdb2->exec($sql);
    }


	function _getStatusSQL($type, $id)
	{
	    $sql = sprintf("select * from %s where %s = %s and %s = %s",
	       $this->names['table'],
	       $this->names['columns']['type'], $this->mdb2->quote($type),
	       $this->names['columns']['id'], $this->mdb2->quote($id));
        return $sql;
	}

	function _getLockSQL($user, $type, $id)
	{
	    $timestamp = time();
	    $sql = sprintf("insert into %s (%s, %s, %s, %s) values(%s, %s, %s, %s)",
	       $this->names['table'],
	       $this->names['columns']['type'], $this->names['columns']['id'], $this->names['columns']['user'], $this->names['columns']['time'],
	       $this->mdb2->quote($type),
	       $this->mdb2->quote($id),
	       $this->mdb2->quote($user),
	       $timestamp);
	    return $sql;
	}

	function _getUnlockSQL($type, $id)
	{
	    $sql = sprintf("delete from %s where %s = %s and %s = %s",
	       $this->names['table'],
	       $this->names['columns']['type'], $this->mdb2->quote($type),
	       $this->names['columns']['id'], $this->mdb2->quote($id));
        return $sql;
	}

	function _getListSQL($type, $id)
	{
	    $sql = sprintf("select * from %s",
	       $this->names['table']);
        return $sql;
	}

}
?>
Return current item: AJAX Login Module