2 commits - plugins/calendar plugins/libcalendaring

Thomas Brüderli bruederli at kolabsys.com
Tue Aug 5 18:55:26 CEST 2014


 plugins/calendar/calendar.php                      |   21 +++++++++++---
 plugins/calendar/calendar_ui.js                    |    2 -
 plugins/libcalendaring/lib/libcalendaring_itip.php |   31 ++++++++++++++++++---
 3 files changed, 45 insertions(+), 9 deletions(-)

New commits:
commit c077643c4386dc6fc9f7cfc26790b468d5521387
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date:   Tue Aug 5 18:54:37 2014 +0200

    Reduce RSVP options for resource confirmation messages (identified by the X-KOLAB-INVITATIONTYPE property)

diff --git a/plugins/calendar/calendar.php b/plugins/calendar/calendar.php
index cb5b5a3..722e64b 100644
--- a/plugins/calendar/calendar.php
+++ b/plugins/calendar/calendar.php
@@ -2155,9 +2155,10 @@ class calendar extends rcube_plugin
     $response = $itip->get_itip_status($data, $existing);
 
     // get a list of writeable calendars to save new events to
-    if (!$existing && $response['action'] == 'rsvp' || $response['action'] == 'import') {
+    if (!$existing && !$data['nosave'] && $response['action'] == 'rsvp' || $response['action'] == 'import') {
       $calendars = $this->driver->list_calendars(false, true);
       $calendar_select = new html_select(array('name' => 'calendar', 'id' => 'itip-saveto', 'is_escaped' => true));
+      $calendar_select->add('--', '');
       $numcals = 0;
       foreach ($calendars as $calendar) {
         if (!$calendar['readonly']) {
@@ -2174,6 +2175,9 @@ class calendar extends rcube_plugin
       $response['select'] = html::span('folder-select', $this->gettext('saveincalendar') . ' ' .
         $calendar_select->show($this->rc->config->get('calendar_default_calendar', $default_calendar['id'])));
     }
+    else if ($data['nosave']) {
+      $response['select'] = html::tag('input', array('type' => 'hidden', 'name' => 'calendar', 'id' => 'itip-saveto', 'value' => ''));
+    }
 
     $this->rc->output->command('plugin.update_itip_object_status', $response);
   }
@@ -2390,8 +2394,13 @@ class calendar extends rcube_plugin
     if ($event = $this->lib->mail_get_itip_object($mbox, $uid, $mime_id, 'event')) {
       // find writeable calendar to store event
       $cal_id = !empty($_REQUEST['_folder']) ? get_input_value('_folder', RCUBE_INPUT_POST) : null;
+      $dontsave = ($_REQUEST['_folder'] === '' && $event['_method'] == 'REQUEST');
       $calendars = $this->driver->list_calendars(false, true);
-      $calendar = $calendars[$cal_id] ?: $this->get_default_calendar(true);
+      $calendar = $calendars[$cal_id];
+
+      // select default calendar except user explicitly selected 'none'
+      if (!$calendar && !$dontsave)
+         $calendar = $this->get_default_calendar(true);
 
       $metadata = array(
         'uid' => $event['uid'],
@@ -2525,7 +2534,7 @@ class calendar extends rcube_plugin
         else if ($status == 'declined')
           $error_msg = null;
       }
-      else if ($status == 'declined')
+      else if ($status == 'declined' || $dontsave)
         $error_msg = null;
       else
         $error_msg = $this->gettext('nowritecalendarfound');
@@ -2534,14 +2543,18 @@ class calendar extends rcube_plugin
     if ($success) {
       $message = $event['_method'] == 'REPLY' ? 'attendeupdateesuccess' : ($deleted ? 'successremoval' : ($existing ? 'updatedsuccessfully' : 'importedsuccessfully'));
       $this->rc->output->command('display_message', $this->gettext(array('name' => $message, 'vars' => array('calendar' => $calendar['name']))), 'confirmation');
+    }
 
+    if ($success || $dontsave) {
+      $metadata['nosave'] = $dontsave;
       $metadata['rsvp'] = intval($metadata['rsvp']);
       $metadata['after_action'] = $this->rc->config->get('calendar_itip_after_action', $this->defaults['calendar_itip_after_action']);
       $this->rc->output->command('plugin.itip_message_processed', $metadata);
       $error_msg = null;
     }
-    else if ($error_msg)
+    else if ($error_msg) {
       $this->rc->output->command('display_message', $error_msg, 'error');
+    }
 
     // send iTip reply
     if ($event['_method'] == 'REQUEST' && $organizer && !$noreply && !in_array(strtolower($organizer['email']), $emails) && !$error_msg) {
diff --git a/plugins/libcalendaring/lib/libcalendaring_itip.php b/plugins/libcalendaring/lib/libcalendaring_itip.php
index 748aa43..0b21ed8 100644
--- a/plugins/libcalendaring/lib/libcalendaring_itip.php
+++ b/plugins/libcalendaring/lib/libcalendaring_itip.php
@@ -434,6 +434,12 @@ class libcalendaring_itip
             $title = $event['sequence'] > 0 ? $this->gettext('itipupdate') : $this->gettext('itipinvitation');
             $metadata['rsvp'] = true;
 
+            // check for X-KOLAB-INVITATIONTYPE property and only show accept/decline buttons
+            if (self::get_custom_property($event, 'X-KOLAB-INVITATIONTYPE') == 'CONFIRMATION') {
+                $this->rsvp_actions = array('accepted','declined');
+                $metadata['nosave'] = true;
+            }
+
             // 1. display RSVP buttons (if the user was invited)
             foreach ($this->rsvp_actions as $method) {
                 $rsvp_buttons .= html::tag('input', array(
@@ -471,7 +477,7 @@ class libcalendaring_itip
             }
 
             // add itip reply message controls
-            $rsvp_buttons .= html::div('itip-reply-controls', $this->itip_rsvp_options_ui($dom_id));
+            $rsvp_buttons .= html::div('itip-reply-controls', $this->itip_rsvp_options_ui($dom_id, $metadata['nosave']));
 
             $buttons[] = html::div(array('id' => 'rsvp-'.$dom_id, 'class' => 'rsvp-buttons', 'style' => 'display:none'), $rsvp_buttons);
             $buttons[] = html::div(array('id' => 'update-'.$dom_id, 'style' => 'display:none'), $update_button);
@@ -507,7 +513,6 @@ class libcalendaring_itip
             $buttons[] = html::div(array('id' => 'import-'.$dom_id, 'style' => 'display:none'), $import_button);
         }
 
-        // TODO: add field for COMMENT on iTip replies
         // TODO: add option/checkbox to delete this message after update
 
         // pass some metadata about the event and trigger the asynchronous status check
@@ -556,11 +561,11 @@ class libcalendaring_itip
     /**
      * Render UI elements to control iTip reply message sending
      */
-    public function itip_rsvp_options_ui($dom_id)
+    public function itip_rsvp_options_ui($dom_id, $disable = false)
     {
         // add checkbox to suppress itip reply message
         $rsvp_additions = html::label(array('class' => 'noreply-toggle'),
-            html::tag('input', array('type' => 'checkbox', 'id' => 'noreply-'.$dom_id, 'value' => 1))
+            html::tag('input', array('type' => 'checkbox', 'id' => 'noreply-'.$dom_id, 'value' => 1, 'disabled' => $disable))
             . ' ' . $this->gettext('itipsuppressreply')
         );
 
@@ -626,4 +631,22 @@ class libcalendaring_itip
         return false;
     }
 
+    /**
+     * Utility function to get the value of a custom property
+     */
+    public static function get_custom_property($event, $name)
+    {
+      $ret = false;
+
+      if (is_array($event['x-custom'])) {
+          array_walk($event['x-custom'], function($prop, $i) use ($name, &$ret) {
+              if (strcasecmp($prop[0], $name) === 0) {
+                  $ret = $prop[1];
+              }
+          });
+      }
+
+      return $ret;
+    }
+
 }


commit af768030d07c36ee6e60be67f3f067a0a05f0074
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date:   Tue Aug 5 12:14:16 2014 +0200

    Send invitations to resources

diff --git a/plugins/calendar/calendar_ui.js b/plugins/calendar/calendar_ui.js
index fae2221..ad699de 100644
--- a/plugins/calendar/calendar_ui.js
+++ b/plugins/calendar/calendar_ui.js
@@ -836,7 +836,7 @@ function rcube_calendar_ui(settings)
         if (allow_invitations) {
           $.each(data.attendees, function (i, v) {
             if (v.role != 'ORGANIZER') {
-              if ($('input.edit-attendee-reply[value="' + v.email + '"]').prop('checked')) {
+              if ($('input.edit-attendee-reply[value="' + v.email + '"]').prop('checked') || v.cutype == 'RESOURCE') {
                 need_invitation = true;
                 delete data.attendees[i]['noreply'];
               }




More information about the commits mailing list