plugins/kolab_notes plugins/libkolab

Aleksander Machniak machniak at kolabsys.com
Wed Aug 20 14:22:00 CEST 2014


 plugins/kolab_notes/kolab_notes.php           |   77 +++++++++++----
 plugins/kolab_notes/notes.js                  |   40 +++----
 plugins/libkolab/lib/kolab_storage_config.php |  131 ++++++++++++++++++++++++++
 3 files changed, 208 insertions(+), 40 deletions(-)

New commits:
commit 26f71de1dbc146e71f692ec8ad09642b50f3a08d
Author: Aleksander Machniak <machniak at kolabsys.com>
Date:   Mon Aug 18 19:58:44 2014 -0400

    Store note tags in relation objects (#3395)

diff --git a/plugins/kolab_notes/kolab_notes.php b/plugins/kolab_notes/kolab_notes.php
index 8475b7d..ad40a86 100644
--- a/plugins/kolab_notes/kolab_notes.php
+++ b/plugins/kolab_notes/kolab_notes.php
@@ -406,10 +406,16 @@ class kolab_notes extends rcube_plugin
     public function notes_fetch()
     {
         $search = rcube_utils::get_input_value('_q', RCUBE_INPUT_GPC, true);
-        $list = rcube_utils::get_input_value('_list', RCUBE_INPUT_GPC);
+        $list   = rcube_utils::get_input_value('_list', RCUBE_INPUT_GPC);
 
         $data = $this->notes_data($this->list_notes($list, $search), $tags);
-        $this->rc->output->command('plugin.data_ready', array('list' => $list, 'search' => $search, 'data' => $data, 'tags' => array_values($tags)));
+
+        $this->rc->output->command('plugin.data_ready', array(
+                'list'   => $list,
+                'search' => $search,
+                'data'   => $data,
+                'tags'   => array_values($tags)
+        ));
     }
 
     /**
@@ -417,18 +423,14 @@ class kolab_notes extends rcube_plugin
      */
     protected function notes_data($records, &$tags)
     {
-        $tags = array();
+        $config = kolab_storage_config::get_instance();
+        $tags   = $config->apply_tags($records);
 
         foreach ($records as $i => $rec) {
             unset($records[$i]['description']);
             $this->_client_encode($records[$i]);
-
-            foreach ((array)$rec['categories'] as $tag) {
-                $tags[] = $tag;
-            }
         }
 
-        $tags = array_unique($tags);
         return $records;
     }
 
@@ -460,8 +462,7 @@ class kolab_notes extends rcube_plugin
                     $matches = 0;
                     $contents = mb_strtolower(
                         $record['title'] .
-                        ($this->is_html($record) ? strip_tags($record['description']) : $record['description']) .
-                        join(' ', (array)$record['categories'])
+                        ($this->is_html($record) ? strip_tags($record['description']) : $record['description'])
                     );
                     foreach ($words as $word) {
                         if (mb_strpos($contents, $word) !== false) {
@@ -519,10 +520,12 @@ class kolab_notes extends rcube_plugin
             return $this->cache[$key];
         }
 
+        $result = false;
+
         $this->_read_lists();
         if ($list_id) {
             if ($folder = $this->get_folder($list_id)) {
-                return $folder->get_object($uid);
+                $result = $folder->get_object($uid);
             }
         }
         // iterate over all calendar folders and search for the event ID
@@ -530,12 +533,17 @@ class kolab_notes extends rcube_plugin
             foreach ($this->folders as $list_id => $folder) {
                 if ($result = $folder->get_object($uid)) {
                     $result['list'] = $list_id;
-                    return $result;
+                    break;
                 }
             }
         }
 
-        return false;
+        if ($result) {
+            // get note tags
+            $result['tags'] = $this->get_tags($result['uid']);
+        }
+
+        return $result;
     }
 
     /**
@@ -576,7 +584,7 @@ class kolab_notes extends rcube_plugin
     public function note_action()
     {
         $action = rcube_utils::get_input_value('_do', RCUBE_INPUT_POST);
-        $note = rcube_utils::get_input_value('_data', RCUBE_INPUT_POST, true);
+        $note   = rcube_utils::get_input_value('_data', RCUBE_INPUT_POST, true);
 
         $success = false;
         switch ($action) {
@@ -665,9 +673,12 @@ class kolab_notes extends rcube_plugin
         // generate new note object from input
         $object = $this->_write_preprocess($note, $old);
 
-        // email links are handled separately
+        // email links and tags are handled separately
         $links = $object['links'];
+        $tags  = $object['tags'];
+
         unset($object['links']);
+        unset($object['tags']);
 
         $saved = $folder->save($object, 'note', $note['uid']);
 
@@ -682,9 +693,12 @@ class kolab_notes extends rcube_plugin
         else {
             // save links in configuration.relation object
             $this->save_links($object['uid'], $links);
+            // save tags in configuration.relation object
+            $this->save_tags($object['uid'], $tags);
 
             $note         = $object;
             $note['list'] = $list_id;
+            $note['tags'] = (array) $tags;
 
             // cache this in memory for later read
             $key = $list_id . ':' . $note['uid'];
@@ -700,7 +714,8 @@ class kolab_notes extends rcube_plugin
     function move_note($note, $list_id)
     {
         $this->_read_lists();
-        $tofolder = $this->get_folder($list_id);
+
+        $tofolder   = $this->get_folder($list_id);
         $fromfolder = $this->get_folder($note['list']);
 
         if ($fromfolder && $tofolder) {
@@ -730,6 +745,7 @@ class kolab_notes extends rcube_plugin
 
         if ($status) {
             $this->save_links($note['uid'], null);
+            $this->save_tags($note['uid'], null);
         }
 
         return $status;
@@ -740,8 +756,8 @@ class kolab_notes extends rcube_plugin
      */
     public function list_action()
     {
-        $action = rcube_utils::get_input_value('_do', RCUBE_INPUT_GPC);
-        $list = rcube_utils::get_input_value('_list', RCUBE_INPUT_GPC, true);
+        $action  = rcube_utils::get_input_value('_do', RCUBE_INPUT_GPC);
+        $list    = rcube_utils::get_input_value('_list', RCUBE_INPUT_GPC, true);
         $success = $update_cmd = false;
 
         if (empty($action)) {
@@ -1038,6 +1054,18 @@ class kolab_notes extends rcube_plugin
     }
 
     /**
+     * Get note tags
+     */
+    private function get_tags($uid)
+    {
+        $config = kolab_storage_config::get_instance();
+        $tags   = $config->get_tags($uid);
+        $tags   = array_map(function($v) { return $v['name']; }, $tags);
+
+        return $tags;
+    }
+
+    /**
      * Find notes assigned to specified message
      */
     private function get_message_notes($message, $folder)
@@ -1149,6 +1177,15 @@ class kolab_notes extends rcube_plugin
     }
 
     /**
+     * Update note tags
+     */
+    private function save_tags($uid, $tags)
+    {
+        $config = kolab_storage_config::get_instance();
+        $config->save_tags($uid, $tags);
+    }
+
+    /**
      * Process the given note data (submitted by the client) before saving it
      */
     private function _write_preprocess($note, $old = array())
@@ -1192,8 +1229,8 @@ class kolab_notes extends rcube_plugin
         }
 
         // make list of categories unique
-        if (is_array($object['categories'])) {
-            $object['categories'] = array_unique(array_filter($object['categories']));
+        if (is_array($object['tags'])) {
+            $object['tags'] = array_unique(array_filter($object['tags']));
         }
 
         unset($object['list'], $object['tempid'], $object['created'], $object['changed'], $object['created_'], $object['changed_']);
diff --git a/plugins/kolab_notes/notes.js b/plugins/kolab_notes/notes.js
index a176370..974e525 100644
--- a/plugins/kolab_notes/notes.js
+++ b/plugins/kolab_notes/notes.js
@@ -325,7 +325,7 @@ function rcube_kolab_notes_ui(settings)
                     uid: null,
                     title: rcmail.gettext('newnote','kolab_notes'),
                     description: '',
-                    categories: [],
+                    tags: [],
                     created: rcmail.gettext('now', 'kolab_notes'),
                     changed: rcmail.gettext('now', 'kolab_notes')
                 }, rcmail.env.kolab_notes_template || {});
@@ -417,7 +417,7 @@ function rcube_kolab_notes_ui(settings)
                 uid: null,
                 title: rcmail.gettext('newnote','kolab_notes'),
                 description: '',
-                categories: [],
+                tags: [],
                 created: rcmail.gettext('now', 'kolab_notes'),
                 changed: rcmail.gettext('now', 'kolab_notes')
             }
@@ -687,9 +687,9 @@ function rcube_kolab_notes_ui(settings)
         for (var id in noteslist.rows) {
             tr = noteslist.rows[id].obj;
             note = notesdata[id];
-            match = note.categories && note.categories.length;
+            match = note.tags && note.tags.length;
             for (var i=0; match && note && i < tagsfilter.length; i++) {
-                if ($.inArray(tagsfilter[i], note.categories) < 0)
+                if ($.inArray(tagsfilter[i], note.tags) < 0)
                     match = false;
             }
 
@@ -787,7 +787,7 @@ function rcube_kolab_notes_ui(settings)
 
         // tag-edit line
         var tagline = $('.tagline', rcmail.gui_objects.noteviewtitle).empty()[readonly?'addClass':'removeClass']('disabled').show();
-        $.each(typeof data.categories == 'object' && data.categories.length ? data.categories : [''], function(i,val){
+        $.each(typeof data.tags == 'object' && data.tags.length ? data.tags : [''], function(i,val) {
             $('<input>')
                 .attr('name', 'tags[]')
                 .attr('tabindex', '0')
@@ -796,7 +796,7 @@ function rcube_kolab_notes_ui(settings)
                 .appendTo(tagline);
         });
 
-        if (!data.categories || !data.categories.length) {
+        if (!data.tags || !data.tags.length) {
             $('<span>').addClass('placeholder')
               .html(rcmail.gettext('notags', 'kolab_notes'))
               .appendTo(tagline)
@@ -941,7 +941,7 @@ function rcube_kolab_notes_ui(settings)
                 printwin.document.title = data.title;
                 $('#notetitle', printwin.document).html(Q(data.title));
                 $('#notebody',  printwin.document).html(data.description);
-                $('#notetags',  printwin.document).html('<span class="tag">' + data.categories.join('</span><span class="tag">') + '</span>');
+                $('#notetags',  printwin.document).html('<span class="tag">' + data.tags.join('</span><span class="tag">') + '</span>');
                 $('#notecreated', printwin.document).html(Q(me.selected_note.created));
                 $('#notechanged', printwin.document).html(Q(me.selected_note.changed));
                 printwin.print();
@@ -1026,8 +1026,8 @@ function rcube_kolab_notes_ui(settings)
         if (typeof counts == 'undefined') {
             counts = {};
             $.each(notesdata, function(id, rec){
-                for (var t, j=0; rec && rec.categories && j < rec.categories.length; j++) {
-                    t = rec.categories[j];
+                for (var t, j=0; rec && rec.tags && j < rec.tags.length; j++) {
+                    t = rec.tags[j];
                     if (typeof counts[t] == 'undefined')
                         counts[t] = 0;
                     counts[t]++;
@@ -1064,10 +1064,10 @@ function rcube_kolab_notes_ui(settings)
 
         if (is_new || me.selected_note && data.id == me.selected_note.id) {
             render_note(data);
-            render_tagslist(data.categories || []);
+            render_tagslist(data.tags || []);
         }
-        else if (data.categories) {
-            render_tagslist(data.categories);
+        else if (data.tags) {
+            render_tagslist(data.tags);
         }
 
         // add list item on top
@@ -1153,18 +1153,18 @@ function rcube_kolab_notes_ui(settings)
             description: editor ? editor.getContent({ format:'html' }).replace(/^<p><\/p>/, '') : $('#notecontent').val(),
             list: listselect.length ? listselect.val() : me.selected_note.list || me.selected_list,
             uid: me.selected_note.uid,
-            categories: []
+            tags: []
         };
 
         // collect tags
         $('.tagedit-list input[type="hidden"]', rcmail.gui_objects.noteviewtitle).each(function(i, elem){
             if (elem.value)
-                savedata.categories.push(elem.value);
+                savedata.tags.push(elem.value);
         });
         // including the "pending" one in the text box
         var newtag = $('#tagedit-input').val();
         if (newtag != '') {
-            savedata.categories.push(newtag);
+            savedata.tags.push(newtag);
         }
 
         return savedata;
@@ -1183,7 +1183,7 @@ function rcube_kolab_notes_ui(settings)
 
         return savedata.title != me.selected_note.title
             || savedata.description != me.selected_note.description
-            || savedata.categories.join(',') != (me.selected_note.categories || []).join(',')
+            || savedata.tags.join(',') != (me.selected_note.tags || []).join(',')
             || savedata.list != me.selected_note.list;
     }
 
@@ -1367,7 +1367,7 @@ function rcube_kolab_notes_ui(settings)
             drop_rec = notesdata[drop_id];
 
         // target already has this tag assigned
-        if (!drop_rec || (drop_rec.categories && $.inArray(tag, drop_rec.categories) >= 0)) {
+        if (!drop_rec || (drop_rec.tags && $.inArray(tag, drop_rec.tags) >= 0)) {
             return false;
         }
 
@@ -1387,9 +1387,9 @@ function rcube_kolab_notes_ui(settings)
             if (savedata.id)   delete savedata.id;
             if (savedata.html) delete savedata.html;
 
-            if (!savedata.categories)
-                savedata.categories = [];
-            savedata.categories.push(tag);
+            if (!savedata.tags)
+                savedata.tags = [];
+            savedata.tags.push(tag);
 
             rcmail.lock_form(rcmail.gui_objects.noteseditform, true);
             saving_lock = rcmail.set_busy(true, 'kolab_notes.savingdata');
diff --git a/plugins/libkolab/lib/kolab_storage_config.php b/plugins/libkolab/lib/kolab_storage_config.php
index 96c4460..a80cf46 100644
--- a/plugins/libkolab/lib/kolab_storage_config.php
+++ b/plugins/libkolab/lib/kolab_storage_config.php
@@ -515,4 +515,135 @@ class kolab_storage_config
 
         return $result;
     }
+
+    /**
+     * Assign tags to kolab objects
+     *
+     * @param array $records List of kolab objects
+     *
+     * @return array List of tags
+     */
+    public function apply_tags(&$records)
+    {
+        // first convert categories into tags
+        foreach ($records as $i => $rec) {
+            if (!empty($rec['categories'])) {
+                $folder = new kolab_storage_folder($rec['_mailbox']);
+                if ($object = $folder->get_object($rec['uid'])) {
+                    $tags = $rec['categories'];
+
+                    unset($object['categories']);
+                    unset($records[$i]['categories']);
+
+                    $this->save_tags($rec['uid'], $tags);
+                    $folder->save($object, $rec['_type'], $rec['uid']);
+                }
+            }
+        }
+
+        $tags = array();
+
+        // assign tags to objects
+        foreach ($this->get_tags() as $tag) {
+            foreach ($records as $idx => $rec) {
+                $uid = self::build_member_url($rec['uid']);
+                if (in_array($uid, (array) $tag['members'])) {
+                    $records[$idx]['tags'][] = $tag['name'];
+                }
+            }
+
+            $tags[] = $tag['name'];
+        }
+
+        $tags = array_unique($tags);
+
+        return $tags;
+    }
+
+    /**
+     * Update object tags
+     *
+     * @param string $uid  Kolab object UID
+     * @param array  $tags List of tag names
+     */
+    public function save_tags($uid, $tags)
+    {
+        $url       = self::build_member_url($uid);
+        $relations = $this->get_tags();
+
+        foreach ($relations as $idx => $relation) {
+            $selected = !empty($tags) && in_array($relation['name'], $tags);
+            $found    = !empty($relation['members']) && in_array($url, $relation['members']);
+            $update   = false;
+
+            // remove member from the relation
+            if ($found && !$selected) {
+                $relation['members'] = array_diff($relation['members'], (array) $url);
+                $update = true;
+            }
+            // add member to the relation
+            else if (!$found && $selected) {
+                $relation['members'][] = $url;
+                $update = true;
+            }
+
+            if ($update) {
+                if ($this->save($relation, 'relation')) {
+                    $this->tags[$idx] = $relation; // update in-memory cache
+                }
+            }
+
+            if ($selected) {
+                $tags = array_diff($tags, (array)$relation['name']);
+            }
+        }
+
+        // create new relations
+        if (!empty($tags)) {
+            foreach ($tags as $tag) {
+                $relation = array(
+                    'name'     => $tag,
+                    'members'  => (array) $url,
+                    'category' => 'tag',
+                );
+
+                if ($this->save($relation, 'relation')) {
+                    $this->tags[] = $relation; // update in-memory cache
+                }
+            }
+        }
+    }
+
+    /**
+     * Get tags (all or referring to specified object)
+     *
+     * @param string $uid Optional object UID
+     *
+     * @return array List of Relation objects
+     */
+    public function get_tags($uid = '*')
+    {
+        if (!isset($this->tags)) {
+            $filter      = array(array('type', '=', 'relation'));
+            $default     = true;
+            $data_filter = array('category' => 'tag');
+
+            $this->tags = $this->get_objects($filter, $default, $data_filter);
+        }
+
+        if ($uid === '*') {
+            return $this->tags;
+        }
+
+        $result = array();
+        $search = self::build_member_url($uid);
+
+        foreach ($this->tags as $tag) {
+            if (in_array($search, (array) $tag['members'])) {
+                $result[] = $tag;
+            }
+        }
+
+        return $result;
+    }
 }




More information about the commits mailing list