Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CalDavBackend.search does not handle VTODO's properly #45333

Open
kesselb opened this issue May 15, 2024 · 1 comment
Open

CalDavBackend.search does not handle VTODO's properly #45333

kesselb opened this issue May 15, 2024 · 1 comment
Labels
1. to develop Accepted and waiting to be taken care of 26-feedback 30-feedback bug feature: caldav Related to CalDAV internals

Comments

@kesselb
Copy link
Contributor

kesselb commented May 15, 2024

Follow-up for #44752 and #45222

The "Upcoming events" widget (provided by the calendar app) is using ICalendar.search / CalDavBackend.search to obtain a list of calendar objects within a given time range since calendar 4.6.0. Former versions sent one xhr request per calendar to the CalDAV api to obtain the calendar objects.

A user also mentioned that tasks (e.g. from the tasks app) were shown in the "Upcoming events" widget with older version and now are missing1.

I had a brief look with the tasks app and found a couple of things:

"Upcoming events" use a search with a time range. That's done by filtering on oc_calendarobjects.firstoccurence and oc_calendarobjects.lastoccurence and additional processing. However, event's from the tasks app with a start and end date still ended up in oc_calendarobjects with firstoccurrence = null and lastoccurence = null.

  • The processing for DTSTART in CalDavBackend.getDenormalizedData is only done for VEVENTS2.
  • VTODO don't have DTEND but DUE or DURATION3. We can handle DURATION, but DUE is missing4.
  • VTODO can omit DTSTART if DUE is given3.
  • CalDavBackend.search uses a comp-filter to check if the given event is within the time range. The filter for component type "name" is mandatory and set to VEVENT and will remove VTODO or VJOURNAL. The component type is already known (from the db result) and can be reused or drop the filter and ask the components directly with isInTimeRange5.
  • CalDavBackend.search uses VCalendar.expand to return the event for the given date and without recurrences. The implemention does not take VTODO in account and therefore they are removed / not added to the expanded result6.
  • 458b1cb will sort the objects by the start date, for VTODOs without start date have to figure something out, likely the start date should be today then.

Proof of concept to bring back tasks in the "Upcoming events" widget.


Index: apps/dav/lib/CalDAV/CalDavBackend.php
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/apps/dav/lib/CalDAV/CalDavBackend.php b/apps/dav/lib/CalDAV/CalDavBackend.php
--- a/apps/dav/lib/CalDAV/CalDavBackend.php	(revision d8189bf775459ca87b654e5eda6eafc86bcdd0a8)
+++ b/apps/dav/lib/CalDAV/CalDavBackend.php	(date 1715795614049)
@@ -2011,6 +2011,7 @@
 
 			// Expand recurrences if an explicit time range is requested
 			if ($calendarData instanceof VCalendar
+				&& isset($calendarData->VEVENT)
 				&& isset($options['timerange']['start'], $options['timerange']['end'])) {
 				$calendarData = $calendarData->expand(
 					$options['timerange']['start'],
@@ -2072,7 +2073,7 @@
 				'name' => 'VCALENDAR',
 				'comp-filters' => [
 					[
-						'name' => 'VEVENT',
+						'name' => $row['componenttype'],
 						'comp-filters' => [],
 						'prop-filters' => [],
 						'is-not-defined' => false,
@@ -2946,7 +2947,7 @@
 		foreach ($vObject->getComponents() as $component) {
 			if ($component->name !== 'VTIMEZONE') {
 				// Finding all VEVENTs, and track them
-				if ($component->name === 'VEVENT') {
+				if ($component->name === 'VEVENT' || $component->name === 'VTODO') {
 					$vEvents[] = $component;
 					if ($component->DTSTART) {
 						$hasDTSTART = true;
@@ -2975,6 +2976,8 @@
 					$endDate = clone $component->DTSTART->getDateTime();
 					$endDate->add(DateTimeParser::parse($component->DURATION->getValue()));
 					$lastOccurrence = $endDate->getTimeStamp();
+				} elseif (isset($component->DUE)) {
+					$lastOccurrence = $component->DUE->getDateTime()->getTimeStamp();
 				} elseif (!$component->DTSTART->hasTime()) {
 					$endDate = clone $component->DTSTART->getDateTime();
 					$endDate->modify('+1 day');

Alternative for $isValid = $this->validateFilterForObject

			$vObject = Reader::read($row['calendardata']);
			$isValid = false;

			if (isset($vObject->VEVENT)) {
				$isValid = $vObject->VEVENT->isInTimeRange($start, $end);
			} else if (isset($vObject->VTODO)) {
				$isValid = $vObject->VTODO->isInTimeRange($start, $end);
			}

Footnotes

  1. https://github.com/nextcloud/calendar/issues/5563#issuecomment-1900129501

  2. https://github.com/nextcloud/server/blob/b24ac6bc714e970cb8dd2f1723a030c2b913368b/apps/dav/lib/CalDAV/CalDavBackend.php#L2878-L2883

  3. https://icalendar.org/iCalendar-RFC-5545/3-6-2-to-do-component.html 2

  4. https://github.com/nextcloud/server/blob/b24ac6bc714e970cb8dd2f1723a030c2b913368b/apps/dav/lib/CalDAV/CalDavBackend.php#L2901-L2913

  5. https://github.com/nextcloud/server/blob/b24ac6bc714e970cb8dd2f1723a030c2b913368b/apps/dav/lib/CalDAV/CalDavBackend.php#L1968-L1985

  6. https://github.com/sabre-io/vobject/blob/a865996a677fd31ad06ca995e538163a89048594/lib/Component/VCalendar.php#L307-L324

@kesselb kesselb added the 1. to develop Accepted and waiting to be taken care of label May 15, 2024
@kesselb kesselb changed the title CalDavBackend.search does not handle VTODO's properly. CalDavBackend.search does not handle VTODO's properly May 15, 2024
@joshtrichards joshtrichards added bug feature: caldav Related to CalDAV internals labels May 15, 2024
@kesselb
Copy link
Contributor Author

kesselb commented May 15, 2024

@szaimen the backend parts are missing / broken down to 26. Should I use a different label then?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
1. to develop Accepted and waiting to be taken care of 26-feedback 30-feedback bug feature: caldav Related to CalDAV internals
Projects
None yet
Development

No branches or pull requests

3 participants