Implement search in notes contents
This commit is contained in:
parent
85176a8615
commit
f9cff418eb
3 changed files with 71 additions and 13 deletions
|
@ -207,7 +207,7 @@ class kolab_notes extends rcube_plugin
|
||||||
*/
|
*/
|
||||||
public function notes_fetch()
|
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);
|
$list = rcube_utils::get_input_value('_list', RCUBE_INPUT_GPC);
|
||||||
|
|
||||||
$data = $this->notes_data($this->list_notes($list, $search), $tags);
|
$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)
|
// full text search (only works with cache enabled)
|
||||||
if (strlen($search)) {
|
if (strlen($search)) {
|
||||||
foreach (rcube_utils::normalize_string(mb_strtolower($search), true) as $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);
|
$query[] = array('words', '~', $word);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$this->_read_lists();
|
$this->_read_lists();
|
||||||
if ($folder = $this->folders[$list_id]) {
|
if ($folder = $this->folders[$list_id]) {
|
||||||
foreach ($folder->select($query) as $record) {
|
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;
|
$record['list'] = $list_id;
|
||||||
$results[] = $record;
|
$results[] = $record;
|
||||||
}
|
}
|
||||||
|
@ -337,7 +359,7 @@ class kolab_notes extends rcube_plugin
|
||||||
}
|
}
|
||||||
|
|
||||||
// clean HTML contents
|
// 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']);
|
$note['html'] = $this->_wash_html($note['description']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -494,6 +516,14 @@ class kolab_notes extends rcube_plugin
|
||||||
return $folder->delete($note['uid'], $force);
|
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
|
* Process the given note data (submitted by the client) before saving it
|
||||||
|
|
|
@ -5,7 +5,7 @@ $labels['navtitle'] = 'Notes';
|
||||||
$labels['tags'] = 'Tags';
|
$labels['tags'] = 'Tags';
|
||||||
$labels['lists'] = 'Notebooks';
|
$labels['lists'] = 'Notebooks';
|
||||||
$labels['notes'] = 'Notes';
|
$labels['notes'] = 'Notes';
|
||||||
$labels['create'] = 'Create';
|
$labels['create'] = 'New Note';
|
||||||
$labels['newnote'] = 'New Note';
|
$labels['newnote'] = 'New Note';
|
||||||
$labels['notags'] = 'No tags';
|
$labels['notags'] = 'No tags';
|
||||||
$labels['removetag'] = 'Remove tag';
|
$labels['removetag'] = 'Remove tag';
|
||||||
|
|
|
@ -31,6 +31,8 @@ function rcube_kolab_notes_ui(settings)
|
||||||
var notesdata = {};
|
var notesdata = {};
|
||||||
var tagsfilter = [];
|
var tagsfilter = [];
|
||||||
var tags = [];
|
var tags = [];
|
||||||
|
var search_request;
|
||||||
|
var search_query;
|
||||||
var me = this;
|
var me = this;
|
||||||
|
|
||||||
/* public members */
|
/* public members */
|
||||||
|
@ -275,19 +277,39 @@ function rcube_kolab_notes_ui(settings)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Execute search
|
||||||
*/
|
*/
|
||||||
function quicksearch()
|
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()
|
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) {
|
if (id && id != me.selected_list) {
|
||||||
me.selected_list = id;
|
me.selected_list = id;
|
||||||
noteslist.clear_selection();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ui_loading = rcmail.set_busy(true, 'loading');
|
ui_loading = rcmail.set_busy(true, 'loading');
|
||||||
rcmail.http_request('fetch', { _list:me.selected_list, _q:search_query }, true);
|
rcmail.http_request('fetch', { _list:me.selected_list, _q:search_query }, true);
|
||||||
|
|
||||||
reset_view();
|
reset_view();
|
||||||
noteslist.clear();
|
noteslist.clear(true);
|
||||||
notesdata = {};
|
notesdata = {};
|
||||||
tagsfilter = [];
|
tagsfilter = [];
|
||||||
}
|
}
|
||||||
|
@ -334,7 +355,6 @@ function rcube_kolab_notes_ui(settings)
|
||||||
|
|
||||||
if (me.selected_note && me.selected_note.uid == note.uid && !match) {
|
if (me.selected_note && me.selected_note.uid == note.uid && !match) {
|
||||||
noteslist.clear_selection();
|
noteslist.clear_selection();
|
||||||
// reset_view();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -363,8 +383,16 @@ function rcube_kolab_notes_ui(settings)
|
||||||
notesdata[rec.id] = rec;
|
notesdata[rec.id] = rec;
|
||||||
}
|
}
|
||||||
|
|
||||||
render_tagslist(data.tags || [], true)
|
render_tagslist(data.tags || [], !data.search)
|
||||||
rcmail.set_busy(false, 'loading', ui_loading);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Add table
Reference in a new issue