<?php
require_once('Driver.php');
require_once('System/SharedMemory.php');
/**
* A driver that use System_SharedMemory as data store
*/
class AJAX_Locking_Driver_SharedMemory extends AJAX_Locking_Driver
{
var $shared;
/**
* Constructor
*
* @return AJAX_Locking_Driver
*/
function AJAX_Locking_Driver_SharedMemory($type = false, $options = false, $timeout = false)
{
parent::AJAX_Locking_Driver($timeout);
$this->shared = &System_SharedMemory::factory($type, $options);
}
/**
* 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)
{
$key = $this->_getKey($type, $id);
$value = $this->shared->get($key);
if (empty($value)) {
// object is unlocked: lock it
$value = $this->_getValue($user, $type, $id);
$this->shared->set($key, $value);
return true;
} else {
// object is locked: check if lock expired
list($owner, $type, $id, $time) = $this->_parseValue($value);
if (time() - $time > $this->timeout) {
// lock expired: remove it and lock
$this->shared->rm($key);
$this->shared->set($key, $value);
return true;
} else {
// object properly locked by another user
return false;
}
}
}
/**
* 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)
{
$key = $this->_getKey($type, $id);
$value = $this->shared->get($key);
if (empty($value)) {
// object was not locked
return false;
} else {
// check if user is owner of the lock
list($owner, $type, $id, $time) = $this->_parseValue($value);
if ($user == $owner) {
// unlock it
$this->shared->rm($key);
return true;
} else {
// user cannot unlock it
return false;
}
}
}
/**
* 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)
{
$key = $this->_getKey($type, $id);
$value = $this->shared->get($key);
if (empty($value)) {
// object is unlocked
return AJAX_LOCKING_UNLOCKED . '~' . 'noboby';
} else {
// object is locked:
// 1. check if current user is owner of the lock
// 2. check if lock expired
list($owner, $type, $id, $time) = $this->_parseValue($value);
$timeout = (time() - $time > $this->timeout);
if ($owner == $user) {
if ($timeout) {
// lock expired: remove it and inform it's ower
$this->shared->rm($key);
return AJAX_LOCKING_TIMEOUT . '~' . $owner;
} else {
return AJAX_LOCKING_OWNED . '~' . $owner;
}
} else {
if ($timeout) {
// lock expired: remove it
$this->shared->rm($key);
return AJAX_LOCKING_UNLOCKED . '~' . 'nobody';
} else {
return AJAX_LOCKING_LOCKED . '~' . $owner;
}
}
}
}
}
?>