1<?php
2
3namespace Sabre\DAV\PropertyStorage;
4
5use Sabre\DAV\INode;
6use Sabre\DAV\PropFind;
7use Sabre\DAV\PropPatch;
8use Sabre\DAV\Server;
9use Sabre\DAV\ServerPlugin;
10
11/**
12 * PropertyStorage Plugin.
13 *
14 * Adding this plugin to your server allows clients to store any arbitrary
15 * WebDAV property.
16 *
17 * See:
18 *   http://sabre.io/dav/property-storage/
19 *
20 * for more information.
21 *
22 * @copyright Copyright (C) fruux GmbH (https://fruux.com/)
23 * @author Evert Pot (http://evertpot.com/)
24 * @license http://sabre.io/license/ Modified BSD License
25 */
26class Plugin extends ServerPlugin {
27
28    /**
29     * If you only want this plugin to store properties for a limited set of
30     * paths, you can use a pathFilter to do this.
31     *
32     * The pathFilter should be a callable. The callable retrieves a path as
33     * its argument, and should return true or false whether it allows
34     * properties to be stored.
35     *
36     * @var callable
37     */
38    public $pathFilter;
39
40    /**
41     * @var Backend\BackendInterface
42     */
43    public $backend;
44
45    /**
46     * Creates the plugin
47     *
48     * @param Backend\BackendInterface $backend
49     */
50    function __construct(Backend\BackendInterface $backend) {
51
52        $this->backend = $backend;
53
54    }
55
56    /**
57     * This initializes the plugin.
58     *
59     * This function is called by Sabre\DAV\Server, after
60     * addPlugin is called.
61     *
62     * This method should set up the required event subscriptions.
63     *
64     * @param Server $server
65     * @return void
66     */
67    function initialize(Server $server) {
68
69        $server->on('propFind',    [$this, 'propFind'], 130);
70        $server->on('propPatch',   [$this, 'propPatch'], 300);
71        $server->on('afterMove',   [$this, 'afterMove']);
72        $server->on('afterUnbind', [$this, 'afterUnbind']);
73
74    }
75
76    /**
77     * Called during PROPFIND operations.
78     *
79     * If there's any requested properties that don't have a value yet, this
80     * plugin will look in the property storage backend to find them.
81     *
82     * @param PropFind $propFind
83     * @param INode $node
84     * @return void
85     */
86    function propFind(PropFind $propFind, INode $node) {
87
88        $path = $propFind->getPath();
89        $pathFilter = $this->pathFilter;
90        if ($pathFilter && !$pathFilter($path)) return;
91        $this->backend->propFind($propFind->getPath(), $propFind);
92
93    }
94
95    /**
96     * Called during PROPPATCH operations
97     *
98     * If there's any updated properties that haven't been stored, the
99     * propertystorage backend can handle it.
100     *
101     * @param string $path
102     * @param PropPatch $propPatch
103     * @return void
104     */
105    function propPatch($path, PropPatch $propPatch) {
106
107        $pathFilter = $this->pathFilter;
108        if ($pathFilter && !$pathFilter($path)) return;
109        $this->backend->propPatch($path, $propPatch);
110
111    }
112
113    /**
114     * Called after a node is deleted.
115     *
116     * This allows the backend to clean up any properties still in the
117     * database.
118     *
119     * @param string $path
120     * @return void
121     */
122    function afterUnbind($path) {
123
124        $pathFilter = $this->pathFilter;
125        if ($pathFilter && !$pathFilter($path)) return;
126        $this->backend->delete($path);
127
128    }
129
130    /**
131     * Called after a node is moved.
132     *
133     * This allows the backend to move all the associated properties.
134     *
135     * @param string $source
136     * @param string $destination
137     * @return void
138     */
139    function afterMove($source, $destination) {
140
141        $pathFilter = $this->pathFilter;
142        if ($pathFilter && !$pathFilter($source)) return;
143        // If the destination is filtered, afterUnbind will handle cleaning up
144        // the properties.
145        if ($pathFilter && !$pathFilter($destination)) return;
146
147        $this->backend->move($source, $destination);
148
149    }
150
151    /**
152     * Returns a plugin name.
153     *
154     * Using this name other plugins will be able to access other plugins
155     * using \Sabre\DAV\Server::getPlugin
156     *
157     * @return string
158     */
159    function getPluginName() {
160
161        return 'property-storage';
162
163    }
164
165    /**
166     * Returns a bunch of meta-data about the plugin.
167     *
168     * Providing this information is optional, and is mainly displayed by the
169     * Browser plugin.
170     *
171     * The description key in the returned array may contain html and will not
172     * be sanitized.
173     *
174     * @return array
175     */
176    function getPluginInfo() {
177
178        return [
179            'name'        => $this->getPluginName(),
180            'description' => 'This plugin allows any arbitrary WebDAV property to be set on any resource.',
181            'link'        => 'http://sabre.io/dav/property-storage/',
182        ];
183
184    }
185}
186