2 commits - lib/kolab_sync_data_email.php lib/kolab_sync_data_notes.php lib/kolab_sync_data.php lib/kolab_sync_data_tasks.php

Aleksander Machniak machniak at kolabsys.com
Wed Aug 27 18:33:57 CEST 2014


 lib/kolab_sync_data.php       |    9 ++-
 lib/kolab_sync_data_email.php |  121 ++++++++++++++++++++++++++++++++++++++++--
 lib/kolab_sync_data_notes.php |    2 
 lib/kolab_sync_data_tasks.php |    2 
 4 files changed, 127 insertions(+), 7 deletions(-)

New commits:
commit eff82d7c5cc100374e93bd39de13af7fe791aa67
Author: Aleksander Machniak <machniak at kolabsys.com>
Date:   Mon Aug 25 19:02:01 2014 -0400

    Support email categories (#3489), todo: tag changes detection

diff --git a/lib/kolab_sync_data_email.php b/lib/kolab_sync_data_email.php
index 03d1f78..99d1af5 100644
--- a/lib/kolab_sync_data_email.php
+++ b/lib/kolab_sync_data_email.php
@@ -106,6 +106,10 @@ class kolab_sync_data_email extends kolab_sync_data implements Syncroton_Data_ID
 
         // Outlook 2013 support multi-folder
         $this->ext_devices[] = 'windowsoutlook15';
+
+        if ($this->asversion >= 14) {
+            $this->tag_categories = true;
+        }
     }
 
     /**
@@ -317,6 +321,12 @@ class kolab_sync_data_email extends kolab_sync_data implements Syncroton_Data_ID
         $result['messageClass'] = 'IPM.Note';
         $result['contentClass'] = 'urn:content-classes:message';
 
+        // Categories (Tags)
+        if ($this->tag_categories) {
+            // convert kolab tags into categories
+            $result['categories'] = $this->getKolabTags($message);
+        }
+
         // attachments
         $attachments = array_merge($message->attachments, $message->inline_parts);
         if (!empty($attachments)) {
@@ -552,13 +562,11 @@ class kolab_sync_data_email extends kolab_sync_data implements Syncroton_Data_ID
     }
 
     /**
-     * update existing entry
+     * Update existing message
      *
      * @param string                 $folderId Folder identifier
      * @param string                 $serverId Entry identifier
      * @param Syncroton_Model_IEntry $entry    Entry
-     *
-     * @return array
      */
     public function updateEntry($folderId, $serverId, Syncroton_Model_IEntry $entry)
     {
@@ -589,6 +597,11 @@ class kolab_sync_data_email extends kolab_sync_data implements Syncroton_Data_ID
                 $this->storage->set_flag($msg['uid'], 'FLAGGED', $msg['foldername']);
             }
         }
+
+        // Categories (Tags) change
+        if (isset($entry->categories)) {
+            $this->setKolabTags($message, $entry->categories);
+        }
     }
 
     /**
@@ -893,6 +906,8 @@ class kolab_sync_data_email extends kolab_sync_data implements Syncroton_Data_ID
             }
         }
 
+        // @TODO: tag objects modification detection
+
         return $result;
     }
 
@@ -1241,6 +1256,106 @@ class kolab_sync_data_email extends kolab_sync_data implements Syncroton_Data_ID
         return mb_strcut(trim($body), 0, $size);
     }
 
+    /**
+     * Returns list of tag names assigned to an email message
+     */
+    protected function getKolabTags($message)
+    {
+        // support only messages with message-id
+        if (!($msg_id = $message->headers->get('message-id', false))) {
+            return null;
+        }
+
+        $config = kolab_storage_config::get_instance();
+        $delta  = Syncroton_Registry::getPingTimeout();
+        $folder = $message->folder;
+        $uid    = $message->uid;
+
+        // get tag objects raleted to specified message-id
+        $tags = $config->get_tags($msg_id);
+
+        foreach ($tags as $idx => $tag) {
+            // resolve members if it wasn't done recently
+            $force   = empty($this->tag_rts[$tag['uid']]) || $this->tag_rts[$tag['uid']] <= time() - $delta;
+            $members = $config->resolve_members($tag, $force);
+
+            if (empty($members[$folder]) || !in_array($uid, $members[$folder])) {
+                unset($tags[$idx]);
+            }
+
+            if ($force) {
+                $this->tag_rts[$tag['uid']] = time();
+            }
+        }
+
+        $tags = array_filter(array_map(function($v) { return $v['name']; }, $tags));
+
+        // make sure current folder is set correctly again
+        $this->storage->set_folder($folder);
+
+        return !empty($tags) ? $tags : null;
+    }
+
+    /**
+     * Set tags to an email message
+     */
+    protected function setKolabTags($message, $tags)
+    {
+        $config = kolab_storage_config::get_instance();
+        $delta  = Syncroton_Registry::getPingTimeout();
+        $folder = $message->folder;
+        $uri    = kolab_storage_config::get_message_uri($message->headers, $folder);
+
+        // for all tag objects...
+        foreach ($config->get_tags() as $idx => $relation) {
+            // resolve members if it wasn't done recently
+            $uid     = $relation['uid'];
+            $force   = empty($this->tag_rts[$uid]) || $this->tag_rts[$uid] <= time() - $delta;
+
+            if ($force) {
+                $config->resolve_members($relation, $force);
+                $this->tag_rts[$tag['uid']] = time();
+            }
+
+            $selected = !empty($tags) && in_array($relation['name'], $tags);
+            $found    = !empty($relation['members']) && in_array($uri, $relation['members']);
+            $update   = false;
+
+            // remove member from the relation
+            if ($found && !$selected) {
+                $relation['members'] = array_diff($relation['members'], (array) $uri);
+                $update = true;
+            }
+            // add member to the relation
+            else if (!$found && $selected) {
+                $relation['members'][] = $uri;
+                $update = true;
+            }
+
+            if ($update) {
+                $config->save($relation, 'relation');
+            }
+
+            $tags = array_diff($tags, (array) $relation['name']);
+        }
+
+        // create new relations
+        if (!empty($tags)) {
+            foreach ($tags as $tag) {
+                $relation = array(
+                    'name'     => $tag,
+                    'members'  => (array) $uri,
+                    'category' => 'tag',
+                );
+
+                $config->save($relation, 'relation');
+            }
+        }
+
+        // make sure current folder is set correctly again
+        $this->storage->set_folder($folder);
+    }
+
     public static function charset_to_cp($charset)
     {
         // @TODO: ?????


commit 70b2e7c805b3aae17daa85c996c2cae912fb3f8a
Author: Aleksander Machniak <machniak at kolabsys.com>
Date:   Mon Aug 25 19:01:15 2014 -0400

    Support kolab tasks/notes object's categories for backward compat.

diff --git a/lib/kolab_sync_data.php b/lib/kolab_sync_data.php
index ac452b1..09956c2 100644
--- a/lib/kolab_sync_data.php
+++ b/lib/kolab_sync_data.php
@@ -1635,13 +1635,18 @@ abstract class kolab_sync_data implements Syncroton_Data_IData
     /**
      * Returns list of tag names assigned to kolab object
      */
-    protected function getKolabTags($uid)
+    protected function getKolabTags($uid, $categories = null)
     {
         $config = kolab_storage_config::get_instance();
         $tags   = $config->get_tags($uid);
         $tags   = array_filter(array_map(function($v) { return $v['name']; }, $tags));
 
-        return !empty($tags) ? $tags : null;
+        // merge result with old categories
+        if (!empty($categories)) {
+            $tags = array_unique(array_merge($tags, (array) $categories));
+        }
+
+        return $tags;
     }
 
     /**
diff --git a/lib/kolab_sync_data_notes.php b/lib/kolab_sync_data_notes.php
index 8c6ad92..480da1d 100644
--- a/lib/kolab_sync_data_notes.php
+++ b/lib/kolab_sync_data_notes.php
@@ -112,7 +112,7 @@ class kolab_sync_data_notes extends kolab_sync_data
         $result['messageClass'] = 'IPM.StickyNote';
 
         // convert kolab tags into categories
-        $result['categories'] = $this->getKolabTags($note['uid']);
+        $result['categories'] = $this->getKolabTags($note['uid'], $result['categories']);
 
         return $as_array ? $result : new Syncroton_Model_Note($result);
     }
diff --git a/lib/kolab_sync_data_tasks.php b/lib/kolab_sync_data_tasks.php
index 5e20178..61beb7c 100644
--- a/lib/kolab_sync_data_tasks.php
+++ b/lib/kolab_sync_data_tasks.php
@@ -156,7 +156,7 @@ class kolab_sync_data_tasks extends kolab_sync_data
         }
 
         // convert kolab tags into categories
-        $result['categories'] = $this->getKolabTags($task['uid']);
+        $result['categories'] = $this->getKolabTags($task['uid'], $result['categories']);
 
         // Recurrence
         $this->recurrence_from_kolab($collection, $task, $result, 'Task');




More information about the commits mailing list