Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/server.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristoph Wurst <christoph@winzerhof-wurst.at>2021-12-02 17:06:05 +0300
committerChristoph Wurst <christoph@winzerhof-wurst.at>2021-12-13 17:58:31 +0300
commitb005846d1f075f77f1e439950e581428d947231c (patch)
treef59d232d5d8c45cdae0917b96412e135ffe72699 /apps/dav/lib/CalDAV
parent168a1b0bc57a7a97c9ca2bdef8031771b05b85d1 (diff)
Carefully filter out non matching time ranges for CalDAV search
When we search for CalDAV objects in the DB we take the first and last occurence into account. For recurring events that is when they take place the very first time and the very last time. Searching in a more specific time range will still match this condition, because the recurring event starts before the end of the requested range but ends after the start of the requested range. Sabre has filters for this. If we apply them on all seach objects of a search with a time range, then only the recurring events actually taking place at the time of the requested time range will be returned. Signed-off-by: Christoph Wurst <christoph@winzerhof-wurst.at>
Diffstat (limited to 'apps/dav/lib/CalDAV')
-rw-r--r--apps/dav/lib/CalDAV/CalDavBackend.php36
1 files changed, 35 insertions, 1 deletions
diff --git a/apps/dav/lib/CalDAV/CalDavBackend.php b/apps/dav/lib/CalDAV/CalDavBackend.php
index 1c26ee2eb8a..fa6e6a7ecbb 100644
--- a/apps/dav/lib/CalDAV/CalDavBackend.php
+++ b/apps/dav/lib/CalDAV/CalDavBackend.php
@@ -100,7 +100,9 @@ use function array_merge;
use function array_values;
use function explode;
use function is_array;
+use function is_resource;
use function pathinfo;
+use function rewind;
use function sprintf;
use function str_replace;
use function strtolower;
@@ -1915,7 +1917,39 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
}
$result = $outerQuery->executeQuery();
- $calendarObjects = $result->fetchAll();
+ $calendarObjects = array_filter($result->fetchAll(), function (array $row) use ($options) {
+ $start = $options['timerange']['start'] ?? null;
+ $end = $options['timerange']['end'] ?? null;
+
+ if ($start === null || !($start instanceof DateTimeInterface) || $end === null || !($end instanceof DateTimeInterface)) {
+ // No filter required
+ return true;
+ }
+
+ $isValid = $this->validateFilterForObject($row, [
+ 'name' => 'VCALENDAR',
+ 'comp-filters' => [
+ [
+ 'name' => 'VEVENT',
+ 'comp-filters' => [],
+ 'prop-filters' => [],
+ 'is-not-defined' => false,
+ 'time-range' => [
+ 'start' => $start,
+ 'end' => $end,
+ ],
+ ],
+ ],
+ 'prop-filters' => [],
+ 'is-not-defined' => false,
+ 'time-range' => null,
+ ]);
+ if (is_resource($row['calendardata'])) {
+ // Put the stream back to the beginning so it can be read another time
+ rewind($row['calendardata']);
+ }
+ return $isValid;
+ });
$result->closeCursor();
return array_map(function ($o) {