From 976986ba8d367b9f01756f70087713dcef64767c Mon Sep 17 00:00:00 2001
From: Vincent Brillault <vincent.brillault@cern.ch>
Date: Thu, 7 Jan 2021 16:59:50 +0100
Subject: [PATCH] CalDAV: Implement MeetingResponse

---
 src/backend/caldav/caldav.php | 40 +++++++++++++++++++++++++++++++++++
 1 file changed, 40 insertions(+)

diff --git a/src/backend/caldav/caldav.php b/src/backend/caldav/caldav.php
index e18c18f8..b4c54e20 100644
--- a/src/backend/caldav/caldav.php
+++ b/src/backend/caldav/caldav.php
@@ -263,6 +263,46 @@ class BackendCalDAV extends BackendDiff {
         return false;
     }
 
+    /**
+     * Processes a response to a meeting request.
+     * CalendarID is a reference and has to be set if a new calendar item is created
+     * @see BackendDiff::MeetingResponse()
+     */
+    public function MeetingResponse($requestid, $folderid, $response) {
+        ZLog::Write(LOGLEVEL_DEBUG, sprintf("BackendCalDAV->MeetingResponse('%s','%s','%s')", $requestid, $folderid, $response));
+        if ($folderid[0] != "C")
+            throw new StatusException("BackendCalDAV->MeetingResponse(): Folder is not a calendar!", SYNC_ITEMOPERATIONSSTATUS_INVALIDATT);
+        $message = $this->GetMessageByID($folderid, $requestid);
+        if ($message == null)
+            throw new StatusException("BackendCalDAV->MeetingResponse(): Error, event not found", SYNC_ITEMOPERATIONSSTATUS_INVALIDATT);
+        $userDetails = ZPush::GetBackend()->GetCurrentUsername();
+        $vcal = Sabre\VObject\Reader::read($message['data'], Sabre\VObject\Reader::OPTION_FORGIVING);
+        foreach ($vcal->VEVENT as $vevent) {
+            foreach ($vevent->children() as $property) {
+                if ($property->name != "ATTENDEE")
+                    continue;
+                $att_email = str_ireplace("MAILTO:", "", (string)$property);
+                if ($att_email == $userDetails['emailaddress']) {
+                    switch($response) {
+                        case 1: // Accepted
+                            $property['PARTSTAT'] = "ACCEPTED";
+                            break;
+                        case 2: // Tentatively accepted
+                            $property['PARTSTAT'] = "TENTATIVE";
+                            break;
+                        case 3: // Declined
+                            $property['PARTSTAT'] = "DECLINED";
+                            break;
+                    }
+                    ZLog::Write(LOGLEVEL_DEBUG, sprintf("BackendCalDAV->MeetingResponse(): Updated participation to %s", $property['PARTSTAT']));
+                }
+            }
+        }
+        $url = $this->_caldav_path . substr($folderid, 1) . "/" . $requestid;
+        $this->CreateUpdateCalendar($vcal->serialize(), $url, $message['etag']);
+        return $requestid;
+    }
+
     /**
      * Get a list of all the folders we are going to sync.
      * Each caldav calendar can contain tasks (prefix T) and events (prefix C), so duplicate each calendar found.
-- 
GitLab