/**
* 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();
$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'])
);
}
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;
+ }
}
?>