ILIAS  release_8 Revision v8.19
All Data Structures Namespaces Files Functions Variables Modules Pages
class.ilQueryParser.php
Go to the documentation of this file.
1 <?php
2 
19 declare(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 }
setGlobalMinLength(int $a_value)
global $DIC
Definition: feed.php:28
setMinWordLength(int $a_length)
const MIN_WORD_LENGTH
Minimum of characters required for search.
__construct(string $a_query_str)
appendMessage(string $a_msg)
getQuotedWords(bool $with_quotation=false)
ilSearchSettings $settings
setMessage(string $a_msg)
setCombination(string $a_combination)
setAllowedWildcards(bool $a_value)