From ae85372d132511ea703768aa90a7efced5c7d12c Mon Sep 17 00:00:00 2001 From: Thomas Bruederli Date: Thu, 16 May 2013 13:32:01 +0200 Subject: [PATCH] Add URL property for events; correct label for chair role of event attendees --- plugins/calendar/calendar.php | 8 +++ plugins/calendar/calendar_ui.js | 24 ++++++- plugins/calendar/drivers/calendar_driver.php | 1 + .../drivers/database/SQL/mysql.initial.sql | 1 + .../drivers/database/SQL/mysql/2013051600.sql | 3 + .../drivers/database/SQL/postgres.initial.sql | 1 + .../database/SQL/postgres/2013051600.sql | 3 + .../drivers/database/SQL/sqlite.initial.sql | 1 + .../database/SQL/sqlite/2013051600.sql | 63 +++++++++++++++++++ .../drivers/database/database_driver.php | 11 ++-- plugins/calendar/lib/calendar_ical.php | 4 ++ plugins/calendar/localization/de_CH.inc | 2 +- plugins/calendar/localization/de_DE.inc | 2 +- plugins/calendar/localization/en_US.inc | 7 ++- plugins/calendar/package.xml | 6 +- .../skins/classic/templates/calendar.html | 6 +- .../skins/classic/templates/eventedit.html | 5 ++ plugins/calendar/skins/larry/calendar.css | 2 +- .../skins/larry/templates/calendar.html | 6 +- .../skins/larry/templates/eventedit.html | 5 ++ 20 files changed, 144 insertions(+), 17 deletions(-) create mode 100644 plugins/calendar/drivers/database/SQL/mysql/2013051600.sql create mode 100644 plugins/calendar/drivers/database/SQL/postgres/2013051600.sql create mode 100644 plugins/calendar/drivers/database/SQL/sqlite/2013051600.sql diff --git a/plugins/calendar/calendar.php b/plugins/calendar/calendar.php index 6537c532..1a94167b 100644 --- a/plugins/calendar/calendar.php +++ b/plugins/calendar/calendar.php @@ -1098,6 +1098,10 @@ class calendar extends rcube_plugin $event['attachments'][$k]['classname'] = rcube_utils::file2class($attachment['mimetype'], $attachment['name']); } + // mapping url => vurl because of the fullcalendar client script + $event['vurl'] = $event['url']; + unset($event['url']); + return array( '_id' => $event['calendar'] . ':' . $event['id'], // unique identifier for fullcalendar 'start' => $this->lib->adjust_timezone($event['start'])->format('c'), @@ -1312,6 +1316,10 @@ class calendar extends rcube_plugin array_unshift($event['attendees'], array('role' => 'ORGANIZER', 'name' => $identity['name'], 'email' => $identity['email'], 'status' => 'ACCEPTED')); } } + + // mapping url => vurl because of the fullcalendar client script + $event['url'] = $event['vurl']; + unset($event['vurl']); } /** diff --git a/plugins/calendar/calendar_ui.js b/plugins/calendar/calendar_ui.js index 4626414f..83f69e02 100644 --- a/plugins/calendar/calendar_ui.js +++ b/plugins/calendar/calendar_ui.js @@ -146,7 +146,20 @@ function rcube_calendar_ui(settings) var zeropad = function(num) { - return (num < 10 ? '0' : '') + num; + return (num < 10 ? '0' : '') + num; + } + + var render_link = function(url) + { + var islink = false, href = url; + if (url.match(/^[fhtpsmailo]+?:\/\//i)) { + islink = true; + } + else if (url.match(/^[a-z0-9.-:]+(\/|$)/i)) { + islink = true; + href = 'http://' + url; + } + return islink ? '' + Q(url) + '' : Q(url); } // determine whether the given date is on a weekend @@ -279,6 +292,8 @@ function rcube_calendar_ui(settings) $('#event-location').html('@ ' + text2html(event.location)).show(); if (event.description) $('#event-description').show().children('.event-text').html(text2html(event.description, 300, 6)); + if (event.vurl) + $('#event-url').show().children('.event-text').html(render_link(event.vurl)); // render from-to in a nice human-readable way // -> now shown in dialog title @@ -347,7 +362,7 @@ function rcube_calendar_ui(settings) .find('a.mailtolink').click(function(e) { rcmail.redirect(rcmail.url('mail/compose', { _to:this.href.substr(7) })); return false; }); } - $('#event-rsvp')[(rsvp?'show':'hide')](); + $('#event-rsvp')[(rsvp&&!organizer?'show':'hide')](); $('#event-rsvp .rsvp-buttons input').prop('disabled', false).filter('input[rel='+rsvp+']').prop('disabled', true); } @@ -419,6 +434,7 @@ function rcube_calendar_ui(settings) var title = $('#edit-title').val(event.title || ''); var location = $('#edit-location').val(event.location || ''); var description = $('#edit-description').html(event.description || ''); + var vurl = $('#edit-url').val(event.vurl || ''); var categories = $('#edit-categories').val(event.categories); var calendars = $('#edit-calendar').val(event.calendar); var freebusy = $('#edit-free-busy').val(event.free_busy); @@ -579,6 +595,7 @@ function rcube_calendar_ui(settings) // init dialog buttons var buttons = {}; + // save action buttons[rcmail.gettext('save', 'calendar')] = function() { var start = parse_datetime(allday.checked ? '12:00' : starttime.val(), startdate.val()); var end = parse_datetime(allday.checked ? '13:00' : endtime.val(), enddate.val()); @@ -599,6 +616,7 @@ function rcube_calendar_ui(settings) description: description.val(), location: location.val(), categories: categories.val(), + vurl: vurl.val(), free_busy: freebusy.val(), priority: priority.val(), sensitivity: sensitivity.val(), @@ -1428,7 +1446,7 @@ function rcube_calendar_ui(settings) opts.ORGANIZER = rcmail.gettext('calendar.roleorganizer'); opts['REQ-PARTICIPANT'] = rcmail.gettext('calendar.rolerequired'); opts['OPT-PARTICIPANT'] = rcmail.gettext('calendar.roleoptional'); - opts['CHAIR'] = rcmail.gettext('calendar.roleresource'); + opts['CHAIR'] = rcmail.gettext('calendar.rolechair'); if (organizer && !readonly) dispname = rcmail.env['identities-selector']; diff --git a/plugins/calendar/drivers/calendar_driver.php b/plugins/calendar/drivers/calendar_driver.php index a9402e1f..41c61815 100644 --- a/plugins/calendar/drivers/calendar_driver.php +++ b/plugins/calendar/drivers/calendar_driver.php @@ -39,6 +39,7 @@ * 'title' => 'Event title/summary', * 'location' => 'Location string', * 'description' => 'Event description', + * 'url' => 'URL to more information', * 'recurrence' => array( // Recurrence definition according to iCalendar (RFC 2445) specification as list of key-value pairs * 'FREQ' => 'DAILY|WEEKLY|MONTHLY|YEARLY', * 'INTERVAL' => 1...n, diff --git a/plugins/calendar/drivers/database/SQL/mysql.initial.sql b/plugins/calendar/drivers/database/SQL/mysql.initial.sql index f7bf9b5b..a8f8d677 100644 --- a/plugins/calendar/drivers/database/SQL/mysql.initial.sql +++ b/plugins/calendar/drivers/database/SQL/mysql.initial.sql @@ -39,6 +39,7 @@ CREATE TABLE `events` ( `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', diff --git a/plugins/calendar/drivers/database/SQL/mysql/2013051600.sql b/plugins/calendar/drivers/database/SQL/mysql/2013051600.sql new file mode 100644 index 00000000..4de44d69 --- /dev/null +++ b/plugins/calendar/drivers/database/SQL/mysql/2013051600.sql @@ -0,0 +1,3 @@ +-- MySQL database updates since version 0.9-beta + +ALTER TABLE `events` ADD `url` VARCHAR(255) NOT NULL AFTER `categories`; \ No newline at end of file diff --git a/plugins/calendar/drivers/database/SQL/postgres.initial.sql b/plugins/calendar/drivers/database/SQL/postgres.initial.sql index bc8962bb..3e794928 100644 --- a/plugins/calendar/drivers/database/SQL/postgres.initial.sql +++ b/plugins/calendar/drivers/database/SQL/postgres.initial.sql @@ -55,6 +55,7 @@ CREATE TABLE events ( description text NOT NULL, location character varying(255) NOT NULL, categories character varying(255) NOT NULL, + url character varying(255) NOT NULL, all_day smallint NOT NULL DEFAULT 0, free_busy smallint NOT NULL DEFAULT 0, priority smallint NOT NULL DEFAULT 0, diff --git a/plugins/calendar/drivers/database/SQL/postgres/2013051600.sql b/plugins/calendar/drivers/database/SQL/postgres/2013051600.sql new file mode 100644 index 00000000..3c1da43e --- /dev/null +++ b/plugins/calendar/drivers/database/SQL/postgres/2013051600.sql @@ -0,0 +1,3 @@ +-- Postgres database updates since version 0.9-beta + +ALTER TABLE events ADD url character varying(255) NOT NULL; diff --git a/plugins/calendar/drivers/database/SQL/sqlite.initial.sql b/plugins/calendar/drivers/database/SQL/sqlite.initial.sql index a9a9d7e7..088f554f 100644 --- a/plugins/calendar/drivers/database/SQL/sqlite.initial.sql +++ b/plugins/calendar/drivers/database/SQL/sqlite.initial.sql @@ -38,6 +38,7 @@ CREATE TABLE events ( 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', diff --git a/plugins/calendar/drivers/database/SQL/sqlite/2013051600.sql b/plugins/calendar/drivers/database/SQL/sqlite/2013051600.sql new file mode 100644 index 00000000..850fae35 --- /dev/null +++ b/plugins/calendar/drivers/database/SQL/sqlite/2013051600.sql @@ -0,0 +1,63 @@ +-- SQLite database updates since version 0.9-beta + +-- ALTER TABLE events ADD url varchar(255) NOT NULL AFTER categories; + +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 '', + 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', + 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, 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, 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 '', + 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', + alarms varchar(255) 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, 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, all_day, free_busy, priority, sensitivity, alarms, attendees, notifyat FROM temp_events; + diff --git a/plugins/calendar/drivers/database/database_driver.php b/plugins/calendar/drivers/database/database_driver.php index 74db88b1..f72f9585 100644 --- a/plugins/calendar/drivers/database/database_driver.php +++ b/plugins/calendar/drivers/database/database_driver.php @@ -235,8 +235,8 @@ class database_driver extends calendar_driver $this->rc->db->query(sprintf( "INSERT INTO " . $this->db_events . " - (calendar_id, created, changed, uid, %s, %s, all_day, recurrence, title, description, location, categories, free_busy, priority, sensitivity, attendees, alarms, notifyat) - VALUES (?, %s, %s, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", + (calendar_id, created, changed, uid, %s, %s, all_day, recurrence, title, description, location, categories, url, free_busy, priority, sensitivity, attendees, alarms, notifyat) + VALUES (?, %s, %s, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", $this->rc->db->quote_identifier('start'), $this->rc->db->quote_identifier('end'), $this->rc->db->now(), @@ -252,6 +252,7 @@ class database_driver extends calendar_driver strval($event['description']), strval($event['location']), strval($event['categories']), + strval($event['url']), intval($event['free_busy']), intval($event['priority']), intval($event['sensitivity']), @@ -454,7 +455,7 @@ class database_driver extends calendar_driver { $event = $this->_save_preprocess($event); $sql_set = array(); - $set_cols = array('start', 'end', 'all_day', 'recurrence_id', 'sequence', 'title', 'description', 'location', 'categories', 'free_busy', 'priority', 'sensitivity', 'attendees', 'alarms', 'notifyat'); + $set_cols = array('start', 'end', 'all_day', 'recurrence_id', 'sequence', 'title', 'description', 'location', 'categories', 'url', 'free_busy', 'priority', 'sensitivity', 'attendees', 'alarms', 'notifyat'); foreach ($set_cols as $col) { if (is_object($event[$col]) && is_a($event[$col], 'DateTime')) $sql_set[] = $this->rc->db->quote_identifier($col) . '=' . $this->rc->db->quote($event[$col]->format(self::DB_DATE_FORMAT)); @@ -537,8 +538,8 @@ class database_driver extends calendar_driver $notify_at = $this->_get_notification(array('alarms' => $event['alarms'], 'start' => $next_start, 'end' => $next_end)); $query = $this->rc->db->query(sprintf( "INSERT INTO " . $this->db_events . " - (calendar_id, recurrence_id, created, changed, uid, %s, %s, all_day, recurrence, title, description, location, categories, free_busy, priority, sensitivity, alarms, notifyat) - SELECT calendar_id, ?, %s, %s, uid, ?, ?, all_day, recurrence, title, description, location, categories, free_busy, priority, sensitivity, alarms, ? + (calendar_id, recurrence_id, created, changed, uid, %s, %s, all_day, recurrence, title, description, location, categories, url, free_busy, priority, sensitivity, alarms, notifyat) + SELECT calendar_id, ?, %s, %s, uid, ?, ?, all_day, recurrence, title, description, location, categories, url, free_busy, priority, sensitivity, alarms, ? FROM " . $this->db_events . " WHERE event_id=? AND calendar_id IN (" . $this->calendar_ids . ")", $this->rc->db->quote_identifier('start'), $this->rc->db->quote_identifier('end'), diff --git a/plugins/calendar/lib/calendar_ical.php b/plugins/calendar/lib/calendar_ical.php index f1716f43..d7eac67e 100644 --- a/plugins/calendar/lib/calendar_ical.php +++ b/plugins/calendar/lib/calendar_ical.php @@ -243,6 +243,7 @@ class calendar_ical case 'DESCRIPTION': case 'LOCATION': + case 'URL': $event[strtolower($attr['name'])] = $attr['value']; break; @@ -394,6 +395,9 @@ class calendar_ical if (!empty($event['location'])) { $vevent .= "LOCATION:" . self::escape($event['location']) . self::EOL; } + if (!empty($event['url'])) { + $vevent .= "URL:" . self::escape($event['url']) . self::EOL; + } if ($event['recurrence'] && !$recurrence_id) { $vevent .= "RRULE:" . libcalendaring::to_rrule($event['recurrence'], self::EOL) . self::EOL; } diff --git a/plugins/calendar/localization/de_CH.inc b/plugins/calendar/localization/de_CH.inc index 025f655f..fb87f9ae 100644 --- a/plugins/calendar/localization/de_CH.inc +++ b/plugins/calendar/localization/de_CH.inc @@ -106,7 +106,7 @@ $labels['addattendee'] = 'Hinzufügen'; $labels['roleorganizer'] = 'Organisator'; $labels['rolerequired'] = 'Erforderlich'; $labels['roleoptional'] = 'Optional'; -$labels['roleresource'] = 'Ressource'; +$labels['rolechair'] = 'Vorsitz'; $labels['availfree'] = 'Frei'; $labels['availbusy'] = 'Gebucht'; $labels['availunknown'] = 'Unbekannt'; diff --git a/plugins/calendar/localization/de_DE.inc b/plugins/calendar/localization/de_DE.inc index 8d0f2bb4..edf93557 100644 --- a/plugins/calendar/localization/de_DE.inc +++ b/plugins/calendar/localization/de_DE.inc @@ -106,7 +106,7 @@ $labels['addattendee'] = 'Hinzufügen'; $labels['roleorganizer'] = 'Organisator'; $labels['rolerequired'] = 'Erforderlich'; $labels['roleoptional'] = 'Optional'; -$labels['roleresource'] = 'Ressource'; +$labels['rolechair'] = 'Vorsitz'; $labels['availfree'] = 'Frei'; $labels['availbusy'] = 'Gebucht'; $labels['availunknown'] = 'Unbekannt'; diff --git a/plugins/calendar/localization/en_US.inc b/plugins/calendar/localization/en_US.inc index 4164d892..fd3352f8 100644 --- a/plugins/calendar/localization/en_US.inc +++ b/plugins/calendar/localization/en_US.inc @@ -47,6 +47,7 @@ $labels['all-day'] = 'all-day'; $labels['export'] = 'Export'; $labels['exporttitle'] = 'Export to iCalendar'; $labels['location'] = 'Location'; +$labels['url'] = 'URL'; $labels['date'] = 'Date'; $labels['start'] = 'Start'; $labels['end'] = 'End'; @@ -106,7 +107,11 @@ $labels['addattendee'] = 'Add participant'; $labels['roleorganizer'] = 'Organizer'; $labels['rolerequired'] = 'Required'; $labels['roleoptional'] = 'Optional'; -$labels['roleresource'] = 'Resource'; +$labels['rolechair'] = 'Chair'; +$labels['cutypeindividual'] = 'Individual'; +$labels['cutypegroup'] = 'Group'; +$labels['cutyperesource'] = 'Resource'; +$labels['cutyperoom'] = 'Room'; $labels['availfree'] = 'Free'; $labels['availbusy'] = 'Busy'; $labels['availunknown'] = 'Unknown'; diff --git a/plugins/calendar/package.xml b/plugins/calendar/package.xml index 881ce650..d8f1e628 100644 --- a/plugins/calendar/package.xml +++ b/plugins/calendar/package.xml @@ -19,10 +19,10 @@ machniak@kolabsys.com yes - 2012-11-08 + 2013-05-16 - 0.9-beta - 0.9-beta + 0.9.1 + 0.9.1 stable diff --git a/plugins/calendar/skins/classic/templates/calendar.html b/plugins/calendar/skins/classic/templates/calendar.html index 80255ffb..2afa653f 100644 --- a/plugins/calendar/skins/classic/templates/calendar.html +++ b/plugins/calendar/skins/classic/templates/calendar.html @@ -51,6 +51,10 @@
+
+
+
+
@@ -131,7 +135,7 @@ - +
diff --git a/plugins/calendar/skins/classic/templates/eventedit.html b/plugins/calendar/skins/classic/templates/eventedit.html index a5ace0dc..6e1c2b36 100644 --- a/plugins/calendar/skins/classic/templates/eventedit.html +++ b/plugins/calendar/skins/classic/templates/eventedit.html @@ -23,6 +23,11 @@
+
+ +
+ +
diff --git a/plugins/calendar/skins/larry/calendar.css b/plugins/calendar/skins/larry/calendar.css index f7278a6d..24f2cfc0 100644 --- a/plugins/calendar/skins/larry/calendar.css +++ b/plugins/calendar/skins/larry/calendar.css @@ -533,7 +533,7 @@ div.form-section, #eventshow div.event-section, #eventtabs div.event-section { margin-top: 0.2em; - margin-bottom: 0.8em; + margin-bottom: 0.6em; } #eventtabs .border-after { diff --git a/plugins/calendar/skins/larry/templates/calendar.html b/plugins/calendar/skins/larry/templates/calendar.html index 289c8b07..67b92508 100644 --- a/plugins/calendar/skins/larry/templates/calendar.html +++ b/plugins/calendar/skins/larry/templates/calendar.html @@ -65,6 +65,10 @@
+
+
+
+
@@ -145,7 +149,7 @@ - +
diff --git a/plugins/calendar/skins/larry/templates/eventedit.html b/plugins/calendar/skins/larry/templates/eventedit.html index 6784891b..0ae2b774 100644 --- a/plugins/calendar/skins/larry/templates/eventedit.html +++ b/plugins/calendar/skins/larry/templates/eventedit.html @@ -20,6 +20,11 @@
+
+ +
+ +