Changeset View
Changeset View
Standalone View
Standalone View
src/app/Backends/DAV.php
Show First 20 Lines • Show All 244 Lines • ▼ Show 20 Lines | class DAV | ||||
public function delete(string $location) | public function delete(string $location) | ||||
{ | { | ||||
$response = $this->request($location, 'DELETE', '', ['Depth' => 1, 'Prefer' => 'return-minimal']); | $response = $this->request($location, 'DELETE', '', ['Depth' => 1, 'Prefer' => 'return-minimal']); | ||||
return $response !== false; | return $response !== false; | ||||
} | } | ||||
/** | /** | ||||
* Create a DAV folder (collection) | |||||
* | |||||
* @param DAV\Folder $folder Folder object | |||||
* | |||||
* @return bool True on success, False on error | |||||
*/ | |||||
public function folderCreate(DAV\Folder $folder) | |||||
{ | |||||
$response = $this->request($folder->href, 'MKCOL', $folder->toXML('mkcol')); | |||||
return $response !== false; | |||||
} | |||||
/** | |||||
* Delete a DAV folder (collection) | |||||
* | |||||
* @param string $location Folder location | |||||
* | |||||
* @return bool True on success, False on error | |||||
*/ | |||||
public function folderDelete($location) | |||||
{ | |||||
$response = $this->request($location, 'DELETE'); | |||||
return $response !== false; | |||||
} | |||||
/** | |||||
* Get all properties of a folder. | * Get all properties of a folder. | ||||
* | * | ||||
* @param string $location Object location | * @param string $location Object location | ||||
* | * | ||||
* @return false|DAV\Folder Folder metadata or False on error | * @return false|DAV\Folder Folder metadata or False on error | ||||
*/ | */ | ||||
public function folderInfo(string $location) | public function folderInfo(string $location) | ||||
{ | { | ||||
$body = '<?xml version="1.0" encoding="utf-8"?>' | $body = DAV\Folder::propfindXML(); | ||||
. '<d:propfind xmlns:d="DAV:">' | |||||
. '<d:allprop/>' | |||||
. '</d:propfind>'; | |||||
// Note: Cyrus CardDAV service requires Depth:1 (CalDAV works without it) | // Note: Cyrus CardDAV service requires Depth:1 (CalDAV works without it) | ||||
$headers = ['Depth' => 1, 'Prefer' => 'return-minimal']; | $response = $this->request($location, 'PROPFIND', $body, ['Depth' => 0, 'Prefer' => 'return-minimal']); | ||||
$response = $this->request($location, 'PROPFIND', $body, $headers); | |||||
if (!empty($response) && ($element = $response->getElementsByTagName('response')->item(0))) { | if (!empty($response) && ($element = $response->getElementsByTagName('response')->item(0))) { | ||||
return DAV\Folder::fromDomElement($element); | return DAV\Folder::fromDomElement($element); | ||||
} | } | ||||
return false; | return false; | ||||
} | } | ||||
/** | /** | ||||
* Update a DAV folder (collection) | |||||
* | |||||
* @param DAV\Folder $folder Folder object | |||||
* | |||||
* @return bool True on success, False on error | |||||
*/ | |||||
public function folderUpdate(DAV\Folder $folder) | |||||
{ | |||||
// Note: Changing resourcetype property is forbidden (at least by Cyrus) | |||||
$response = $this->request($folder->href, 'PROPPATCH', $folder->toXML('propertyupdate')); | |||||
return $response !== false; | |||||
} | |||||
/** | |||||
* Initialize DAV folders (collections) | |||||
* | |||||
* @param \App\User $user User object | |||||
* @param array<array> $folders Folders list (path, displayname, type, components) | |||||
* | |||||
* @return bool True on success, False on error | |||||
*/ | |||||
public static function initDefaultFolders(\App\User $user, array $folders) | |||||
{ | |||||
// FIXME: It looks like we'll need a way to authenticate the user, or cyrus admin | |||||
$dav = new self($email, $password); | |||||
foreach ($folders as $props) { | |||||
$folder = new DAV\Folder(); | |||||
$folder->href = "addressbooks/user/{$user->email}/{$props['path']}"; | |||||
$folder->name = $props['displayname'] ?? ''; | |||||
$folder->types = ['collection', $props['type']]; | |||||
$folder->components = $props['components'] ?? []; | |||||
// folder already exists? check the properties and update if needed | |||||
if ($existing = $dav->folderInfo($folder->href)) { | |||||
if ($existing->name != $folder->name || $existing->components != $folder->components) { | |||||
if (!$dav->folderUpdate($folder)) { | |||||
\Log::error("Failed to update DAV folder {$folder->href}"); | |||||
return false; | |||||
} | |||||
} | |||||
} | |||||
if (!$dav->folderCreate($folder)) { | |||||
\Log::error("Failed to create DAV folder {$folder->href}"); | |||||
return false; | |||||
} | |||||
} | |||||
return true; | |||||
} | |||||
/** | |||||
* Search DAV objects in a folder. | * Search DAV objects in a folder. | ||||
* | * | ||||
* @param string $location Folder location | * @param string $location Folder location | ||||
* @param string $component Object type (VEVENT, VTODO, VCARD) | * @param string $component Object type (VEVENT, VTODO, VCARD) | ||||
* | * | ||||
* @return false|array Objects metadata on success, False on error | * @return false|array Objects metadata on success, False on error | ||||
*/ | */ | ||||
public function search(string $location, string $component) | public function search(string $location, string $component) | ||||
▲ Show 20 Lines • Show All 223 Lines • Show Last 20 Lines |