Commit 98f9165c authored by Daniel Morlock's avatar Daniel Morlock

Merge branch 'roundcubemail-plugins-kolab-3.2.8-merge-branch' into feature_caldav

parents 560b6faf ea8a8b29
[main]
host = https://www.transifex.com
lang_map = en: en_US, de: de_DE, da: da_DK, es: es_ES, fi: fi_FI, fr: fr_FR, ja: ja_JP, nl: nl_NL, cs: cs_CZ
lang_map = en: en_US, de: de_DE, da: da_DK, es: es_ES, fi: fi_FI, fr: fr_FR, ja: ja_JP, nl: nl_NL, cs: cs_CZ, vi: vi_VN, pl: pl_PL, th: th_TH, sv: sv_SE, he: he_IL, hr: hr_HR, sk: sk_SK, sl: sl_SI, uk: uk_UA
type = PHP_ALT_ARRAY
[kolab.calendar]
......
......@@ -8,10 +8,10 @@ updatedb.sh --package=calendar-<driver> --version=<version> \
--dir=../plugins/calendar/drivers/<driver>/SQL
[*] Replace <driver> with "database" or "kolab" (without quotes)
[*] Replace <version> with Roundcube version e.g. 0.7.3
[*] Replace <version> with Roundcube version e.g. 0.9.0
[*] Roundcube should be upgraded before plugin upgrades
Example:
updatedb.sh --package=calendar-kolab --version=0.8.0 \
updatedb.sh --package=calendar-kolab --version=0.9.0 \
--dir=../plugins/calendar/drivers/kolab/SQL
This diff is collapsed.
......@@ -8,7 +8,7 @@
* JavaScript code in this page.
*
* Copyright (C) 2010, Lazlo Westerhof <hello@lazlo.me>
* Copyright (C) 2013, Kolab Systems AG <contact@kolabsys.com>
* Copyright (C) 2013-2015, Kolab Systems AG <contact@kolabsys.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
......
This diff is collapsed.
......@@ -4,7 +4,7 @@
"description": "Calendar plugin",
"homepage": "http://git.kolab.org/roundcubemail-plugins-kolab/",
"license": "AGPLv3",
"version": "3.2.3",
"version": "3.2.8",
"authors": [
{
"name": "Thomas Bruederli",
......@@ -26,6 +26,6 @@
"require": {
"php": ">=5.3.0",
"roundcube/plugin-installer": ">=0.1.3",
"kolab/libcalendaring": ">=3.2.3"
"kolab/libcalendaring": ">=3.2.8"
}
}
......@@ -44,6 +44,8 @@ CREATE TABLE IF NOT EXISTS `caldav_events` (
`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',
......@@ -60,7 +62,7 @@ CREATE TABLE IF NOT EXISTS `caldav_events` (
`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,
`alarms` text NULL DEFAULT NULL,
`attendees` text DEFAULT NULL,
`notifyat` datetime DEFAULT NULL,
......@@ -87,4 +89,4 @@ CREATE TABLE IF NOT EXISTS `caldav_attachments` (
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 */;
REPLACE INTO `system` (`name`, `value`) VALUES ('calendar-caldav-version', '2015032500');
\ No newline at end of file
REPLACE INTO `system` (`name`, `value`) VALUES ('calendar-caldav-version', '2015022700');
\ No newline at end of file
-- 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
......@@ -8,7 +8,7 @@
* @author Thomas Bruederli <bruederli@kolabsys.com>
*
* Copyright (C) 2010, Lazlo Westerhof <hello@lazlo.me>
* Copyright (C) 2012-2014, Kolab Systems AG <contact@kolabsys.com>
* Copyright (C) 2012-2015, Kolab Systems AG <contact@kolabsys.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
......@@ -50,6 +50,7 @@
* 'EXCEPTIONS' => array(<event>), list of event objects which denote exceptions in the recurrence chain
* ),
* 'recurrence_id' => 'ID of the recurrence group', // usually the ID of the starting event
* '_instance' => 'ID of the recurring instance', // identifies an instance within a recurrence chain
* 'categories' => 'Event category',
* 'free_busy' => 'free|busy|outofoffice|tentative', // Show time as
* 'status' => 'TENTATIVE|CONFIRMED|CANCELLED', // event status according to RFC 2445
......@@ -93,6 +94,13 @@
*/
abstract class calendar_driver
{
const FILTER_ALL = 0;
const FILTER_WRITEABLE = 1;
const FILTER_INSERTABLE = 2;
const FILTER_ACTIVE = 4;
const FILTER_PERSONAL = 8;
const FILTER_PRIVATE = 16;
const FILTER_CONFIDENTIAL = 32;
const BIRTHDAY_CALENDAR_ID = '__bdays__';
// features supported by backend
......@@ -117,12 +125,11 @@ abstract class calendar_driver
/**
* Get a list of available calendars from this source
*
* @param bool $active Return only active calendars
* @param bool $personal Return only personal calendars
*
* @param integer Bitmask defining filter criterias.
* See FILTER_* constants for possible values.
* @return array List of calendars
*/
abstract function list_calendars($active = false, $personal = false);
abstract function list_calendars($filter = 0);
/**
* Create a new calendar assigned to the current user
......@@ -196,9 +203,22 @@ abstract class calendar_driver
*
* @param array Hash array with event properties
* @param string New participant status
* @param array List of hash arrays with updated attendees
* @return boolean True on success, False on error
*/
public function edit_rsvp(&$event, $status, $attendees)
{
return $this->edit_event($event);
}
/**
* Update the participant status for the given attendee
*
* @param array Hash array with event properties
* @param array List of hash arrays each represeting an updated attendee
* @return boolean True on success, False on error
*/
public function edit_rsvp(&$event, $status)
public function update_attendees(&$event, $attendees)
{
return $this->edit_event($event);
}
......@@ -255,15 +275,17 @@ abstract class calendar_driver
* Return data of a single event
*
* @param mixed UID string or hash array with event properties:
* id: Event identifier
* calendar: Calendar identifier (optional)
* @param boolean If true, only writeable calendars shall be searched
* @param boolean If true, only active calendars shall be searched
* @param boolean If true, only personal calendars shall be searched
* id: Event identifier
* uid: Event UID
* _instance: Instance identifier in combination with uid (optional)
* calendar: Calendar identifier (optional)
* @param integer Bitmask defining the scope to search events in.
* See FILTER_* constants for possible values.
* @param boolean If true, recurrence exceptions shall be added
*
* @return array Event object as hash array
*/
abstract function get_event($event, $writeable = false, $active = false, $personal = false);
abstract function get_event($event, $scope = 0, $full = false);
/**
* Get events from source.
......@@ -431,6 +453,61 @@ abstract class calendar_driver
return false;
}
/**
* Create instances of a recurring event
*
* @param array Hash array with event properties
* @param object DateTime Start date of the recurrence window
* @param object DateTime End date of the recurrence window
* @return array List of recurring event instances
*/
public function get_recurring_events($event, $start, $end = null)
{
$events = array();
if ($event['recurrence']) {
// include library class
require_once(dirname(__FILE__) . '/../lib/calendar_recurrence.php');
$rcmail = rcmail::get_instance();
$recurrence = new calendar_recurrence($rcmail->plugins->get_plugin('calendar'), $event);
$recurrence_id_format = libcalendaring::recurrence_id_format($event);
// determine a reasonable end date if none given
if (!$end) {
switch ($event['recurrence']['FREQ']) {
case 'YEARLY': $intvl = 'P100Y'; break;
case 'MONTHLY': $intvl = 'P20Y'; break;
default: $intvl = 'P10Y'; break;
}
$end = clone $event['start'];
$end->add(new DateInterval($intvl));
}
$i = 0;
while ($next_event = $recurrence->next_instance()) {
// add to output if in range
if (($next_event['start'] <= $end && $next_event['end'] >= $start)) {
$next_event['_instance'] = $next_event['start']->format($recurrence_id_format);
$next_event['id'] = $next_event['uid'] . '-' . $next_event['_instance'];
$next_event['recurrence_id'] = $event['uid'];
$events[] = $next_event;
}
else if ($next_event['start'] > $end) { // stop loop if out of range
break;
}
// avoid endless recursion loops
if (++$i > 1000) {
break;
}
}
}
return $events;
}
/**
* Provide a list of revisions for the given event
*
......
......@@ -28,6 +28,8 @@ CREATE TABLE IF NOT EXISTS `events` (
`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',
......@@ -44,7 +46,7 @@ CREATE TABLE IF NOT EXISTS `events` (
`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,
`alarms` text DEFAULT NULL,
`attendees` text DEFAULT NULL,
`notifyat` datetime DEFAULT NULL,
PRIMARY KEY(`event_id`),
......@@ -80,4 +82,4 @@ CREATE TABLE IF NOT EXISTS `itipinvitations` (
REFERENCES `users`(`user_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-database-version', '2014040900');
REPLACE INTO system (name, value) VALUES ('calendar-database-version', '2015022700');
-- add identifier for recurring instances and exceptions
ALTER TABLE `events` ADD `instance` varchar(16) NOT NULL DEFAULT '' AFTER `uid`;
ALTER TABLE `events` ADD `isexception` tinyint(1) NOT NULL DEFAULT '0' AFTER `instance`;
UPDATE `events` SET `instance` = DATE_FORMAT(`start`, '%Y%m%d')
WHERE `recurrence_id` != 0 AND `instance` = '' AND `all_day` = 1;
UPDATE `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 `events` CHANGE `alarms` `alarms` TEXT NULL DEFAULT NULL;
......@@ -44,6 +44,8 @@ CREATE TABLE events (
REFERENCES calendars (calendar_id) ON UPDATE CASCADE ON DELETE CASCADE,
recurrence_id integer NOT NULL DEFAULT 0,
uid varchar(255) NOT NULL DEFAULT '',
instance varchar(16) NOT NULL DEFAULT '',
isexception smallint NOT NULL DEFAULT '0',
created timestamp without time zone DEFAULT now() NOT NULL,
changed timestamp without time zone DEFAULT now(),
sequence integer NOT NULL DEFAULT 0,
......@@ -60,7 +62,7 @@ CREATE TABLE events (
priority smallint NOT NULL DEFAULT 0,
sensitivity smallint NOT NULL DEFAULT 0,
status character varying(32) NOT NULL DEFAULT '',
alarms varchar(255) DEFAULT NULL,
alarms text DEFAULT NULL,
attendees text DEFAULT NULL,
notifyat timestamp without time zone DEFAULT NULL,
PRIMARY KEY (event_id)
......@@ -104,4 +106,4 @@ CREATE TABLE itipinvitations (
CREATE INDEX itipinvitations_user_id_event_uid_idx ON itipinvitations (user_id, event_uid);
INSERT INTO system (name, value) VALUES ('calendar-database-version', '2014040900');
INSERT INTO system (name, value) VALUES ('calendar-database-version', '2015022700');
-- add identifier for recurring instances and exceptions
ALTER TABLE events ADD instance character varying(16) NOT NULL;
ALTER TABLE events ADD isexception smallint NOT NULL DEFAULT '0';
-- extend alarms columns for multiple values
ALTER TABLE events ALTER COLUMN alarms TYPE text;
......@@ -27,6 +27,8 @@ CREATE TABLE events (
calendar_id integer NOT NULL default '0',
recurrence_id integer 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 integer NOT NULL default '0',
......@@ -43,7 +45,7 @@ CREATE TABLE events (
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,
alarms text default NULL,
attendees text default NULL,
notifyat datetime default NULL,
CONSTRAINT fk_events_calendar_id FOREIGN KEY (calendar_id)
......@@ -74,4 +76,4 @@ CREATE TABLE itipinvitations (
CREATE INDEX ix_itipinvitations_uid ON itipinvitations(user_id, event_uid);
INSERT INTO system (name, value) VALUES ('calendar-database-version', '2014040900');
INSERT INTO system (name, value) VALUES ('calendar-database-version', '2015022700');
-- ALTER TABLE `events` ADD `instance` varchar(16) NOT NULL DEFAULT '' AFTER `uid`;
-- ALTER TABLE `events` ADD `isexception` tinyint(3) NOT NULL DEFAULT '0' AFTER `instance`;
-- ALTER TABLE `events` CHANGE `alarms` `alarms` TEXT NULL DEFAULT NULL;
CREATE TABLE temp_events (
event_id integer NOT NULL PRIMARY KEY,
calendar_id integer NOT NULL default '0',
recurrence_id integer 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 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 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
);
INSERT INTO temp_events (event_id, calendar_id, recurrence_id, uid, created, changed, sequence, start, end, recurrence, title, description, location, categories, url, all_day, free_busy, priority, sensitivity, alarms, attendees, notifyat)
SELECT event_id, calendar_id, recurrence_id, uid, created, changed, sequence, start, end, recurrence, title, description, location, categories, url, all_day, free_busy, priority, sensitivity, alarms, attendees, notifyat
FROM events;
DROP TABLE events;
CREATE TABLE events (
event_id integer NOT NULL PRIMARY KEY,
calendar_id integer NOT NULL default '0',
recurrence_id integer 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 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 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 default NULL,
attendees text default NULL,
notifyat datetime default NULL,
CONSTRAINT fk_events_calendar_id FOREIGN KEY (calendar_id)
REFERENCES calendars(calendar_id)
);
INSERT INTO events (event_id, calendar_id, recurrence_id, uid, created, changed, sequence, start, end, recurrence, title, description, location, categories, url, all_day, free_busy, priority, sensitivity, alarms, attendees, notifyat)
SELECT event_id, calendar_id, recurrence_id, uid, created, changed, sequence, start, end, recurrence, title, description, location, categories, url, all_day, free_busy, priority, sensitivity, alarms, attendees, notifyat
FROM temp_events;
DROP TABLE temp_events;
-- Derrive instance columns from start date/time
UPDATE events SET instance = strftime('%Y%m%d', start)
WHERE recurrence_id != 0 AND instance = '' AND all_day = 1;
UPDATE events SET instance = strftime('%Y%m%dT%H%M%S', start)
WHERE recurrence_id != 0 AND instance = '' AND all_day = 0;
......@@ -43,6 +43,8 @@ CREATE TABLE IF NOT EXISTS `ical_events` (
`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',
......@@ -59,7 +61,7 @@ CREATE TABLE IF NOT EXISTS `ical_events` (
`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,
`alarms` text NULL DEFAULT NULL,
`attendees` text DEFAULT NULL,
`notifyat` datetime DEFAULT NULL,
......@@ -86,4 +88,4 @@ CREATE TABLE IF NOT EXISTS `ical_attachments` (
REFERENCES `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-ical-version', '2015032500');
\ No newline at end of file
REPLACE INTO `system` (`name`, `value`) VALUES ('calendar-ical-version', '2015022700');
\ No newline at end of file
-- add identifier for recurring instances and exceptions
ALTER TABLE `ical_events` ADD `instance` varchar(16) NOT NULL DEFAULT '' AFTER `uid`;
ALTER TABLE `ical_events` ADD `isexception` tinyint(1) NOT NULL DEFAULT '0' AFTER `instance`;
UPDATE `ical_events` SET `instance` = DATE_FORMAT(`start`, '%Y%m%d')
WHERE `recurrence_id` != 0 AND `instance` = '' AND `all_day` = 1;
UPDATE `ical_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 `ical_events` CHANGE `alarms` `alarms` TEXT NULL DEFAULT NULL;
\ No newline at end of file
......@@ -5,7 +5,7 @@
*
* @author Thomas Bruederli <bruederli@kolabsys.com>
*
* Copyright (C) 2014, Kolab Systems AG <contact@kolabsys.com>
* Copyright (C) 2014-2015, Kolab Systems AG <contact@kolabsys.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
......@@ -26,7 +26,8 @@ class kolab_invitation_calendar
public $id = '__invitation__';
public $ready = true;
public $alarms = false;
public $readonly = true;
public $rights = 'lrsv';
public $editable = false;
public $attachments = false;
public $subscriptions = false;
public $partstats = array('unknown');
......@@ -177,7 +178,7 @@ class kolab_invitation_calendar
public function get_event($id)
{
// redirect call to kolab_driver::get_event()
$event = $this->cal->driver->get_event($id, true);
$event = $this->cal->driver->get_event($id, calendar_driver::FILTER_WRITEABLE);