4 * This Lock Backend stores all its data in the filesystem in separate file per
7 * This Lock Manager is now deprecated. It has a bug that allows parent
8 * collections to be deletes when children deeper in the tree are locked.
10 * This also means that using this backend means you will not pass the Neon
13 * You are recommended to use either the PDO or the File backend instead.
18 * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
19 * @author Evert Pot (http://www.rooftopsolutions.nl/)
20 * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
22 class Sabre_DAV_Locks_Backend_FS extends Sabre_DAV_Locks_Backend_Abstract {
25 * The default data directory
31 public function __construct($dataDir) {
33 $this->dataDir = $dataDir;
37 protected function getFileNameForUri($uri) {
39 return $this->dataDir . '/sabredav_' . md5($uri) . '.locks';
45 * Returns a list of Sabre_DAV_Locks_LockInfo objects
47 * This method should return all the locks for a particular uri, including
48 * locks that might be set on a parent uri.
50 * If returnChildLocks is set to true, this method should also look for
51 * any locks in the subtree of the uri for locks.
54 * @param bool $returnChildLocks
57 public function getLocks($uri, $returnChildLocks) {
62 foreach(explode('/',$uri) as $uriPart) {
64 // weird algorithm that can probably be improved, but we're traversing the path top down
65 if ($currentPath) $currentPath.='/';
66 $currentPath.=$uriPart;
68 $uriLocks = $this->getData($currentPath);
70 foreach($uriLocks as $uriLock) {
72 // Unless we're on the leaf of the uri-tree we should ignore locks with depth 0
73 if($uri==$currentPath || $uriLock->depth!=0) {
74 $uriLock->uri = $currentPath;
75 $lockList[] = $uriLock;
82 // Checking if we can remove any of these locks
83 foreach($lockList as $k=>$lock) {
84 if (time() > $lock->timeout + $lock->created) unset($lockList[$k]);
94 * @param Sabre_DAV_Locks_LockInfo $lockInfo
97 public function lock($uri,Sabre_DAV_Locks_LockInfo $lockInfo) {
99 // We're making the lock timeout 30 minutes
100 $lockInfo->timeout = 1800;
101 $lockInfo->created = time();
103 $locks = $this->getLocks($uri,false);
104 foreach($locks as $k=>$lock) {
105 if ($lock->token == $lockInfo->token) unset($locks[$k]);
107 $locks[] = $lockInfo;
108 $this->putData($uri,$locks);
114 * Removes a lock from a uri
117 * @param Sabre_DAV_Locks_LockInfo $lockInfo
120 public function unlock($uri,Sabre_DAV_Locks_LockInfo $lockInfo) {
122 $locks = $this->getLocks($uri,false);
123 foreach($locks as $k=>$lock) {
125 if ($lock->token == $lockInfo->token) {
128 $this->putData($uri,$locks);
138 * Returns the stored data for a uri
143 protected function getData($uri) {
145 $path = $this->getFilenameForUri($uri);
146 if (!file_exists($path)) return array();
148 // opening up the file, and creating a shared lock
149 $handle = fopen($path,'r');
150 flock($handle,LOCK_SH);
153 // Reading data until the eof
154 while(!feof($handle)) {
155 $data.=fread($handle,8192);
161 // Unserializing and checking if the resource file contains data for this file
162 $data = unserialize($data);
163 if (!$data) return array();
169 * Updates the lock information
172 * @param array $newData
175 protected function putData($uri,array $newData) {
177 $path = $this->getFileNameForUri($uri);
179 // opening up the file, and creating a shared lock
180 $handle = fopen($path,'a+');
181 flock($handle,LOCK_EX);
182 ftruncate($handle,0);
185 fwrite($handle,serialize($newData));