- <?php
- require_once('Driver.php');
- require_once('System/SharedMemory.php');
-
- /**
- * A driver that use plain filesystem as data store
- */
- class AJAX_Locking_Driver_File extends AJAX_Locking_Driver
- {
- var $dir;
-
- /**
- * Constructor
- *
- * @return AJAX_Locking_Driver
- */
- function AJAX_Locking_Driver_File($dir = '/tmp', $timeout = false)
- {
- parent::AJAX_Locking_Driver($timeout);
-
- $this->dir = realpath($dir);
- }
-
- /**
- * 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->_get($key);
- if (empty($value)) {
- // object is unlocked: lock it
- $value = $this->_getValue($user, $type, $id);
- $this->_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->_rm($key);
- $this->_set($key, $value);
- return true;
- } else {
- // object properly locked by (another?) user
- return ($owner == $user);
- }
- }
-
- }
-
- /**
- * 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->_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->_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->_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->_rm($key);
- return AJAX_LOCKING_TIMEOUT . '~' . $owner;
- } else {
- return AJAX_LOCKING_OWNED . '~' . $owner;
- }
- } else {
- if ($timeout) {
- // lock expired: remove it
- $this->_rm($key);
- return AJAX_LOCKING_UNLOCKED . '~' . 'nobody';
- } else {
- return AJAX_LOCKING_LOCKED . '~' . $owner;
- }
- }
- }
- }
-
- /**
- * Returns the list of all active locks for administration purpose
- *
- * @return array of locks (owner, type, id), false if not implemented
- */
- function getLocks()
- {
- $files = array();
- $dh = opendir($this->dir);
- while (false !== ($filename = readdir($dh))) {
- if (strstr($filename, AJAX_LOCKING_PREFIX) == $filename) {
- $files[] = $filename;
- }
- }
-
- $locks = array();
- foreach ($files as $f) {
- $value = file_get_contents($this->dir . DIRECTORY_SEPARATOR . $f);
- if ($value) {
- list($owner, $type, $id, $time) = $this->_parseValue($value);
- $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 delete($type, $id)
- {
- $key = $this->_getKey($type, $id);
- $this->_rm($key);
- }
-
-
- /**
- * Returns the values stored in file $key
- *
- * @param string $key
- * @return string
- */
- function _get($key)
- {
- $value = '';
- $filename = $this->dir . DIRECTORY_SEPARATOR . $key;
- if (file_exists($filename)) {
- $value = file_get_contents($filename);
- }
- return $value;
- }
-
- /**
- * Puts the value $value into file $key
- *
- * @param string $key
- * @param string $value
- */
- function _set($key, $value)
- {
- $filename = $this->dir . DIRECTORY_SEPARATOR . $key;
- $fp = fopen($filename, 'w');
- fwrite($fp, $value);
- fclose($fp);
- }
-
- /**
- * Remove the file $key
- *
- * @param string $key
- */
- function _rm($key)
- {
- $filename = $this->dir . DIRECTORY_SEPARATOR . $key;
- return @unlink($filename);
- }
-
- }
- ?>