ILIAS  release_4-3 Revision
 All Data Structures Namespaces Files Functions Variables Groups Pages
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 {
40  var $lng = null;
41 
43  var $global_min_length = null;
44 
46  var $quoted_words = array();
47  var $message; // Translated error message
48  var $combination; // combiniation of search words e.g 'and' or 'or'
49  protected $settings = null;
50  protected $wildcards_allowed; // [bool]
51 
56  function ilQueryParser($a_query_str)
57  {
58  global $lng;
59 
60  define(MIN_WORD_LENGTH,3);
61 
62  $this->lng =& $lng;
63 
64  $this->query_str = $a_query_str;
65  $this->message = '';
66 
67  include_once './Services/Search/classes/class.ilSearchSettings.php';
68  $this->settings = ilSearchSettings::getInstance();
69 
70  if(!$this->setMinWordLength(1))
71  {
72  $this->setMinWordLength(MIN_WORD_LENGTH);
73  }
74 
75  $this->setAllowedWildcards(false);
76  }
77 
78  function setMinWordLength($a_length,$a_force = false)
79  {
80  // Due to a bug in mysql fulltext search queries with min_word_legth < 3
81  // might freeze the system.
82  // Thus min_word_length cannot be set to values < 3 if the mysql fulltext is used.
83  if(!$a_force and $this->settings->enabledIndex() and $a_length < 3)
84  {
85  $GLOBALS['ilLog']->write(__METHOD__.': Disabled min word length');
86  return false;
87  }
88  $this->min_word_length = $a_length;
89  return true;
90  }
91  function getMinWordLength()
92  {
94  }
95 
96  function setGlobalMinLength($a_value)
97  {
98  if($a_value !== null)
99  {
100  $a_value = (int)$a_value;
101  if($a_value < 1)
102  {
103  return;
104  }
105  }
106  $this->global_min_length = $a_value;
107  }
108 
110  {
112  }
113 
114  function setAllowedWildcards($a_value)
115  {
116  $this->wildcards_allowed = (bool)$a_value;
117  }
118 
120  {
122  }
123 
124  function setMessage($a_msg)
125  {
126  $this->message = $a_msg;
127  }
128  function getMessage()
129  {
130  return $this->message;
131  }
132  function appendMessage($a_msg)
133  {
134  if(strlen($this->getMessage()))
135  {
136  $this->message .= '<br />';
137  }
138  $this->message .= $a_msg;
139  }
140 
141  function setCombination($a_combination)
142  {
143  $this->combination = $a_combination;
144  }
145  function getCombination()
146  {
147  return $this->combination;
148  }
149 
150  function getQueryString()
151  {
152  return trim($this->query_str);
153  }
154  function getWords()
155  {
156  return $this->words ? $this->words : array();
157  }
158 
159  function getQuotedWords($with_quotation = false)
160  {
161  if($with_quotation)
162  {
163  return $this->quoted_words ? $this->quoted_words : array();
164  }
165  else
166  {
167  foreach($this->quoted_words as $word)
168  {
169  $tmp_word[] = str_replace('\"','',$word);
170  }
171  return $tmp_word ? $tmp_word : array();
172  }
173  }
174 
176  {
177  $counter = 0;
178  $tmp_str = "";
179  foreach($this->getQuotedWords(true) as $word) {
180  if($counter++)
181  {
182  $tmp_str .= (" ".strtoupper($this->getCombination())." ");
183  }
184  $tmp_str .= $word;
185  }
186  return $tmp_str;
187  }
188  function parse()
189  {
190  $this->words = array();
191 
192  #if(!strlen($this->getQueryString()))
193  #{
194  # return false;
195  #}
196 
197  $words = explode(' ',trim($this->getQueryString()));
198  foreach($words as $word)
199  {
200  if(!strlen(trim($word)))
201  {
202  continue;
203  }
204 
205  if(strlen(trim($word)) < $this->getMinWordLength())
206  {
207  $this->setMessage($this->lng->txt('search_minimum_three'));
208  continue;
209  }
210  $this->words[] = ilUtil::prepareDBString($word);
211  }
212 
213  $fullstr = trim($this->getQueryString());
214  if (!in_array($fullstr, $this->words))
215  {
216  $this->words[] = ilUtil::prepareDBString($fullstr);
217  }
218 
219  if(!$this->getAllowedWildcards())
220  {
221  // #14768
222  foreach($this->words as $idx => $word)
223  {
224  if(!stristr($word, '\\'))
225  {
226  $word = str_replace('%', '\%', $word);
227  $word = str_replace('_', '\_', $word);
228  }
229  $this->words[$idx] = $word;
230  }
231  }
232 
233 
234  // Parse strings like && 'A "B C D" E' as 'A' && 'B C D' && 'E'
235  // Can be used in LIKE search or fulltext search > MYSQL 4.0
236  $this->__parseQuotation();
237 
238  return true;
239  }
240 
241  function __parseQuotation()
242  {
243  if(!strlen($this->getQueryString()))
244  {
245  $this->quoted_words[] = '';
246  return false;
247  }
248  $query_str = $this->getQueryString();
249  while(preg_match("/\".*?\"/",$query_str,$matches))
250  {
251  $query_str = str_replace($matches[0],'',$query_str);
252  $this->quoted_words[] = ilUtil::prepareDBString($matches[0]);
253  }
254 
255  // Parse the rest
256  $words = explode(' ',trim($query_str));
257  foreach($words as $word)
258  {
259  if(!strlen(trim($word)))
260  {
261  continue;
262  }
263  $this->quoted_words[] = ilUtil::prepareDBString($word);
264  }
265 
266  if(!$this->getAllowedWildcards())
267  {
268  // #14768
269  foreach($this->quoted_words as $idx => $word)
270  {
271  if(!stristr($word, '\\'))
272  {
273  $word = str_replace('%', '\%', $word);
274  $word = str_replace('_', '\_', $word);
275  }
276  $this->quoted_words[$idx] = $word;
277  }
278  }
279  }
280 
281  function validate()
282  {
283  // Words with less than 3 characters
284  if(strlen($this->getMessage()))
285  {
286  return false;
287  }
288  // No search string given
289  if($this->getMinWordLength() and !count($this->getWords()))
290  {
291  $this->setMessage($this->lng->txt('msg_no_search_string'));
292  return false;
293  }
294  // No search string given
295  if($this->getGlobalMinLength() and strlen(str_replace('"', '', $this->getQueryString())) < $this->getGlobalMinLength())
296  {
297  $this->setMessage(sprintf($this->lng->txt('search_minimum_three'), $this->getGlobalMinLength()));
298  return false;
299  }
300 
301  return true;
302  }
303 }
304 ?>