Completed
Branch develop (fa72bb)
by
unknown
26:08
created
htdocs/includes/sabre/sabre/dav/lib/CalDAV/Principal/ProxyWrite.php 1 patch
Indentation   +138 added lines, -138 removed lines patch added patch discarded remove patch
@@ -20,142 +20,142 @@
 block discarded – undo
20 20
  */
21 21
 class ProxyWrite implements IProxyWrite
22 22
 {
23
-    /**
24
-     * Parent principal information.
25
-     *
26
-     * @var array
27
-     */
28
-    protected $principalInfo;
29
-
30
-    /**
31
-     * Principal Backend.
32
-     *
33
-     * @var DAVACL\PrincipalBackend\BackendInterface
34
-     */
35
-    protected $principalBackend;
36
-
37
-    /**
38
-     * Creates the object.
39
-     *
40
-     * Note that you MUST supply the parent principal information.
41
-     */
42
-    public function __construct(DAVACL\PrincipalBackend\BackendInterface $principalBackend, array $principalInfo)
43
-    {
44
-        $this->principalInfo = $principalInfo;
45
-        $this->principalBackend = $principalBackend;
46
-    }
47
-
48
-    /**
49
-     * Returns this principals name.
50
-     *
51
-     * @return string
52
-     */
53
-    public function getName()
54
-    {
55
-        return 'calendar-proxy-write';
56
-    }
57
-
58
-    /**
59
-     * Returns the last modification time.
60
-     */
61
-    public function getLastModified()
62
-    {
63
-        return null;
64
-    }
65
-
66
-    /**
67
-     * Deletes the current node.
68
-     *
69
-     * @throws DAV\Exception\Forbidden
70
-     */
71
-    public function delete()
72
-    {
73
-        throw new DAV\Exception\Forbidden('Permission denied to delete node');
74
-    }
75
-
76
-    /**
77
-     * Renames the node.
78
-     *
79
-     * @param string $name The new name
80
-     *
81
-     * @throws DAV\Exception\Forbidden
82
-     */
83
-    public function setName($name)
84
-    {
85
-        throw new DAV\Exception\Forbidden('Permission denied to rename file');
86
-    }
87
-
88
-    /**
89
-     * Returns a list of alternative urls for a principal.
90
-     *
91
-     * This can for example be an email address, or ldap url.
92
-     *
93
-     * @return array
94
-     */
95
-    public function getAlternateUriSet()
96
-    {
97
-        return [];
98
-    }
99
-
100
-    /**
101
-     * Returns the full principal url.
102
-     *
103
-     * @return string
104
-     */
105
-    public function getPrincipalUrl()
106
-    {
107
-        return $this->principalInfo['uri'].'/'.$this->getName();
108
-    }
109
-
110
-    /**
111
-     * Returns the list of group members.
112
-     *
113
-     * If this principal is a group, this function should return
114
-     * all member principal uri's for the group.
115
-     *
116
-     * @return array
117
-     */
118
-    public function getGroupMemberSet()
119
-    {
120
-        return $this->principalBackend->getGroupMemberSet($this->getPrincipalUrl());
121
-    }
122
-
123
-    /**
124
-     * Returns the list of groups this principal is member of.
125
-     *
126
-     * If this principal is a member of a (list of) groups, this function
127
-     * should return a list of principal uri's for it's members.
128
-     *
129
-     * @return array
130
-     */
131
-    public function getGroupMembership()
132
-    {
133
-        return $this->principalBackend->getGroupMembership($this->getPrincipalUrl());
134
-    }
135
-
136
-    /**
137
-     * Sets a list of group members.
138
-     *
139
-     * If this principal is a group, this method sets all the group members.
140
-     * The list of members is always overwritten, never appended to.
141
-     *
142
-     * This method should throw an exception if the members could not be set.
143
-     */
144
-    public function setGroupMemberSet(array $principals)
145
-    {
146
-        $this->principalBackend->setGroupMemberSet($this->getPrincipalUrl(), $principals);
147
-    }
148
-
149
-    /**
150
-     * Returns the displayname.
151
-     *
152
-     * This should be a human readable name for the principal.
153
-     * If none is available, return the nodename.
154
-     *
155
-     * @return string
156
-     */
157
-    public function getDisplayName()
158
-    {
159
-        return $this->getName();
160
-    }
23
+	/**
24
+	 * Parent principal information.
25
+	 *
26
+	 * @var array
27
+	 */
28
+	protected $principalInfo;
29
+
30
+	/**
31
+	 * Principal Backend.
32
+	 *
33
+	 * @var DAVACL\PrincipalBackend\BackendInterface
34
+	 */
35
+	protected $principalBackend;
36
+
37
+	/**
38
+	 * Creates the object.
39
+	 *
40
+	 * Note that you MUST supply the parent principal information.
41
+	 */
42
+	public function __construct(DAVACL\PrincipalBackend\BackendInterface $principalBackend, array $principalInfo)
43
+	{
44
+		$this->principalInfo = $principalInfo;
45
+		$this->principalBackend = $principalBackend;
46
+	}
47
+
48
+	/**
49
+	 * Returns this principals name.
50
+	 *
51
+	 * @return string
52
+	 */
53
+	public function getName()
54
+	{
55
+		return 'calendar-proxy-write';
56
+	}
57
+
58
+	/**
59
+	 * Returns the last modification time.
60
+	 */
61
+	public function getLastModified()
62
+	{
63
+		return null;
64
+	}
65
+
66
+	/**
67
+	 * Deletes the current node.
68
+	 *
69
+	 * @throws DAV\Exception\Forbidden
70
+	 */
71
+	public function delete()
72
+	{
73
+		throw new DAV\Exception\Forbidden('Permission denied to delete node');
74
+	}
75
+
76
+	/**
77
+	 * Renames the node.
78
+	 *
79
+	 * @param string $name The new name
80
+	 *
81
+	 * @throws DAV\Exception\Forbidden
82
+	 */
83
+	public function setName($name)
84
+	{
85
+		throw new DAV\Exception\Forbidden('Permission denied to rename file');
86
+	}
87
+
88
+	/**
89
+	 * Returns a list of alternative urls for a principal.
90
+	 *
91
+	 * This can for example be an email address, or ldap url.
92
+	 *
93
+	 * @return array
94
+	 */
95
+	public function getAlternateUriSet()
96
+	{
97
+		return [];
98
+	}
99
+
100
+	/**
101
+	 * Returns the full principal url.
102
+	 *
103
+	 * @return string
104
+	 */
105
+	public function getPrincipalUrl()
106
+	{
107
+		return $this->principalInfo['uri'].'/'.$this->getName();
108
+	}
109
+
110
+	/**
111
+	 * Returns the list of group members.
112
+	 *
113
+	 * If this principal is a group, this function should return
114
+	 * all member principal uri's for the group.
115
+	 *
116
+	 * @return array
117
+	 */
118
+	public function getGroupMemberSet()
119
+	{
120
+		return $this->principalBackend->getGroupMemberSet($this->getPrincipalUrl());
121
+	}
122
+
123
+	/**
124
+	 * Returns the list of groups this principal is member of.
125
+	 *
126
+	 * If this principal is a member of a (list of) groups, this function
127
+	 * should return a list of principal uri's for it's members.
128
+	 *
129
+	 * @return array
130
+	 */
131
+	public function getGroupMembership()
132
+	{
133
+		return $this->principalBackend->getGroupMembership($this->getPrincipalUrl());
134
+	}
135
+
136
+	/**
137
+	 * Sets a list of group members.
138
+	 *
139
+	 * If this principal is a group, this method sets all the group members.
140
+	 * The list of members is always overwritten, never appended to.
141
+	 *
142
+	 * This method should throw an exception if the members could not be set.
143
+	 */
144
+	public function setGroupMemberSet(array $principals)
145
+	{
146
+		$this->principalBackend->setGroupMemberSet($this->getPrincipalUrl(), $principals);
147
+	}
148
+
149
+	/**
150
+	 * Returns the displayname.
151
+	 *
152
+	 * This should be a human readable name for the principal.
153
+	 * If none is available, return the nodename.
154
+	 *
155
+	 * @return string
156
+	 */
157
+	public function getDisplayName()
158
+	{
159
+		return $this->getName();
160
+	}
161 161
 }
Please login to merge, or discard this patch.
htdocs/includes/sabre/sabre/dav/lib/CalDAV/ICSExportPlugin.php 1 patch
Indentation   +326 added lines, -326 removed lines patch added patch discarded remove patch
@@ -48,330 +48,330 @@
 block discarded – undo
48 48
  */
49 49
 class ICSExportPlugin extends DAV\ServerPlugin
50 50
 {
51
-    /**
52
-     * Reference to Server class.
53
-     *
54
-     * @var \Sabre\DAV\Server
55
-     */
56
-    protected $server;
57
-
58
-    /**
59
-     * Initializes the plugin and registers event handlers.
60
-     *
61
-     * @param \Sabre\DAV\Server $server
62
-     */
63
-    public function initialize(DAV\Server $server)
64
-    {
65
-        $this->server = $server;
66
-        $server->on('method:GET', [$this, 'httpGet'], 90);
67
-        $server->on('browserButtonActions', function ($path, $node, &$actions) {
68
-            if ($node instanceof ICalendar) {
69
-                $actions .= '<a href="'.htmlspecialchars($path, ENT_QUOTES, 'UTF-8').'?export"><span class="oi" data-glyph="calendar"></span></a>';
70
-            }
71
-        });
72
-    }
73
-
74
-    /**
75
-     * Intercepts GET requests on calendar urls ending with ?export.
76
-     *
77
-     * @throws BadRequest
78
-     * @throws DAV\Exception\NotFound
79
-     * @throws VObject\InvalidDataException
80
-     *
81
-     * @return bool
82
-     */
83
-    public function httpGet(RequestInterface $request, ResponseInterface $response)
84
-    {
85
-        $queryParams = $request->getQueryParameters();
86
-        if (!array_key_exists('export', $queryParams)) {
87
-            return;
88
-        }
89
-
90
-        $path = $request->getPath();
91
-
92
-        $node = $this->server->getProperties($path, [
93
-            '{DAV:}resourcetype',
94
-            '{DAV:}displayname',
95
-            '{http://sabredav.org/ns}sync-token',
96
-            '{DAV:}sync-token',
97
-            '{http://apple.com/ns/ical/}calendar-color',
98
-        ]);
99
-
100
-        if (!isset($node['{DAV:}resourcetype']) || !$node['{DAV:}resourcetype']->is('{'.Plugin::NS_CALDAV.'}calendar')) {
101
-            return;
102
-        }
103
-        // Marking the transactionType, for logging purposes.
104
-        $this->server->transactionType = 'get-calendar-export';
105
-
106
-        $properties = $node;
107
-
108
-        $start = null;
109
-        $end = null;
110
-        $expand = false;
111
-        $componentType = false;
112
-        if (isset($queryParams['start'])) {
113
-            if (!ctype_digit($queryParams['start'])) {
114
-                throw new BadRequest('The start= parameter must contain a unix timestamp');
115
-            }
116
-            $start = DateTime::createFromFormat('U', $queryParams['start']);
117
-        }
118
-        if (isset($queryParams['end'])) {
119
-            if (!ctype_digit($queryParams['end'])) {
120
-                throw new BadRequest('The end= parameter must contain a unix timestamp');
121
-            }
122
-            $end = DateTime::createFromFormat('U', $queryParams['end']);
123
-        }
124
-        if (isset($queryParams['expand']) && (bool) $queryParams['expand']) {
125
-            if (!$start || !$end) {
126
-                throw new BadRequest('If you\'d like to expand recurrences, you must specify both a start= and end= parameter.');
127
-            }
128
-            $expand = true;
129
-            $componentType = 'VEVENT';
130
-        }
131
-        if (isset($queryParams['componentType'])) {
132
-            if (!in_array($queryParams['componentType'], ['VEVENT', 'VTODO', 'VJOURNAL'])) {
133
-                throw new BadRequest('You are not allowed to search for components of type: '.$queryParams['componentType'].' here');
134
-            }
135
-            $componentType = $queryParams['componentType'];
136
-        }
137
-
138
-        $format = \Sabre\HTTP\negotiateContentType(
139
-            $request->getHeader('Accept'),
140
-            [
141
-                'text/calendar',
142
-                'application/calendar+json',
143
-            ]
144
-        );
145
-
146
-        if (isset($queryParams['accept'])) {
147
-            if ('application/calendar+json' === $queryParams['accept'] || 'jcal' === $queryParams['accept']) {
148
-                $format = 'application/calendar+json';
149
-            }
150
-        }
151
-        if (!$format) {
152
-            $format = 'text/calendar';
153
-        }
154
-
155
-        $this->generateResponse($path, $start, $end, $expand, $componentType, $format, $properties, $response);
156
-
157
-        // Returning false to break the event chain
158
-        return false;
159
-    }
160
-
161
-    /**
162
-     * This method is responsible for generating the actual, full response.
163
-     *
164
-     * @param string        $path
165
-     * @param DateTime|null $start
166
-     * @param DateTime|null $end
167
-     * @param bool          $expand
168
-     * @param string        $componentType
169
-     * @param string        $format
170
-     * @param array         $properties
171
-     *
172
-     * @throws DAV\Exception\NotFound
173
-     * @throws VObject\InvalidDataException
174
-     */
175
-    protected function generateResponse($path, $start, $end, $expand, $componentType, $format, $properties, ResponseInterface $response)
176
-    {
177
-        $calDataProp = '{'.Plugin::NS_CALDAV.'}calendar-data';
178
-        $calendarNode = $this->server->tree->getNodeForPath($path);
179
-
180
-        $blobs = [];
181
-        if ($start || $end || $componentType) {
182
-            // If there was a start or end filter, we need to enlist
183
-            // calendarQuery for speed.
184
-            $queryResult = $calendarNode->calendarQuery([
185
-                'name' => 'VCALENDAR',
186
-                'comp-filters' => [
187
-                    [
188
-                        'name' => $componentType,
189
-                        'comp-filters' => [],
190
-                        'prop-filters' => [],
191
-                        'is-not-defined' => false,
192
-                        'time-range' => [
193
-                            'start' => $start,
194
-                            'end' => $end,
195
-                        ],
196
-                    ],
197
-                ],
198
-                'prop-filters' => [],
199
-                'is-not-defined' => false,
200
-                'time-range' => null,
201
-            ]);
202
-
203
-            // queryResult is just a list of base urls. We need to prefix the
204
-            // calendar path.
205
-            $queryResult = array_map(
206
-                function ($item) use ($path) {
207
-                    return $path.'/'.$item;
208
-                },
209
-                $queryResult
210
-            );
211
-            $nodes = $this->server->getPropertiesForMultiplePaths($queryResult, [$calDataProp]);
212
-            unset($queryResult);
213
-        } else {
214
-            $nodes = $this->server->getPropertiesForPath($path, [$calDataProp], 1);
215
-        }
216
-
217
-        // Flattening the arrays
218
-        foreach ($nodes as $node) {
219
-            if (isset($node[200][$calDataProp])) {
220
-                $blobs[$node['href']] = $node[200][$calDataProp];
221
-            }
222
-        }
223
-        unset($nodes);
224
-
225
-        $mergedCalendar = $this->mergeObjects(
226
-            $properties,
227
-            $blobs
228
-        );
229
-
230
-        if ($expand) {
231
-            $calendarTimeZone = null;
232
-            // We're expanding, and for that we need to figure out the
233
-            // calendar's timezone.
234
-            $tzProp = '{'.Plugin::NS_CALDAV.'}calendar-timezone';
235
-            $tzResult = $this->server->getProperties($path, [$tzProp]);
236
-            if (isset($tzResult[$tzProp])) {
237
-                // This property contains a VCALENDAR with a single
238
-                // VTIMEZONE.
239
-                $vtimezoneObj = VObject\Reader::read($tzResult[$tzProp]);
240
-                $calendarTimeZone = $vtimezoneObj->VTIMEZONE->getTimeZone();
241
-                // Destroy circular references to PHP will GC the object.
242
-                $vtimezoneObj->destroy();
243
-                unset($vtimezoneObj);
244
-            } else {
245
-                // Defaulting to UTC.
246
-                $calendarTimeZone = new DateTimeZone('UTC');
247
-            }
248
-
249
-            $mergedCalendar = $mergedCalendar->expand($start, $end, $calendarTimeZone);
250
-        }
251
-
252
-        $filenameExtension = '.ics';
253
-
254
-        switch ($format) {
255
-            case 'text/calendar':
256
-                $mergedCalendar = $mergedCalendar->serialize();
257
-                $filenameExtension = '.ics';
258
-                break;
259
-            case 'application/calendar+json':
260
-                $mergedCalendar = json_encode($mergedCalendar->jsonSerialize());
261
-                $filenameExtension = '.json';
262
-                break;
263
-        }
264
-
265
-        $filename = preg_replace(
266
-            '/[^a-zA-Z0-9-_ ]/um',
267
-            '',
268
-            $calendarNode->getName()
269
-        );
270
-        $filename .= '-'.date('Y-m-d').$filenameExtension;
271
-
272
-        $response->setHeader('Content-Disposition', 'attachment; filename="'.$filename.'"');
273
-        $response->setHeader('Content-Type', $format);
274
-
275
-        $response->setStatus(200);
276
-        $response->setBody($mergedCalendar);
277
-    }
278
-
279
-    /**
280
-     * Merges all calendar objects, and builds one big iCalendar blob.
281
-     *
282
-     * @param array $properties Some CalDAV properties
283
-     *
284
-     * @return VObject\Component\VCalendar
285
-     */
286
-    public function mergeObjects(array $properties, array $inputObjects)
287
-    {
288
-        $calendar = new VObject\Component\VCalendar();
289
-        $calendar->VERSION = '2.0';
290
-        if (DAV\Server::$exposeVersion) {
291
-            $calendar->PRODID = '-//SabreDAV//SabreDAV '.DAV\Version::VERSION.'//EN';
292
-        } else {
293
-            $calendar->PRODID = '-//SabreDAV//SabreDAV//EN';
294
-        }
295
-        if (isset($properties['{DAV:}displayname'])) {
296
-            $calendar->{'X-WR-CALNAME'} = $properties['{DAV:}displayname'];
297
-        }
298
-        if (isset($properties['{http://apple.com/ns/ical/}calendar-color'])) {
299
-            $calendar->{'X-APPLE-CALENDAR-COLOR'} = $properties['{http://apple.com/ns/ical/}calendar-color'];
300
-        }
301
-
302
-        $collectedTimezones = [];
303
-
304
-        $timezones = [];
305
-        $objects = [];
306
-
307
-        foreach ($inputObjects as $href => $inputObject) {
308
-            $nodeComp = VObject\Reader::read($inputObject);
309
-
310
-            foreach ($nodeComp->children() as $child) {
311
-                switch ($child->name) {
312
-                    case 'VEVENT':
313
-                    case 'VTODO':
314
-                    case 'VJOURNAL':
315
-                        $objects[] = clone $child;
316
-                        break;
317
-
318
-                    // VTIMEZONE is special, because we need to filter out the duplicates
319
-                    case 'VTIMEZONE':
320
-                        // Naively just checking tzid.
321
-                        if (in_array((string) $child->TZID, $collectedTimezones)) {
322
-                            break;
323
-                        }
324
-
325
-                        $timezones[] = clone $child;
326
-                        $collectedTimezones[] = $child->TZID;
327
-                        break;
328
-                }
329
-            }
330
-            // Destroy circular references to PHP will GC the object.
331
-            $nodeComp->destroy();
332
-            unset($nodeComp);
333
-        }
334
-
335
-        foreach ($timezones as $tz) {
336
-            $calendar->add($tz);
337
-        }
338
-        foreach ($objects as $obj) {
339
-            $calendar->add($obj);
340
-        }
341
-
342
-        return $calendar;
343
-    }
344
-
345
-    /**
346
-     * Returns a plugin name.
347
-     *
348
-     * Using this name other plugins will be able to access other plugins
349
-     * using \Sabre\DAV\Server::getPlugin
350
-     *
351
-     * @return string
352
-     */
353
-    public function getPluginName()
354
-    {
355
-        return 'ics-export';
356
-    }
357
-
358
-    /**
359
-     * Returns a bunch of meta-data about the plugin.
360
-     *
361
-     * Providing this information is optional, and is mainly displayed by the
362
-     * Browser plugin.
363
-     *
364
-     * The description key in the returned array may contain html and will not
365
-     * be sanitized.
366
-     *
367
-     * @return array
368
-     */
369
-    public function getPluginInfo()
370
-    {
371
-        return [
372
-            'name' => $this->getPluginName(),
373
-            'description' => 'Adds the ability to export CalDAV calendars as a single iCalendar file.',
374
-            'link' => 'http://sabre.io/dav/ics-export-plugin/',
375
-        ];
376
-    }
51
+	/**
52
+	 * Reference to Server class.
53
+	 *
54
+	 * @var \Sabre\DAV\Server
55
+	 */
56
+	protected $server;
57
+
58
+	/**
59
+	 * Initializes the plugin and registers event handlers.
60
+	 *
61
+	 * @param \Sabre\DAV\Server $server
62
+	 */
63
+	public function initialize(DAV\Server $server)
64
+	{
65
+		$this->server = $server;
66
+		$server->on('method:GET', [$this, 'httpGet'], 90);
67
+		$server->on('browserButtonActions', function ($path, $node, &$actions) {
68
+			if ($node instanceof ICalendar) {
69
+				$actions .= '<a href="'.htmlspecialchars($path, ENT_QUOTES, 'UTF-8').'?export"><span class="oi" data-glyph="calendar"></span></a>';
70
+			}
71
+		});
72
+	}
73
+
74
+	/**
75
+	 * Intercepts GET requests on calendar urls ending with ?export.
76
+	 *
77
+	 * @throws BadRequest
78
+	 * @throws DAV\Exception\NotFound
79
+	 * @throws VObject\InvalidDataException
80
+	 *
81
+	 * @return bool
82
+	 */
83
+	public function httpGet(RequestInterface $request, ResponseInterface $response)
84
+	{
85
+		$queryParams = $request->getQueryParameters();
86
+		if (!array_key_exists('export', $queryParams)) {
87
+			return;
88
+		}
89
+
90
+		$path = $request->getPath();
91
+
92
+		$node = $this->server->getProperties($path, [
93
+			'{DAV:}resourcetype',
94
+			'{DAV:}displayname',
95
+			'{http://sabredav.org/ns}sync-token',
96
+			'{DAV:}sync-token',
97
+			'{http://apple.com/ns/ical/}calendar-color',
98
+		]);
99
+
100
+		if (!isset($node['{DAV:}resourcetype']) || !$node['{DAV:}resourcetype']->is('{'.Plugin::NS_CALDAV.'}calendar')) {
101
+			return;
102
+		}
103
+		// Marking the transactionType, for logging purposes.
104
+		$this->server->transactionType = 'get-calendar-export';
105
+
106
+		$properties = $node;
107
+
108
+		$start = null;
109
+		$end = null;
110
+		$expand = false;
111
+		$componentType = false;
112
+		if (isset($queryParams['start'])) {
113
+			if (!ctype_digit($queryParams['start'])) {
114
+				throw new BadRequest('The start= parameter must contain a unix timestamp');
115
+			}
116
+			$start = DateTime::createFromFormat('U', $queryParams['start']);
117
+		}
118
+		if (isset($queryParams['end'])) {
119
+			if (!ctype_digit($queryParams['end'])) {
120
+				throw new BadRequest('The end= parameter must contain a unix timestamp');
121
+			}
122
+			$end = DateTime::createFromFormat('U', $queryParams['end']);
123
+		}
124
+		if (isset($queryParams['expand']) && (bool) $queryParams['expand']) {
125
+			if (!$start || !$end) {
126
+				throw new BadRequest('If you\'d like to expand recurrences, you must specify both a start= and end= parameter.');
127
+			}
128
+			$expand = true;
129
+			$componentType = 'VEVENT';
130
+		}
131
+		if (isset($queryParams['componentType'])) {
132
+			if (!in_array($queryParams['componentType'], ['VEVENT', 'VTODO', 'VJOURNAL'])) {
133
+				throw new BadRequest('You are not allowed to search for components of type: '.$queryParams['componentType'].' here');
134
+			}
135
+			$componentType = $queryParams['componentType'];
136
+		}
137
+
138
+		$format = \Sabre\HTTP\negotiateContentType(
139
+			$request->getHeader('Accept'),
140
+			[
141
+				'text/calendar',
142
+				'application/calendar+json',
143
+			]
144
+		);
145
+
146
+		if (isset($queryParams['accept'])) {
147
+			if ('application/calendar+json' === $queryParams['accept'] || 'jcal' === $queryParams['accept']) {
148
+				$format = 'application/calendar+json';
149
+			}
150
+		}
151
+		if (!$format) {
152
+			$format = 'text/calendar';
153
+		}
154
+
155
+		$this->generateResponse($path, $start, $end, $expand, $componentType, $format, $properties, $response);
156
+
157
+		// Returning false to break the event chain
158
+		return false;
159
+	}
160
+
161
+	/**
162
+	 * This method is responsible for generating the actual, full response.
163
+	 *
164
+	 * @param string        $path
165
+	 * @param DateTime|null $start
166
+	 * @param DateTime|null $end
167
+	 * @param bool          $expand
168
+	 * @param string        $componentType
169
+	 * @param string        $format
170
+	 * @param array         $properties
171
+	 *
172
+	 * @throws DAV\Exception\NotFound
173
+	 * @throws VObject\InvalidDataException
174
+	 */
175
+	protected function generateResponse($path, $start, $end, $expand, $componentType, $format, $properties, ResponseInterface $response)
176
+	{
177
+		$calDataProp = '{'.Plugin::NS_CALDAV.'}calendar-data';
178
+		$calendarNode = $this->server->tree->getNodeForPath($path);
179
+
180
+		$blobs = [];
181
+		if ($start || $end || $componentType) {
182
+			// If there was a start or end filter, we need to enlist
183
+			// calendarQuery for speed.
184
+			$queryResult = $calendarNode->calendarQuery([
185
+				'name' => 'VCALENDAR',
186
+				'comp-filters' => [
187
+					[
188
+						'name' => $componentType,
189
+						'comp-filters' => [],
190
+						'prop-filters' => [],
191
+						'is-not-defined' => false,
192
+						'time-range' => [
193
+							'start' => $start,
194
+							'end' => $end,
195
+						],
196
+					],
197
+				],
198
+				'prop-filters' => [],
199
+				'is-not-defined' => false,
200
+				'time-range' => null,
201
+			]);
202
+
203
+			// queryResult is just a list of base urls. We need to prefix the
204
+			// calendar path.
205
+			$queryResult = array_map(
206
+				function ($item) use ($path) {
207
+					return $path.'/'.$item;
208
+				},
209
+				$queryResult
210
+			);
211
+			$nodes = $this->server->getPropertiesForMultiplePaths($queryResult, [$calDataProp]);
212
+			unset($queryResult);
213
+		} else {
214
+			$nodes = $this->server->getPropertiesForPath($path, [$calDataProp], 1);
215
+		}
216
+
217
+		// Flattening the arrays
218
+		foreach ($nodes as $node) {
219
+			if (isset($node[200][$calDataProp])) {
220
+				$blobs[$node['href']] = $node[200][$calDataProp];
221
+			}
222
+		}
223
+		unset($nodes);
224
+
225
+		$mergedCalendar = $this->mergeObjects(
226
+			$properties,
227
+			$blobs
228
+		);
229
+
230
+		if ($expand) {
231
+			$calendarTimeZone = null;
232
+			// We're expanding, and for that we need to figure out the
233
+			// calendar's timezone.
234
+			$tzProp = '{'.Plugin::NS_CALDAV.'}calendar-timezone';
235
+			$tzResult = $this->server->getProperties($path, [$tzProp]);
236
+			if (isset($tzResult[$tzProp])) {
237
+				// This property contains a VCALENDAR with a single
238
+				// VTIMEZONE.
239
+				$vtimezoneObj = VObject\Reader::read($tzResult[$tzProp]);
240
+				$calendarTimeZone = $vtimezoneObj->VTIMEZONE->getTimeZone();
241
+				// Destroy circular references to PHP will GC the object.
242
+				$vtimezoneObj->destroy();
243
+				unset($vtimezoneObj);
244
+			} else {
245
+				// Defaulting to UTC.
246
+				$calendarTimeZone = new DateTimeZone('UTC');
247
+			}
248
+
249
+			$mergedCalendar = $mergedCalendar->expand($start, $end, $calendarTimeZone);
250
+		}
251
+
252
+		$filenameExtension = '.ics';
253
+
254
+		switch ($format) {
255
+			case 'text/calendar':
256
+				$mergedCalendar = $mergedCalendar->serialize();
257
+				$filenameExtension = '.ics';
258
+				break;
259
+			case 'application/calendar+json':
260
+				$mergedCalendar = json_encode($mergedCalendar->jsonSerialize());
261
+				$filenameExtension = '.json';
262
+				break;
263
+		}
264
+
265
+		$filename = preg_replace(
266
+			'/[^a-zA-Z0-9-_ ]/um',
267
+			'',
268
+			$calendarNode->getName()
269
+		);
270
+		$filename .= '-'.date('Y-m-d').$filenameExtension;
271
+
272
+		$response->setHeader('Content-Disposition', 'attachment; filename="'.$filename.'"');
273
+		$response->setHeader('Content-Type', $format);
274
+
275
+		$response->setStatus(200);
276
+		$response->setBody($mergedCalendar);
277
+	}
278
+
279
+	/**
280
+	 * Merges all calendar objects, and builds one big iCalendar blob.
281
+	 *
282
+	 * @param array $properties Some CalDAV properties
283
+	 *
284
+	 * @return VObject\Component\VCalendar
285
+	 */
286
+	public function mergeObjects(array $properties, array $inputObjects)
287
+	{
288
+		$calendar = new VObject\Component\VCalendar();
289
+		$calendar->VERSION = '2.0';
290
+		if (DAV\Server::$exposeVersion) {
291
+			$calendar->PRODID = '-//SabreDAV//SabreDAV '.DAV\Version::VERSION.'//EN';
292
+		} else {
293
+			$calendar->PRODID = '-//SabreDAV//SabreDAV//EN';
294
+		}
295
+		if (isset($properties['{DAV:}displayname'])) {
296
+			$calendar->{'X-WR-CALNAME'} = $properties['{DAV:}displayname'];
297
+		}
298
+		if (isset($properties['{http://apple.com/ns/ical/}calendar-color'])) {
299
+			$calendar->{'X-APPLE-CALENDAR-COLOR'} = $properties['{http://apple.com/ns/ical/}calendar-color'];
300
+		}
301
+
302
+		$collectedTimezones = [];
303
+
304
+		$timezones = [];
305
+		$objects = [];
306
+
307
+		foreach ($inputObjects as $href => $inputObject) {
308
+			$nodeComp = VObject\Reader::read($inputObject);
309
+
310
+			foreach ($nodeComp->children() as $child) {
311
+				switch ($child->name) {
312
+					case 'VEVENT':
313
+					case 'VTODO':
314
+					case 'VJOURNAL':
315
+						$objects[] = clone $child;
316
+						break;
317
+
318
+					// VTIMEZONE is special, because we need to filter out the duplicates
319
+					case 'VTIMEZONE':
320
+						// Naively just checking tzid.
321
+						if (in_array((string) $child->TZID, $collectedTimezones)) {
322
+							break;
323
+						}
324
+
325
+						$timezones[] = clone $child;
326
+						$collectedTimezones[] = $child->TZID;
327
+						break;
328
+				}
329
+			}
330
+			// Destroy circular references to PHP will GC the object.
331
+			$nodeComp->destroy();
332
+			unset($nodeComp);
333
+		}
334
+
335
+		foreach ($timezones as $tz) {
336
+			$calendar->add($tz);
337
+		}
338
+		foreach ($objects as $obj) {
339
+			$calendar->add($obj);
340
+		}
341
+
342
+		return $calendar;
343
+	}
344
+
345
+	/**
346
+	 * Returns a plugin name.
347
+	 *
348
+	 * Using this name other plugins will be able to access other plugins
349
+	 * using \Sabre\DAV\Server::getPlugin
350
+	 *
351
+	 * @return string
352
+	 */
353
+	public function getPluginName()
354
+	{
355
+		return 'ics-export';
356
+	}
357
+
358
+	/**
359
+	 * Returns a bunch of meta-data about the plugin.
360
+	 *
361
+	 * Providing this information is optional, and is mainly displayed by the
362
+	 * Browser plugin.
363
+	 *
364
+	 * The description key in the returned array may contain html and will not
365
+	 * be sanitized.
366
+	 *
367
+	 * @return array
368
+	 */
369
+	public function getPluginInfo()
370
+	{
371
+		return [
372
+			'name' => $this->getPluginName(),
373
+			'description' => 'Adds the ability to export CalDAV calendars as a single iCalendar file.',
374
+			'link' => 'http://sabre.io/dav/ics-export-plugin/',
375
+		];
376
+	}
377 377
 }
Please login to merge, or discard this patch.
htdocs/includes/sabre/sabre/dav/lib/CalDAV/Backend/BackendInterface.php 1 patch
Indentation   +246 added lines, -246 removed lines patch added patch discarded remove patch
@@ -13,261 +13,261 @@
 block discarded – undo
13 13
  */
14 14
 interface BackendInterface
15 15
 {
16
-    /**
17
-     * Returns a list of calendars for a principal.
18
-     *
19
-     * Every project is an array with the following keys:
20
-     *  * id, a unique id that will be used by other functions to modify the
21
-     *    calendar. This can be the same as the uri or a database key.
22
-     *  * uri, which is the basename of the uri with which the calendar is
23
-     *    accessed.
24
-     *  * principaluri. The owner of the calendar. Almost always the same as
25
-     *    principalUri passed to this method.
26
-     *
27
-     * Furthermore it can contain webdav properties in clark notation. A very
28
-     * common one is '{DAV:}displayname'.
29
-     *
30
-     * Many clients also require:
31
-     * {urn:ietf:params:xml:ns:caldav}supported-calendar-component-set
32
-     * For this property, you can just return an instance of
33
-     * Sabre\CalDAV\Property\SupportedCalendarComponentSet.
34
-     *
35
-     * If you return {http://sabredav.org/ns}read-only and set the value to 1,
36
-     * ACL will automatically be put in read-only mode.
37
-     *
38
-     * @param string $principalUri
39
-     *
40
-     * @return array
41
-     */
42
-    public function getCalendarsForUser($principalUri);
16
+	/**
17
+	 * Returns a list of calendars for a principal.
18
+	 *
19
+	 * Every project is an array with the following keys:
20
+	 *  * id, a unique id that will be used by other functions to modify the
21
+	 *    calendar. This can be the same as the uri or a database key.
22
+	 *  * uri, which is the basename of the uri with which the calendar is
23
+	 *    accessed.
24
+	 *  * principaluri. The owner of the calendar. Almost always the same as
25
+	 *    principalUri passed to this method.
26
+	 *
27
+	 * Furthermore it can contain webdav properties in clark notation. A very
28
+	 * common one is '{DAV:}displayname'.
29
+	 *
30
+	 * Many clients also require:
31
+	 * {urn:ietf:params:xml:ns:caldav}supported-calendar-component-set
32
+	 * For this property, you can just return an instance of
33
+	 * Sabre\CalDAV\Property\SupportedCalendarComponentSet.
34
+	 *
35
+	 * If you return {http://sabredav.org/ns}read-only and set the value to 1,
36
+	 * ACL will automatically be put in read-only mode.
37
+	 *
38
+	 * @param string $principalUri
39
+	 *
40
+	 * @return array
41
+	 */
42
+	public function getCalendarsForUser($principalUri);
43 43
 
44
-    /**
45
-     * Creates a new calendar for a principal.
46
-     *
47
-     * If the creation was a success, an id must be returned that can be used to
48
-     * reference this calendar in other methods, such as updateCalendar.
49
-     *
50
-     * The id can be any type, including ints, strings, objects or array.
51
-     *
52
-     * @param string $principalUri
53
-     * @param string $calendarUri
54
-     *
55
-     * @return mixed
56
-     */
57
-    public function createCalendar($principalUri, $calendarUri, array $properties);
44
+	/**
45
+	 * Creates a new calendar for a principal.
46
+	 *
47
+	 * If the creation was a success, an id must be returned that can be used to
48
+	 * reference this calendar in other methods, such as updateCalendar.
49
+	 *
50
+	 * The id can be any type, including ints, strings, objects or array.
51
+	 *
52
+	 * @param string $principalUri
53
+	 * @param string $calendarUri
54
+	 *
55
+	 * @return mixed
56
+	 */
57
+	public function createCalendar($principalUri, $calendarUri, array $properties);
58 58
 
59
-    /**
60
-     * Updates properties for a calendar.
61
-     *
62
-     * The list of mutations is stored in a Sabre\DAV\PropPatch object.
63
-     * To do the actual updates, you must tell this object which properties
64
-     * you're going to process with the handle() method.
65
-     *
66
-     * Calling the handle method is like telling the PropPatch object "I
67
-     * promise I can handle updating this property".
68
-     *
69
-     * Read the PropPatch documentation for more info and examples.
70
-     *
71
-     * @param mixed $calendarId
72
-     */
73
-    public function updateCalendar($calendarId, \Sabre\DAV\PropPatch $propPatch);
59
+	/**
60
+	 * Updates properties for a calendar.
61
+	 *
62
+	 * The list of mutations is stored in a Sabre\DAV\PropPatch object.
63
+	 * To do the actual updates, you must tell this object which properties
64
+	 * you're going to process with the handle() method.
65
+	 *
66
+	 * Calling the handle method is like telling the PropPatch object "I
67
+	 * promise I can handle updating this property".
68
+	 *
69
+	 * Read the PropPatch documentation for more info and examples.
70
+	 *
71
+	 * @param mixed $calendarId
72
+	 */
73
+	public function updateCalendar($calendarId, \Sabre\DAV\PropPatch $propPatch);
74 74
 
75
-    /**
76
-     * Delete a calendar and all its objects.
77
-     *
78
-     * @param mixed $calendarId
79
-     */
80
-    public function deleteCalendar($calendarId);
75
+	/**
76
+	 * Delete a calendar and all its objects.
77
+	 *
78
+	 * @param mixed $calendarId
79
+	 */
80
+	public function deleteCalendar($calendarId);
81 81
 
82
-    /**
83
-     * Returns all calendar objects within a calendar.
84
-     *
85
-     * Every item contains an array with the following keys:
86
-     *   * calendardata - The iCalendar-compatible calendar data
87
-     *   * uri - a unique key which will be used to construct the uri. This can
88
-     *     be any arbitrary string, but making sure it ends with '.ics' is a
89
-     *     good idea. This is only the basename, or filename, not the full
90
-     *     path.
91
-     *   * lastmodified - a timestamp of the last modification time
92
-     *   * etag - An arbitrary string, surrounded by double-quotes. (e.g.:
93
-     *   '"abcdef"')
94
-     *   * size - The size of the calendar objects, in bytes.
95
-     *   * component - optional, a string containing the type of object, such
96
-     *     as 'vevent' or 'vtodo'. If specified, this will be used to populate
97
-     *     the Content-Type header.
98
-     *
99
-     * Note that the etag is optional, but it's highly encouraged to return for
100
-     * speed reasons.
101
-     *
102
-     * The calendardata is also optional. If it's not returned
103
-     * 'getCalendarObject' will be called later, which *is* expected to return
104
-     * calendardata.
105
-     *
106
-     * If neither etag or size are specified, the calendardata will be
107
-     * used/fetched to determine these numbers. If both are specified the
108
-     * amount of times this is needed is reduced by a great degree.
109
-     *
110
-     * @param mixed $calendarId
111
-     *
112
-     * @return array
113
-     */
114
-    public function getCalendarObjects($calendarId);
82
+	/**
83
+	 * Returns all calendar objects within a calendar.
84
+	 *
85
+	 * Every item contains an array with the following keys:
86
+	 *   * calendardata - The iCalendar-compatible calendar data
87
+	 *   * uri - a unique key which will be used to construct the uri. This can
88
+	 *     be any arbitrary string, but making sure it ends with '.ics' is a
89
+	 *     good idea. This is only the basename, or filename, not the full
90
+	 *     path.
91
+	 *   * lastmodified - a timestamp of the last modification time
92
+	 *   * etag - An arbitrary string, surrounded by double-quotes. (e.g.:
93
+	 *   '"abcdef"')
94
+	 *   * size - The size of the calendar objects, in bytes.
95
+	 *   * component - optional, a string containing the type of object, such
96
+	 *     as 'vevent' or 'vtodo'. If specified, this will be used to populate
97
+	 *     the Content-Type header.
98
+	 *
99
+	 * Note that the etag is optional, but it's highly encouraged to return for
100
+	 * speed reasons.
101
+	 *
102
+	 * The calendardata is also optional. If it's not returned
103
+	 * 'getCalendarObject' will be called later, which *is* expected to return
104
+	 * calendardata.
105
+	 *
106
+	 * If neither etag or size are specified, the calendardata will be
107
+	 * used/fetched to determine these numbers. If both are specified the
108
+	 * amount of times this is needed is reduced by a great degree.
109
+	 *
110
+	 * @param mixed $calendarId
111
+	 *
112
+	 * @return array
113
+	 */
114
+	public function getCalendarObjects($calendarId);
115 115
 
116
-    /**
117
-     * Returns information from a single calendar object, based on it's object
118
-     * uri.
119
-     *
120
-     * The object uri is only the basename, or filename and not a full path.
121
-     *
122
-     * The returned array must have the same keys as getCalendarObjects. The
123
-     * 'calendardata' object is required here though, while it's not required
124
-     * for getCalendarObjects.
125
-     *
126
-     * This method must return null if the object did not exist.
127
-     *
128
-     * @param mixed  $calendarId
129
-     * @param string $objectUri
130
-     *
131
-     * @return array|null
132
-     */
133
-    public function getCalendarObject($calendarId, $objectUri);
116
+	/**
117
+	 * Returns information from a single calendar object, based on it's object
118
+	 * uri.
119
+	 *
120
+	 * The object uri is only the basename, or filename and not a full path.
121
+	 *
122
+	 * The returned array must have the same keys as getCalendarObjects. The
123
+	 * 'calendardata' object is required here though, while it's not required
124
+	 * for getCalendarObjects.
125
+	 *
126
+	 * This method must return null if the object did not exist.
127
+	 *
128
+	 * @param mixed  $calendarId
129
+	 * @param string $objectUri
130
+	 *
131
+	 * @return array|null
132
+	 */
133
+	public function getCalendarObject($calendarId, $objectUri);
134 134
 
135
-    /**
136
-     * Returns a list of calendar objects.
137
-     *
138
-     * This method should work identical to getCalendarObject, but instead
139
-     * return all the calendar objects in the list as an array.
140
-     *
141
-     * If the backend supports this, it may allow for some speed-ups.
142
-     *
143
-     * @param mixed $calendarId
144
-     *
145
-     * @return array
146
-     */
147
-    public function getMultipleCalendarObjects($calendarId, array $uris);
135
+	/**
136
+	 * Returns a list of calendar objects.
137
+	 *
138
+	 * This method should work identical to getCalendarObject, but instead
139
+	 * return all the calendar objects in the list as an array.
140
+	 *
141
+	 * If the backend supports this, it may allow for some speed-ups.
142
+	 *
143
+	 * @param mixed $calendarId
144
+	 *
145
+	 * @return array
146
+	 */
147
+	public function getMultipleCalendarObjects($calendarId, array $uris);
148 148
 
149
-    /**
150
-     * Creates a new calendar object.
151
-     *
152
-     * The object uri is only the basename, or filename and not a full path.
153
-     *
154
-     * It is possible to return an etag from this function, which will be used
155
-     * in the response to this PUT request. Note that the ETag must be
156
-     * surrounded by double-quotes.
157
-     *
158
-     * However, you should only really return this ETag if you don't mangle the
159
-     * calendar-data. If the result of a subsequent GET to this object is not
160
-     * the exact same as this request body, you should omit the ETag.
161
-     *
162
-     * @param mixed  $calendarId
163
-     * @param string $objectUri
164
-     * @param string $calendarData
165
-     *
166
-     * @return string|null
167
-     */
168
-    public function createCalendarObject($calendarId, $objectUri, $calendarData);
149
+	/**
150
+	 * Creates a new calendar object.
151
+	 *
152
+	 * The object uri is only the basename, or filename and not a full path.
153
+	 *
154
+	 * It is possible to return an etag from this function, which will be used
155
+	 * in the response to this PUT request. Note that the ETag must be
156
+	 * surrounded by double-quotes.
157
+	 *
158
+	 * However, you should only really return this ETag if you don't mangle the
159
+	 * calendar-data. If the result of a subsequent GET to this object is not
160
+	 * the exact same as this request body, you should omit the ETag.
161
+	 *
162
+	 * @param mixed  $calendarId
163
+	 * @param string $objectUri
164
+	 * @param string $calendarData
165
+	 *
166
+	 * @return string|null
167
+	 */
168
+	public function createCalendarObject($calendarId, $objectUri, $calendarData);
169 169
 
170
-    /**
171
-     * Updates an existing calendarobject, based on it's uri.
172
-     *
173
-     * The object uri is only the basename, or filename and not a full path.
174
-     *
175
-     * It is possible return an etag from this function, which will be used in
176
-     * the response to this PUT request. Note that the ETag must be surrounded
177
-     * by double-quotes.
178
-     *
179
-     * However, you should only really return this ETag if you don't mangle the
180
-     * calendar-data. If the result of a subsequent GET to this object is not
181
-     * the exact same as this request body, you should omit the ETag.
182
-     *
183
-     * @param mixed  $calendarId
184
-     * @param string $objectUri
185
-     * @param string $calendarData
186
-     *
187
-     * @return string|null
188
-     */
189
-    public function updateCalendarObject($calendarId, $objectUri, $calendarData);
170
+	/**
171
+	 * Updates an existing calendarobject, based on it's uri.
172
+	 *
173
+	 * The object uri is only the basename, or filename and not a full path.
174
+	 *
175
+	 * It is possible return an etag from this function, which will be used in
176
+	 * the response to this PUT request. Note that the ETag must be surrounded
177
+	 * by double-quotes.
178
+	 *
179
+	 * However, you should only really return this ETag if you don't mangle the
180
+	 * calendar-data. If the result of a subsequent GET to this object is not
181
+	 * the exact same as this request body, you should omit the ETag.
182
+	 *
183
+	 * @param mixed  $calendarId
184
+	 * @param string $objectUri
185
+	 * @param string $calendarData
186
+	 *
187
+	 * @return string|null
188
+	 */
189
+	public function updateCalendarObject($calendarId, $objectUri, $calendarData);
190 190
 
191
-    /**
192
-     * Deletes an existing calendar object.
193
-     *
194
-     * The object uri is only the basename, or filename and not a full path.
195
-     *
196
-     * @param mixed  $calendarId
197
-     * @param string $objectUri
198
-     */
199
-    public function deleteCalendarObject($calendarId, $objectUri);
191
+	/**
192
+	 * Deletes an existing calendar object.
193
+	 *
194
+	 * The object uri is only the basename, or filename and not a full path.
195
+	 *
196
+	 * @param mixed  $calendarId
197
+	 * @param string $objectUri
198
+	 */
199
+	public function deleteCalendarObject($calendarId, $objectUri);
200 200
 
201
-    /**
202
-     * Performs a calendar-query on the contents of this calendar.
203
-     *
204
-     * The calendar-query is defined in RFC4791 : CalDAV. Using the
205
-     * calendar-query it is possible for a client to request a specific set of
206
-     * object, based on contents of iCalendar properties, date-ranges and
207
-     * iCalendar component types (VTODO, VEVENT).
208
-     *
209
-     * This method should just return a list of (relative) urls that match this
210
-     * query.
211
-     *
212
-     * The list of filters are specified as an array. The exact array is
213
-     * documented by Sabre\CalDAV\CalendarQueryParser.
214
-     *
215
-     * Note that it is extremely likely that getCalendarObject for every path
216
-     * returned from this method will be called almost immediately after. You
217
-     * may want to anticipate this to speed up these requests.
218
-     *
219
-     * This method provides a default implementation, which parses *all* the
220
-     * iCalendar objects in the specified calendar.
221
-     *
222
-     * This default may well be good enough for personal use, and calendars
223
-     * that aren't very large. But if you anticipate high usage, big calendars
224
-     * or high loads, you are strongly adviced to optimize certain paths.
225
-     *
226
-     * The best way to do so is override this method and to optimize
227
-     * specifically for 'common filters'.
228
-     *
229
-     * Requests that are extremely common are:
230
-     *   * requests for just VEVENTS
231
-     *   * requests for just VTODO
232
-     *   * requests with a time-range-filter on either VEVENT or VTODO.
233
-     *
234
-     * ..and combinations of these requests. It may not be worth it to try to
235
-     * handle every possible situation and just rely on the (relatively
236
-     * easy to use) CalendarQueryValidator to handle the rest.
237
-     *
238
-     * Note that especially time-range-filters may be difficult to parse. A
239
-     * time-range filter specified on a VEVENT must for instance also handle
240
-     * recurrence rules correctly.
241
-     * A good example of how to interprete all these filters can also simply
242
-     * be found in Sabre\CalDAV\CalendarQueryFilter. This class is as correct
243
-     * as possible, so it gives you a good idea on what type of stuff you need
244
-     * to think of.
245
-     *
246
-     * @param mixed $calendarId
247
-     *
248
-     * @return array
249
-     */
250
-    public function calendarQuery($calendarId, array $filters);
201
+	/**
202
+	 * Performs a calendar-query on the contents of this calendar.
203
+	 *
204
+	 * The calendar-query is defined in RFC4791 : CalDAV. Using the
205
+	 * calendar-query it is possible for a client to request a specific set of
206
+	 * object, based on contents of iCalendar properties, date-ranges and
207
+	 * iCalendar component types (VTODO, VEVENT).
208
+	 *
209
+	 * This method should just return a list of (relative) urls that match this
210
+	 * query.
211
+	 *
212
+	 * The list of filters are specified as an array. The exact array is
213
+	 * documented by Sabre\CalDAV\CalendarQueryParser.
214
+	 *
215
+	 * Note that it is extremely likely that getCalendarObject for every path
216
+	 * returned from this method will be called almost immediately after. You
217
+	 * may want to anticipate this to speed up these requests.
218
+	 *
219
+	 * This method provides a default implementation, which parses *all* the
220
+	 * iCalendar objects in the specified calendar.
221
+	 *
222
+	 * This default may well be good enough for personal use, and calendars
223
+	 * that aren't very large. But if you anticipate high usage, big calendars
224
+	 * or high loads, you are strongly adviced to optimize certain paths.
225
+	 *
226
+	 * The best way to do so is override this method and to optimize
227
+	 * specifically for 'common filters'.
228
+	 *
229
+	 * Requests that are extremely common are:
230
+	 *   * requests for just VEVENTS
231
+	 *   * requests for just VTODO
232
+	 *   * requests with a time-range-filter on either VEVENT or VTODO.
233
+	 *
234
+	 * ..and combinations of these requests. It may not be worth it to try to
235
+	 * handle every possible situation and just rely on the (relatively
236
+	 * easy to use) CalendarQueryValidator to handle the rest.
237
+	 *
238
+	 * Note that especially time-range-filters may be difficult to parse. A
239
+	 * time-range filter specified on a VEVENT must for instance also handle
240
+	 * recurrence rules correctly.
241
+	 * A good example of how to interprete all these filters can also simply
242
+	 * be found in Sabre\CalDAV\CalendarQueryFilter. This class is as correct
243
+	 * as possible, so it gives you a good idea on what type of stuff you need
244
+	 * to think of.
245
+	 *
246
+	 * @param mixed $calendarId
247
+	 *
248
+	 * @return array
249
+	 */
250
+	public function calendarQuery($calendarId, array $filters);
251 251
 
252
-    /**
253
-     * Searches through all of a users calendars and calendar objects to find
254
-     * an object with a specific UID.
255
-     *
256
-     * This method should return the path to this object, relative to the
257
-     * calendar home, so this path usually only contains two parts:
258
-     *
259
-     * calendarpath/objectpath.ics
260
-     *
261
-     * If the uid is not found, return null.
262
-     *
263
-     * This method should only consider * objects that the principal owns, so
264
-     * any calendars owned by other principals that also appear in this
265
-     * collection should be ignored.
266
-     *
267
-     * @param string $principalUri
268
-     * @param string $uid
269
-     *
270
-     * @return string|null
271
-     */
272
-    public function getCalendarObjectByUID($principalUri, $uid);
252
+	/**
253
+	 * Searches through all of a users calendars and calendar objects to find
254
+	 * an object with a specific UID.
255
+	 *
256
+	 * This method should return the path to this object, relative to the
257
+	 * calendar home, so this path usually only contains two parts:
258
+	 *
259
+	 * calendarpath/objectpath.ics
260
+	 *
261
+	 * If the uid is not found, return null.
262
+	 *
263
+	 * This method should only consider * objects that the principal owns, so
264
+	 * any calendars owned by other principals that also appear in this
265
+	 * collection should be ignored.
266
+	 *
267
+	 * @param string $principalUri
268
+	 * @param string $uid
269
+	 *
270
+	 * @return string|null
271
+	 */
272
+	public function getCalendarObjectByUID($principalUri, $uid);
273 273
 }
Please login to merge, or discard this patch.
htdocs/includes/sabre/sabre/dav/lib/CalDAV/Backend/NotificationSupport.php 1 patch
Indentation   +31 added lines, -31 removed lines patch added patch discarded remove patch
@@ -26,37 +26,37 @@
 block discarded – undo
26 26
  */
27 27
 interface NotificationSupport extends BackendInterface
28 28
 {
29
-    /**
30
-     * Returns a list of notifications for a given principal url.
31
-     *
32
-     * @param string $principalUri
33
-     *
34
-     * @return NotificationInterface[]
35
-     */
36
-    public function getNotificationsForPrincipal($principalUri);
29
+	/**
30
+	 * Returns a list of notifications for a given principal url.
31
+	 *
32
+	 * @param string $principalUri
33
+	 *
34
+	 * @return NotificationInterface[]
35
+	 */
36
+	public function getNotificationsForPrincipal($principalUri);
37 37
 
38
-    /**
39
-     * This deletes a specific notifcation.
40
-     *
41
-     * This may be called by a client once it deems a notification handled.
42
-     *
43
-     * @param string $principalUri
44
-     */
45
-    public function deleteNotification($principalUri, NotificationInterface $notification);
38
+	/**
39
+	 * This deletes a specific notifcation.
40
+	 *
41
+	 * This may be called by a client once it deems a notification handled.
42
+	 *
43
+	 * @param string $principalUri
44
+	 */
45
+	public function deleteNotification($principalUri, NotificationInterface $notification);
46 46
 
47
-    /**
48
-     * This method is called when a user replied to a request to share.
49
-     *
50
-     * If the user chose to accept the share, this method should return the
51
-     * newly created calendar url.
52
-     *
53
-     * @param string $href        The sharee who is replying (often a mailto: address)
54
-     * @param int    $status      One of the SharingPlugin::STATUS_* constants
55
-     * @param string $calendarUri The url to the calendar thats being shared
56
-     * @param string $inReplyTo   The unique id this message is a response to
57
-     * @param string $summary     A description of the reply
58
-     *
59
-     * @return string|null
60
-     */
61
-    public function shareReply($href, $status, $calendarUri, $inReplyTo, $summary = null);
47
+	/**
48
+	 * This method is called when a user replied to a request to share.
49
+	 *
50
+	 * If the user chose to accept the share, this method should return the
51
+	 * newly created calendar url.
52
+	 *
53
+	 * @param string $href        The sharee who is replying (often a mailto: address)
54
+	 * @param int    $status      One of the SharingPlugin::STATUS_* constants
55
+	 * @param string $calendarUri The url to the calendar thats being shared
56
+	 * @param string $inReplyTo   The unique id this message is a response to
57
+	 * @param string $summary     A description of the reply
58
+	 *
59
+	 * @return string|null
60
+	 */
61
+	public function shareReply($href, $status, $calendarUri, $inReplyTo, $summary = null);
62 62
 }
Please login to merge, or discard this patch.
htdocs/includes/sabre/sabre/dav/lib/CalDAV/Backend/SimplePDO.php 1 patch
Indentation   +232 added lines, -232 removed lines patch added patch discarded remove patch
@@ -35,255 +35,255 @@
 block discarded – undo
35 35
  */
36 36
 class SimplePDO extends AbstractBackend
37 37
 {
38
-    /**
39
-     * pdo.
40
-     *
41
-     * @var \PDO
42
-     */
43
-    protected $pdo;
38
+	/**
39
+	 * pdo.
40
+	 *
41
+	 * @var \PDO
42
+	 */
43
+	protected $pdo;
44 44
 
45
-    /**
46
-     * Creates the backend.
47
-     */
48
-    public function __construct(\PDO $pdo)
49
-    {
50
-        $this->pdo = $pdo;
51
-    }
45
+	/**
46
+	 * Creates the backend.
47
+	 */
48
+	public function __construct(\PDO $pdo)
49
+	{
50
+		$this->pdo = $pdo;
51
+	}
52 52
 
53
-    /**
54
-     * Returns a list of calendars for a principal.
55
-     *
56
-     * Every project is an array with the following keys:
57
-     *  * id, a unique id that will be used by other functions to modify the
58
-     *    calendar. This can be the same as the uri or a database key.
59
-     *  * uri. This is just the 'base uri' or 'filename' of the calendar.
60
-     *  * principaluri. The owner of the calendar. Almost always the same as
61
-     *    principalUri passed to this method.
62
-     *
63
-     * Furthermore it can contain webdav properties in clark notation. A very
64
-     * common one is '{DAV:}displayname'.
65
-     *
66
-     * Many clients also require:
67
-     * {urn:ietf:params:xml:ns:caldav}supported-calendar-component-set
68
-     * For this property, you can just return an instance of
69
-     * Sabre\CalDAV\Xml\Property\SupportedCalendarComponentSet.
70
-     *
71
-     * If you return {http://sabredav.org/ns}read-only and set the value to 1,
72
-     * ACL will automatically be put in read-only mode.
73
-     *
74
-     * @param string $principalUri
75
-     *
76
-     * @return array
77
-     */
78
-    public function getCalendarsForUser($principalUri)
79
-    {
80
-        // Making fields a comma-delimited list
81
-        $stmt = $this->pdo->prepare('SELECT id, uri FROM simple_calendars WHERE principaluri = ? ORDER BY id ASC');
82
-        $stmt->execute([$principalUri]);
53
+	/**
54
+	 * Returns a list of calendars for a principal.
55
+	 *
56
+	 * Every project is an array with the following keys:
57
+	 *  * id, a unique id that will be used by other functions to modify the
58
+	 *    calendar. This can be the same as the uri or a database key.
59
+	 *  * uri. This is just the 'base uri' or 'filename' of the calendar.
60
+	 *  * principaluri. The owner of the calendar. Almost always the same as
61
+	 *    principalUri passed to this method.
62
+	 *
63
+	 * Furthermore it can contain webdav properties in clark notation. A very
64
+	 * common one is '{DAV:}displayname'.
65
+	 *
66
+	 * Many clients also require:
67
+	 * {urn:ietf:params:xml:ns:caldav}supported-calendar-component-set
68
+	 * For this property, you can just return an instance of
69
+	 * Sabre\CalDAV\Xml\Property\SupportedCalendarComponentSet.
70
+	 *
71
+	 * If you return {http://sabredav.org/ns}read-only and set the value to 1,
72
+	 * ACL will automatically be put in read-only mode.
73
+	 *
74
+	 * @param string $principalUri
75
+	 *
76
+	 * @return array
77
+	 */
78
+	public function getCalendarsForUser($principalUri)
79
+	{
80
+		// Making fields a comma-delimited list
81
+		$stmt = $this->pdo->prepare('SELECT id, uri FROM simple_calendars WHERE principaluri = ? ORDER BY id ASC');
82
+		$stmt->execute([$principalUri]);
83 83
 
84
-        $calendars = [];
85
-        while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
86
-            $calendars[] = [
87
-                'id' => $row['id'],
88
-                'uri' => $row['uri'],
89
-                'principaluri' => $principalUri,
90
-            ];
91
-        }
84
+		$calendars = [];
85
+		while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
86
+			$calendars[] = [
87
+				'id' => $row['id'],
88
+				'uri' => $row['uri'],
89
+				'principaluri' => $principalUri,
90
+			];
91
+		}
92 92
 
93
-        return $calendars;
94
-    }
93
+		return $calendars;
94
+	}
95 95
 
96
-    /**
97
-     * Creates a new calendar for a principal.
98
-     *
99
-     * If the creation was a success, an id must be returned that can be used
100
-     * to reference this calendar in other methods, such as updateCalendar.
101
-     *
102
-     * @param string $principalUri
103
-     * @param string $calendarUri
104
-     *
105
-     * @return string
106
-     */
107
-    public function createCalendar($principalUri, $calendarUri, array $properties)
108
-    {
109
-        $stmt = $this->pdo->prepare('INSERT INTO simple_calendars (principaluri, uri) VALUES (?, ?)');
110
-        $stmt->execute([$principalUri, $calendarUri]);
96
+	/**
97
+	 * Creates a new calendar for a principal.
98
+	 *
99
+	 * If the creation was a success, an id must be returned that can be used
100
+	 * to reference this calendar in other methods, such as updateCalendar.
101
+	 *
102
+	 * @param string $principalUri
103
+	 * @param string $calendarUri
104
+	 *
105
+	 * @return string
106
+	 */
107
+	public function createCalendar($principalUri, $calendarUri, array $properties)
108
+	{
109
+		$stmt = $this->pdo->prepare('INSERT INTO simple_calendars (principaluri, uri) VALUES (?, ?)');
110
+		$stmt->execute([$principalUri, $calendarUri]);
111 111
 
112
-        return $this->pdo->lastInsertId();
113
-    }
112
+		return $this->pdo->lastInsertId();
113
+	}
114 114
 
115
-    /**
116
-     * Delete a calendar and all it's objects.
117
-     *
118
-     * @param string $calendarId
119
-     */
120
-    public function deleteCalendar($calendarId)
121
-    {
122
-        $stmt = $this->pdo->prepare('DELETE FROM simple_calendarobjects WHERE calendarid = ?');
123
-        $stmt->execute([$calendarId]);
115
+	/**
116
+	 * Delete a calendar and all it's objects.
117
+	 *
118
+	 * @param string $calendarId
119
+	 */
120
+	public function deleteCalendar($calendarId)
121
+	{
122
+		$stmt = $this->pdo->prepare('DELETE FROM simple_calendarobjects WHERE calendarid = ?');
123
+		$stmt->execute([$calendarId]);
124 124
 
125
-        $stmt = $this->pdo->prepare('DELETE FROM simple_calendars WHERE id = ?');
126
-        $stmt->execute([$calendarId]);
127
-    }
125
+		$stmt = $this->pdo->prepare('DELETE FROM simple_calendars WHERE id = ?');
126
+		$stmt->execute([$calendarId]);
127
+	}
128 128
 
129
-    /**
130
-     * Returns all calendar objects within a calendar.
131
-     *
132
-     * Every item contains an array with the following keys:
133
-     *   * calendardata - The iCalendar-compatible calendar data
134
-     *   * uri - a unique key which will be used to construct the uri. This can
135
-     *     be any arbitrary string, but making sure it ends with '.ics' is a
136
-     *     good idea. This is only the basename, or filename, not the full
137
-     *     path.
138
-     *   * lastmodified - a timestamp of the last modification time
139
-     *   * etag - An arbitrary string, surrounded by double-quotes. (e.g.:
140
-     *   '  "abcdef"')
141
-     *   * size - The size of the calendar objects, in bytes.
142
-     *   * component - optional, a string containing the type of object, such
143
-     *     as 'vevent' or 'vtodo'. If specified, this will be used to populate
144
-     *     the Content-Type header.
145
-     *
146
-     * Note that the etag is optional, but it's highly encouraged to return for
147
-     * speed reasons.
148
-     *
149
-     * The calendardata is also optional. If it's not returned
150
-     * 'getCalendarObject' will be called later, which *is* expected to return
151
-     * calendardata.
152
-     *
153
-     * If neither etag or size are specified, the calendardata will be
154
-     * used/fetched to determine these numbers. If both are specified the
155
-     * amount of times this is needed is reduced by a great degree.
156
-     *
157
-     * @param string $calendarId
158
-     *
159
-     * @return array
160
-     */
161
-    public function getCalendarObjects($calendarId)
162
-    {
163
-        $stmt = $this->pdo->prepare('SELECT id, uri, calendardata FROM simple_calendarobjects WHERE calendarid = ?');
164
-        $stmt->execute([$calendarId]);
129
+	/**
130
+	 * Returns all calendar objects within a calendar.
131
+	 *
132
+	 * Every item contains an array with the following keys:
133
+	 *   * calendardata - The iCalendar-compatible calendar data
134
+	 *   * uri - a unique key which will be used to construct the uri. This can
135
+	 *     be any arbitrary string, but making sure it ends with '.ics' is a
136
+	 *     good idea. This is only the basename, or filename, not the full
137
+	 *     path.
138
+	 *   * lastmodified - a timestamp of the last modification time
139
+	 *   * etag - An arbitrary string, surrounded by double-quotes. (e.g.:
140
+	 *   '  "abcdef"')
141
+	 *   * size - The size of the calendar objects, in bytes.
142
+	 *   * component - optional, a string containing the type of object, such
143
+	 *     as 'vevent' or 'vtodo'. If specified, this will be used to populate
144
+	 *     the Content-Type header.
145
+	 *
146
+	 * Note that the etag is optional, but it's highly encouraged to return for
147
+	 * speed reasons.
148
+	 *
149
+	 * The calendardata is also optional. If it's not returned
150
+	 * 'getCalendarObject' will be called later, which *is* expected to return
151
+	 * calendardata.
152
+	 *
153
+	 * If neither etag or size are specified, the calendardata will be
154
+	 * used/fetched to determine these numbers. If both are specified the
155
+	 * amount of times this is needed is reduced by a great degree.
156
+	 *
157
+	 * @param string $calendarId
158
+	 *
159
+	 * @return array
160
+	 */
161
+	public function getCalendarObjects($calendarId)
162
+	{
163
+		$stmt = $this->pdo->prepare('SELECT id, uri, calendardata FROM simple_calendarobjects WHERE calendarid = ?');
164
+		$stmt->execute([$calendarId]);
165 165
 
166
-        $result = [];
167
-        foreach ($stmt->fetchAll(\PDO::FETCH_ASSOC) as $row) {
168
-            $result[] = [
169
-                'id' => $row['id'],
170
-                'uri' => $row['uri'],
171
-                'etag' => '"'.md5($row['calendardata']).'"',
172
-                'calendarid' => $calendarId,
173
-                'size' => strlen($row['calendardata']),
174
-                'calendardata' => $row['calendardata'],
175
-            ];
176
-        }
166
+		$result = [];
167
+		foreach ($stmt->fetchAll(\PDO::FETCH_ASSOC) as $row) {
168
+			$result[] = [
169
+				'id' => $row['id'],
170
+				'uri' => $row['uri'],
171
+				'etag' => '"'.md5($row['calendardata']).'"',
172
+				'calendarid' => $calendarId,
173
+				'size' => strlen($row['calendardata']),
174
+				'calendardata' => $row['calendardata'],
175
+			];
176
+		}
177 177
 
178
-        return $result;
179
-    }
178
+		return $result;
179
+	}
180 180
 
181
-    /**
182
-     * Returns information from a single calendar object, based on it's object
183
-     * uri.
184
-     *
185
-     * The object uri is only the basename, or filename and not a full path.
186
-     *
187
-     * The returned array must have the same keys as getCalendarObjects. The
188
-     * 'calendardata' object is required here though, while it's not required
189
-     * for getCalendarObjects.
190
-     *
191
-     * This method must return null if the object did not exist.
192
-     *
193
-     * @param string $calendarId
194
-     * @param string $objectUri
195
-     *
196
-     * @return array|null
197
-     */
198
-    public function getCalendarObject($calendarId, $objectUri)
199
-    {
200
-        $stmt = $this->pdo->prepare('SELECT id, uri, calendardata FROM simple_calendarobjects WHERE calendarid = ? AND uri = ?');
201
-        $stmt->execute([$calendarId, $objectUri]);
202
-        $row = $stmt->fetch(\PDO::FETCH_ASSOC);
181
+	/**
182
+	 * Returns information from a single calendar object, based on it's object
183
+	 * uri.
184
+	 *
185
+	 * The object uri is only the basename, or filename and not a full path.
186
+	 *
187
+	 * The returned array must have the same keys as getCalendarObjects. The
188
+	 * 'calendardata' object is required here though, while it's not required
189
+	 * for getCalendarObjects.
190
+	 *
191
+	 * This method must return null if the object did not exist.
192
+	 *
193
+	 * @param string $calendarId
194
+	 * @param string $objectUri
195
+	 *
196
+	 * @return array|null
197
+	 */
198
+	public function getCalendarObject($calendarId, $objectUri)
199
+	{
200
+		$stmt = $this->pdo->prepare('SELECT id, uri, calendardata FROM simple_calendarobjects WHERE calendarid = ? AND uri = ?');
201
+		$stmt->execute([$calendarId, $objectUri]);
202
+		$row = $stmt->fetch(\PDO::FETCH_ASSOC);
203 203
 
204
-        if (!$row) {
205
-            return null;
206
-        }
204
+		if (!$row) {
205
+			return null;
206
+		}
207 207
 
208
-        return [
209
-            'id' => $row['id'],
210
-            'uri' => $row['uri'],
211
-            'etag' => '"'.md5($row['calendardata']).'"',
212
-            'calendarid' => $calendarId,
213
-            'size' => strlen($row['calendardata']),
214
-            'calendardata' => $row['calendardata'],
215
-         ];
216
-    }
208
+		return [
209
+			'id' => $row['id'],
210
+			'uri' => $row['uri'],
211
+			'etag' => '"'.md5($row['calendardata']).'"',
212
+			'calendarid' => $calendarId,
213
+			'size' => strlen($row['calendardata']),
214
+			'calendardata' => $row['calendardata'],
215
+		 ];
216
+	}
217 217
 
218
-    /**
219
-     * Creates a new calendar object.
220
-     *
221
-     * The object uri is only the basename, or filename and not a full path.
222
-     *
223
-     * It is possible return an etag from this function, which will be used in
224
-     * the response to this PUT request. Note that the ETag must be surrounded
225
-     * by double-quotes.
226
-     *
227
-     * However, you should only really return this ETag if you don't mangle the
228
-     * calendar-data. If the result of a subsequent GET to this object is not
229
-     * the exact same as this request body, you should omit the ETag.
230
-     *
231
-     * @param mixed  $calendarId
232
-     * @param string $objectUri
233
-     * @param string $calendarData
234
-     *
235
-     * @return string|null
236
-     */
237
-    public function createCalendarObject($calendarId, $objectUri, $calendarData)
238
-    {
239
-        $stmt = $this->pdo->prepare('INSERT INTO simple_calendarobjects (calendarid, uri, calendardata) VALUES (?,?,?)');
240
-        $stmt->execute([
241
-            $calendarId,
242
-            $objectUri,
243
-            $calendarData,
244
-        ]);
218
+	/**
219
+	 * Creates a new calendar object.
220
+	 *
221
+	 * The object uri is only the basename, or filename and not a full path.
222
+	 *
223
+	 * It is possible return an etag from this function, which will be used in
224
+	 * the response to this PUT request. Note that the ETag must be surrounded
225
+	 * by double-quotes.
226
+	 *
227
+	 * However, you should only really return this ETag if you don't mangle the
228
+	 * calendar-data. If the result of a subsequent GET to this object is not
229
+	 * the exact same as this request body, you should omit the ETag.
230
+	 *
231
+	 * @param mixed  $calendarId
232
+	 * @param string $objectUri
233
+	 * @param string $calendarData
234
+	 *
235
+	 * @return string|null
236
+	 */
237
+	public function createCalendarObject($calendarId, $objectUri, $calendarData)
238
+	{
239
+		$stmt = $this->pdo->prepare('INSERT INTO simple_calendarobjects (calendarid, uri, calendardata) VALUES (?,?,?)');
240
+		$stmt->execute([
241
+			$calendarId,
242
+			$objectUri,
243
+			$calendarData,
244
+		]);
245 245
 
246
-        return '"'.md5($calendarData).'"';
247
-    }
246
+		return '"'.md5($calendarData).'"';
247
+	}
248 248
 
249
-    /**
250
-     * Updates an existing calendarobject, based on it's uri.
251
-     *
252
-     * The object uri is only the basename, or filename and not a full path.
253
-     *
254
-     * It is possible return an etag from this function, which will be used in
255
-     * the response to this PUT request. Note that the ETag must be surrounded
256
-     * by double-quotes.
257
-     *
258
-     * However, you should only really return this ETag if you don't mangle the
259
-     * calendar-data. If the result of a subsequent GET to this object is not
260
-     * the exact same as this request body, you should omit the ETag.
261
-     *
262
-     * @param mixed  $calendarId
263
-     * @param string $objectUri
264
-     * @param string $calendarData
265
-     *
266
-     * @return string|null
267
-     */
268
-    public function updateCalendarObject($calendarId, $objectUri, $calendarData)
269
-    {
270
-        $stmt = $this->pdo->prepare('UPDATE simple_calendarobjects SET calendardata = ? WHERE calendarid = ? AND uri = ?');
271
-        $stmt->execute([$calendarData, $calendarId, $objectUri]);
249
+	/**
250
+	 * Updates an existing calendarobject, based on it's uri.
251
+	 *
252
+	 * The object uri is only the basename, or filename and not a full path.
253
+	 *
254
+	 * It is possible return an etag from this function, which will be used in
255
+	 * the response to this PUT request. Note that the ETag must be surrounded
256
+	 * by double-quotes.
257
+	 *
258
+	 * However, you should only really return this ETag if you don't mangle the
259
+	 * calendar-data. If the result of a subsequent GET to this object is not
260
+	 * the exact same as this request body, you should omit the ETag.
261
+	 *
262
+	 * @param mixed  $calendarId
263
+	 * @param string $objectUri
264
+	 * @param string $calendarData
265
+	 *
266
+	 * @return string|null
267
+	 */
268
+	public function updateCalendarObject($calendarId, $objectUri, $calendarData)
269
+	{
270
+		$stmt = $this->pdo->prepare('UPDATE simple_calendarobjects SET calendardata = ? WHERE calendarid = ? AND uri = ?');
271
+		$stmt->execute([$calendarData, $calendarId, $objectUri]);
272 272
 
273
-        return '"'.md5($calendarData).'"';
274
-    }
273
+		return '"'.md5($calendarData).'"';
274
+	}
275 275
 
276
-    /**
277
-     * Deletes an existing calendar object.
278
-     *
279
-     * The object uri is only the basename, or filename and not a full path.
280
-     *
281
-     * @param string $calendarId
282
-     * @param string $objectUri
283
-     */
284
-    public function deleteCalendarObject($calendarId, $objectUri)
285
-    {
286
-        $stmt = $this->pdo->prepare('DELETE FROM simple_calendarobjects WHERE calendarid = ? AND uri = ?');
287
-        $stmt->execute([$calendarId, $objectUri]);
288
-    }
276
+	/**
277
+	 * Deletes an existing calendar object.
278
+	 *
279
+	 * The object uri is only the basename, or filename and not a full path.
280
+	 *
281
+	 * @param string $calendarId
282
+	 * @param string $objectUri
283
+	 */
284
+	public function deleteCalendarObject($calendarId, $objectUri)
285
+	{
286
+		$stmt = $this->pdo->prepare('DELETE FROM simple_calendarobjects WHERE calendarid = ? AND uri = ?');
287
+		$stmt->execute([$calendarId, $objectUri]);
288
+	}
289 289
 }
Please login to merge, or discard this patch.
htdocs/includes/sabre/sabre/dav/lib/CalDAV/Backend/SubscriptionSupport.php 1 patch
Indentation   +68 added lines, -68 removed lines patch added patch discarded remove patch
@@ -15,75 +15,75 @@
 block discarded – undo
15 15
  */
16 16
 interface SubscriptionSupport extends BackendInterface
17 17
 {
18
-    /**
19
-     * Returns a list of subscriptions for a principal.
20
-     *
21
-     * Every subscription is an array with the following keys:
22
-     *  * id, a unique id that will be used by other functions to modify the
23
-     *    subscription. This can be the same as the uri or a database key.
24
-     *  * uri. This is just the 'base uri' or 'filename' of the subscription.
25
-     *  * principaluri. The owner of the subscription. Almost always the same as
26
-     *    principalUri passed to this method.
27
-     *
28
-     * Furthermore, all the subscription info must be returned too:
29
-     *
30
-     * 1. {DAV:}displayname
31
-     * 2. {http://apple.com/ns/ical/}refreshrate
32
-     * 3. {http://calendarserver.org/ns/}subscribed-strip-todos (omit if todos
33
-     *    should not be stripped).
34
-     * 4. {http://calendarserver.org/ns/}subscribed-strip-alarms (omit if alarms
35
-     *    should not be stripped).
36
-     * 5. {http://calendarserver.org/ns/}subscribed-strip-attachments (omit if
37
-     *    attachments should not be stripped).
38
-     * 6. {http://calendarserver.org/ns/}source (Must be a
39
-     *     Sabre\DAV\Property\Href).
40
-     * 7. {http://apple.com/ns/ical/}calendar-color
41
-     * 8. {http://apple.com/ns/ical/}calendar-order
42
-     * 9. {urn:ietf:params:xml:ns:caldav}supported-calendar-component-set
43
-     *    (should just be an instance of
44
-     *    Sabre\CalDAV\Property\SupportedCalendarComponentSet, with a bunch of
45
-     *    default components).
46
-     *
47
-     * @param string $principalUri
48
-     *
49
-     * @return array
50
-     */
51
-    public function getSubscriptionsForUser($principalUri);
18
+	/**
19
+	 * Returns a list of subscriptions for a principal.
20
+	 *
21
+	 * Every subscription is an array with the following keys:
22
+	 *  * id, a unique id that will be used by other functions to modify the
23
+	 *    subscription. This can be the same as the uri or a database key.
24
+	 *  * uri. This is just the 'base uri' or 'filename' of the subscription.
25
+	 *  * principaluri. The owner of the subscription. Almost always the same as
26
+	 *    principalUri passed to this method.
27
+	 *
28
+	 * Furthermore, all the subscription info must be returned too:
29
+	 *
30
+	 * 1. {DAV:}displayname
31
+	 * 2. {http://apple.com/ns/ical/}refreshrate
32
+	 * 3. {http://calendarserver.org/ns/}subscribed-strip-todos (omit if todos
33
+	 *    should not be stripped).
34
+	 * 4. {http://calendarserver.org/ns/}subscribed-strip-alarms (omit if alarms
35
+	 *    should not be stripped).
36
+	 * 5. {http://calendarserver.org/ns/}subscribed-strip-attachments (omit if
37
+	 *    attachments should not be stripped).
38
+	 * 6. {http://calendarserver.org/ns/}source (Must be a
39
+	 *     Sabre\DAV\Property\Href).
40
+	 * 7. {http://apple.com/ns/ical/}calendar-color
41
+	 * 8. {http://apple.com/ns/ical/}calendar-order
42
+	 * 9. {urn:ietf:params:xml:ns:caldav}supported-calendar-component-set
43
+	 *    (should just be an instance of
44
+	 *    Sabre\CalDAV\Property\SupportedCalendarComponentSet, with a bunch of
45
+	 *    default components).
46
+	 *
47
+	 * @param string $principalUri
48
+	 *
49
+	 * @return array
50
+	 */
51
+	public function getSubscriptionsForUser($principalUri);
52 52
 
53
-    /**
54
-     * Creates a new subscription for a principal.
55
-     *
56
-     * If the creation was a success, an id must be returned that can be used to reference
57
-     * this subscription in other methods, such as updateSubscription.
58
-     *
59
-     * @param string $principalUri
60
-     * @param string $uri
61
-     *
62
-     * @return mixed
63
-     */
64
-    public function createSubscription($principalUri, $uri, array $properties);
53
+	/**
54
+	 * Creates a new subscription for a principal.
55
+	 *
56
+	 * If the creation was a success, an id must be returned that can be used to reference
57
+	 * this subscription in other methods, such as updateSubscription.
58
+	 *
59
+	 * @param string $principalUri
60
+	 * @param string $uri
61
+	 *
62
+	 * @return mixed
63
+	 */
64
+	public function createSubscription($principalUri, $uri, array $properties);
65 65
 
66
-    /**
67
-     * Updates a subscription.
68
-     *
69
-     * The list of mutations is stored in a Sabre\DAV\PropPatch object.
70
-     * To do the actual updates, you must tell this object which properties
71
-     * you're going to process with the handle() method.
72
-     *
73
-     * Calling the handle method is like telling the PropPatch object "I
74
-     * promise I can handle updating this property".
75
-     *
76
-     * Read the PropPatch documentation for more info and examples.
77
-     *
78
-     * @param mixed                $subscriptionId
79
-     * @param \Sabre\DAV\PropPatch $propPatch
80
-     */
81
-    public function updateSubscription($subscriptionId, DAV\PropPatch $propPatch);
66
+	/**
67
+	 * Updates a subscription.
68
+	 *
69
+	 * The list of mutations is stored in a Sabre\DAV\PropPatch object.
70
+	 * To do the actual updates, you must tell this object which properties
71
+	 * you're going to process with the handle() method.
72
+	 *
73
+	 * Calling the handle method is like telling the PropPatch object "I
74
+	 * promise I can handle updating this property".
75
+	 *
76
+	 * Read the PropPatch documentation for more info and examples.
77
+	 *
78
+	 * @param mixed                $subscriptionId
79
+	 * @param \Sabre\DAV\PropPatch $propPatch
80
+	 */
81
+	public function updateSubscription($subscriptionId, DAV\PropPatch $propPatch);
82 82
 
83
-    /**
84
-     * Deletes a subscription.
85
-     *
86
-     * @param mixed $subscriptionId
87
-     */
88
-    public function deleteSubscription($subscriptionId);
83
+	/**
84
+	 * Deletes a subscription.
85
+	 *
86
+	 * @param mixed $subscriptionId
87
+	 */
88
+	public function deleteSubscription($subscriptionId);
89 89
 }
Please login to merge, or discard this patch.
htdocs/includes/sabre/sabre/dav/lib/CalDAV/Backend/SharingSupport.php 1 patch
Indentation   +31 added lines, -31 removed lines patch added patch discarded remove patch
@@ -24,37 +24,37 @@
 block discarded – undo
24 24
  */
25 25
 interface SharingSupport extends BackendInterface
26 26
 {
27
-    /**
28
-     * Updates the list of shares.
29
-     *
30
-     * @param mixed                           $calendarId
31
-     * @param \Sabre\DAV\Xml\Element\Sharee[] $sharees
32
-     */
33
-    public function updateInvites($calendarId, array $sharees);
27
+	/**
28
+	 * Updates the list of shares.
29
+	 *
30
+	 * @param mixed                           $calendarId
31
+	 * @param \Sabre\DAV\Xml\Element\Sharee[] $sharees
32
+	 */
33
+	public function updateInvites($calendarId, array $sharees);
34 34
 
35
-    /**
36
-     * Returns the list of people whom this calendar is shared with.
37
-     *
38
-     * Every item in the returned list must be a Sharee object with at
39
-     * least the following properties set:
40
-     *   $href
41
-     *   $shareAccess
42
-     *   $inviteStatus
43
-     *
44
-     * and optionally:
45
-     *   $properties
46
-     *
47
-     * @param mixed $calendarId
48
-     *
49
-     * @return \Sabre\DAV\Xml\Element\Sharee[]
50
-     */
51
-    public function getInvites($calendarId);
35
+	/**
36
+	 * Returns the list of people whom this calendar is shared with.
37
+	 *
38
+	 * Every item in the returned list must be a Sharee object with at
39
+	 * least the following properties set:
40
+	 *   $href
41
+	 *   $shareAccess
42
+	 *   $inviteStatus
43
+	 *
44
+	 * and optionally:
45
+	 *   $properties
46
+	 *
47
+	 * @param mixed $calendarId
48
+	 *
49
+	 * @return \Sabre\DAV\Xml\Element\Sharee[]
50
+	 */
51
+	public function getInvites($calendarId);
52 52
 
53
-    /**
54
-     * Publishes a calendar.
55
-     *
56
-     * @param mixed $calendarId
57
-     * @param bool  $value
58
-     */
59
-    public function setPublishStatus($calendarId, $value);
53
+	/**
54
+	 * Publishes a calendar.
55
+	 *
56
+	 * @param mixed $calendarId
57
+	 * @param bool  $value
58
+	 */
59
+	public function setPublishStatus($calendarId, $value);
60 60
 }
Please login to merge, or discard this patch.
htdocs/includes/sabre/sabre/dav/lib/CalDAV/Backend/SchedulingSupport.php 1 patch
Indentation   +46 added lines, -46 removed lines patch added patch discarded remove patch
@@ -14,53 +14,53 @@
 block discarded – undo
14 14
  */
15 15
 interface SchedulingSupport extends BackendInterface
16 16
 {
17
-    /**
18
-     * Returns a single scheduling object for the inbox collection.
19
-     *
20
-     * The returned array should contain the following elements:
21
-     *   * uri - A unique basename for the object. This will be used to
22
-     *           construct a full uri.
23
-     *   * calendardata - The iCalendar object
24
-     *   * lastmodified - The last modification date. Can be an int for a unix
25
-     *                    timestamp, or a PHP DateTime object.
26
-     *   * etag - A unique token that must change if the object changed.
27
-     *   * size - The size of the object, in bytes.
28
-     *
29
-     * @param string $principalUri
30
-     * @param string $objectUri
31
-     *
32
-     * @return array
33
-     */
34
-    public function getSchedulingObject($principalUri, $objectUri);
17
+	/**
18
+	 * Returns a single scheduling object for the inbox collection.
19
+	 *
20
+	 * The returned array should contain the following elements:
21
+	 *   * uri - A unique basename for the object. This will be used to
22
+	 *           construct a full uri.
23
+	 *   * calendardata - The iCalendar object
24
+	 *   * lastmodified - The last modification date. Can be an int for a unix
25
+	 *                    timestamp, or a PHP DateTime object.
26
+	 *   * etag - A unique token that must change if the object changed.
27
+	 *   * size - The size of the object, in bytes.
28
+	 *
29
+	 * @param string $principalUri
30
+	 * @param string $objectUri
31
+	 *
32
+	 * @return array
33
+	 */
34
+	public function getSchedulingObject($principalUri, $objectUri);
35 35
 
36
-    /**
37
-     * Returns all scheduling objects for the inbox collection.
38
-     *
39
-     * These objects should be returned as an array. Every item in the array
40
-     * should follow the same structure as returned from getSchedulingObject.
41
-     *
42
-     * The main difference is that 'calendardata' is optional.
43
-     *
44
-     * @param string $principalUri
45
-     *
46
-     * @return array
47
-     */
48
-    public function getSchedulingObjects($principalUri);
36
+	/**
37
+	 * Returns all scheduling objects for the inbox collection.
38
+	 *
39
+	 * These objects should be returned as an array. Every item in the array
40
+	 * should follow the same structure as returned from getSchedulingObject.
41
+	 *
42
+	 * The main difference is that 'calendardata' is optional.
43
+	 *
44
+	 * @param string $principalUri
45
+	 *
46
+	 * @return array
47
+	 */
48
+	public function getSchedulingObjects($principalUri);
49 49
 
50
-    /**
51
-     * Deletes a scheduling object from the inbox collection.
52
-     *
53
-     * @param string $principalUri
54
-     * @param string $objectUri
55
-     */
56
-    public function deleteSchedulingObject($principalUri, $objectUri);
50
+	/**
51
+	 * Deletes a scheduling object from the inbox collection.
52
+	 *
53
+	 * @param string $principalUri
54
+	 * @param string $objectUri
55
+	 */
56
+	public function deleteSchedulingObject($principalUri, $objectUri);
57 57
 
58
-    /**
59
-     * Creates a new scheduling object. This should land in a users' inbox.
60
-     *
61
-     * @param string          $principalUri
62
-     * @param string          $objectUri
63
-     * @param string|resource $objectData
64
-     */
65
-    public function createSchedulingObject($principalUri, $objectUri, $objectData);
58
+	/**
59
+	 * Creates a new scheduling object. This should land in a users' inbox.
60
+	 *
61
+	 * @param string          $principalUri
62
+	 * @param string          $objectUri
63
+	 * @param string|resource $objectData
64
+	 */
65
+	public function createSchedulingObject($principalUri, $objectUri, $objectData);
66 66
 }
Please login to merge, or discard this patch.
htdocs/includes/sabre/sabre/dav/lib/CalDAV/CalendarRoot.php 1 patch
Indentation   +48 added lines, -48 removed lines patch added patch discarded remove patch
@@ -21,55 +21,55 @@
 block discarded – undo
21 21
  */
22 22
 class CalendarRoot extends \Sabre\DAVACL\AbstractPrincipalCollection
23 23
 {
24
-    /**
25
-     * CalDAV backend.
26
-     *
27
-     * @var Backend\BackendInterface
28
-     */
29
-    protected $caldavBackend;
24
+	/**
25
+	 * CalDAV backend.
26
+	 *
27
+	 * @var Backend\BackendInterface
28
+	 */
29
+	protected $caldavBackend;
30 30
 
31
-    /**
32
-     * Constructor.
33
-     *
34
-     * This constructor needs both an authentication and a caldav backend.
35
-     *
36
-     * By default this class will show a list of calendar collections for
37
-     * principals in the 'principals' collection. If your main principals are
38
-     * actually located in a different path, use the $principalPrefix argument
39
-     * to override this.
40
-     *
41
-     * @param string $principalPrefix
42
-     */
43
-    public function __construct(PrincipalBackend\BackendInterface $principalBackend, Backend\BackendInterface $caldavBackend, $principalPrefix = 'principals')
44
-    {
45
-        parent::__construct($principalBackend, $principalPrefix);
46
-        $this->caldavBackend = $caldavBackend;
47
-    }
31
+	/**
32
+	 * Constructor.
33
+	 *
34
+	 * This constructor needs both an authentication and a caldav backend.
35
+	 *
36
+	 * By default this class will show a list of calendar collections for
37
+	 * principals in the 'principals' collection. If your main principals are
38
+	 * actually located in a different path, use the $principalPrefix argument
39
+	 * to override this.
40
+	 *
41
+	 * @param string $principalPrefix
42
+	 */
43
+	public function __construct(PrincipalBackend\BackendInterface $principalBackend, Backend\BackendInterface $caldavBackend, $principalPrefix = 'principals')
44
+	{
45
+		parent::__construct($principalBackend, $principalPrefix);
46
+		$this->caldavBackend = $caldavBackend;
47
+	}
48 48
 
49
-    /**
50
-     * Returns the nodename.
51
-     *
52
-     * We're overriding this, because the default will be the 'principalPrefix',
53
-     * and we want it to be Sabre\CalDAV\Plugin::CALENDAR_ROOT
54
-     *
55
-     * @return string
56
-     */
57
-    public function getName()
58
-    {
59
-        return Plugin::CALENDAR_ROOT;
60
-    }
49
+	/**
50
+	 * Returns the nodename.
51
+	 *
52
+	 * We're overriding this, because the default will be the 'principalPrefix',
53
+	 * and we want it to be Sabre\CalDAV\Plugin::CALENDAR_ROOT
54
+	 *
55
+	 * @return string
56
+	 */
57
+	public function getName()
58
+	{
59
+		return Plugin::CALENDAR_ROOT;
60
+	}
61 61
 
62
-    /**
63
-     * This method returns a node for a principal.
64
-     *
65
-     * The passed array contains principal information, and is guaranteed to
66
-     * at least contain a uri item. Other properties may or may not be
67
-     * supplied by the authentication backend.
68
-     *
69
-     * @return \Sabre\DAV\INode
70
-     */
71
-    public function getChildForPrincipal(array $principal)
72
-    {
73
-        return new CalendarHome($this->caldavBackend, $principal);
74
-    }
62
+	/**
63
+	 * This method returns a node for a principal.
64
+	 *
65
+	 * The passed array contains principal information, and is guaranteed to
66
+	 * at least contain a uri item. Other properties may or may not be
67
+	 * supplied by the authentication backend.
68
+	 *
69
+	 * @return \Sabre\DAV\INode
70
+	 */
71
+	public function getChildForPrincipal(array $principal)
72
+	{
73
+		return new CalendarHome($this->caldavBackend, $principal);
74
+	}
75 75
 }
Please login to merge, or discard this patch.