Implement search in notes contents

This commit is contained in:
Thomas Bruederli 2014-04-01 16:29:48 +02:00
parent 85176a8615
commit f9cff418eb
3 changed files with 71 additions and 13 deletions

View file

@ -207,7 +207,7 @@ class kolab_notes extends rcube_plugin
*/
public function notes_fetch()
{
$search = rcube_utils::get_input_value('_q', RCUBE_INPUT_GPC);
$search = rcube_utils::get_input_value('_q', RCUBE_INPUT_GPC, true);
$list = rcube_utils::get_input_value('_list', RCUBE_INPUT_GPC);
$data = $this->notes_data($this->list_notes($list, $search), $tags);
@ -246,14 +246,36 @@ class kolab_notes extends rcube_plugin
// full text search (only works with cache enabled)
if (strlen($search)) {
foreach (rcube_utils::normalize_string(mb_strtolower($search), true) as $word) {
$query[] = array('words', '~', $word);
$words = array_filter(rcube_utils::normalize_string(mb_strtolower($search), true));
foreach ($words as $word) {
if (strlen($word) > 2) { // only words > 3 chars are stored in DB
$query[] = array('words', '~', $word);
}
}
}
$this->_read_lists();
if ($folder = $this->folders[$list_id]) {
foreach ($folder->select($query) as $record) {
// post-filter search results
if (strlen($search)) {
$matches = 0;
$contents = mb_strtolower(
$record['title'] .
($this->is_html($record) ? strip_tags($record['description']) : $record['description']) .
join(' ', (array)$record['categories'])
);
foreach ($words as $word) {
if (mb_strpos($contents, $word) !== false) {
$matches++;
}
}
// skip records not matching all search words
if ($matches < count($words)) {
continue;
}
}
$record['list'] = $list_id;
$results[] = $record;
}
@ -337,7 +359,7 @@ class kolab_notes extends rcube_plugin
}
// clean HTML contents
if (!empty($note['description']) && preg_match('/<(html|body)(\s+[a-z]|>)/', $note['description'], $m) && strpos($note['description'], '</'.$m[1].'>') > 0) {
if (!empty($note['description']) && $this->is_html($note)) {
$note['html'] = $this->_wash_html($note['description']);
}
@ -494,6 +516,14 @@ class kolab_notes extends rcube_plugin
return $folder->delete($note['uid'], $force);
}
/**
* Determine whether the given note is HTML formatted
*/
private function is_html($note)
{
// check for opening and closing <html> or <body> tags
return (preg_match('/<(html|body)(\s+[a-z]|>)/', $note['description'], $m) && strpos($note['description'], '</'.$m[1].'>') > 0);
}
/**
* Process the given note data (submitted by the client) before saving it

View file

@ -5,7 +5,7 @@ $labels['navtitle'] = 'Notes';
$labels['tags'] = 'Tags';
$labels['lists'] = 'Notebooks';
$labels['notes'] = 'Notes';
$labels['create'] = 'Create';
$labels['create'] = 'New Note';
$labels['newnote'] = 'New Note';
$labels['notags'] = 'No tags';
$labels['removetag'] = 'Remove tag';

View file

@ -31,6 +31,8 @@ function rcube_kolab_notes_ui(settings)
var notesdata = {};
var tagsfilter = [];
var tags = [];
var search_request;
var search_query;
var me = this;
/* public members */
@ -275,19 +277,39 @@ function rcube_kolab_notes_ui(settings)
}
/**
*
* Execute search
*/
function quicksearch()
{
var q;
if (rcmail.gui_objects.qsearchbox && (q = rcmail.gui_objects.qsearchbox.value)) {
var id = 'search-'+q;
// ignore if query didn't change
if (search_request == id)
return;
search_request = id;
search_query = q;
fetch_notes();
}
else { // empty search input equals reset
reset_search();
}
}
/**
*
* Reset search and get back to normal listing
*/
function reset_search()
{
$(rcmail.gui_objects.qsearchbox).val('');
if (search_request) {
search_request = search_query = null;
fetch_notes();
}
}
/**
@ -300,14 +322,13 @@ function rcube_kolab_notes_ui(settings)
if (id && id != me.selected_list) {
me.selected_list = id;
noteslist.clear_selection();
}
ui_loading = rcmail.set_busy(true, 'loading');
rcmail.http_request('fetch', { _list:me.selected_list, _q:search_query }, true);
reset_view();
noteslist.clear();
noteslist.clear(true);
notesdata = {};
tagsfilter = [];
}
@ -334,7 +355,6 @@ function rcube_kolab_notes_ui(settings)
if (me.selected_note && me.selected_note.uid == note.uid && !match) {
noteslist.clear_selection();
// reset_view();
}
}
}
@ -363,8 +383,16 @@ function rcube_kolab_notes_ui(settings)
notesdata[rec.id] = rec;
}
render_tagslist(data.tags || [], true)
render_tagslist(data.tags || [], !data.search)
rcmail.set_busy(false, 'loading', ui_loading);
// select the single result
if (data.data.length == 1) {
noteslist.select(data.data[0].id);
}
else if (me.selected_note && notesdata[me.selected_note.id]) {
noteslist.select(me.selected_note.id);
}
}
/**