ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
class.ilQueryParser.php
Go to the documentation of this file.
1 <?php
2 /*
3  +-----------------------------------------------------------------------------+
4  | ILIAS open source |
5  +-----------------------------------------------------------------------------+
6  | Copyright (c) 1998-2001 ILIAS open source, University of Cologne |
7  | |
8  | This program is free software; you can redistribute it and/or |
9  | modify it under the terms of the GNU General Public License |
10  | as published by the Free Software Foundation; either version 2 |
11  | of the License, or (at your option) any later version. |
12  | |
13  | This program is distributed in the hope that it will be useful, |
14  | but WITHOUT ANY WARRANTY; without even the implied warranty of |
15  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16  | GNU General Public License for more details. |
17  | |
18  | You should have received a copy of the GNU General Public License |
19  | along with this program; if not, write to the Free Software |
20  | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
21  +-----------------------------------------------------------------------------+
22 */
23 
35 define('QP_COMBINATION_AND', 'and');
36 define('QP_COMBINATION_OR', 'or');
37 
39 {
43  const MIN_WORD_LENGTH = 3;
44 
45  public $lng = null;
46 
47  public $min_word_length = 0;
48  public $global_min_length = null;
49 
50  public $query_str;
51  public $quoted_words = array();
52  public $message; // Translated error message
53  public $combination; // combiniation of search words e.g 'and' or 'or'
54  protected $settings = null;
55  protected $wildcards_allowed; // [bool]
56 
61  public function __construct($a_query_str)
62  {
63  global $DIC;
64 
65  $lng = $DIC['lng'];
66 
67  define('MIN_WORD_LENGTH', self::MIN_WORD_LENGTH);
68 
69  $this->lng = $lng;
70 
71  $this->query_str = $a_query_str;
72  $this->message = '';
73 
74  include_once './Services/Search/classes/class.ilSearchSettings.php';
76 
77  if (!$this->setMinWordLength(1)) {
79  }
80 
81  $this->setAllowedWildcards(false);
82  }
83 
84  public function setMinWordLength($a_length, $a_force = false)
85  {
86  // Due to a bug in mysql fulltext search queries with min_word_legth < 3
87  // might freeze the system.
88  // Thus min_word_length cannot be set to values < 3 if the mysql fulltext is used.
89  if (!$a_force and $this->settings->enabledIndex() and $a_length < 3) {
90  ilLoggerFactory::getLogger('src')->debug('Disabled min word length');
91  return false;
92  }
93  $this->min_word_length = $a_length;
94  return true;
95  }
96  public function getMinWordLength()
97  {
99  }
100 
101  public function setGlobalMinLength($a_value)
102  {
103  if ($a_value !== null) {
104  $a_value = (int) $a_value;
105  if ($a_value < 1) {
106  return;
107  }
108  }
109  $this->global_min_length = $a_value;
110  }
111 
112  public function getGlobalMinLength()
113  {
115  }
116 
117  public function setAllowedWildcards($a_value)
118  {
119  $this->wildcards_allowed = (bool) $a_value;
120  }
121 
122  public function getAllowedWildcards()
123  {
125  }
126 
127  public function setMessage($a_msg)
128  {
129  $this->message = $a_msg;
130  }
131  public function getMessage()
132  {
133  return $this->message;
134  }
135  public function appendMessage($a_msg)
136  {
137  if (strlen($this->getMessage())) {
138  $this->message .= '<br />';
139  }
140  $this->message .= $a_msg;
141  }
142 
143  public function setCombination($a_combination)
144  {
145  $this->combination = $a_combination;
146  }
147  public function getCombination()
148  {
149  return $this->combination;
150  }
151 
152  public function getQueryString()
153  {
154  return trim($this->query_str);
155  }
156  public function getWords()
157  {
158  return $this->words ? $this->words : array();
159  }
160 
161  public function getQuotedWords($with_quotation = false)
162  {
163  if ($with_quotation) {
164  return $this->quoted_words ? $this->quoted_words : array();
165  } else {
166  foreach ($this->quoted_words as $word) {
167  $tmp_word[] = str_replace('\"', '', $word);
168  }
169  return $tmp_word ? $tmp_word : array();
170  }
171  }
172 
173  public function getLuceneQueryString()
174  {
175  $counter = 0;
176  $tmp_str = "";
177  foreach ($this->getQuotedWords(true) as $word) {
178  if ($counter++) {
179  $tmp_str .= (" " . strtoupper($this->getCombination()) . " ");
180  }
181  $tmp_str .= $word;
182  }
183  return $tmp_str;
184  }
185  public function parse()
186  {
187  $this->words = array();
188 
189  #if(!strlen($this->getQueryString()))
190  #{
191  # return false;
192  #}
193 
194  $words = explode(' ', trim($this->getQueryString()));
195  foreach ($words as $word) {
196  if (!strlen(trim($word))) {
197  continue;
198  }
199 
200  if (strlen(trim($word)) < $this->getMinWordLength()) {
201  $this->setMessage(sprintf($this->lng->txt('search_minimum_info'), $this->getMinWordLength()));
202  continue;
203  }
204 
205  $this->words[] = ilUtil::prepareDBString($word);
206  }
207 
208  $fullstr = trim($this->getQueryString());
209  if (!in_array($fullstr, $this->words)) {
210  $this->words[] = ilUtil::prepareDBString($fullstr);
211  }
212 
213  if (!$this->getAllowedWildcards()) {
214  // #14768
215  foreach ($this->words as $idx => $word) {
216  if (!stristr($word, '\\')) {
217  $word = str_replace('%', '\%', $word);
218  $word = str_replace('_', '\_', $word);
219  }
220  $this->words[$idx] = $word;
221  }
222  }
223 
224  // Parse strings like && 'A "B C D" E' as 'A' && 'B C D' && 'E'
225  // Can be used in LIKE search or fulltext search > MYSQL 4.0
226  $this->__parseQuotation();
227 
228  return true;
229  }
230 
231  public function __parseQuotation()
232  {
233  if (!strlen($this->getQueryString())) {
234  $this->quoted_words[] = '';
235  return false;
236  }
237  $query_str = $this->getQueryString();
238  while (preg_match("/\".*?\"/", $query_str, $matches)) {
239  $query_str = str_replace($matches[0], '', $query_str);
240  $this->quoted_words[] = ilUtil::prepareDBString($matches[0]);
241  }
242 
243  // Parse the rest
244  $words = explode(' ', trim($query_str));
245  foreach ($words as $word) {
246  if (!strlen(trim($word))) {
247  continue;
248  }
249 
250  $this->quoted_words[] = ilUtil::prepareDBString($word);
251  }
252 
253  if (!$this->getAllowedWildcards()) {
254  // #14768
255  foreach ($this->quoted_words as $idx => $word) {
256  if (!stristr($word, '\\')) {
257  $word = str_replace('%', '\%', $word);
258  $word = str_replace('_', '\_', $word);
259  }
260  $this->quoted_words[$idx] = $word;
261  }
262  }
263  }
264 
265  public function validate()
266  {
267  // Words with less than 3 characters
268  if (strlen($this->getMessage())) {
269  return false;
270  }
271  // No search string given
272  if ($this->getMinWordLength() and !count($this->getWords())) {
273  $this->setMessage($this->lng->txt('msg_no_search_string'));
274  return false;
275  }
276  // No search string given
277  if ($this->getGlobalMinLength() and strlen(str_replace('"', '', $this->getQueryString())) < $this->getGlobalMinLength()) {
278  $this->setMessage(sprintf($this->lng->txt('search_minimum_info'), $this->getGlobalMinLength()));
279  return false;
280  }
281 
282  return true;
283  }
284 }
settings()
Definition: settings.php:2
getQuotedWords($with_quotation=false)
global $DIC
Definition: saml.php:7
const MIN_WORD_LENGTH
Minimum of characters required for search.
__construct($a_query_str)
Constructor public.
setGlobalMinLength($a_value)
static prepareDBString($a_str)
prepare a string for db writing (insert/update)
setCombination($a_combination)
static getLogger($a_component_id)
Get component logger.
setMinWordLength($a_length, $a_force=false)
setAllowedWildcards($a_value)