2 commits - plugins/calendar plugins/kolab_delegation

Aleksander Machniak machniak at kolabsys.com
Mon Dec 17 15:54:42 CET 2012


 plugins/calendar/calendar.php                        |    2 
 plugins/calendar/calendar_ui.js                      |   19 ++
 plugins/kolab_delegation/kolab_delegation.js         |   87 ++++++++++++-
 plugins/kolab_delegation/kolab_delegation.php        |   42 ++++--
 plugins/kolab_delegation/kolab_delegation_engine.php |  126 +++++++++++++++----
 5 files changed, 234 insertions(+), 42 deletions(-)

New commits:
commit 0745ebf406d20820889c6f45c6f90656728b78db
Author: Aleksander Machniak <machniak at kolabsys.com>
Date:   Mon Dec 17 15:53:38 2012 +0100

    Fix filtering emails/folders list when not in delegator context

diff --git a/plugins/calendar/calendar.php b/plugins/calendar/calendar.php
index 350903d..0584606 100644
--- a/plugins/calendar/calendar.php
+++ b/plugins/calendar/calendar.php
@@ -1820,7 +1820,7 @@ class calendar extends rcube_plugin
         $event['calendar'] = $calendar['id'];
         
         // check for existing event with the same UID
-        $existing = $this->driver->get_event($event['uid'], true);
+        $existing = $this->driver->get_event($event['uid'], true, false, true);
         
         if ($existing) {
           // only update attendee status
diff --git a/plugins/kolab_delegation/kolab_delegation.php b/plugins/kolab_delegation/kolab_delegation.php
index 0adb28e..1e2b81f 100644
--- a/plugins/kolab_delegation/kolab_delegation.php
+++ b/plugins/kolab_delegation/kolab_delegation.php
@@ -166,11 +166,9 @@ class kolab_delegation extends rcube_plugin
         // In delegator context we'll use delegator's addresses
         // instead of current user addresses
 
-        $engine = $this->engine();
-
-        if ($context = $engine->delegator_context()) {
-            $args['emails'] = $_SESSION['delegators'][$context];
-            $args['abort']  = true;
+        if (!empty($_SESSION['delegators'])) {
+            $engine = $this->engine();
+            $engine->delegator_emails_filter($args);
         }
 
         return $args;
@@ -184,11 +182,9 @@ class kolab_delegation extends rcube_plugin
         // In delegator context we'll use delegator's folders
         // instead of current user folders
 
-        $engine = $this->engine();
-
-        if ($engine->delegator_context()) {
-            $args['calendars'] = $engine->delegator_folder_filter($args);
-            $args['abort']     = true;
+        if (!empty($_SESSION['delegators'])) {
+            $engine = $this->engine();
+            $engine->delegator_folder_filter($args);
         }
 
         return $args;
@@ -202,10 +198,9 @@ class kolab_delegation extends rcube_plugin
         // In delegator context we'll use delegator's address/name
         // for invitation responses
 
-        $engine = $this->engine();
-
-        if ($engine->delegator_context()) {
-            $args['identity'] = $engine->delegator_identity();
+        if (!empty($_SESSION['delegators'])) {
+            $engine = $this->engine();
+            $engine->delegator_identity_filter($args);
         }
 
         return $args;
diff --git a/plugins/kolab_delegation/kolab_delegation_engine.php b/plugins/kolab_delegation/kolab_delegation_engine.php
index 9d10084..aefaeeb 100644
--- a/plugins/kolab_delegation/kolab_delegation_engine.php
+++ b/plugins/kolab_delegation/kolab_delegation_engine.php
@@ -681,39 +681,72 @@ class kolab_delegation_engine
     }
 
     /**
-     * Return identity of the current delegator
+     * Set user identity according to delegator delegator
      *
-     * @return array Identity data (name and email)
+     * @param array $args Reference to plugin hook arguments
      */
-    public function delegator_identity()
+    public function delegator_identity_filter(&$args)
     {
-        if (!$this->context) {
+        $context = $this->delegator_context();
+
+        if (!$context) {
             return;
         }
 
         $identities = $this->rc->user->list_identities();
-        $emails     = $_SESSION['delegators'][$this->context];
+        $emails     = $_SESSION['delegators'][$context];
 
         foreach ($identities as $ident) {
             if (in_array($ident['email'], $emails)) {
-                return $ident;
+                $args['identity'] = $ident;
+                return;
             }
         }
+
+        // fallback to default identity
+        $args['identity'] = array_shift($identities);
     }
 
     /**
-     * Filters list of calendars according to delegator context
-     *
-     * @param array $args Plugin hook arguments
+     * Filter user emails according to delegator context
      *
-     * @return array List of calendars
+     * @param array $args Reference to plugin hook arguments
      */
-    public function delegator_folder_filter($args)
+    public function delegator_emails_filter(&$args)
     {
-        if (empty($this->context)) {
-            return;
+        $context = $this->delegator_context();
+
+        // return delegator's addresses
+        if ($context) {
+            $args['emails'] = $_SESSION['delegators'][$context];
+            $args['abort']  = true;
         }
+        // return only user addresses (exclude all delegators addresses)
+        else if (!empty($_SESSION['delegators'])) {
+            $identities = $this->rc->user->list_identities();
+            $emails[]   = $this->rc->user->get_username();
+
+            foreach ($this->rc->user->list_identities() as $identity) {
+                $emails[] = $identity['email'];
+            }
+
+            foreach ($_SESSION['delegators'] as $delegator_emails) {
+                $emails = array_diff($emails, $delegator_emails);
+            }
+
+            $args['emails'] = array_unique($emails);
+            $args['abort']  = true;
+        }
+    }
 
+    /**
+     * Filters list of calendars according to delegator context
+     *
+     * @param array $args Reference to plugin hook arguments
+     */
+    public function delegator_folder_filter(&$args)
+    {
+        $context   = $this->delegator_context();
         $storage   = $this->rc->get_storage();
         $other_ns  = $storage->get_namespace('other');
         $delim     = $storage->get_hierarchy_delimiter();
@@ -734,22 +767,30 @@ class kolab_delegation_engine
                 $ns   = $cal->get_namespace();
                 $name = $cal->get_realname(); // UTF-7 IMAP folder name
 
-                if ($ns != 'other') {
-                    continue;
+                if (empty($context)) {
+                    if ($ns != 'personal') {
+                        continue;
+                    }
                 }
-
-                foreach ($other_ns as $ns) {
-                    $folder = $ns[0] . $this->context . $delim;
-                    if (strpos($name, $folder) !== 0) {
+                else {
+                    if ($ns != 'other') {
                         continue;
                     }
+
+                    foreach ($other_ns as $ns) {
+                        $folder = $ns[0] . $context . $delim;
+                        if (strpos($name, $folder) !== 0) {
+                            continue;
+                        }
+                    }
                 }
             }
 
             $calendars[$cal->id] = $cal;
         }
 
-        return $calendars;
+        $args['calendars'] = $calendars;
+        $args['abort']     = true;
     }
 
     /**


commit 343a4371ab5b8a1b38d266429ba73d33e2cb2933
Author: Aleksander Machniak <machniak at kolabsys.com>
Date:   Mon Dec 17 14:47:02 2012 +0100

    Delegation support in Calendar event edit/create

diff --git a/plugins/calendar/calendar_ui.js b/plugins/calendar/calendar_ui.js
index a93f050..1a5a38b 100644
--- a/plugins/calendar/calendar_ui.js
+++ b/plugins/calendar/calendar_ui.js
@@ -253,6 +253,9 @@ function rcube_calendar_ui(settings)
       var calendar = event.calendar && me.calendars[event.calendar] ? me.calendars[event.calendar] : { editable:false };
       me.selected_event = event;
 
+      // allow other plugins to do actions when event form is opened
+      rcmail.triggerEvent('calendar-event-init', {o: event});
+
       $dialog.find('div.event-section, div.event-line').hide();
       $('#event-title').html(Q(event.title)).show();
       
@@ -298,7 +301,7 @@ function rcube_calendar_ui(settings)
       else if (calendar.attachments) {
         // fetch attachments, some drivers doesn't set 'attachments' prop of the event?
       }
-      
+
       // list event attendees
       if (calendar.attendees && event.attendees) {
         var data, dispname, organizer = false, rsvp = false, html = '';
@@ -383,7 +386,7 @@ function rcube_calendar_ui(settings)
     {
       // close show dialog first
       $("#eventshow:ui-dialog").dialog('close');
-      
+
       var $dialog = $('<div>');
       var calendar = event.calendar && me.calendars[event.calendar] ? me.calendars[event.calendar] : { editable:action=='new' };
       me.selected_event = $.extend($.extend({}, event_defaults), event);  // clone event object (with defaults)
@@ -393,6 +396,9 @@ function rcube_calendar_ui(settings)
       // reset dialog first
       $('#eventtabs').get(0).reset();
 
+      // allow other plugins to do actions when event form is opened
+      rcmail.triggerEvent('calendar-event-init', {o: event});
+
       // event details
       var title = $('#edit-title').val(event.title || '');
       var location = $('#edit-location').val(event.location || '');
@@ -552,7 +558,6 @@ function rcube_calendar_ui(settings)
         }
       };
       
-      
       // init dialog buttons
       var buttons = {};
       
@@ -1411,6 +1416,10 @@ function rcube_calendar_ui(settings)
       
       tr.find('a.deletelink').click({ id:(data.email || data.name) }, function(e) { remove_attendee(this, e.data.id); return false; });
       tr.find('a.mailtolink').click(function(e) { rcmail.redirect(rcmail.url('mail/compose', { _to:this.href.substr(7) })); return false; });
+
+      // select organizer identity
+      if (data.identity_id)
+        $('#edit-identities-list').val(data.identity_id);
       
       // check free-busy status
       if (avail == 'loading') {
@@ -2607,14 +2616,14 @@ function rcube_calendar_ui(settings)
 
       $('#event-rsvp input.button').click(function(){
         event_rsvp($(this).attr('rel'))
-      })
+      });
 
       $('#agenda-listrange').change(function(e){
         settings['agenda_range'] = parseInt($(this).val());
         fc.fullCalendar('option', 'listRange', settings['agenda_range']).fullCalendar('render');
         // TODO: save new settings in prefs
       }).val(settings['agenda_range']);
-      
+
       $('#agenda-listsections').change(function(e){
         settings['agenda_sections'] = $(this).val();
         fc.fullCalendar('option', 'listSections', settings['agenda_sections']).fullCalendar('render');
diff --git a/plugins/kolab_delegation/kolab_delegation.js b/plugins/kolab_delegation/kolab_delegation.js
index 75e77b8..1efa70b 100644
--- a/plugins/kolab_delegation/kolab_delegation.js
+++ b/plugins/kolab_delegation/kolab_delegation.js
@@ -22,10 +22,18 @@
  */
 
 window.rcmail && rcmail.addEventListener('init', function(evt) {
-  if (rcmail.env.task == 'mail') {
+  if (rcmail.env.task == 'mail' || rcmail.env.task == 'calendar') {
     // set delegator context for calendar requests on invitation message
     rcmail.addEventListener('requestcalendar/event', function(o) { rcmail.event_delegator_request(o); });
     rcmail.addEventListener('requestcalendar/mailimportevent', function(o) { rcmail.event_delegator_request(o); });
+
+    if (rcmail.env.delegators && window.rcube_calendar_ui) {
+      rcmail.calendar_identity_init();
+      // delegator context for calendar event form
+      rcmail.addEventListener('calendar-event-init', function(o) { return rcmail.calendar_event_init(o); });
+      // change organizer identity on calendar folder change
+      $('#edit-calendar').change(function() { rcmail.calendar_change(); });
+    }
   }
   else if (rcmail.env.task != 'settings')
     return;
@@ -190,7 +198,7 @@ rcube_webmail.prototype.delegate_save = function()
   this.http_post('plugin.delegation-save', data, lock);
 };
 
-  // callback function when saving/deleting has completed successfully
+// callback function when saving/deleting has completed successfully
 rcube_webmail.prototype.delegate_save_complete = function(p)
 {
   // delegate created
@@ -239,3 +247,78 @@ rcube_webmail.prototype.event_delegator_request = function(data)
 
   return data;
 };
+
+// callback for calendar event form initialization
+rcube_webmail.prototype.calendar_event_init = function(data)
+{
+  // set identity for delegator context
+  this.env.calendar_settings.identity = this.calendar_folder_delegator(data.o.calendar);
+};
+
+// returns delegator's identity data according to selected calendar folder
+rcube_webmail.prototype.calendar_folder_delegator = function(calendar)
+{
+  var d, delegator;
+
+  $.each(this.env.namespace, function(i, v) {
+    var delim = v[v.length-1], pos;
+    if (calendar.indexOf(v) === 0 && (pos = calendar.indexOf(delim, v.length))) {
+      delegator = calendar.substr(v.length, pos - v.length)
+      return false;
+    }
+  });
+
+  if (delegator && (d = this.env.delegators[delegator])) {
+    // find delegator's identity id
+    if (!d.identity_id)
+      $.each(this.env.calendar_settings.identities, function(i, v) {
+        if (d.email == v) {
+          d.identity_id = i;
+          return false;
+        }
+      });
+
+    d.uid = delegator;
+  }
+  else
+    d = this.env.original_identity;
+
+  this.env.delegator_context = d.uid;
+
+  return d;
+};
+
+// handler for calendar folder change
+rcube_webmail.prototype.calendar_change = function()
+{
+  var calendar = $('#edit-calendar').val(),
+    select = $('#edit-identities-list'),
+    old = this.env.calendar_settings.identity;
+
+  this.env.calendar_settings.identity = this.calendar_folder_delegator(calendar);
+
+  // change organizer identity in identity selector
+  if (select.length && old != this.env.calendar_settings.identity) {
+    // @TODO: run freebusy update?
+    var id = this.env.calendar_settings.identity.identity_id;
+    select.val(id ? id : '');
+  }
+};
+
+// modify default identity of the user
+rcube_webmail.prototype.calendar_identity_init = function()
+{
+  var identity = this.env.calendar_settings.identity,
+    emails = identity.emails.split(';');
+
+  // remove delegators' emails from list of emails of the current user
+  emails = $.map(emails, function(v) {
+    for (var n in rcmail.env.delegators)
+      if (rcmail.env.delegators[n].emails.indexOf(';'+v) > -1)
+        return null;
+    return v;
+  });
+
+  identity.emails = emails.join(';');
+  this.env.original_identity = identity;
+}
diff --git a/plugins/kolab_delegation/kolab_delegation.php b/plugins/kolab_delegation/kolab_delegation.php
index 6b37e3f..0adb28e 100644
--- a/plugins/kolab_delegation/kolab_delegation.php
+++ b/plugins/kolab_delegation/kolab_delegation.php
@@ -66,6 +66,10 @@ class kolab_delegation extends rcube_plugin
                 $this->include_stylesheet($this->skin_path . '/style.css');
             }
         }
+        // Calendar plugin UI bindings
+        else if ($this->rc->task == 'calendar' && empty($_REQUEST['_framed'])) {
+            $this->calendar_ui();
+        }
     }
 
     /**
@@ -208,6 +212,21 @@ class kolab_delegation extends rcube_plugin
     }
 
     /**
+     * Delegation support in Calendar plugin UI
+     */
+    public function calendar_ui()
+    {
+        // Initialize handling of delegators' identities in event form
+
+        if (!empty($_SESSION['delegators'])) {
+            $engine = $this->engine();
+            $this->rc->output->set_env('namespace', $engine->namespace_js());
+            $this->rc->output->set_env('delegators', $engine->list_delegators_js());
+            $this->include_script('kolab_delegation.js');
+        }
+    }
+
+    /**
      * Delegation UI handler
      */
     public function controller_ui()
diff --git a/plugins/kolab_delegation/kolab_delegation_engine.php b/plugins/kolab_delegation/kolab_delegation_engine.php
index f2a7125..9d10084 100644
--- a/plugins/kolab_delegation/kolab_delegation_engine.php
+++ b/plugins/kolab_delegation/kolab_delegation_engine.php
@@ -297,6 +297,51 @@ class kolab_delegation_engine
     }
 
     /**
+     * List current user delegators in format compatible with Calendar plugin
+     *
+     * @return array List of delegators
+     */
+    public function list_delegators_js()
+    {
+        $list   = $this->list_delegators();
+        $result = array();
+
+        foreach ($list as $delegator) {
+            $name = $delegator['name'];
+            if ($pos = strrpos($name, '(')) {
+                $name = trim(substr($name, 0, $pos));
+            }
+
+            $result[$delegator['imap_uid']] = array(
+                'emails' => ';' . implode(';', $delegator['email']),
+                'email'  => $delegator['email'][0],
+                'name'   => $name,
+            );
+        }
+
+        return $result;
+    }
+
+    /**
+     * Prepare namespace prefixes for JS environment
+     *
+     * @return array List of prefixes
+     */
+    public function namespace_js()
+    {
+        $storage = $this->rc->get_storage();
+        $ns      = $storage->get_namespace('other');
+
+        if ($ns) {
+            foreach ($ns as $idx => $nsval) {
+                $ns[$idx] = kolab_storage::folder_id($nsval[0]);
+            }
+        }
+
+        return $ns;
+    }
+
+    /**
      * Get all folders to which current user has admin access
      *
      * @param string $delegate IMAP user identifier





More information about the commits mailing list