2 commits - plugins/calendar plugins/tasklist

Thomas Brüderli bruederli at kolabsys.com
Tue Nov 4 10:57:08 CET 2014


 plugins/calendar/drivers/database/database_driver.php    |    4 
 plugins/tasklist/drivers/kolab/tasklist_kolab_driver.php |  116 +++++++++++----
 plugins/tasklist/tasklist.js                             |    2 
 plugins/tasklist/tasklist.php                            |    7 
 4 files changed, 95 insertions(+), 34 deletions(-)

New commits:
commit ef166c2479f197b47425e808ea5e9698f52c613c
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date:   Tue Nov 4 10:56:19 2014 +0100

    Use unique identifiers (folder + uid) for task records (#3533)

diff --git a/plugins/tasklist/drivers/kolab/tasklist_kolab_driver.php b/plugins/tasklist/drivers/kolab/tasklist_kolab_driver.php
index 3ee1100..be51d23 100644
--- a/plugins/tasklist/drivers/kolab/tasklist_kolab_driver.php
+++ b/plugins/tasklist/drivers/kolab/tasklist_kolab_driver.php
@@ -492,7 +492,7 @@ class tasklist_kolab_driver extends tasklist_driver
                 continue;
             }
             foreach ($folder->select(array(array('tags','!~','x-complete'))) as $record) {
-                $rec = $this->_to_rcube_task($record);
+                $rec = $this->_to_rcube_task($record, $list_id);
 
                 if ($this->is_complete($rec))  // don't count complete tasks
                     continue;
@@ -567,8 +567,7 @@ class tasklist_kolab_driver extends tasklist_driver
             }
             foreach ($folder->select($query) as $record) {
                 $this->load_tags($record);
-                $task = $this->_to_rcube_task($record);
-                $task['list'] = $list_id;
+                $task = $this->_to_rcube_task($record, $list_id);
 
                 // TODO: post-filter tasks returned from storage
 
@@ -590,8 +589,9 @@ class tasklist_kolab_driver extends tasklist_driver
      */
     public function get_task($prop)
     {
-        $id      = is_array($prop) ? ($prop['uid'] ?: $prop['id']) : $prop;
-        $list_id = is_array($prop) ? $prop['list'] : null;
+        $this->_parse_id($prop);
+        $id      = $prop['uid'];
+        $list_id = $prop['list'];
         $folders = $list_id ? array($list_id => $this->get_folder($list_id)) : $this->folders;
 
         // find task in the available folders
@@ -600,8 +600,7 @@ class tasklist_kolab_driver extends tasklist_driver
                 continue;
             if (!$this->tasks[$id] && ($object = $folder->get_object($id))) {
                 $this->load_tags($object);
-                $this->tasks[$id] = $this->_to_rcube_task($object);
-                $this->tasks[$id]['list'] = $list_id;
+                $this->tasks[$id] = $this->_to_rcube_task($object, $list_id);
                 break;
             }
         }
@@ -620,12 +619,15 @@ class tasklist_kolab_driver extends tasklist_driver
     {
         if (is_string($prop)) {
             $task = $this->get_task($prop);
-            $prop = array('id' => $task['id'], 'list' => $task['list']);
+            $prop = array('uid' => $task['uid'], 'list' => $task['list']);
+        }
+        else {
+            $this->_parse_id($prop);
         }
 
         $childs = array();
         $list_id = $prop['list'];
-        $task_ids = array($prop['id']);
+        $task_ids = array($prop['uid']);
         $folder = $this->get_folder($list_id);
 
         // query for childs (recursively)
@@ -636,7 +638,7 @@ class tasklist_kolab_driver extends tasklist_driver
                 foreach ($folder->select($query) as $record) {
                     // don't rely on kolab_storage_folder filtering
                     if ($record['parent_id'] == $task_id) {
-                        $childs[] = $record['uid'];
+                        $childs[] = $list_id . ':' . $record['uid'];
                         $query_ids[] = $record['uid'];
                     }
                 }
@@ -691,7 +693,7 @@ class tasklist_kolab_driver extends tasklist_driver
                 if (!($record['valarms'] || $record['alarms']) || $record['status'] == 'COMPLETED' || $record['complete'] == 100)  // don't trust query :-)
                     continue;
 
-                $task = $this->_to_rcube_task($record);
+                $task = $this->_to_rcube_task($record, $lid);
 
                 // add to list if alarm is set
                 $alarm = libcalendaring::get_next_alarm($task, 'task');
@@ -873,12 +875,61 @@ class tasklist_kolab_driver extends tasklist_driver
     }
 
     /**
+     * Extract uid + list identifiers from the given input
+     *
+     * @param mixed array or string with task identifier(s)
+     */
+    private function _parse_id(&$prop)
+    {
+        $id_ = null;
+        if (is_array($prop)) {
+            // 'uid' + 'list' available, nothing to be done
+            if (!empty($prop['uid']) && !empty($prop['list'])) {
+                return;
+            }
+
+            // 'id' is given
+            if (!empty($prop['id'])) {
+                if (!empty($prop['list'])) {
+                    $list_id = $prop['_fromlist'] ?: $prop['list'];
+                    if (strpos($prop['id'], $list_id.':') === 0) {
+                        $prop['uid'] = substr($prop['id'], strlen($list_id)+1);
+                    }
+                    else {
+                        $prop['uid'] = $prop['id'];
+                    }
+                }
+                else {
+                    $id_ = $prop['id'];
+                }
+            }
+        }
+        else {
+            $id_ = strval($prop);
+            $prop = array();
+        }
+
+        // split 'id' into list + uid
+        if (!empty($id_)) {
+            list($list, $uid) = explode(':', $id_, 2);
+            if (!empty($uid)) {
+                $prop['uid'] = $uid;
+                $prop['list'] = $list;
+            }
+            else {
+                $prop['uid'] = $id_;
+            }
+        }
+    }
+
+    /**
      * Convert from Kolab_Format to internal representation
      */
-    private function _to_rcube_task($record)
+    private function _to_rcube_task($record, $list_id)
     {
+        $id_prefix = $list_id . ':';
         $task = array(
-            'id' => $record['uid'],
+            'id' => $id_prefix . $record['uid'],
             'uid' => $record['uid'],
             'title' => $record['title'],
 //            'location' => $record['location'],
@@ -886,13 +937,14 @@ class tasklist_kolab_driver extends tasklist_driver
             'flagged' => $record['priority'] == 1,
             'complete' => floatval($record['complete'] / 100),
             'status' => $record['status'],
-            'parent_id' => $record['parent_id'],
+            'parent_id' => $record['parent_id'] ? $id_prefix . $record['parent_id'] : null,
             'recurrence' => $record['recurrence'],
             'attendees' => $record['attendees'],
             'organizer' => $record['organizer'],
             'sequence' => $record['sequence'],
             'tags' => $record['tags'],
             'links' => $this->get_links($record['uid']),
+            'list' => $list_id,
         );
 
         // convert from DateTime to internal date format
@@ -956,6 +1008,7 @@ class tasklist_kolab_driver extends tasklist_driver
     private function _from_rcube_task($task, $old = array())
     {
         $object = $task;
+        $id_prefix = $task['list'] . ':';
 
         if (!empty($task['date'])) {
             $object['due'] = rcube_utils::anytodatetime($task['date'].' '.$task['time'], $this->plugin->timezone);
@@ -980,6 +1033,11 @@ class tasklist_kolab_driver extends tasklist_driver
         else
             $object['priority'] = $old['priority'] > 1 ? $old['priority'] : 0;
 
+        // remove list: prefix from parent_id
+        if (!empty($task['parent_id']) && strpos($task['parent_id'], $id_prefix) === 0) {
+            $object['parent_id'] = substr($task['parent_id'], strlen($id_prefix));
+        }
+
         // copy meta data (starting with _) from old object
         foreach ((array)$old as $key => $val) {
             if (!isset($object[$key]) && $key[0] == '_')
@@ -1063,6 +1121,7 @@ class tasklist_kolab_driver extends tasklist_driver
      */
     public function edit_task($task)
     {
+        $this->_parse_id($task);
         $list_id = $task['list'];
         if (!$list_id || !($folder = $this->get_folder($list_id)))
             return false;
@@ -1074,7 +1133,7 @@ class tasklist_kolab_driver extends tasklist_driver
 
         // moved from another folder
         if ($task['_fromlist'] && ($fromfolder = $this->get_folder($task['_fromlist']))) {
-            if (!$fromfolder->move($task['id'], $folder))
+            if (!$fromfolder->move($task['uid'], $folder))
                 return false;
 
             unset($task['_fromlist']);
@@ -1082,18 +1141,18 @@ class tasklist_kolab_driver extends tasklist_driver
 
         // load previous version of this task to merge
         if ($task['id']) {
-            $old = $folder->get_object($task['id']);
+            $old = $folder->get_object($task['uid']);
             if (!$old || PEAR::isError($old))
                 return false;
 
             // merge existing properties if the update isn't complete
             if (!isset($task['title']) || !isset($task['complete']))
-                $task += $this->_to_rcube_task($old);
+                $task += $this->_to_rcube_task($old, $list_id);
         }
 
         // generate new task object from RC input
         $object = $this->_from_rcube_task($task, $old);
-        $saved  = $folder->save($object, 'task', $task['id']);
+        $saved  = $folder->save($object, 'task', $task['uid']);
 
         if (!$saved) {
             raise_error(array(
@@ -1109,10 +1168,9 @@ class tasklist_kolab_driver extends tasklist_driver
             // save tags in configuration.relation object
             $this->save_tags($object['uid'], $tags);
 
-            $task = $this->_to_rcube_task($object);
-            $task['list'] = $list_id;
+            $task = $this->_to_rcube_task($object, $list_id);
             $task['tags'] = (array) $tags;
-            $this->tasks[$task['id']] = $task;
+            $this->tasks[$task['uid']] = $task;
         }
 
         return $saved;
@@ -1127,13 +1185,14 @@ class tasklist_kolab_driver extends tasklist_driver
      */
     public function move_task($task)
     {
+        $this->_parse_id($task);
         $list_id = $task['list'];
         if (!$list_id || !($folder = $this->get_folder($list_id)))
             return false;
 
         // execute move command
         if ($task['_fromlist'] && ($fromfolder = $this->get_folder($task['_fromlist']))) {
-            return $fromfolder->move($task['id'], $folder);
+            return $fromfolder->move($task['uid'], $folder);
         }
 
         return false;
@@ -1149,16 +1208,17 @@ class tasklist_kolab_driver extends tasklist_driver
      */
     public function delete_task($task, $force = true)
     {
+        $this->_parse_id($task);
         $list_id = $task['list'];
         if (!$list_id || !($folder = $this->get_folder($list_id)))
             return false;
 
-        $status = $folder->delete($task['id']);
+        $status = $folder->delete($task['uid']);
 
         if ($status) {
             // remove tag assignments
             // @TODO: don't do this when undelete feature will be implemented
-            $this->save_tags($task['id'], null);
+            $this->save_tags($task['uid'], null);
         }
 
         return $status;
@@ -1194,7 +1254,6 @@ class tasklist_kolab_driver extends tasklist_driver
      */
     public function get_attachment($id, $task)
     {
-        $task['uid'] = $task['id'];
         $task = $this->get_task($task);
 
         if ($task && !empty($task['attachments'])) {
@@ -1219,8 +1278,9 @@ class tasklist_kolab_driver extends tasklist_driver
      */
     public function get_attachment_body($id, $task)
     {
+        $this->_parse_id($task);
         if ($storage = $this->get_folder($task['list'])) {
-            return $storage->get_attachment($task['id'], $id);
+            return $storage->get_attachment($task['uid'], $id);
         }
 
         return false;
@@ -1248,9 +1308,7 @@ class tasklist_kolab_driver extends tasklist_driver
         $result = $config->get_message_relations($headers, $folder, 'task');
 
         foreach ($result as $idx => $rec) {
-            $task = $this->_to_rcube_task($rec);
-            $task['list'] = kolab_storage::folder_id($rec['_mailbox']);
-            $result[$idx] = $task;
+            $result[$idx] = $this->_to_rcube_task($rec, kolab_storage::folder_id($rec['_mailbox']));
         }
 
         return $result;
diff --git a/plugins/tasklist/tasklist.js b/plugins/tasklist/tasklist.js
index 5ec467d..5bed07f 100644
--- a/plugins/tasklist/tasklist.js
+++ b/plugins/tasklist/tasklist.js
@@ -1873,7 +1873,7 @@ function rcube_tasklist_ui(settings)
                     .html(Q(rcmail.gettext('itip' + mystatus, 'libcalendaring')));
             }
 */
-            var show_rsvp = rsvp && !is_organizer(rec) && rec.status != 'CANCELLED';
+            var show_rsvp = rsvp && list.editable && !is_organizer(rec) && rec.status != 'CANCELLED';
             $('#task-rsvp')[(show_rsvp ? 'show' : 'hide')]();
             $('#task-rsvp .rsvp-buttons input').prop('disabled', false).filter('input[rel='+mystatus+']').prop('disabled', true);
 
diff --git a/plugins/tasklist/tasklist.php b/plugins/tasklist/tasklist.php
index dc01f3c..5f34e86 100644
--- a/plugins/tasklist/tasklist.php
+++ b/plugins/tasklist/tasklist.php
@@ -277,16 +277,19 @@ class tasklist extends rcube_plugin
                   $r = $rec;
                   $r['id'] = $id;
                   if ($this->driver->move_task($r)) {
-                      $refresh[] = $this->driver->get_task($r);
+                      $new_task = $this->driver->get_task($r);
+                      $new_task['tempid'] = $id;
+                      $refresh[] = $new_task;
                       $success = true;
 
                       // move all childs, too
-                      foreach ($this->driver->get_childs(array('id' => $rec['id'], 'list' => $rec['_fromlist']), true) as $cid) {
+                      foreach ($this->driver->get_childs(array('id' => $id, 'list' => $rec['_fromlist']), true) as $cid) {
                           $child = $rec;
                           $child['id'] = $cid;
                           if ($this->driver->move_task($child)) {
                               $r = $this->driver->get_task($child);
                               if ((bool)($filter & self::FILTER_MASK_COMPLETE) == $this->driver->is_complete($r)) {
+                                  $r['tempid'] = $cid;
                                   $refresh[] = $r;
                               }
                           }


commit 5dbd509af5dcb443839d1f41307e56c5071558dc
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date:   Tue Nov 4 08:34:20 2014 +0100

    Fix input check to work with numeric calendar IDs from database (#3835)

diff --git a/plugins/calendar/drivers/database/database_driver.php b/plugins/calendar/drivers/database/database_driver.php
index c1e37da..891e7b8 100644
--- a/plugins/calendar/drivers/database/database_driver.php
+++ b/plugins/calendar/drivers/database/database_driver.php
@@ -795,8 +795,8 @@ class database_driver extends calendar_driver
   {
     if (empty($calendars))
       $calendars = array_keys($this->calendars);
-    else if (is_string($calendars))
-      $calendars = explode(',', $calendars);
+    else if (!is_array($calendars))
+      $calendars = explode(',', strval($calendars));
       
     // only allow to select from calendars of this use
     $calendar_ids = array_map(array($this->rc->db, 'quote'), array_intersect($calendars, array_keys($this->calendars)));




More information about the commits mailing list