diff --git a/plugins/libkolab/lib/kolab_dav_client.php b/plugins/libkolab/lib/kolab_dav_client.php --- a/plugins/libkolab/lib/kolab_dav_client.php +++ b/plugins/libkolab/lib/kolab_dav_client.php @@ -375,15 +375,18 @@ */ public function folderCreate($location, $component, $properties = []) { - $ns = 'xmlns:d="DAV:"'; - $props = ''; + [$props, $ns] = $this->folderPropertiesToXml($properties, 'xmlns:d="DAV:"'); if ($component == 'VCARD') { $ns .= ' xmlns:c="urn:ietf:params:xml:ns:carddav"'; - $props = ''; + $props .= ''; } else { $ns .= ' xmlns:c="urn:ietf:params:xml:ns:caldav"'; - $props = ''; + $props .= '' + // Note: Some clients, but also Cyrus by default allows everything in calendar folders, + // i.e. VEVENT, VTODO, VJOURNAL, VFREEBUSY, VAVAILABILITY, but we prefer a single-type folders, + // to keep tasks and event separated + . ''; } $body = '' @@ -396,12 +399,7 @@ // Create the collection $response = $this->request($location, 'MKCOL', $body); - if (empty($response)) { - return false; - } - - // Update collection properties - return $this->folderUpdate($location, $component, $properties); + return $response !== false; } /** @@ -429,29 +427,35 @@ */ public function folderUpdate($location, $component, $properties = []) { - $ns = 'xmlns:d="DAV:"'; - $props = ''; + // Note: Changing resourcetype property is forbidden (at least by Cyrus) - if ($component == 'VCARD') { - $ns .= ' xmlns:c="urn:ietf:params:xml:ns:carddav"'; - // Resourcetype property is protected - // $props = ''; - } else { - $ns .= ' xmlns:c="urn:ietf:params:xml:ns:caldav"'; - // Resourcetype property is protected - // $props = ''; - /* - // Note: These are set by Cyrus automatically for calendars - . '' - . '' - . '' - . '' - . '' - . '' - . ''; - */ + [$props, $ns] = $this->folderPropertiesToXml($properties, 'xmlns:d="DAV:"'); + + if (empty($props)) { + return true; } + $body = '' + . '' + . '' + . '' . $props . '' + . '' + . ''; + + $response = $this->request($location, 'PROPPATCH', $body); + + // TODO: Should we make sure "200 OK" status is set for all requested properties? + + return $response !== false; + } + + /** + * Parse folder properties input into XML string to use in a request + */ + protected function folderPropertiesToXml($properties, $ns = '') + { + $props = ''; + foreach ($properties as $name => $value) { if ($name == 'name') { $props .= '' . htmlspecialchars($value, ENT_XML1, 'UTF-8') . ''; @@ -471,22 +475,7 @@ } } - if (empty($props)) { - return true; - } - - $body = '' - . '' - . '' - . '' . $props . '' - . '' - . ''; - - $response = $this->request($location, 'PROPPATCH', $body); - - // TODO: Should we make sure "200 OK" status is set for all requested properties? - - return $response !== false; + return [$props, $ns]; } /**