From: Christian Weiske Date: Fri, 24 Oct 2014 15:23:55 +0000 (+0200) Subject: support query splitting and quoting and search content and tags X-Git-Tag: v0.4.0~11 X-Git-Url: https://git.cweiske.de/grauphel.git/commitdiff_plain/16bb2f544c636425ed9e6bff90654b8fa3c0f2e3 support query splitting and quoting and search content and tags --- diff --git a/lib/notestorage.php b/lib/notestorage.php index 951bf06..67baa20 100644 --- a/lib/notestorage.php +++ b/lib/notestorage.php @@ -274,17 +274,27 @@ class NoteStorage /** * Search for a note * - * @param string $query Query string + * @param string $keywords AND-concatenated query strings * * @return array Database rows with note_guid and note_title */ - public function search($query) + public function search($keywords) { + $sqlWhere = ' AND (note_title LIKE ? OR note_tags LIKE ? OR note_content LIKE ?)'; + $arData = array( + $this->username + ); + foreach ($keywords as $keyword) { + $arData[] = '%' . $keyword . '%';//title + $arData[] = '%' . $keyword . '%';//tags + $arData[] = '%' . $keyword . '%';//content + } $result = \OC_DB::executeAudited( 'SELECT `note_guid`, `note_title`' . ' FROM `*PREFIX*grauphel_notes`' - . ' WHERE note_user = ? AND note_title LIKE ?', - array($this->username, '%' . $query . '%') + . ' WHERE note_user = ?' + . str_repeat($sqlWhere, count($keywords)), + $arData ); $notes = array(); diff --git a/lib/search/provider.php b/lib/search/provider.php index 5b42bb7..8b867bb 100644 --- a/lib/search/provider.php +++ b/lib/search/provider.php @@ -40,13 +40,13 @@ class Provider extends \OCP\Search\Provider $urlGen = \OC::$server->getURLGenerator(); $notes = new NoteStorage($urlGen); $notes->setUsername(\OC_User::getUser()); - $rows = $notes->search($query); + $rows = $notes->search($this->parseQuery($query)); $results = array(); foreach ($rows as $row) { $res = new Note(); $res->id = $row['note_guid']; - $res->name = $row['note_title']; + $res->name = htmlspecialchars_decode($row['note_title']); $res->link = $urlGen->linkToRoute( 'grauphel.gui.note', array('guid' => $row['note_guid']) ); @@ -54,5 +54,48 @@ class Provider extends \OCP\Search\Provider } return $results; } + + /** + * Splits the user's query string up into several keywords + * that all have to be within the note (AND). + * + * Split by space, quotes are supported: + * - foo bar + * -> searches for notes that contain "foo" and "bar" + * - foo "bar baz" + * -> searches for notes that contain "foo" and "bar baz" + * + * @param string $query User-given query string + * + * @return array Array of keywords + */ + protected function parseQuery($query) + { + $keywords = explode(' ', $query); + array_map('trim', $keywords); + $loop = 0; + do { + $changed = false; + foreach ($keywords as $key => &$keyword) { + if ($keyword{0} != '"') { + continue; + } + if (substr($keyword, -1) == '"') { + // "foo" + $keyword = trim($keyword, '"'); + continue; + } + if ($key < count($keywords) -1) { + //not at the end + $keyword .= ' ' . $keywords[$key + 1]; + unset($keywords[$key + 1]); + $changed = true; + break; + } + } + } while ($changed && ++$loop < 20); + + return $keywords; + } } ?>