From 277e3094f7606f645edf7656f31d2b4d0f660fec Mon Sep 17 00:00:00 2001 From: JodliDev Date: Tue, 24 Aug 2021 12:55:41 +0200 Subject: [PATCH] - Added iCal Support - Bugfixes - automatically generated sqlite & postgres support (not tested!) --- drivers/caldav/Isync.php | 75 +++++++++++ drivers/caldav/SQL/mysql.initial.sql | 137 ++++++++++---------- drivers/caldav/SQL/mysql/2014081300.sql | 24 ---- drivers/caldav/SQL/mysql/2015022500.sql | 125 ------------------ drivers/caldav/SQL/mysql/2015022700.sql | 14 -- drivers/caldav/SQL/postgres.initial.sql | 130 +++++++++++++++---- drivers/caldav/SQL/sqlite.initial.sql | 101 +++++++++++++++ drivers/caldav/caldav_driver.php | 111 +++++++++++----- drivers/caldav/caldav_sync.php | 17 ++- drivers/caldav/ical_sync.php | 163 ++++++++++++++++++++++++ localization/de.inc | 10 +- localization/de_CH.inc | 10 +- localization/de_DE.inc | 10 +- localization/en_US.inc | 9 +- 14 files changed, 622 insertions(+), 314 deletions(-) create mode 100644 drivers/caldav/Isync.php delete mode 100644 drivers/caldav/SQL/mysql/2014081300.sql delete mode 100644 drivers/caldav/SQL/mysql/2015022500.sql delete mode 100644 drivers/caldav/SQL/mysql/2015022700.sql create mode 100644 drivers/caldav/SQL/sqlite.initial.sql create mode 100644 drivers/caldav/ical_sync.php diff --git a/drivers/caldav/Isync.php b/drivers/caldav/Isync.php new file mode 100644 index 0000000..8cbfc06 --- /dev/null +++ b/drivers/caldav/Isync.php @@ -0,0 +1,75 @@ + + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +interface Isync { + /** + * Getter for current calendar ctag (only for CalDAV). + * @return string + */ + public function get_ctag(); + + /** + * Determines whether current calendar needs to be synced + * + * @return boolean True if the current calendar needs to be synced, false otherwise. + */ + public function is_synced(); + + /** + * Synchronizes given events with server and returns updates. + * + * @param array List of hash arrays with event properties, must include "caldav_url" and "tag". + * @return array Tuple containing the following lists: + * + * Caldav properties for events to be created or to be updated with the keys: + * url: Event ical URL relative to calendar URL + * etag: Remote etag of the event + * local_event: The local event in case of an update. + * remote_event: The current event retrieved from caldav server. + * + * A list of event ids that are in sync. + */ + public function get_updates($events); + + /** + * Creates the given event. + * + * @param array Hash array with event properties. + * @return array with updated "caldav_url" and "caldav_tag" attributes, null on error. + */ + public function create_event($event); + + /** + * Updates the given event. + * + * @param array Hash array with event properties to update, must include "uid", "caldav_url" and "caldav_tag". + * @return boolean True on success, false on error, -1 if the given event/etag is not up to date. + */ + public function update_event($event); + + /** + * Removes the given event. + * + * @param array Hash array with events properties, must include "caldav_url". + * @return boolean True on success, false on error. + */ + public function remove_event($event); +} \ No newline at end of file diff --git a/drivers/caldav/SQL/mysql.initial.sql b/drivers/caldav/SQL/mysql.initial.sql index 1c0c2cf..fcd6d0a 100644 --- a/drivers/caldav/SQL/mysql.initial.sql +++ b/drivers/caldav/SQL/mysql.initial.sql @@ -22,86 +22,89 @@ */ CREATE TABLE IF NOT EXISTS `caldav_sources` ( - `source_id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, - `user_id` int(10) UNSIGNED NOT NULL DEFAULT '0', + `source_id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, + `user_id` int(10) UNSIGNED NOT NULL DEFAULT '0', - `caldav_url` varchar(255) NOT NULL, - `caldav_user` varchar(255) DEFAULT NULL, - `caldav_pass` varchar(1024) DEFAULT NULL, + `caldav_url` varchar(1024) NOT NULL, + `caldav_user` varchar(255) DEFAULT NULL, + `caldav_pass` varchar(1024) DEFAULT NULL, - PRIMARY KEY(`source_id`), - CONSTRAINT `fk_caldav_sources_user_id` FOREIGN KEY (`user_id`) - REFERENCES `users`(`user_id`) ON DELETE CASCADE ON UPDATE CASCADE + PRIMARY KEY(`source_id`), + CONSTRAINT `fk_caldav_sources_user_id` FOREIGN KEY (`user_id`) + REFERENCES `users`(`user_id`) ON DELETE CASCADE ON UPDATE CASCADE ) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */; CREATE TABLE IF NOT EXISTS `caldav_calendars` ( - `calendar_id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, - `user_id` int(10) UNSIGNED NOT NULL DEFAULT '0', - `source_id` int(10) UNSIGNED NOT NULL DEFAULT '0', - `name` varchar(255) NOT NULL, - `color` varchar(8) NOT NULL, - `showalarms` tinyint(1) NOT NULL DEFAULT '1', + `calendar_id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, + `user_id` int(10) UNSIGNED NOT NULL DEFAULT '0', + `source_id` int(10) UNSIGNED NOT NULL DEFAULT '0', + `name` varchar(255) NOT NULL, + `color` varchar(8) NOT NULL, + `showalarms` tinyint(1) NOT NULL DEFAULT '1', - `caldav_tag` varchar(255) DEFAULT NULL, - `caldav_url` varchar(255) NOT NULL, - `caldav_last_change` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `caldav_tag` varchar(255) DEFAULT NULL, + `caldav_url` varchar(1024) NOT NULL, + `caldav_last_change` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `is_ical` tinyint(1) NOT NULL DEFAULT '0', + `ical_user` varchar(255) DEFAULT NULL, + `ical_pass` varchar(1024) DEFAULT NULL, - PRIMARY KEY(`calendar_id`), - INDEX `caldav_user_name_idx` (`user_id`, `name`), - CONSTRAINT `fk_caldav_calendars_user_id` FOREIGN KEY (`user_id`) - REFERENCES `users`(`user_id`) ON DELETE CASCADE ON UPDATE CASCADE, - CONSTRAINT `fk_caldav_calendars_sources` FOREIGN KEY (`source_id`) - REFERENCES `caldav_sources`(`source_id`) ON DELETE CASCADE ON UPDATE CASCADE + PRIMARY KEY(`calendar_id`), + INDEX `caldav_user_name_idx` (`user_id`, `name`), + CONSTRAINT `fk_caldav_calendars_user_id` FOREIGN KEY (`user_id`) + REFERENCES `users`(`user_id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `fk_caldav_calendars_sources` FOREIGN KEY (`source_id`) + REFERENCES `caldav_sources`(`source_id`) ON DELETE CASCADE ON UPDATE CASCADE ) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */; CREATE TABLE IF NOT EXISTS `caldav_events` ( - `event_id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, - `calendar_id` int(11) UNSIGNED NOT NULL DEFAULT '0', - `recurrence_id` int(11) UNSIGNED NOT NULL DEFAULT '0', - `uid` varchar(255) NOT NULL DEFAULT '', - `instance` varchar(16) NOT NULL DEFAULT '', - `isexception` tinyint(1) NOT NULL DEFAULT '0', - `created` datetime NOT NULL DEFAULT '1000-01-01 00:00:00', - `changed` datetime NOT NULL DEFAULT '1000-01-01 00:00:00', - `sequence` int(1) UNSIGNED NOT NULL DEFAULT '0', - `start` datetime NOT NULL DEFAULT '1000-01-01 00:00:00', - `end` datetime NOT NULL DEFAULT '1000-01-01 00:00:00', - `recurrence` varchar(255) DEFAULT NULL, - `title` varchar(255) NOT NULL, - `description` text NOT NULL, - `location` varchar(255) NOT NULL DEFAULT '', - `categories` varchar(255) NOT NULL DEFAULT '', - `url` varchar(255) NOT NULL DEFAULT '', - `all_day` tinyint(1) NOT NULL DEFAULT '0', - `free_busy` tinyint(1) NOT NULL DEFAULT '0', - `priority` tinyint(1) NOT NULL DEFAULT '0', - `sensitivity` tinyint(1) NOT NULL DEFAULT '0', - `status` varchar(32) NOT NULL DEFAULT '', - `alarms` text NULL DEFAULT NULL, - `attendees` text DEFAULT NULL, - `notifyat` datetime DEFAULT NULL, + `event_id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, + `calendar_id` int(11) UNSIGNED NOT NULL DEFAULT '0', + `recurrence_id` int(11) UNSIGNED NOT NULL DEFAULT '0', + `uid` varchar(255) NOT NULL DEFAULT '', + `instance` varchar(16) NOT NULL DEFAULT '', + `isexception` tinyint(1) NOT NULL DEFAULT '0', + `created` datetime NOT NULL DEFAULT '1000-01-01 00:00:00', + `changed` datetime NOT NULL DEFAULT '1000-01-01 00:00:00', + `sequence` int(1) UNSIGNED NOT NULL DEFAULT '0', + `start` datetime NOT NULL DEFAULT '1000-01-01 00:00:00', + `end` datetime NOT NULL DEFAULT '1000-01-01 00:00:00', + `recurrence` varchar(255) DEFAULT NULL, + `title` varchar(255) NOT NULL, + `description` text NOT NULL, + `location` varchar(255) NOT NULL DEFAULT '', + `categories` varchar(255) NOT NULL DEFAULT '', + `url` varchar(255) NOT NULL DEFAULT '', + `all_day` tinyint(1) NOT NULL DEFAULT '0', + `free_busy` tinyint(1) NOT NULL DEFAULT '0', + `priority` tinyint(1) NOT NULL DEFAULT '0', + `sensitivity` tinyint(1) NOT NULL DEFAULT '0', + `status` varchar(32) NOT NULL DEFAULT '', + `alarms` text NULL DEFAULT NULL, + `attendees` text DEFAULT NULL, + `notifyat` datetime DEFAULT NULL, - `caldav_url` varchar(255) NOT NULL, - `caldav_tag` varchar(255) DEFAULT NULL, - `caldav_last_change` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `caldav_url` varchar(255) NOT NULL, + `caldav_tag` varchar(255) DEFAULT NULL, + `caldav_last_change` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - PRIMARY KEY(`event_id`), - INDEX `caldav_uid_idx` (`uid`), - INDEX `caldav_recurrence_idx` (`recurrence_id`), - INDEX `caldav_calendar_notify_idx` (`calendar_id`,`notifyat`), - CONSTRAINT `fk_caldav_events_calendar_id` FOREIGN KEY (`calendar_id`) - REFERENCES `caldav_calendars`(`calendar_id`) ON DELETE CASCADE ON UPDATE CASCADE + PRIMARY KEY(`event_id`), + INDEX `caldav_uid_idx` (`uid`), + INDEX `caldav_recurrence_idx` (`recurrence_id`), + INDEX `caldav_calendar_notify_idx` (`calendar_id`,`notifyat`), + CONSTRAINT `fk_caldav_events_calendar_id` FOREIGN KEY (`calendar_id`) + REFERENCES `caldav_calendars`(`calendar_id`) ON DELETE CASCADE ON UPDATE CASCADE ) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */; CREATE TABLE IF NOT EXISTS `caldav_attachments` ( - `attachment_id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, - `event_id` int(11) UNSIGNED NOT NULL DEFAULT '0', - `filename` varchar(255) NOT NULL DEFAULT '', - `mimetype` varchar(255) NOT NULL DEFAULT '', - `size` int(11) NOT NULL DEFAULT '0', - `data` longtext NOT NULL, - PRIMARY KEY(`attachment_id`), - CONSTRAINT `fk_caldav_attachments_event_id` FOREIGN KEY (`event_id`) - REFERENCES `caldav_events`(`event_id`) ON DELETE CASCADE ON UPDATE CASCADE + `attachment_id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, + `event_id` int(11) UNSIGNED NOT NULL DEFAULT '0', + `filename` varchar(255) NOT NULL DEFAULT '', + `mimetype` varchar(255) NOT NULL DEFAULT '', + `size` int(11) NOT NULL DEFAULT '0', + `data` longtext NOT NULL, + PRIMARY KEY(`attachment_id`), + CONSTRAINT `fk_caldav_attachments_event_id` FOREIGN KEY (`event_id`) + REFERENCES `caldav_events`(`event_id`) ON DELETE CASCADE ON UPDATE CASCADE ) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */; -REPLACE INTO `system` (`name`, `value`) VALUES ('calendar-caldav-version', '2015022700'); \ No newline at end of file +REPLACE INTO `system` (`name`, `value`) VALUES ('calendar-caldav-version', '2021082400'); \ No newline at end of file diff --git a/drivers/caldav/SQL/mysql/2014081300.sql b/drivers/caldav/SQL/mysql/2014081300.sql deleted file mode 100644 index f1a3c98..0000000 --- a/drivers/caldav/SQL/mysql/2014081300.sql +++ /dev/null @@ -1,24 +0,0 @@ -/** - * CalDAV Client - * - * @version @package_version@ - * @author Daniel Morlock - * - * Copyright (C) Awesome IT GbR - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -ALTER TABLE `caldav_props` change `user` `username` varchar(255); -ALTER TABLE `events` ADD `status` VARCHAR(32) NOT NULL DEFAULT '' AFTER `sensitivity`; \ No newline at end of file diff --git a/drivers/caldav/SQL/mysql/2015022500.sql b/drivers/caldav/SQL/mysql/2015022500.sql deleted file mode 100644 index df0f613..0000000 --- a/drivers/caldav/SQL/mysql/2015022500.sql +++ /dev/null @@ -1,125 +0,0 @@ -/** - * CalDAV Client - * - * @version @package_version@ - * @author Daniel Morlock - * - * Copyright (C) Awesome IT GbR - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -/* Create new tables */ -CREATE TABLE IF NOT EXISTS `caldav_calendars` ( - `calendar_id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, - `user_id` int(10) UNSIGNED NOT NULL DEFAULT '0', - `name` varchar(255) NOT NULL, - `color` varchar(8) NOT NULL, - `showalarms` tinyint(1) NOT NULL DEFAULT '1', - - `caldav_url` varchar(255) NOT NULL, - `caldav_tag` varchar(255) DEFAULT NULL, - `caldav_user` varchar(255) DEFAULT NULL, - `caldav_pass` varchar(1024) DEFAULT NULL, - `caldav_last_change` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - - PRIMARY KEY(`calendar_id`), - INDEX `caldav_user_name_idx` (`user_id`, `name`), - CONSTRAINT `fk_caldav_calendars_user_id` FOREIGN KEY (`user_id`) - REFERENCES `users`(`user_id`) ON DELETE CASCADE ON UPDATE CASCADE -) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */; - -CREATE TABLE IF NOT EXISTS `caldav_events` ( - `event_id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, - `calendar_id` int(11) UNSIGNED NOT NULL DEFAULT '0', - `recurrence_id` int(11) UNSIGNED NOT NULL DEFAULT '0', - `uid` varchar(255) NOT NULL DEFAULT '', - `created` datetime NOT NULL DEFAULT '1000-01-01 00:00:00', - `changed` datetime NOT NULL DEFAULT '1000-01-01 00:00:00', - `sequence` int(1) UNSIGNED NOT NULL DEFAULT '0', - `start` datetime NOT NULL DEFAULT '1000-01-01 00:00:00', - `end` datetime NOT NULL DEFAULT '1000-01-01 00:00:00', - `recurrence` varchar(255) DEFAULT NULL, - `title` varchar(255) NOT NULL, - `description` text NOT NULL, - `location` varchar(255) NOT NULL DEFAULT '', - `categories` varchar(255) NOT NULL DEFAULT '', - `url` varchar(255) NOT NULL DEFAULT '', - `all_day` tinyint(1) NOT NULL DEFAULT '0', - `free_busy` tinyint(1) NOT NULL DEFAULT '0', - `priority` tinyint(1) NOT NULL DEFAULT '0', - `sensitivity` tinyint(1) NOT NULL DEFAULT '0', - `status` varchar(32) NOT NULL DEFAULT '', - `alarms` varchar(255) DEFAULT NULL, - `attendees` text DEFAULT NULL, - `notifyat` datetime DEFAULT NULL, - - `caldav_url` varchar(255) NOT NULL, - `caldav_tag` varchar(255) DEFAULT NULL, - `caldav_last_change` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - - PRIMARY KEY(`event_id`), - INDEX `caldav_uid_idx` (`uid`), - INDEX `caldav_recurrence_idx` (`recurrence_id`), - INDEX `caldav_calendar_notify_idx` (`calendar_id`,`notifyat`), - CONSTRAINT `fk_caldav_events_calendar_id` FOREIGN KEY (`calendar_id`) - REFERENCES `calendars`(`calendar_id`) ON DELETE CASCADE ON UPDATE CASCADE -) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */; - -CREATE TABLE IF NOT EXISTS `caldav_attachments` ( - `attachment_id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, - `event_id` int(11) UNSIGNED NOT NULL DEFAULT '0', - `filename` varchar(255) NOT NULL DEFAULT '', - `mimetype` varchar(255) NOT NULL DEFAULT '', - `size` int(11) NOT NULL DEFAULT '0', - `data` longtext NOT NULL, - PRIMARY KEY(`attachment_id`), - CONSTRAINT `fk_caldav_attachments_event_id` FOREIGN KEY (`event_id`) - REFERENCES `events`(`event_id`) ON DELETE CASCADE ON UPDATE CASCADE -) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */; - -/* Migrate Data */ -INSERT INTO caldav_calendars SELECT calendar_id, user_id, `name`, color, showalarms, url as caldav_url, - tag as caldav_tag, username as caldav_user, pass as caldav_pass, - last_change as caldav_last_change -FROM calendars cal, caldav_props dav -WHERE dav.obj_id = cal.calendar_id -AND dav.obj_type = 'vcal'; - -INSERT INTO caldav_events SELECT e.*, dav.url as caldav_url, dav.tag as caldav_tag, dav.last_change as caldav_last_change -FROM `events` e, caldav_props dav -WHERE dav.obj_id = e.event_id -AND dav.obj_type = 'vevent'; - -INSERT INTO caldav_attachments SELECT * FROM attachments a -WHERE a.event_id IN ( - SELECT obj_id FROM caldav_props dav - WHERE dav.obj_type = 'vevent' -); - -/* Drop deprecated data */ -DELETE FROM `events` WHERE event_id IN ( - SELECT obj_id FROM caldav_props dav - WHERE dav.obj_type = 'vevent' -); -DELETE FROM calendars WHERE calendar_id IN ( - SELECT obj_id FROM caldav_props dav - WHERE dav.obj_type = 'vcal' -); -DELETE FROM attachments WHERE event_id IN ( - SELECT obj_id FROM caldav_props dav - WHERE dav.obj_type = 'vevent' -); -DROP TABLE caldav_props; - diff --git a/drivers/caldav/SQL/mysql/2015022700.sql b/drivers/caldav/SQL/mysql/2015022700.sql deleted file mode 100644 index f44b49e..0000000 --- a/drivers/caldav/SQL/mysql/2015022700.sql +++ /dev/null @@ -1,14 +0,0 @@ --- add identifier for recurring instances and exceptions - -ALTER TABLE `caldav_events` ADD `instance` varchar(16) NOT NULL DEFAULT '' AFTER `uid`; -ALTER TABLE `caldav_events` ADD `isexception` tinyint(1) NOT NULL DEFAULT '0' AFTER `instance`; - -UPDATE `caldav_events` SET `instance` = DATE_FORMAT(`start`, '%Y%m%d') - WHERE `recurrence_id` != 0 AND `instance` = '' AND `all_day` = 1; - -UPDATE `caldav_events` SET `instance` = DATE_FORMAT(`start`, '%Y%m%dT%k%i%s') - WHERE `recurrence_id` != 0 AND `instance` = '' AND `all_day` = 0; - --- extend alarms columns for multiple values - -ALTER TABLE `caldav_events` CHANGE `alarms` `alarms` TEXT NULL DEFAULT NULL; \ No newline at end of file diff --git a/drivers/caldav/SQL/postgres.initial.sql b/drivers/caldav/SQL/postgres.initial.sql index f49da4e..02c62cd 100644 --- a/drivers/caldav/SQL/postgres.initial.sql +++ b/drivers/caldav/SQL/postgres.initial.sql @@ -1,10 +1,9 @@ /** * CalDAV Client + * (not tested & automatically generated from mysql) * * @version @package_version@ - * @author Hugo Slabbert - * - * Copyright (C) 2014, Hugo Slabbert + * @author JodliDev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -20,32 +19,107 @@ * along with this program. If not, see . */ -CREATE TYPE caldav_type AS ENUM ('vcal','vevent','vtodo',''); +-- SQLINES LICENSE FOR EVALUATION USE ONLY +CREATE SEQUENCE caldav_sources_seq; -CREATE TABLE IF NOT EXISTS caldav_props ( - obj_id int NOT NULL, - obj_type caldav_type NOT NULL, - url varchar(255) NOT NULL, - tag varchar(255) DEFAULT NULL, - username varchar(255) DEFAULT NULL, - pass varchar(1024) DEFAULT NULL, - last_change timestamp without time zone DEFAULT now() NOT NULL, - PRIMARY KEY (obj_id, obj_type) -); +CREATE TABLE IF NOT EXISTS caldav_sources ( + source_id int CHECK (source_id > 0) NOT NULL DEFAULT NEXTVAL ('caldav_sources_seq'), + user_id int CHECK (user_id > 0) NOT NULL DEFAULT '0', -CREATE OR REPLACE FUNCTION upd_timestamp() RETURNS TRIGGER -LANGUAGE plpgsql -AS -$$ -BEGIN - NEW.last_change = CURRENT_TIMESTAMP; - RETURN NEW; -END; -$$; + caldav_url varchar(1024) NOT NULL, + caldav_user varchar(255) DEFAULT NULL, + caldav_pass varchar(1024) DEFAULT NULL, -CREATE TRIGGER update_timestamp - BEFORE INSERT OR UPDATE - ON caldav_props - FOR EACH ROW - EXECUTE PROCEDURE upd_timestamp(); + PRIMARY KEY(source_id), + CONSTRAINT fk_caldav_sources_user_id FOREIGN KEY (user_id) + REFERENCES users(user_id) ON DELETE CASCADE ON UPDATE CASCADE + ) /* SQLINES DEMO *** DB */ /* SQLINES DEMO *** ET utf8 COLLATE utf8_general_ci */; +-- SQLINES LICENSE FOR EVALUATION USE ONLY +CREATE SEQUENCE caldav_calendars_seq; + +CREATE TABLE IF NOT EXISTS caldav_calendars ( + calendar_id int CHECK (calendar_id > 0) NOT NULL DEFAULT NEXTVAL ('caldav_calendars_seq'), + user_id int CHECK (user_id > 0) NOT NULL DEFAULT '0', + source_id int CHECK (source_id > 0) NOT NULL DEFAULT '0', + name varchar(255) NOT NULL, + color varchar(8) NOT NULL, + showalarms smallint NOT NULL DEFAULT '1', + + caldav_tag varchar(255) DEFAULT NULL, + caldav_url varchar(1024) NOT NULL, + caldav_last_change timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP, + is_ical smallint NOT NULL DEFAULT '0', + ical_user varchar(255) DEFAULT NULL, + ical_pass varchar(1024) DEFAULT NULL, + + PRIMARY KEY(calendar_id) + , + CONSTRAINT fk_caldav_calendars_user_id FOREIGN KEY (user_id) + REFERENCES users(user_id) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT fk_caldav_calendars_sources FOREIGN KEY (source_id) + REFERENCES caldav_sources(source_id) ON DELETE CASCADE ON UPDATE CASCADE + ) /* SQLINES DEMO *** DB */ /* SQLINES DEMO *** ET utf8 COLLATE utf8_general_ci */; + +CREATE INDEX caldav_user_name_idx ON caldav_calendars (user_id, name); + +-- SQLINES LICENSE FOR EVALUATION USE ONLY +CREATE SEQUENCE caldav_events_seq; + +CREATE TABLE IF NOT EXISTS caldav_events ( + event_id int CHECK (event_id > 0) NOT NULL DEFAULT NEXTVAL ('caldav_events_seq'), + calendar_id int CHECK (calendar_id > 0) NOT NULL DEFAULT '0', + recurrence_id int CHECK (recurrence_id > 0) NOT NULL DEFAULT '0', + uid varchar(255) NOT NULL DEFAULT '', + instance varchar(16) NOT NULL DEFAULT '', + isexception smallint NOT NULL DEFAULT '0', + created timestamp(0) NOT NULL DEFAULT '1000-01-01 00:00:00', + changed timestamp(0) NOT NULL DEFAULT '1000-01-01 00:00:00', + sequence int CHECK (sequence > 0) NOT NULL DEFAULT '0', + start timestamp(0) NOT NULL DEFAULT '1000-01-01 00:00:00', + end timestamp(0) NOT NULL DEFAULT '1000-01-01 00:00:00', + recurrence varchar(255) DEFAULT NULL, + title varchar(255) NOT NULL, + description text NOT NULL, + location varchar(255) NOT NULL DEFAULT '', + categories varchar(255) NOT NULL DEFAULT '', + url varchar(255) NOT NULL DEFAULT '', + all_day smallint NOT NULL DEFAULT '0', + free_busy smallint NOT NULL DEFAULT '0', + priority smallint NOT NULL DEFAULT '0', + sensitivity smallint NOT NULL DEFAULT '0', + status varchar(32) NOT NULL DEFAULT '', + alarms text NULL DEFAULT NULL, + attendees text DEFAULT NULL, + notifyat timestamp(0) DEFAULT NULL, + + caldav_url varchar(255) NOT NULL, + caldav_tag varchar(255) DEFAULT NULL, + caldav_last_change timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP, + + PRIMARY KEY(event_id) + , + CONSTRAINT fk_caldav_events_calendar_id FOREIGN KEY (calendar_id) + REFERENCES caldav_calendars(calendar_id) ON DELETE CASCADE ON UPDATE CASCADE + ) /* SQLINES DEMO *** DB */ /* SQLINES DEMO *** ET utf8 COLLATE utf8_general_ci */; + +CREATE INDEX caldav_uid_idx ON caldav_events (uid); +CREATE INDEX caldav_recurrence_idx ON caldav_events (recurrence_id); +CREATE INDEX caldav_calendar_notify_idx ON caldav_events (calendar_id,notifyat); + +-- SQLINES LICENSE FOR EVALUATION USE ONLY +CREATE SEQUENCE caldav_attachments_seq; + +CREATE TABLE IF NOT EXISTS caldav_attachments ( + attachment_id int CHECK (attachment_id > 0) NOT NULL DEFAULT NEXTVAL ('caldav_attachments_seq'), + event_id int CHECK (event_id > 0) NOT NULL DEFAULT '0', + filename varchar(255) NOT NULL DEFAULT '', + mimetype varchar(255) NOT NULL DEFAULT '', + size int NOT NULL DEFAULT '0', + data TEXT NOT NULL, + PRIMARY KEY(attachment_id), + CONSTRAINT fk_caldav_attachments_event_id FOREIGN KEY (event_id) + REFERENCES caldav_events(event_id) ON DELETE CASCADE ON UPDATE CASCADE + ) /* SQLINES DEMO *** DB */ /* SQLINES DEMO *** ET utf8 COLLATE utf8_general_ci */; + +REPLACE INTO `system` (name, value) SELECT ('calendar-caldav-version', '2021082400'); \ No newline at end of file diff --git a/drivers/caldav/SQL/sqlite.initial.sql b/drivers/caldav/SQL/sqlite.initial.sql new file mode 100644 index 0000000..ff599c7 --- /dev/null +++ b/drivers/caldav/SQL/sqlite.initial.sql @@ -0,0 +1,101 @@ +/** + * CalDAV Client + * (not tested & automatically generated from mysql) + * + * @version @package_version@ + * @author JodliDev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + + +CREATE TABLE IF NOT EXISTS `caldav_sources` ( + `source_id` INTEGER NOT NULL PRIMARY KEY, + `user_id` INTEGER NOT NULL DEFAULT '0', + `caldav_url` TEXT NOT NULL, + `caldav_user` TEXT DEFAULT NULL, + `caldav_pass` TEXT DEFAULT NULL, + CONSTRAINT fk_itipinvitations_user_id FOREIGN KEY (`user_id`) + REFERENCES `users`(`user_id`) ON DELETE CASCADE ON UPDATE CASCADE +); + +CREATE TABLE IF NOT EXISTS `caldav_calendars` ( + `calendar_id` INTEGER NOT NULL PRIMARY KEY, + `user_id` INTEGER NOT NULL DEFAULT '0', + `source_id` INTEGER NOT NULL DEFAULT '0', + `name` TEXT NOT NULL, + `color` TEXT NOT NULL, + `showalarms` tinyINTEGER NOT NULL DEFAULT '1', + `caldav_tag` TEXT DEFAULT NULL, + `caldav_url` TEXT NOT NULL, + `caldav_last_change` timestamp NOT NULL , + `is_ical` tinyINTEGER NOT NULL DEFAULT '0', + `ical_user` TEXT DEFAULT NULL, + `ical_pass` TEXT DEFAULT NULL, + + CONSTRAINT `fk_caldav_calendars_user_id` FOREIGN KEY (`user_id`) + REFERENCES `users`(`user_id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `fk_caldav_calendars_sources` FOREIGN KEY (`source_id`) + REFERENCES `caldav_sources`(`source_id`) ON DELETE CASCADE ON UPDATE CASCADE +); + +CREATE TABLE IF NOT EXISTS `caldav_events` ( + `event_id` INTEGER NOT NULL PRIMARY KEY, + `calendar_id` INTEGER NOT NULL DEFAULT '0', + `recurrence_id` INTEGER NOT NULL DEFAULT '0', + `uid` TEXT NOT NULL DEFAULT '', + `instance` TEXT NOT NULL DEFAULT '', + `isexception` tinyINTEGER NOT NULL DEFAULT '0', + `created` datetime NOT NULL DEFAULT '1000-01-01 00:00:00', + `changed` datetime NOT NULL DEFAULT '1000-01-01 00:00:00', + `sequence` INTEGER NOT NULL DEFAULT '0', + `start` datetime NOT NULL DEFAULT '1000-01-01 00:00:00', + `end` datetime NOT NULL DEFAULT '1000-01-01 00:00:00', + `recurrence` TEXT DEFAULT NULL, + `title` TEXT NOT NULL, + `description` text NOT NULL, + `location` TEXT NOT NULL DEFAULT '', + `categories` TEXT NOT NULL DEFAULT '', + `url` TEXT NOT NULL DEFAULT '', + `all_day` tinyINTEGER NOT NULL DEFAULT '0', + `free_busy` tinyINTEGER NOT NULL DEFAULT '0', + `priority` tinyINTEGER NOT NULL DEFAULT '0', + `sensitivity` tinyINTEGER NOT NULL DEFAULT '0', + `status` TEXT NOT NULL DEFAULT '', + `alarms` text NULL DEFAULT NULL, + `attendees` text DEFAULT NULL, + `notifyat` datetime DEFAULT NULL, + `caldav_url` TEXT NOT NULL, + `caldav_tag` TEXT DEFAULT NULL, + `caldav_last_change` timestamp NOT NULL , + FOREIGN KEY (`calendar_id`) + REFERENCES `caldav_calendars`(`calendar_id`) ON DELETE CASCADE ON UPDATE CASCADE +); + +CREATE TABLE IF NOT EXISTS `caldav_attachments` ( + `attachment_id` INTEGER NOT NULL PRIMARY KEY, + `event_id` INTEGER NOT NULL DEFAULT '0', + `filename` TEXT NOT NULL DEFAULT '', + `mimetype` TEXT NOT NULL DEFAULT '', + `size` INTEGER NOT NULL DEFAULT '0', + `data` TEXT NOT NULL, + FOREIGN KEY (`event_id`) + REFERENCES `caldav_events`(`event_id`) ON DELETE CASCADE ON UPDATE CASCADE +); +REPLACE INTO `system` (`name`, `value`) VALUES ('calendar-caldav-version', '2021082400'); + +CREATE INDEX caldav_user_name_idx ON caldav_calendars(user_id, name); +CREATE INDEX caldav_uid_idx ON caldav_events(uid); +CREATE INDEX caldav_recurrence_idx ON caldav_events(recurrence_id); +CREATE INDEX caldav_calendar_notify_idx ON caldav_events(calendar_id, notifyat); diff --git a/drivers/caldav/caldav_driver.php b/drivers/caldav/caldav_driver.php index 1ad6426..9b1a9ef 100644 --- a/drivers/caldav/caldav_driver.php +++ b/drivers/caldav/caldav_driver.php @@ -23,6 +23,7 @@ */ require_once 'caldav_sync.php'; +require_once 'ical_sync.php'; require_once 'encryption.php'; @@ -113,7 +114,7 @@ class caldav_driver extends calendar_driver if (!empty($this->rc->user->ID)) { $calendar_ids = array(); $result = $this->rc->db->query('SELECT - cal.calendar_id AS `calendar_id`, + cal.calendar_id AS `id`, cal.source_id AS `source_id`, cal.name AS `name`, cal.color AS `color`, @@ -123,7 +124,7 @@ class caldav_driver extends calendar_driver s.caldav_user AS `caldav_user`, s.caldav_pass AS `caldav_pass`, cal.caldav_last_change AS `caldav_last_change`, - cal.calendar_id AS `id` + cal.is_ical AS `is_ical` FROM ' . $this->db_calendars . ' AS cal LEFT JOIN ' .$this->db_sources .' AS s ON (cal.source_id = s.source_id) WHERE cal.user_id=? @@ -138,13 +139,18 @@ class caldav_driver extends calendar_driver $arr['rights'] = 'lrswikxteav'; $arr['editable'] = true; $arr['caldav_pass'] = $this->_decrypt_pass($arr['caldav_pass']); - $this->calendars[$arr['calendar_id']] = $arr; - $calendar_ids[] = $this->rc->db->quote($arr['calendar_id']); + $this->calendars[$arr['id']] = $arr; + $calendar_ids[] = $this->rc->db->quote($arr['id']); - // Init sync client - $cal_id = $arr['calendar_id']; - - $this->sync_clients[$cal_id] = new caldav_sync($arr); + if($arr['is_ical']) { + $this->sync_clients[$arr['id']] = new ical_sync($arr); + $cal["readonly"] = true; + $cal["deletable"] = true; + $cal["editable_name"] = true; + } + else { + $this->sync_clients[$arr['id']] = new caldav_sync($arr); + } } $this->calendar_ids = join(',', $calendar_ids); } @@ -170,8 +176,6 @@ class caldav_driver extends calendar_driver } } - // 'personal' is unsupported in this driver - // append the virtual birthdays calendar if ($this->rc->config->get('calendar_contact_birthdays', false)) { $prefs = $this->rc->config->get('birthday_calendar', array('color' => '87CEFA')); @@ -205,10 +209,23 @@ class caldav_driver extends calendar_driver */ public function create_calendar($cal) { - if(isset($cal['new-source'])) { + if(isset($cal['new-source'])) { //add new source return $this->create_source($cal); } - else { + else if($cal['is_ical']) { //add an ics calendar + $cal['caldav_url'] = $cal['ical_url']; + $cal_id = $this->_db_create_calendar($cal); + if($cal_id) { + $this->_read_calendars(); + $cal['id'] = $cal_id; + $this->sync_clients[$cal_id] = new ical_sync($cal); + $this->_sync_calendar($cal_id); + return true; + } + else + return false; + } + else { //add a calendar to a source $result = $this->rc->db->query('SELECT source_id, caldav_url, caldav_user, caldav_pass FROM ' . $this->db_sources . ' WHERE user_id=? AND source_id=?', @@ -332,19 +349,20 @@ class caldav_driver extends calendar_driver * * @return mixed ID of the calendar on success, False on error */ - private function _db_create_calendar($prop, $source) + private function _db_create_calendar($prop, $source=null) { $result = $this->rc->db->query( "INSERT INTO " . $this->db_calendars . " - (user_id, source_id, name, color, showalarms, caldav_url, caldav_tag) - VALUES (?, ?, ?, ?, ?, ?, ?)", + (user_id, source_id, name, color, showalarms, caldav_url, caldav_tag, is_ical) + VALUES (?, ?, ?, ?, ?, ?, ?, ?)", $this->rc->user->ID, - $source['source_id'], + $source ? $source['source_id'] : null, $prop['name'], $prop['color'], $prop['showalarms']?1:0, $prop['caldav_url'], - isset($prop["caldav_tag"]) ? $prop["caldav_tag"] : null + isset($prop["caldav_tag"]) ? $prop["caldav_tag"] : null, + !!$prop['is_ical'] ); if ($result) @@ -414,10 +432,11 @@ class caldav_driver extends calendar_driver return $count; } else { - if(!$this->calendars[$prop['id']]) + if(!isset($this->calendars[$prop['id']])) return false; + $calendar = $this->calendars[$prop['id']]; - if(!$this->sync_clients[$prop['id']]->caldav->delete_calendar()) + if(!$calendar['is_ical'] && !$this->sync_clients[$prop['id']]->caldav->delete_calendar()) return false; $query = $this->rc->db->query( @@ -455,20 +474,14 @@ class caldav_driver extends calendar_driver return false; if (!empty($this->calendars)) { - if ($event['calendar'] && !$this->calendars[$event['calendar']]) + if (!$event['calendar'] || !$this->calendars[$event['calendar']]) return false; - if (!$event['calendar']) { - $keys = array_keys($this->calendars); - $event['calendar'] = reset($keys); - } if($event = $this->_save_preprocess($event)) { - $sync_client = $this->sync_clients[$event["calendar"]]; // Only push event if caldav_tag is not set to avoid pushing it twice - if (isset($event["caldav_tag"]) || ($event = $sync_client->create_event($event)) !== false) { - + if (isset($event["caldav_tag"]) || ($event = $sync_client->create_event($event)) !== null) { if ($event_id = $this->_insert_event($event)) { $this->_update_recurring($event); } @@ -1878,17 +1891,43 @@ class caldav_driver extends calendar_driver $this->rc->user->ID ); if($this->rc->db->num_rows($result)) { - $select = new html_select([ + $is_ical = new html_checkbox( array( + 'name' => "is_ical", + 'value' => 1, + 'onload' => 'alert(123)', + 'onclick' => ' +if(this.checked) { + $("#ical_url").removeClass("hidden"); + $("#caldav_url").addClass("hidden"); +} +else { + $("#ical_url").addClass("hidden"); + $("#caldav_url").removeClass("hidden"); +}' + )); + $formfields['is_ical'] = array( + 'label' => $this->cal->gettext('calendar_is_ical'), + 'value' => $is_ical->show(null), + 'class' => 'hidden' + ); + $ical_url = new html_inputfield( array( + 'name' => 'ical_url', + 'size' => 20, + 'id' => 'ical_url', + 'class' => 'hidden' + )); + + + $caldav_url = new html_select([ 'name' => 'source_id', 'id' => 'caldav_url' ]); while($source = $this->rc->db->fetch_assoc($result)) { - $select->add($source['caldav_url'], $source['source_id']); + $caldav_url->add($source['caldav_url'], $source['source_id']); } - $formfields['source_id'] = array( + $formfields['url'] = array( 'label' => $this->cal->gettext('url'), - 'value' => $select->show(null), - 'id' => 'caldav_url', + 'value' => $caldav_url->show(null) .$ical_url->show(null), ); } else { @@ -2139,7 +2178,13 @@ class caldav_driver extends calendar_driver "caldav_url" => $update["url"], "caldav_tag" => $update["etag"])); - $event_id = $this->new_event($event); + try { + $event_id = $this->new_event($event); + } + catch(Exception $e) { + self::debug_log($e); + $event_id = 0; + } if($event_id) { self::debug_log("Created event \"$event_id\"."); diff --git a/drivers/caldav/caldav_sync.php b/drivers/caldav/caldav_sync.php index e270180..d5b87cd 100644 --- a/drivers/caldav/caldav_sync.php +++ b/drivers/caldav/caldav_sync.php @@ -4,6 +4,7 @@ * * @version @package_version@ * @author Daniel Morlock + * @author JodliDev * * Copyright (C) Awesome IT GbR * @@ -22,8 +23,9 @@ */ require_once 'caldav_client.php'; +require_once 'Isync.php'; -class caldav_sync +class caldav_sync implements Isync { private $cal_id = null; private $ctag = null; @@ -67,7 +69,7 @@ class caldav_sync * Determines whether current calendar needs to be synced * regarding the CalDAV ctag. * - * @return True if the current calendar ctag differs from the CalDAV tag which + * @return boolean True if the current calendar ctag differs from the CalDAV tag which * indicates that there are changes that must be synched. Returns false * if the calendar is up to date, no sync necesarry. */ @@ -177,7 +179,7 @@ class caldav_sync /** * Fetches event data and attaches it to the given update properties. * - * @param $updates List of update properties. + * @param $updates array of update properties. * @return array List of update properties with additional key "remote_event" containing the current caldav event. */ private function _get_event_data($updates) @@ -208,7 +210,7 @@ class caldav_sync * Creates the given event on the CalDAV server. * * @param array Hash array with event properties. - * @return Event with updated "caldav_url" and "caldav_tag" attributes, false on error. + * @return array with updated "caldav_url" and "caldav_tag" attributes, null on error. */ public function create_event($event) { @@ -220,7 +222,8 @@ class caldav_sync caldav_driver::debug_log("Push new event to url ".$props["caldav_url"]); $result = $this->caldav->put_event($props["caldav_url"], $event); - if($result == false || $result < 0) return false; + if($result == false || $result < 0) + return null; return array_merge($event, $props); } @@ -228,7 +231,7 @@ class caldav_sync * Updates the given event on the CalDAV server. * * @param array Hash array with event properties to update, must include "uid", "caldav_url" and "caldav_tag". - * @return True on success, false on error, -1 if the given event/etag is not up to date. + * @return boolean True on success, false on error, -1 if the given event/etag is not up to date. */ public function update_event($event) { @@ -240,7 +243,7 @@ class caldav_sync * Removes the given event from the caldav server. * * @param array Hash array with events properties, must include "caldav_url". - * @return True on success, false on error. + * @return boolean True on success, false on error. */ public function remove_event($event) { diff --git a/drivers/caldav/ical_sync.php b/drivers/caldav/ical_sync.php new file mode 100644 index 0000000..69fb99d --- /dev/null +++ b/drivers/caldav/ical_sync.php @@ -0,0 +1,163 @@ + + * @author JodliDev + * + * Copyright (C) Awesome IT GbR + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +class ical_sync implements Isync +{ + const ACTION_NONE = 1; + const ACTION_UPDATE = 2; + const ACTION_CREATE = 4; + + private $cal_id = null; + private $url = null; + private $user = null; + private $pass = null; + private $ical = null; + + /** + * Default constructor for calendar synchronization adapter. + * + * @param int Calendar id. + * @param array Hash array with ical properties: + * url: Absolute URL to iCAL resource. + */ + public function __construct($props) + { + $this->ical = libcalendaring::get_ical(); + $this->cal_id = $props["id"]; + + $this->url = $props["caldav_url"]; + $this->user = isset($props["ical_user"]) ? $props["ical_user"] : null; + $this->pass = isset($props["ical_pass"]) ? $props["ical_pass"] : null; + } + + /** + * Determines whether current calendar needs to be synced. + * + * @return boolean True if the current calendar needs to be synced, false otherwise. + */ + public function is_synced() + { + // No change to check that so far. + return false; + } + + /** + * Fetches events from iCAL resource and returns updates. + * + * @param array List of local events. + * @return array Tuple containing the following lists: + * + * Hash list for iCAL events to be created or to be updated with the keys: + * local_event: The local event in case of an update. + * remote_event: The current event retrieved from caldav server. + * + * A list of event ids that are in sync. + */ + public function get_updates($events) + { + $context = null; + if($this->user != null && $this->pass != null) + { + $context = stream_context_create(array( + 'http' => array( + 'header' => "Authorization: Basic " . base64_encode("$this->user:$this->pass") + ) + )); + } + + $vcal = file_get_contents($this->url, false, $context); + $updates = array(); + $synced = array(); + if($vcal !== false) { + + // Hash existing events by uid. + $events_hash = array(); + foreach($events as $event) { + $events_hash[$event['uid']] = $event; + } + + foreach ($this->ical->import($vcal) as $remote_event) { + + // Attach remote event to current calendar + $remote_event['calendar'] = $this->cal_id; + + $local_event = null; + if($events_hash[$remote_event['uid']]) + $local_event = $events_hash[$remote_event['uid']]; + + // Determine whether event don't need an update. + if($local_event && $local_event['changed'] >= $remote_event['changed']) { + array_push($synced, $local_event["id"]); + } + else if($local_event) { + array_push($updates, array('local_event' => $local_event, 'remote_event' => $remote_event, 'url' => $this->url)); + } + else { + array_push($updates, array('remote_event' => $remote_event, 'url' => $this->url)); + } + } + } + + return array($updates, $synced); + } + + /** + * Getter for current calendar ctag (only for CalDAV). + * @return string + */ + public function get_ctag() { + return 'none'; + } + + /** + * Creates the given event. + * + * @param array Hash array with event properties. + * @return array with updated "caldav_url" and "caldav_tag" attributes, null on error. + */ + public function create_event($event) { + return $event; + } + + /** + * Updates the given event. + * + * @param array Hash array with event properties to update, must include "uid", "caldav_url" and "caldav_tag". + * @return boolean True on success, false on error, -1 if the given event/etag is not up to date. + */ + public function update_event($event) { + return false; + } + + /** + * Removes the given event. + * + * @param array Hash array with events properties, must include "caldav_url". + * @return boolean True on success, false on error. + */ + public function remove_event($event) { + return false; + } +} +?> \ No newline at end of file diff --git a/localization/de.inc b/localization/de.inc index b85daec..38e3529 100644 --- a/localization/de.inc +++ b/localization/de.inc @@ -6,10 +6,12 @@ * * For translation see https://www.transifex.com/projects/p/kolab/resource/calendar/ */ -$labels['addsources'] = 'Externe Quellen hinzufügen '; -$labels['deletesources'] = 'Externe Quellen löschen '; -$labels['nosources_error'] = 'Keine externen Quellen vorhanden.'; -$labels['source_notadded_error'] = 'Externe Quelle konnte nicht hinzugefügt werden.'; +$labels['addsources'] = 'CalDAV Quellen hinzufügen'; +$labels['deletesources'] = 'CalDAV Quellen löschen'; +$labels['nosources_error'] = 'Keine CalDAV Quellen vorhanden.'; +$labels['source_notadded_error'] = 'CalDAV Quelle konnte nicht hinzugefügt werden.'; +$labels['calendar_is_ical'] = 'Ist ics-Datei'; + $labels['default_view'] = 'Standardansicht'; $labels['time_format'] = 'Zeitformatierung'; $labels['timeslots'] = 'Zeitfenster pro Stunde'; diff --git a/localization/de_CH.inc b/localization/de_CH.inc index d99cd86..41c84c8 100644 --- a/localization/de_CH.inc +++ b/localization/de_CH.inc @@ -6,10 +6,12 @@ * * For translation see https://www.transifex.com/projects/p/kolab/resource/calendar/ */ -$labels['addsources'] = 'Externe Quellen hinzufügen '; -$labels['deletesources'] = 'Externe Quellen löschen '; -$labels['nosources_error'] = 'Keine externen Quellen vorhanden.'; -$labels['source_notadded_error'] = 'Externe Quelle konnte nicht hinzugefügt werden.'; +$labels['addsources'] = 'CalDAV Quellen hinzufügen'; +$labels['deletesources'] = 'CalDAV Quellen löschen'; +$labels['nosources_error'] = 'Keine CalDAV Quellen vorhanden.'; +$labels['source_notadded_error'] = 'CalDAV Quelle konnte nicht hinzugefügt werden.'; +$labels['calendar_is_ical'] = 'Ist ics-Datei'; + $labels['default_view'] = 'Standardansicht'; $labels['time_format'] = 'Zeitformatierung'; $labels['timeslots'] = 'Abschnitte pro Stunde'; diff --git a/localization/de_DE.inc b/localization/de_DE.inc index 4239d37..9839876 100644 --- a/localization/de_DE.inc +++ b/localization/de_DE.inc @@ -6,10 +6,12 @@ * * For translation see https://www.transifex.com/projects/p/kolab/resource/calendar/ */ -$labels['addsources'] = 'Externe Quellen hinzufügen'; -$labels['deletesources'] = 'Externe Quellen löschen'; -$labels['nosources_error'] = 'Keine externen Quellen vorhanden.'; -$labels['source_notadded_error'] = 'Externe Quelle konnte nicht hinzugefügt werden.'; +$labels['addsources'] = 'CalDAV Quellen hinzufügen'; +$labels['deletesources'] = 'CalDAV Quellen löschen'; +$labels['nosources_error'] = 'Keine CalDAV Quellen vorhanden.'; +$labels['source_notadded_error'] = 'CalDAV Quelle konnte nicht hinzugefügt werden.'; +$labels['calendar_is_ical'] = 'Ist ics-Datei'; + $labels['default_view'] = 'Standardansicht'; $labels['time_format'] = 'Zeitformatierung'; $labels['timeslots'] = 'Zeitfenster pro Stunde'; diff --git a/localization/en_US.inc b/localization/en_US.inc index 07fc355..d47e708 100644 --- a/localization/en_US.inc +++ b/localization/en_US.inc @@ -11,10 +11,11 @@ $labels = array(); //caldav driver -$labels['addsources'] = 'Add external sources'; -$labels['deletesources'] = 'Delete external sources'; -$labels['nosources_error'] = 'No external sources available.'; -$labels['source_notadded_error'] = 'External source could not be added.'; +$labels['addsources'] = 'Add CalDAV sources'; +$labels['deletesources'] = 'Delete CalDAV sources'; +$labels['nosources_error'] = 'No CalDAV sources available.'; +$labels['source_notadded_error'] = 'CalDAV source could not be added.'; +$labels['calendar_is_ical'] = 'Is ics file'; // preferences $labels['default_view'] = 'Default view';