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