aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMax Kostikov <max@kostikov.co>2020-02-24 10:02:09 +0100
committerMario <mario@mariovavti.com>2020-02-24 10:02:09 +0100
commit989fbe70cd566da4c5757527aa77022036af6274 (patch)
tree3f2f031445c4f5cf1e97d548a9df335a12a98c5b
parent7bb94f999350dfdc2c2cdf5b5d094ef52953edd6 (diff)
downloadvolse-hubzilla-989fbe70cd566da4c5757527aa77022036af6274.tar.gz
volse-hubzilla-989fbe70cd566da4c5757527aa77022036af6274.tar.bz2
volse-hubzilla-989fbe70cd566da4c5757527aa77022036af6274.zip
Implement DAV calendars sync with clones
-rw-r--r--Zotlabs/Lib/Libsync.php5
-rw-r--r--Zotlabs/Module/Cdav.php156
-rw-r--r--include/cdav.php4
-rw-r--r--include/import.php71
-rw-r--r--include/zot.php3
5 files changed, 203 insertions, 36 deletions
diff --git a/Zotlabs/Lib/Libsync.php b/Zotlabs/Lib/Libsync.php
index d1756cf47..c39720735 100644
--- a/Zotlabs/Lib/Libsync.php
+++ b/Zotlabs/Lib/Libsync.php
@@ -246,7 +246,10 @@ class Libsync {
sync_apps($channel,$arr['app']);
if(array_key_exists('addressbook',$arr) && $arr['addressbook'])
- sync_addressbook($channel,$arr['addressbook']);
+ sync_addressbook($channel,$arr['addressbook']);
+
+ if(array_key_exists('calendar',$arr) && $arr['calendar'])
+ sync_calendar($channel,$arr['calendar']);
if(array_key_exists('chatroom',$arr) && $arr['chatroom'])
sync_chatrooms($channel,$arr['chatroom']);
diff --git a/Zotlabs/Module/Cdav.php b/Zotlabs/Module/Cdav.php
index 593a78a53..ac73b8a5b 100644
--- a/Zotlabs/Module/Cdav.php
+++ b/Zotlabs/Module/Cdav.php
@@ -169,24 +169,34 @@ class Cdav extends Controller {
logger("debug: method: " . $httpmethod, LOGGER_DEBUG);
logger("debug: uri: " . $httpuri, LOGGER_DEBUG);
- // currently we process CardDAV requests only
if(strpos($httpuri, 'cdav/addressbooks')) {
+ $sync = 'addressbook';
+ $cdavtable = 'addressbooks';
+ }
+ elseif(strpos($httpuri, 'cdav/calendars')) {
+ $sync = 'calendar';
+ $cdavtable = 'calendarinstances';
+ }
+ else
+ $sync = false;
+
+ if($sync) {
$uri = basename($httpuri);
$httpbody = file_get_contents('php://input');
logger("debug: body: " . $httpbody, LOGGER_DEBUG);
- if($id = get_cdav_id($principalUri, explode("/", $httpuri)[4], 'addressbooks')) {
+ if($x = get_cdav_id($principalUri, explode("/", $httpuri)[4], $cdavtable)) {
- $cdavdata = $this->get_cdav_data($id, 'addressbooks');
+ $cdavdata = $this->get_cdav_data($x['id'], $cdavtable);
$etag = (isset($_SERVER['HTTP_IF_MATCH']) ? $_SERVER['HTTP_IF_MATCH'] : false);
// delete
if($httpmethod === 'DELETE' && $cdavdata['etag'] == $etag)
build_sync_packet($channel['channel_id'], [
- 'addressbook' => [
+ $sync => [
'action' => 'delete_card',
'uri' => $cdavdata['uri'],
'carduri' => $uri
@@ -197,7 +207,7 @@ class Cdav extends Controller {
// update
if($cdavdata['etag'] !== $etag)
build_sync_packet($channel['channel_id'], [
- 'addressbook' => [
+ $sync => [
'action' => 'update_card',
'uri' => $cdavdata['uri'],
'carduri' => $uri,
@@ -208,7 +218,7 @@ class Cdav extends Controller {
else {
// new
build_sync_packet($channel['channel_id'], [
- 'addressbook' => [
+ $sync => [
'action' => 'import',
'uri' => $cdavdata['uri'],
'ids' => [ $uri ],
@@ -326,6 +336,14 @@ class Cdav extends Controller {
// set new calendar to be visible
set_pconfig(local_channel(), 'cdav_calendar' , $id[0], 1);
+
+ build_sync_packet($channel['channel_id'], [
+ 'calendar' => [
+ 'action' => 'create',
+ 'uri' => $calendarUri,
+ 'properties' => $properties
+ ]
+ ]);
}
//create new calendar object via ajax request
@@ -336,6 +354,8 @@ class Cdav extends Controller {
if(!cdav_perms($id[0],$calendars,true))
return;
+ $cdavdata = $this->get_cdav_data($id[0], 'calendarinstances');
+
$timezone = ((x($_POST,'timezone_select')) ? escape_tags(trim($_POST['timezone_select'])) : '');
$tz = (($timezone) ? $timezone : date_default_timezone_get());
@@ -391,9 +411,17 @@ class Cdav extends Controller {
$vcalendar->VEVENT->DTSTART['TZID'] = $tz;
$calendarData = $vcalendar->serialize();
-
$caldavBackend->createCalendarObject($id, $objectUri, $calendarData);
+ build_sync_packet($channel['channel_id'], [
+ 'calendar' => [
+ 'action' => 'import',
+ 'uri' => $cdavdata['uri'],
+ 'ids' => [ $objectUri ],
+ 'card' => $calendarData
+ ]
+ ]);
+
killme();
}
@@ -405,17 +433,24 @@ class Cdav extends Controller {
if(! cdav_perms($id[0],$calendars))
return;
+ $cdavdata = $this->get_cdav_data($id[0], 'calendarinstances');
+
$mutations = [
'{DAV:}displayname' => $_REQUEST['{DAV:}displayname'],
'{http://apple.com/ns/ical/}calendar-color' => $_REQUEST['color']
];
$patch = new \Sabre\DAV\PropPatch($mutations);
-
$caldavBackend->updateCalendar($id, $patch);
-
$patch->commit();
+ build_sync_packet($channel['channel_id'], [
+ 'calendar' => [
+ 'action' => 'edit',
+ 'uri' => $cdavdata['uri'],
+ 'mutations' => $mutations,
+ ]
+ ]);
}
//edit calendar object via ajax request
@@ -423,9 +458,11 @@ class Cdav extends Controller {
$id = explode(':', $_REQUEST['target']);
- if(!cdav_perms($id[0],$calendars,true))
+ if(! cdav_perms($id[0],$calendars,true))
return;
+ $cdavdata = $this->get_cdav_data($id[0], 'calendarinstances');
+
$timezone = ((x($_POST,'timezone_select')) ? escape_tags(trim($_POST['timezone_select'])) : '');
$tz = (($timezone) ? $timezone : date_default_timezone_get());
@@ -471,9 +508,17 @@ class Cdav extends Controller {
$vcalendar->VEVENT->LOCATION = $location;
$calendarData = $vcalendar->serialize();
-
$caldavBackend->updateCalendarObject($id, $uri, $calendarData);
+ build_sync_packet($channel['channel_id'], [
+ 'calendar' => [
+ 'action' => 'update_card',
+ 'uri' => $cdavdata['uri'],
+ 'carduri' => $uri,
+ 'card' => $calendarData
+ ]
+ ]);
+
killme();
}
@@ -482,13 +527,23 @@ class Cdav extends Controller {
$id = explode(':', $_REQUEST['target']);
- if(!cdav_perms($id[0],$calendars,true))
+ if(! cdav_perms($id[0],$calendars,true))
return;
+ $cdavdata = $this->get_cdav_data($id[0], 'calendarinstances');
+
$uri = $_REQUEST['uri'];
$caldavBackend->deleteCalendarObject($id, $uri);
+ build_sync_packet($channel['channel_id'], [
+ 'calendar' => [
+ 'action' => 'delete_card',
+ 'uri' => $cdavdata['uri'],
+ 'carduri' => $uri
+ ]
+ ]);
+
killme();
}
@@ -497,9 +552,11 @@ class Cdav extends Controller {
$id = [$_REQUEST['id'][0], $_REQUEST['id'][1]];
- if(!cdav_perms($id[0],$calendars,true))
+ if(! cdav_perms($id[0],$calendars,true))
return;
+ $cdavdata = $this->get_cdav_data($id[0], 'calendarinstances');
+
$timezone = ((x($_POST,'timezone_select')) ? escape_tags(trim($_POST['timezone_select'])) : '');
$tz = (($timezone) ? $timezone : date_default_timezone_get());
@@ -535,9 +592,17 @@ class Cdav extends Controller {
unset($vcalendar->VEVENT->DTEND);
$calendarData = $vcalendar->serialize();
-
$caldavBackend->updateCalendarObject($id, $uri, $calendarData);
+ build_sync_packet($channel['channel_id'], [
+ 'calendar' => [
+ 'action' => 'update_card',
+ 'uri' => $cdavdata['uri'],
+ 'carduri' => $uri,
+ 'card' => $calendarData
+ ]
+ ]);
+
killme();
}
@@ -602,11 +667,11 @@ class Cdav extends Controller {
$id = $_REQUEST['id'];
- $cdavdata = $this->get_cdav_data($id, 'addressbooks');
-
if(! cdav_perms($id,$addressbooks))
return;
+ $cdavdata = $this->get_cdav_data($id, 'addressbooks');
+
$mutations = [
'{DAV:}displayname' => $_REQUEST['{DAV:}displayname']
];
@@ -626,6 +691,7 @@ class Cdav extends Controller {
//create addressbook card
if($_REQUEST['create'] && $_REQUEST['target'] && $_REQUEST['fn']) {
+
$id = $_REQUEST['target'];
$cdavdata = $this->get_cdav_data($id, 'addressbooks');
@@ -656,7 +722,6 @@ class Cdav extends Controller {
process_cdav_card($fields, $vcard);
$cardData = $vcard->serialize();
-
$carddavBackend->createCard($id, $uri, $cardData);
build_sync_packet($channel['channel_id'], [
@@ -674,11 +739,11 @@ class Cdav extends Controller {
$id = $_REQUEST['target'];
- $cdavdata = $this->get_cdav_data($id, 'addressbooks');
-
- if(!cdav_perms($id,$addressbooks))
+ if(! cdav_perms($id,$addressbooks))
return;
+ $cdavdata = $this->get_cdav_data($id, 'addressbooks');
+
$uri = $_REQUEST['uri'];
$object = $carddavBackend->getCard($id, $uri);
@@ -714,11 +779,11 @@ class Cdav extends Controller {
$id = $_REQUEST['target'];
- $cdavdata = $this->get_cdav_data($id, 'addressbooks');
-
- if(!cdav_perms($id,$addressbooks))
+ if(! cdav_perms($id,$addressbooks))
return;
+ $cdavdata = $this->get_cdav_data($id, 'addressbooks');
+
$uri = $_REQUEST['uri'];
$carddavBackend->deleteCard($id, $uri);
@@ -758,9 +823,12 @@ class Cdav extends Controller {
$ext = 'ics';
$table = 'calendarobjects';
$column = 'calendarid';
+ $sync = 'calendar';
$objects = new \Sabre\VObject\Splitter\ICalendar($carddata);
$profile = \Sabre\VObject\Node::PROFILE_CALDAV;
$backend = new \Sabre\CalDAV\Backend\PDO($pdo);
+
+ $cdavdata = $this->get_cdav_data($id, 'calendarinstances');
}
if($_REQUEST['a_upload']) {
@@ -768,6 +836,7 @@ class Cdav extends Controller {
$ext = 'vcf';
$table = 'cards';
$column = 'addressbookid';
+ $sync = 'addressbook';
$objects = new \Sabre\VObject\Splitter\VCard($carddata);
$profile = \Sabre\VObject\Node::PROFILE_CARDDAV;
$backend = new \Sabre\CardDAV\Backend\PDO($pdo);
@@ -778,15 +847,14 @@ class Cdav extends Controller {
$ids = [];
import_cdav_card($id, $ext, $table, $column, $objects, $profile, $backend, $ids, true);
- if(isset($cdavdata))
- build_sync_packet($channel['channel_id'], [
- 'addressbook' => [
- 'action' => 'import',
- 'uri' => $cdavdata['uri'],
- 'ids' => $ids,
- 'card' => $carddata
- ]
- ]);
+ build_sync_packet($channel['channel_id'], [
+ $sync => [
+ 'action' => 'import',
+ 'uri' => $cdavdata['uri'],
+ 'ids' => $ids,
+ 'card' => $carddata
+ ]
+ ]);
}
@unlink($src);
}
@@ -1095,7 +1163,18 @@ class Cdav extends Controller {
if(! cdav_perms($id,$calendars))
killme();
- set_pconfig(local_channel(), 'cdav_calendar' , argv(3), argv(4));
+ $cdavdata = $this->get_cdav_data($id, 'calendarinstances');
+
+ set_pconfig(local_channel(), 'cdav_calendar', $id, argv(4));
+
+ build_sync_packet(local_channel(), [
+ 'calendar' => [
+ 'action' => 'switch',
+ 'uri' => $cdavdata['uri'],
+ 'switch' => intval(argv(4))
+ ]
+ ]);
+
killme();
}
@@ -1106,7 +1185,18 @@ class Cdav extends Controller {
if(! cdav_perms($id[0],$calendars))
killme();
+ // get metadata before we delete it
+ $cdavdata = $this->get_cdav_data($id[0], 'calendarinstances');
+
$caldavBackend->deleteCalendar($id);
+
+ build_sync_packet($channel['channel_id'], [
+ 'calendar' => [
+ 'action' => 'drop',
+ 'uri' => $cdavdata['uri']
+ ]
+ ]);
+
killme();
}
diff --git a/include/cdav.php b/include/cdav.php
index d72caa442..cdf7775db 100644
--- a/include/cdav.php
+++ b/include/cdav.php
@@ -175,12 +175,12 @@ function import_cdav_card($id, $ext, $table, $column, $objects, $profile, $backe
function get_cdav_id($principaluri, $uri, $table) {
- $r = q("SELECT id FROM $table WHERE principaluri = '%s' AND uri = '%s' LIMIT 1",
+ $r = q("SELECT * FROM $table WHERE principaluri = '%s' AND uri = '%s' LIMIT 1",
dbesc($principaluri),
dbesc($uri)
);
if(! $r)
return false;
- return $r[0]['id'];
+ return $r[0];
}
diff --git a/include/import.php b/include/import.php
index 0519052d8..bfe71963f 100644
--- a/include/import.php
+++ b/include/import.php
@@ -1503,6 +1503,7 @@ function sync_files($channel, $files) {
}
}
+
/**
* @brief Synchronize addressbooks.
*
@@ -1571,6 +1572,76 @@ function sync_addressbook($channel, $data) {
/**
+ * @brief Synchronize calendars.
+ *
+ * @param array $channel
+ * @param array $data
+ */
+function sync_calendar($channel, $data) {
+
+ if(! \Zotlabs\Lib\Apps::system_app_installed($channel['channel_id'], 'Calendar'))
+ return;
+
+ logger("debug: " . print_r($data,true), LOGGER_DEBUG);
+
+ require_once('include/cdav.php');
+
+ $principalUri = 'principals/' . $channel['channel_address'];
+
+ if($data['action'] !== 'create') {
+ $x = get_cdav_id($principalUri, $data['uri'], 'calendarinstances');
+ if(! $x)
+ return;
+ $id = [ $x['id'], $x['calendarid'] ];
+ }
+
+ $pdo = \DBA::$dba->db;
+
+ $caldavBackend = new \Sabre\CalDAV\Backend\PDO($pdo);
+ $calendars = $caldavBackend->getCalendarsForUser($principalUri);
+
+ switch($data['action']) {
+
+ case 'create':
+ $id = $caldavBackend->createCalendar($principalUri, $data['uri'], $data['properties']);
+ set_pconfig($channel['channel_id'], 'cdav_calendar', $id[0], 1);
+ break;
+
+ case 'drop':
+ $caldavBackend->deleteCalendar($id);
+ break;
+
+ case 'edit':
+ $patch = new \Sabre\DAV\PropPatch($data['mutations']);
+ $caldavBackend->updateCalendar($id, $patch);
+ $patch->commit();
+ break;
+
+ case 'delete_card':
+ $caldavBackend->deleteCalendarObject($id, $data['carduri']);
+ break;
+
+ case 'update_card':
+ $caldavBackend->updateCalendarObject($id, $data['carduri'], $data['card']);
+ break;
+
+ case 'switch':
+ set_pconfig($channel['channel_id'], 'cdav_calendar', $id[0], $data['switch']);
+ break;
+
+ case 'import':
+ $objects = new \Sabre\VObject\Splitter\ICalendar($data['card']);
+ $profile = \Sabre\VObject\Node::PROFILE_CALDAV;
+ import_cdav_card($id, 'ics', 'calendarobjects', 'calendarid', $objects, $profile, $caldavBackend, $data['ids']);
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+/**
* @brief Rename a key in an array.
*
* Replaces $old key with $new key in $arr.
diff --git a/include/zot.php b/include/zot.php
index c02dab162..5d5ac8424 100644
--- a/include/zot.php
+++ b/include/zot.php
@@ -3614,6 +3614,9 @@ function process_channel_sync_delivery($sender, $arr, $deliveries) {
if(array_key_exists('addressbook',$arr) && $arr['addressbook'])
sync_addressbook($channel,$arr['addressbook']);
+ if(array_key_exists('calendar',$arr) && $arr['calendar'])
+ sync_calendar($channel,$arr['calendar']);
+
if(array_key_exists('chatroom',$arr) && $arr['chatroom'])
sync_chatrooms($channel,$arr['chatroom']);