ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
class.ilQueryParser.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
32{
36 public const MIN_WORD_LENGTH = 3;
37 public const QP_COMBINATION_AND = 'and';
38 public const QP_COMBINATION_OR = 'or';
39
40 protected ilLanguage $lng;
42
43 private int $min_word_length = 0;
44 private int $global_min_length = 0;
45
46 private string $query_str;
47 private array $quoted_words = array();
48 private string $message; // Translated error message
49 private string $combination = ''; // combiniation of search words e.g 'and' or 'or'
50 private bool $wildcards_allowed; // [bool]
54 private array $words;
55
56
57 public function __construct(string $a_query_str)
58 {
59 global $DIC;
60
61 $this->lng = $DIC->language();
63
64 if (!defined('MIN_WORD_LENGTH')) {
65 define('MIN_WORD_LENGTH', self::MIN_WORD_LENGTH);
66 }
67
68
69 $this->query_str = $a_query_str;
70 $this->message = '';
71
72 $this->setMinWordLength(1);
73
74 $this->setAllowedWildcards(false);
75 }
76
77 public function setMinWordLength(int $a_length): void
78 {
79 $this->min_word_length = $a_length;
80 }
81
82 public function getMinWordLength(): int
83 {
85 }
86
87 public function setGlobalMinLength(int $a_value): void
88 {
89 if ($a_value < 1) {
90 return;
91 }
92
93 $this->global_min_length = $a_value;
94 }
95
96 public function getGlobalMinLength(): int
97 {
99 }
100
101 public function setAllowedWildcards(bool $a_value): void
102 {
103 $this->wildcards_allowed = $a_value;
104 }
105
106 public function getAllowedWildcards(): bool
107 {
109 }
110
111 public function setMessage(string $a_msg): void
112 {
113 $this->message = $a_msg;
114 }
115 public function getMessage(): string
116 {
117 return $this->message;
118 }
119 public function appendMessage(string $a_msg): void
120 {
121 if (strlen($this->getMessage())) {
122 $this->message .= '<br />';
123 }
124 $this->message .= $a_msg;
125 }
126
127 public function setCombination(string $a_combination): void
128 {
129 $this->combination = $a_combination;
130 }
131 public function getCombination(): string
132 {
133 return $this->combination;
134 }
135
136 public function getQueryString(): string
137 {
138 return trim($this->query_str);
139 }
140
144 public function getWords(): array
145 {
146 return $this->words ?? array();
147 }
148
152 public function getQuotedWords(bool $with_quotation = false): array
153 {
154 if ($with_quotation) {
155 return $this->quoted_words ?: [];
156 }
157
158 foreach ($this->quoted_words as $word) {
159 $tmp_word[] = str_replace("\"", '', $word);
160 }
161 return $tmp_word ?? [];
162 }
163
164 public function getLuceneQueryString(): string
165 {
166 $counter = 0;
167 $tmp_str = "";
168 foreach ($this->getQuotedWords(true) as $word) {
169 if ($counter++) {
170 $tmp_str .= (" " . strtoupper($this->getCombination()) . " ");
171 }
172 $tmp_str .= $word;
173 }
174 return $tmp_str;
175 }
176 public function parse(): bool
177 {
178 $this->words = array();
179
180
181 $words = explode(' ', trim($this->getQueryString()));
182 foreach ($words as $word) {
183 if (!strlen(trim($word))) {
184 continue;
185 }
186
187 if (strlen(trim($word)) < $this->getMinWordLength()) {
188 $this->setMessage(sprintf($this->lng->txt('search_minimum_info'), $this->getMinWordLength()));
189 continue;
190 }
191
192 $this->words[] = $word;
193 }
194
195 $fullstr = trim($this->getQueryString());
196 if (!in_array($fullstr, $this->words)) {
197 $this->words[] = $fullstr;
198 }
199
200 if (!$this->getAllowedWildcards()) {
201 // #14768
202 foreach ($this->words as $idx => $word) {
203 if (!stristr($word, '\\')) {
204 $word = str_replace('%', '\%', $word);
205 $word = str_replace('_', '\_', $word);
206 }
207 $this->words[$idx] = $word;
208 }
209 }
210
211 // Parse strings like && 'A "B C D" E' as 'A' && 'B C D' && 'E'
212 // Can be used in LIKE search or fulltext search > MYSQL 4.0
213 $this->__parseQuotation();
214
215 return true;
216 }
217
218 public function __parseQuotation(): bool
219 {
220 if (!strlen($this->getQueryString())) {
221 $this->quoted_words[] = '';
222 return false;
223 }
224 $query_str = $this->getQueryString();
225 while (preg_match("/\".*?\"/", $query_str, $matches)) {
226 $query_str = str_replace($matches[0], '', $query_str);
227 $this->quoted_words[] = $matches[0];
228 }
229
230 // Parse the rest
231 $words = explode(' ', trim($query_str));
232 foreach ($words as $word) {
233 if (!strlen(trim($word))) {
234 continue;
235 }
236
237 $this->quoted_words[] = $word;
238 }
239
240 if (!$this->getAllowedWildcards()) {
241 // #14768
242 foreach ($this->quoted_words as $idx => $word) {
243 if (!stristr($word, '\\')) {
244 $word = str_replace('%', '\%', $word);
245 $word = str_replace('_', '\_', $word);
246 }
247 $this->quoted_words[$idx] = $word;
248 }
249 }
250 return true;
251 }
252
253 public function validate(): bool
254 {
255 // Words with less than 3 characters
256 if (strlen($this->getMessage())) {
257 return false;
258 }
259 // No search string given
260 if ($this->getMinWordLength() and !count($this->getWords())) {
261 $this->setMessage($this->lng->txt('msg_no_search_string'));
262 return false;
263 }
264 // No search string given
265 if ($this->getGlobalMinLength() and strlen(str_replace('"', '', $this->getQueryString())) < $this->getGlobalMinLength()) {
266 $this->setMessage(sprintf($this->lng->txt('search_minimum_info'), $this->getGlobalMinLength()));
267 return false;
268 }
269
270 return true;
271 }
272}
language handling
setGlobalMinLength(int $a_value)
const MIN_WORD_LENGTH
Minimum of characters required for search.
__construct(string $a_query_str)
setMinWordLength(int $a_length)
getQuotedWords(bool $with_quotation=false)
setAllowedWildcards(bool $a_value)
setMessage(string $a_msg)
ilSearchSettings $settings
setCombination(string $a_combination)
appendMessage(string $a_msg)
global $DIC
Definition: shib_login.php:26
$counter