blob: 7e96aaaeaa4503a37dfedc53a11f3b80f6038d8b (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
|
<?php
/**
* Part of grauphel
*
* PHP version 5
*
* @category Tools
* @package Grauphel
* @author Christian Weiske <cweiske@cweiske.de>
* @copyright 2014 Christian Weiske
* @license http://www.gnu.org/licenses/agpl.html GNU AGPL v3
* @link http://cweiske.de/grauphel.htm
*/
namespace OCA\Grauphel\Search;
/**
* User search query parser
*
* @category Tools
* @package Grauphel
* @author Christian Weiske <cweiske@cweiske.de>
* @copyright 2014 Christian Weiske
* @license http://www.gnu.org/licenses/agpl.html GNU AGPL v3
* @version Release: @package_version@
* @link http://cweiske.de/grauphel.htm
*/
class QueryParser
{
/**
* Splits the user's query string up into several keywords
* that all have to be within or not appear in the note (AND, NOT).
*
* 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"
*
* Exclusion is supported:
* - foo -bar
* -> search for notes that contain "foo" but not "bar"
* - foo -"bar baz"
* -> search for notes that contain "foo" but not "bar baz"
*
* @param string $query User-given query string
*
* @return array Array of keyword arrays, grouped by "AND" and "NOT"
*/
public function parse($query)
{
$keywords = array();
$query = trim($query);
$groupMap = array(
'+' => 'AND',
'-' => 'NOT',
);
$chQuote = null;
$curKeyword = '';
$group = 'AND';
foreach (str_split($query) as $char) {
if ($char == '"' || $char == '\'') {
if ($chQuote === null) {
//new quote
$chQuote = $char;
continue;
} else if ($char == $chQuote) {
//quote end
if (strlen($curKeyword)) {
$keywords[$group][] = $curKeyword;
$curKeyword = '';
}
$chQuote = null;
continue;
}
} else if ($char == ' ' && $chQuote === null) {
if (strlen($curKeyword)) {
$keywords[$group][] = $curKeyword;
$curKeyword = '';
$group = 'AND';
}
continue;
} else if ($char == '+' || $char == '-' && $curKeyword == '') {
$group = $groupMap[$char];
continue;
}
$curKeyword .= $char;
}
if (strlen($curKeyword)) {
$keywords[$group][] = $curKeyword;
}
return $keywords;
}
}
?>
|