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