1<?php
2
3// (c) Copyright by authors of the Tiki Wiki CMS Groupware Project
4//
5// All Rights Reserved. See copyright.txt for details and a complete list of authors.
6// Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details.
7// $Id$
8
9namespace Tiki\SabreDav;
10
11use Sabre\DAV;
12use Sabre\DAV\Locks\Backend\File as FileBackend;
13use Sabre\DAV\Locks\LockInfo;
14
15use TikiLib;
16
17class LocksBackend extends FileBackend {
18  /**
19   * Returns a list of Sabre\DAV\Locks\LockInfo objects
20   *
21   * This method should return all the locks for a particular uri, including
22   * locks that might be set on a parent uri.
23   *
24   * If returnChildLocks is set to true, this method should also look for
25   * any locks in the subtree of the uri for locks.
26   *
27   * Works on the basis of File backend which allows us to have locks on URIs
28   * of nonexistent files or wiki pages and adds what other locks are available
29   * in Tiki.
30   *
31   * @param string $uri
32   * @param bool $returnChildLocks
33   * @return array
34   */
35  function getLocks($uri, $returnChildLocks) {
36    $locks = parent::getLocks($uri, $returnChildLocks);
37    // check wiki page locks
38    if (preg_match('#^Wiki Pages/#', $uri)) {
39      $lockedPages = TikiLib::lib('wiki')->get_locked();
40      foreach ($lockedPages as $page) {
41        $existing = array_filter($locks, function($lockInfo) use ($page) {
42          return $lockInfo->uri == 'Wiki Pages/'.$page['pageName'];
43        });
44        if (! $existing) {
45          $lockInfo = new LockInfo();
46          $lockInfo->owner = $page['lockedby'];
47          $lockInfo->token = DAV\UUIDUtil::getUUID();
48          $lockInfo->timeout = 0;
49          $lockInfo->created = $page['lastModif'];
50          $lockInfo->uri = 'Wiki Pages/'.$page['pageName'];
51          $locks[] = $lockInfo;
52        }
53      }
54      return $locks;
55    }
56    // since only file locks are supported, we don't need to search for parent uri locks
57    try {
58      $file = new File($uri);
59      if ($file->getFile()->lockedby) {
60        $existing = array_filter($locks, function($lockInfo) use ($uri) {
61          return $lockInfo->uri == $uri;
62        });
63        if (! $existing) {
64          $lockInfo = new LockInfo();
65          $lockInfo->owner = $file->getFile()->lockedby;
66          $lockInfo->token = DAV\UUIDUtil::getUUID();
67          $lockInfo->timeout = 0;
68          $lockInfo->created = $file->getFile()->lastModif;
69          $lockInfo->uri = $uri;
70          $locks[] = $lockInfo;
71        }
72      }
73    } catch( DAV\Exception\NotFound $e ) {
74      # ignore missing file or unsupported file gallery locks
75    }
76    if ($returnChildLocks) {
77      try {
78        $directory = new Directory($uri);
79        foreach ($directory->getChildren() as $child) {
80          if (get_class($child) == 'File') {
81            if ($child->getFile()->lockedby) {
82              $childUri = TikiLib::lib('filegal')->get_full_virtual_path($child->getFile()->fileId);
83              $existing = array_filter($locks, function($lockInfo) use ($childUri) {
84                return $lockInfo->uri == $childUri;
85              });
86              if (! $existing) {
87                $lockInfo = new LockInfo();
88                $lockInfo->owner = $child->getFile()->lockedby;
89                $lockInfo->token = DAV\UUIDUtil::getUUID();
90                $lockInfo->timeout = 0;
91                $lockInfo->created = $child->getFile()->lastModif;
92                $lockInfo->uri = $childUri;
93                $locks[] = $lockInfo;
94              }
95            }
96          } else {
97            $galUri = TikiLib::lib('filegal')->get_full_virtual_path($child->getGalleryId());
98            $locks = array_merge($locks, $this->getLocks($galUri, $returnChildLocks));
99          }
100        }
101      } catch( DAV\Exception\NotFound $e ) {
102        # ignore missing file gallery
103      }
104    }
105    return $locks;
106  }
107
108  /**
109   * Locks a uri
110   *
111   * @param string $uri
112   * @param LockInfo $lockInfo
113   * @return bool
114   */
115  function lock($uri, LockInfo $lockInfo) {
116    parent::lock($uri, $lockInfo);
117    try {
118      if ($m = preg_match('#^Wiki Pages/(.*)$#', $uri)) {
119        if (TikiLib::lib('tiki')->page_exists($m[1])) {
120          TikiLib::lib('wiki')->lock_page($m[1]);
121        }
122      } else {
123        $file = new File($uri);
124        TikiLib::lib('filegal')->lock_file($file->getFile()->fileId, $lockInfo->owner);
125      }
126    } catch( DAV\Exception\NotFound $e ) {
127      # ignore missing file or unsupported file gallery locks
128    }
129    return true;
130  }
131
132  /**
133   * Removes a lock from a uri
134   *
135   * @param string $uri
136   * @param LockInfo $lockInfo
137   * @return bool
138   */
139  function unlock($uri, LockInfo $lockInfo) {
140    parent::unlock($uri, $lockInfo);
141    try {
142      if ($m = preg_match('#^Wiki Pages/(.*)$#', $uri)) {
143        if (TikiLib::lib('tiki')->page_exists($m[1])) {
144          TikiLib::lib('wiki')->unlock_page($m[1]);
145        }
146      } else {
147        $file = new File($uri);
148        TikiLib::lib('filegal')->unlock_file($file->getFile()->fileId);
149      }
150    } catch( DAV\Exception\NotFound $e ) {
151      # ignore missing file or unsupported file gallery locks
152    }
153    return true;
154  }
155}
156