Add option to save .ics attachments to calendar (without iTip processing)

This commit is contained in:
Thomas Bruederli 2014-03-26 10:41:13 +01:00
parent 099d72186e
commit 6a0a3cb849
5 changed files with 112 additions and 7 deletions

View file

@ -112,7 +112,7 @@ class calendar extends rcube_plugin
return;
// load Calendar user interface
if (!$this->rc->output->ajax_call && !$this->rc->output->env['framed']) {
if (!$this->rc->output->ajax_call && (!$this->rc->output->env['framed'] || $args['action'] == 'preview')) {
$this->ui->init();
// settings are required in (almost) every GUI step
@ -138,7 +138,8 @@ class calendar extends rcube_plugin
$this->register_action('freebusy-times', array($this, 'freebusy_times'));
$this->register_action('randomdata', array($this, 'generate_randomdata'));
$this->register_action('print', array($this,'print_view'));
$this->register_action('mailimportitip', array($this, 'mail_import_event'));
$this->register_action('mailimportitip', array($this, 'mail_import_itip'));
$this->register_action('mailimportattach', array($this, 'mail_import_attachment'));
$this->register_action('mailtoevent', array($this, 'mail_message2event'));
$this->register_action('inlineui', array($this, 'get_inline_ui'));
$this->register_action('check-recent', array($this, 'check_recent'));
@ -2190,9 +2191,9 @@ class calendar extends rcube_plugin
// load iCalendar functions (if necessary)
if (!empty($this->ics_parts)) {
$this->get_ical();
$this->load_itip();
}
$this->load_itip();
$html = '';
foreach ($this->ics_parts as $mime_id) {
$part = $this->message->mime_parts[$mime_id];
@ -2233,6 +2234,21 @@ class calendar extends rcube_plugin
$this->rc->output->add_label('calendar.savingdata','calendar.deleteventconfirm','calendar.declinedeleteconfirm');
}
// add "Save to calendar" button into attachment menu
if (!empty($this->ics_parts)) {
$this->add_button(array(
'id' => 'attachmentsavecal',
'name' => 'attachmentsavecal',
'type' => 'link',
'wrapper' => 'li',
'command' => 'attachment-save-calendar',
'class' => 'icon calendarlink',
'classact' => 'icon calendarlink active',
'innerclass' => 'icon calendar',
'label' => 'calendar.savetocalendar',
), 'attachmentmenu');
}
return $p;
}
@ -2274,7 +2290,7 @@ class calendar extends rcube_plugin
/**
* Handler for POST request to import an event attached to a mail message
*/
public function mail_import_event()
public function mail_import_itip()
{
$uid = get_input_value('_uid', RCUBE_INPUT_POST);
$mbox = get_input_value('_mbox', RCUBE_INPUT_POST);
@ -2465,6 +2481,66 @@ class calendar extends rcube_plugin
}
}
/**
* Import the full payload from a mail message attachment
*/
public function mail_import_attachment()
{
$uid = get_input_value('_uid', RCUBE_INPUT_POST);
$mbox = get_input_value('_mbox', RCUBE_INPUT_POST);
$mime_id = get_input_value('_part', RCUBE_INPUT_POST);
$charset = RCMAIL_CHARSET;
// establish imap connection
$imap = $this->rc->get_storage();
$imap->set_mailbox($mbox);
if ($uid && $mime_id) {
$part = $imap->get_message_part($uid, $mime_id);
if ($part->ctype_parameters['charset'])
$charset = $part->ctype_parameters['charset'];
$headers = $imap->get_message_headers($uid);
if ($part) {
$events = $this->get_ical()->import($part, $charset);
}
}
$success = $existing = 0;
if (!empty($events)) {
// find writeable calendar to store event
$cal_id = !empty($_REQUEST['_calendar']) ? get_input_value('_calendar', RCUBE_INPUT_POST) : null;
$calendars = $this->driver->list_calendars(false, true);
$calendar = $calendars[$cal_id] ?: $this->get_default_calendar(true);
foreach ($events as $event) {
// save to calendar
if ($calendar && !$calendar['readonly'] && $event['_type'] == 'event') {
$event['calendar'] = $calendar['id'];
if (!$this->driver->get_event($event['uid'], true, false)) {
$success += (bool)$this->driver->new_event($event);
}
else {
$existing++;
}
}
}
}
if ($success) {
$this->rc->output->command('display_message', $this->gettext(array(
'name' => 'importsuccess',
'vars' => array('nr' => $success),
)), 'confirmation');
}
else if ($existing) {
$this->rc->output->command('display_message', $this->gettext('importwarningexists'), 'warning');
}
else {
$this->rc->output->command('display_message', $this->gettext('errorimportingevent'), 'error');
}
}
/**
* Read email message and return contents for a new event based on that message

View file

@ -31,6 +31,7 @@ function rcube_calendar(settings)
// member vars
this.ui;
this.ui_loaded = false;
this.selected_attachment = null;
// private vars
var me = this;
@ -75,6 +76,20 @@ function rcube_calendar(settings)
rcmail.message_list.blur();
}
};
// handler for attachment-save-calendar commands
this.save_to_calendar = function(p)
{
// TODO: show dialog to select the calendar for importing
if (this.selected_attachment && window.rcube_libcalendaring) {
rcmail.http_post('calendar/mailimportattach', {
_uid: rcmail.env.uid,
_mbox: rcmail.env.mailbox,
_part: this.selected_attachment,
// _calendar: $('#calendar-attachment-saveto').val(),
}, rcmail.set_busy(true, 'itip.savingdata'));
}
}
}
@ -86,6 +101,7 @@ window.rcmail && rcmail.addEventListener('init', function(evt) {
// register create-from-mail command to message_commands array
if (rcmail.env.task == 'mail') {
rcmail.register_command('calendar-create-from-mail', function() { cal.create_from_mail() });
rcmail.register_command('attachment-save-calendar', function() { cal.save_to_calendar() });
rcmail.addEventListener('plugin.mail2event_dialog', function(p){ cal.mail2event_dialog(p) });
rcmail.addEventListener('plugin.unlock_saving', function(p){ cal.ui && cal.ui.unlock_saving(); });
@ -93,8 +109,17 @@ window.rcmail && rcmail.addEventListener('init', function(evt) {
rcmail.env.message_commands.push('calendar-create-from-mail');
rcmail.add_element($('<a>'));
}
else
else {
rcmail.enable_command('calendar-create-from-mail', true);
}
rcmail.addEventListener('beforemenu-open', function(p) {
if (p.menu == 'attachmentmenu') {
cal.selected_attachment = p.id;
var mimetype = rcmail.env.attachments[p.id];
rcmail.enable_command('attachment-save-calendar', mimetype == 'text/calendar' || mimetype == 'text/x-vcalendar' || mimetype == 'application/ics');
}
});
// add contextmenu item
if (window.rcm_contextmenu_register_command) {

View file

@ -158,6 +158,7 @@ $labels['notanattendee'] = 'You\'re not listed as an attendee of this event';
$labels['eventcancelled'] = 'The event has been cancelled';
$labels['saveincalendar'] = 'save in';
$labels['updatemycopy'] = 'Update in my calendar';
$labels['savetocalendar'] = 'Save to calendar';
// resources
$labels['resource'] = 'Resource';
@ -191,6 +192,7 @@ $labels['successremoval'] = 'The event has been deleted successfully.';
$labels['successrestore'] = 'The event has been restored successfully.';
$labels['errornotifying'] = 'Failed to send notifications to event participants';
$labels['errorimportingevent'] = 'Failed to import the event';
$labels['importwarningexists'] = 'A copy of this event already exists in your calendar.';
$labels['newerversionexists'] = 'A newer version of this event already exists! Aborted.';
$labels['nowritecalendarfound'] = 'No calendar found to save the event';
$labels['importedsuccessfully'] = 'The event was successfully added to \'$calendar\'';

View file

@ -1379,7 +1379,8 @@ fieldset #calendarcategories div {
/* Invitation UI in mail */
#messagemenu li a.calendarlink {
#messagemenu li a.calendarlink,
#attachmentmenu li a.calendarlink {
background-image: url(images/calendars.png);
background-position: 7px -109px;
background-repeat: no-repeat;

View file

@ -1535,7 +1535,8 @@ fieldset #calendarcategories div {
/* Invitation UI in mail */
#messagemenu li a.calendarlink span.calendar {
#messagemenu li a.calendarlink span.calendar,
#attachmentmenu li a.calendarlink span.calendar {
background-position: 0px -2197px;
}