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