1<?php
2
3namespace Sabre\CalDAV\Backend;
4
5use Sabre\CalDAV;
6use Sabre\DAV;
7
8class Mock extends AbstractBackend {
9
10    protected $calendarData;
11    protected $calendars;
12
13    function __construct(array $calendars = [], array $calendarData = []) {
14
15        foreach ($calendars as &$calendar) {
16            if (!isset($calendar['id'])) {
17                $calendar['id'] = DAV\UUIDUtil::getUUID();
18            }
19        }
20
21        $this->calendars = $calendars;
22        $this->calendarData = $calendarData;
23
24    }
25
26    /**
27     * Returns a list of calendars for a principal.
28     *
29     * Every project is an array with the following keys:
30     *  * id, a unique id that will be used by other functions to modify the
31     *    calendar. This can be the same as the uri or a database key.
32     *  * uri, which the basename of the uri with which the calendar is
33     *    accessed.
34     *  * principalUri. The owner of the calendar. Almost always the same as
35     *    principalUri passed to this method.
36     *
37     * Furthermore it can contain webdav properties in clark notation. A very
38     * common one is '{DAV:}displayname'.
39     *
40     * @param string $principalUri
41     * @return array
42     */
43    function getCalendarsForUser($principalUri) {
44
45        $r = [];
46        foreach ($this->calendars as $row) {
47            if ($row['principaluri'] == $principalUri) {
48                $r[] = $row;
49            }
50        }
51
52        return $r;
53
54    }
55
56    /**
57     * Creates a new calendar for a principal.
58     *
59     * If the creation was a success, an id must be returned that can be used to reference
60     * this calendar in other methods, such as updateCalendar.
61     *
62     * This function must return a server-wide unique id that can be used
63     * later to reference the calendar.
64     *
65     * @param string $principalUri
66     * @param string $calendarUri
67     * @param array $properties
68     * @return string|int
69     */
70    function createCalendar($principalUri, $calendarUri, array $properties) {
71
72        $id = DAV\UUIDUtil::getUUID();
73        $this->calendars[] = array_merge([
74            'id'                                                                 => $id,
75            'principaluri'                                                       => $principalUri,
76            'uri'                                                                => $calendarUri,
77            '{' . CalDAV\Plugin::NS_CALDAV . '}supported-calendar-component-set' => new CalDAV\Xml\Property\SupportedCalendarComponentSet(['VEVENT', 'VTODO']),
78        ], $properties);
79
80        return $id;
81
82    }
83
84    /**
85     * Updates properties for a calendar.
86     *
87     * The list of mutations is stored in a Sabre\DAV\PropPatch object.
88     * To do the actual updates, you must tell this object which properties
89     * you're going to process with the handle() method.
90     *
91     * Calling the handle method is like telling the PropPatch object "I
92     * promise I can handle updating this property".
93     *
94     * Read the PropPatch documentation for more info and examples.
95     *
96     * @param mixed $calendarId
97     * @param \Sabre\DAV\PropPatch $propPatch
98     * @return void
99     */
100    function updateCalendar($calendarId, \Sabre\DAV\PropPatch $propPatch) {
101
102        $propPatch->handleRemaining(function($props) use ($calendarId) {
103
104            foreach ($this->calendars as $k => $calendar) {
105
106                if ($calendar['id'] === $calendarId) {
107                    foreach ($props as $propName => $propValue) {
108                        if (is_null($propValue)) {
109                            unset($this->calendars[$k][$propName]);
110                        } else {
111                            $this->calendars[$k][$propName] = $propValue;
112                        }
113                    }
114                    return true;
115
116                }
117
118            }
119
120        });
121
122    }
123
124    /**
125     * Delete a calendar and all it's objects
126     *
127     * @param string $calendarId
128     * @return void
129     */
130    function deleteCalendar($calendarId) {
131
132        foreach ($this->calendars as $k => $calendar) {
133            if ($calendar['id'] === $calendarId) {
134                unset($this->calendars[$k]);
135            }
136        }
137
138    }
139
140    /**
141     * Returns all calendar objects within a calendar object.
142     *
143     * Every item contains an array with the following keys:
144     *   * id - unique identifier which will be used for subsequent updates
145     *   * calendardata - The iCalendar-compatible calendar data
146     *   * uri - a unique key which will be used to construct the uri. This can be any arbitrary string.
147     *   * lastmodified - a timestamp of the last modification time
148     *   * etag - An arbitrary string, surrounded by double-quotes. (e.g.:
149     *   '  "abcdef"')
150     *   * calendarid - The calendarid as it was passed to this function.
151     *
152     * Note that the etag is optional, but it's highly encouraged to return for
153     * speed reasons.
154     *
155     * The calendardata is also optional. If it's not returned
156     * 'getCalendarObject' will be called later, which *is* expected to return
157     * calendardata.
158     *
159     * @param string $calendarId
160     * @return array
161     */
162    function getCalendarObjects($calendarId) {
163
164        if (!isset($this->calendarData[$calendarId]))
165            return [];
166
167        $objects = $this->calendarData[$calendarId];
168
169        foreach ($objects as $uri => &$object) {
170            $object['calendarid'] = $calendarId;
171            $object['uri'] = $uri;
172            $object['lastmodified'] = null;
173        }
174        return $objects;
175
176    }
177
178    /**
179     * Returns information from a single calendar object, based on it's object
180     * uri.
181     *
182     * The object uri is only the basename, or filename and not a full path.
183     *
184     * The returned array must have the same keys as getCalendarObjects. The
185     * 'calendardata' object is required here though, while it's not required
186     * for getCalendarObjects.
187     *
188     * This method must return null if the object did not exist.
189     *
190     * @param mixed $calendarId
191     * @param string $objectUri
192     * @return array|null
193     */
194    function getCalendarObject($calendarId, $objectUri) {
195
196        if (!isset($this->calendarData[$calendarId][$objectUri])) {
197            return null;
198        }
199        $object = $this->calendarData[$calendarId][$objectUri];
200        $object['calendarid'] = $calendarId;
201        $object['uri'] = $objectUri;
202        $object['lastmodified'] = null;
203        return $object;
204
205    }
206
207    /**
208     * Creates a new calendar object.
209     *
210     * @param string $calendarId
211     * @param string $objectUri
212     * @param string $calendarData
213     * @return void
214     */
215    function createCalendarObject($calendarId, $objectUri, $calendarData) {
216
217        $this->calendarData[$calendarId][$objectUri] = [
218            'calendardata' => $calendarData,
219            'calendarid'   => $calendarId,
220            'uri'          => $objectUri,
221        ];
222        return '"' . md5($calendarData) . '"';
223
224    }
225
226    /**
227     * Updates an existing calendarobject, based on it's uri.
228     *
229     * @param string $calendarId
230     * @param string $objectUri
231     * @param string $calendarData
232     * @return void
233     */
234    function updateCalendarObject($calendarId, $objectUri, $calendarData) {
235
236        $this->calendarData[$calendarId][$objectUri] = [
237            'calendardata' => $calendarData,
238            'calendarid'   => $calendarId,
239            'uri'          => $objectUri,
240        ];
241        return '"' . md5($calendarData) . '"';
242
243    }
244
245    /**
246     * Deletes an existing calendar object.
247     *
248     * @param string $calendarId
249     * @param string $objectUri
250     * @return void
251     */
252    function deleteCalendarObject($calendarId, $objectUri) {
253
254        unset($this->calendarData[$calendarId][$objectUri]);
255
256    }
257
258}
259