plugins/calendar

Thomas Brüderli bruederli at kolabsys.com
Wed Mar 26 10:41:26 CET 2014


 plugins/calendar/calendar.php               |   84 ++++++++++++++++++++++++++--
 plugins/calendar/calendar_base.js           |   27 ++++++++-
 plugins/calendar/localization/en_US.inc     |    2 
 plugins/calendar/skins/classic/calendar.css |    3 -
 plugins/calendar/skins/larry/calendar.css   |    3 -
 5 files changed, 112 insertions(+), 7 deletions(-)

New commits:
commit 6a0a3cb849dfaee4df15f0ef7a33739704974c2f
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date:   Wed Mar 26 10:41:13 2014 +0100

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

diff --git a/plugins/calendar/calendar.php b/plugins/calendar/calendar.php
index a742efa..98c7b58 100644
--- a/plugins/calendar/calendar.php
+++ b/plugins/calendar/calendar.php
@@ -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
diff --git a/plugins/calendar/calendar_base.js b/plugins/calendar/calendar_base.js
index 37552ce..cc7c65a 100644
--- a/plugins/calendar/calendar_base.js
+++ b/plugins/calendar/calendar_base.js
@@ -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) {
diff --git a/plugins/calendar/localization/en_US.inc b/plugins/calendar/localization/en_US.inc
index cc8b397..b243c24 100644
--- a/plugins/calendar/localization/en_US.inc
+++ b/plugins/calendar/localization/en_US.inc
@@ -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\'';
diff --git a/plugins/calendar/skins/classic/calendar.css b/plugins/calendar/skins/classic/calendar.css
index 346d61f..87ef2da 100644
--- a/plugins/calendar/skins/classic/calendar.css
+++ b/plugins/calendar/skins/classic/calendar.css
@@ -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;
diff --git a/plugins/calendar/skins/larry/calendar.css b/plugins/calendar/skins/larry/calendar.css
index d2ade1a..803ceb6 100644
--- a/plugins/calendar/skins/larry/calendar.css
+++ b/plugins/calendar/skins/larry/calendar.css
@@ -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;
 }
 




More information about the commits mailing list