CalDAV: Multi-folder support

This commit is contained in:
Aleksander Machniak 2022-11-08 12:34:35 +01:00
parent f9e8f7f084
commit b6cc8c0715
6 changed files with 50 additions and 81 deletions

View file

@ -61,7 +61,7 @@ class caldav_calendar extends kolab_storage_dav_folder
$this->storage = $folder_or_id; $this->storage = $folder_or_id;
} }
else { else {
// $this->storage = kolab_storage_dav::get_folder($folder_or_id); // $this->storage = kolab_storage_dav::get_folder($folder_or_id, 'event');
} }
$this->cal = $calendar; $this->cal = $calendar;
@ -368,8 +368,8 @@ class caldav_calendar extends kolab_storage_dav_folder
// $config = kolab_storage_config::get_instance(); // $config = kolab_storage_config::get_instance();
// $config->apply_links($events); // $config->apply_links($events);
// avoid session race conditions that will loose temporary subscriptions // Avoid session race conditions that will loose temporary subscriptions
$this->cal->rc->session->nowrite = true; // $this->cal->rc->session->nowrite = true;
return $events; return $events;
} }

View file

@ -125,6 +125,7 @@ class caldav_driver extends kolab_driver
$folders = $this->filter_calendars($filter); $folders = $this->filter_calendars($filter);
$calendars = []; $calendars = [];
$prefs = $this->rc->config->get('kolab_calendars', []);
// include virtual folders for a full folder tree // include virtual folders for a full folder tree
/* /*
@ -181,11 +182,11 @@ class caldav_driver extends kolab_driver
'color' => $cal->get_color(), 'color' => $cal->get_color(),
'editable' => $cal->editable, 'editable' => $cal->editable,
'group' => $is_user ? 'other user' : $cal->get_namespace(), 'group' => $is_user ? 'other user' : $cal->get_namespace(),
'active' => $cal->is_active(), 'active' => !isset($prefs[$cal->id]['active']) || !empty($prefs[$cal->id]['active']),
'owner' => $cal->get_owner(), 'owner' => $cal->get_owner(),
'removable' => !$cal->default, 'removable' => !$cal->default,
// extras to hide some elements in the UI // extras to hide some elements in the UI
'subscriptions' => false, 'subscriptions' => $cal->subscriptions,
'driver' => 'caldav', 'driver' => 'caldav',
]; ];
@ -306,10 +307,8 @@ class caldav_driver extends kolab_driver
*/ */
public function create_calendar($prop) public function create_calendar($prop)
{ {
$prop['type'] = 'event'; $prop['type'] = 'event';
$prop['active'] = true; // TODO $prop['alarms'] = !empty($prop['showalarms']);
$prop['subscribed'] = true;
$prop['alarms'] = !empty($prop['showalarms']);
$id = $this->storage->folder_update($prop); $id = $this->storage->folder_update($prop);
@ -317,6 +316,10 @@ class caldav_driver extends kolab_driver
return false; return false;
} }
$prefs['kolab_calendars'] = $this->rc->config->get('kolab_calendars', []);
$prefs['kolab_calendars'][$id]['active'] = true;
$this->rc->user->save_prefs($prefs);
return $id; return $id;
} }
@ -362,48 +365,19 @@ class caldav_driver extends kolab_driver
*/ */
public function subscribe_calendar($prop) public function subscribe_calendar($prop)
{ {
if (!empty($prop['id']) && ($cal = $this->get_calendar($prop['id'])) && !empty($cal->storage)) { if (empty($prop['id'])) {
$ret = false; return false;
if (isset($prop['permanent'])) {
$ret |= $cal->storage->subscribe(intval($prop['permanent']));
}
if (isset($prop['active'])) {
$ret |= $cal->storage->activate(intval($prop['active']));
}
// apply to child folders, too
if (!empty($prop['recursive'])) {
foreach ((array) $this->storage->list_folders($cal->storage->name, '*', 'event') as $subfolder) {
if (isset($prop['permanent'])) {
if ($prop['permanent']) {
$this->storage->folder_subscribe($subfolder);
}
else {
$this->storage->folder_unsubscribe($subfolder);
}
}
if (isset($prop['active'])) {
if ($prop['active']) {
$this->storage->folder_activate($subfolder);
}
else {
$this->storage->folder_deactivate($subfolder);
}
}
}
}
return $ret;
} }
else {
// save state in local prefs // save state in local prefs
if (isset($prop['active'])) {
$prefs['kolab_calendars'] = $this->rc->config->get('kolab_calendars', []); $prefs['kolab_calendars'] = $this->rc->config->get('kolab_calendars', []);
$prefs['kolab_calendars'][$prop['id']]['active'] = !empty($prop['active']); $prefs['kolab_calendars'][$prop['id']]['active'] = !empty($prop['active']);
$this->rc->user->save_prefs($prefs); $this->rc->user->save_prefs($prefs);
return true;
} }
return false; return true;
} }
/** /**

View file

@ -352,7 +352,7 @@ class calendar_ui
$color = !empty($prop['color']) ? $prop['color'] : 'f00'; $color = !empty($prop['color']) ? $prop['color'] : 'f00';
$actions = ''; $actions = '';
if (!EMPTY($prop['removable'])) { if (!empty($prop['removable'])) {
$actions .= html::a([ $actions .= html::a([
'href' => '#', 'href' => '#',
'class' => 'remove', 'class' => 'remove',
@ -370,28 +370,28 @@ class calendar_ui
], '' ], ''
); );
if (!empty($prop['subscribed'])) { if (!isset($prop['subscriptions']) || $prop['subscriptions'] !== false) {
$actions .= html::a([ if (!empty($prop['subscribed'])) {
'href' => '#', $actions .= html::a([
'class' => 'subscribed', 'href' => '#',
'title' => $this->cal->gettext('calendarsubscribe'), 'class' => 'subscribed',
'role' => 'checkbox', 'title' => $this->cal->gettext('calendarsubscribe'),
'aria-checked' => !empty($prop['subscribed']) ? 'true' : 'false' 'role' => 'checkbox',
], ' ' 'aria-checked' => !empty($prop['subscribed']) ? 'true' : 'false'
); ], ' '
);
}
} }
if (!isset($prop['subscriptions']) || $prop['subscriptions'] !== false) { $content .= html::tag('input', [
$content .= html::tag('input', [ 'type' => 'checkbox',
'type' => 'checkbox', 'name' => '_cal[]',
'name' => '_cal[]', 'value' => $id,
'value' => $id, 'checked' => !empty($prop['active']),
'checked' => !empty($prop['active']), 'aria-labelledby' => $label_id
'aria-labelledby' => $label_id ])
]) . html::span('actions', $actions)
. html::span('actions', $actions) . html::span(['class' => 'handle', 'style' => "background-color: #$color"], ' ');
. html::span(['class' => 'handle', 'style' => "background-color: #$color"], ' ');
}
} }
$content = html::div(join(' ', $classes), $content); $content = html::div(join(' ', $classes), $content);

View file

@ -227,8 +227,7 @@ class kolab_dav_client
$ns .= ' xmlns:c="urn:ietf:params:xml:ns:caldav" xmlns:a="http://apple.com/ns/ical/" xmlns:k="Kolab:"'; $ns .= ' xmlns:c="urn:ietf:params:xml:ns:caldav" xmlns:a="http://apple.com/ns/ical/" xmlns:k="Kolab:"';
$props = '<c:supported-calendar-component-set />' $props = '<c:supported-calendar-component-set />'
. '<a:calendar-color />' . '<a:calendar-color />'
. '<k:alarms />' . '<k:alarms />';
. '<k:subscribed />';
} }
$body = '<?xml version="1.0" encoding="utf-8"?>' $body = '<?xml version="1.0" encoding="utf-8"?>'
@ -436,7 +435,7 @@ class kolab_dav_client
$ns .= ' xmlns:a="http://apple.com/ns/ical/"'; $ns .= ' xmlns:a="http://apple.com/ns/ical/"';
$props .= '<a:calendar-color>' . htmlspecialchars($value, ENT_XML1, 'UTF-8') . '</a:calendar-color>'; $props .= '<a:calendar-color>' . htmlspecialchars($value, ENT_XML1, 'UTF-8') . '</a:calendar-color>';
} }
else if ($name == 'subscribed' || $name == 'alarms') { else if ($name == 'alarms') {
if (!strpos($ns, 'Kolab:')) { if (!strpos($ns, 'Kolab:')) {
$ns .= ' xmlns:k="Kolab:"'; $ns .= ' xmlns:k="Kolab:"';
} }
@ -677,7 +676,7 @@ class kolab_dav_client
'resource_type' => $types, 'resource_type' => $types,
]; ];
foreach (['subscribed', 'alarms'] as $tag) { foreach (['alarms'] as $tag) {
if ($el = $element->getElementsByTagName($tag)->item(0)) { if ($el = $element->getElementsByTagName($tag)->item(0)) {
if (strlen($el->nodeValue) > 0) { if (strlen($el->nodeValue) > 0) {
$result[$tag] = strtolower($el->nodeValue) === 'true'; $result[$tag] = strtolower($el->nodeValue) === 'true';

View file

@ -435,8 +435,7 @@ class kolab_storage_dav
*/ */
public function folder_is_active($folder) public function folder_is_active($folder)
{ {
// TODO return true; // TODO
return true;
} }
/** /**
@ -448,7 +447,7 @@ class kolab_storage_dav
*/ */
public function folder_activate($folder) public function folder_activate($folder)
{ {
return true; return true; // TODO
} }
/** /**
@ -460,7 +459,7 @@ class kolab_storage_dav
*/ */
public function folder_deactivate($folder) public function folder_deactivate($folder)
{ {
return false; return false; // TODO
} }
/** /**

View file

@ -200,8 +200,7 @@ class kolab_storage_dav_folder extends kolab_storage_folder
*/ */
public function is_active() public function is_active()
{ {
// TODO return true; // Unused
return true;
} }
/** /**
@ -213,8 +212,7 @@ class kolab_storage_dav_folder extends kolab_storage_folder
*/ */
public function activate($active) public function activate($active)
{ {
// TODO return true; // Unused
return true;
} }
/** /**
@ -224,7 +222,7 @@ class kolab_storage_dav_folder extends kolab_storage_folder
*/ */
public function is_subscribed() public function is_subscribed()
{ {
return !isset($this->attributes['subscribed']) || $this->attributes['subscribed']; return true; // TODO
} }
/** /**
@ -236,8 +234,7 @@ class kolab_storage_dav_folder extends kolab_storage_folder
*/ */
public function subscribe($subscribed) public function subscribe($subscribed)
{ {
// TODO return true; // TODO
return true;
} }
/** /**