00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088 class tslib_search {
00089 var $tables = Array ();
00090
00091 var $group_by = 'PRIMARY_KEY';
00092 var $default_operator = 'AND';
00093 var $operator_translate_table_caseinsensitive = TRUE;
00094 var $operator_translate_table = Array (
00095 Array ('+' , 'AND'),
00096 Array ('|' , 'AND'),
00097 Array ('-' , 'AND NOT'),
00098
00099 Array ('and' , 'AND'),
00100 Array ('or' , 'OR'),
00101 Array ('not' , 'AND NOT'),
00102 );
00103
00104
00105 var $sword_array;
00106 var $queryParts;
00107
00108 var $other_where_clauses;
00109 var $fTable;
00110
00111 var $res_offset = 0;
00112 var $res_shows = 20;
00113 var $res_count;
00114
00115 var $pageIdList='';
00116
00117 var $listOfSearchFields ='';
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127 function register_tables_and_columns($requestedCols,$allowedCols) {
00128 $rCols=$this->explodeCols($requestedCols);
00129 $aCols=$this->explodeCols($allowedCols);
00130
00131 foreach ($rCols as $k => $v) {
00132 $rCols[$k]=trim($v);
00133 if (in_array($rCols[$k], $aCols)) {
00134 $parts = explode('.',$rCols[$k]);
00135 $this->tables[$parts[0]]['searchfields'][] = $parts[1];
00136 }
00137 }
00138 $this->tables['pages']['primary_key'] = 'uid';
00139 $this->tables['pages']['resultfields'][] = 'uid';
00140 unset($this->tables['pages']['fkey']);
00141
00142 foreach ($aCols as $k => $v) {
00143 $aCols[$k]=trim($v);
00144 $parts = explode('.',$aCols[$k]);
00145 $this->tables[$parts[0]]['resultfields'][] = $parts[1].' AS '.str_replace('.','_',$aCols[$k]);
00146 $this->tables[$parts[0]]['fkey']='pid';
00147 }
00148
00149 $this->fTable='';
00150 foreach ($this->tables as $t => $v) {
00151 if ($t!='pages') {
00152 if (!$this->fTable) {
00153 $this->fTable = $t;
00154 } else {
00155 unset($this->tables[$t]);
00156 }
00157 }
00158 }
00159 }
00160
00161
00162
00163
00164
00165
00166
00167
00168 function explodeCols($in) {
00169 $theArray = explode(':',$in);
00170 $out = Array();
00171 foreach ($theArray as $val) {
00172 $val=trim($val);
00173 $parts = explode('.',$val);
00174 if ($parts[0] && $parts[1]) {
00175 $subparts = explode('-',$parts[1]);
00176 foreach ($subparts as $piece) {
00177 $piece=trim($piece);
00178 if ($piece) $out[]=$parts[0].'.'.$piece;
00179 }
00180 }
00181 }
00182 return $out;
00183 }
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193 function register_and_explode_search_string($sword) {
00194 $sword = trim($sword);
00195 if ($sword) {
00196 $components = $this->split($sword);
00197 $s_sword = '';
00198 if (is_array($components)) {
00199 $i=0;
00200 $lastoper = '';
00201 foreach ($components as $key => $val) {
00202 $operator=$this->get_operator($val);
00203 if ($operator) {
00204 $lastoper = $operator;
00205 } elseif (strlen($val)>1) {
00206 $this->sword_array[$i]['sword'] = $val;
00207 $this->sword_array[$i]['oper'] = ($lastoper) ? $lastoper : $this->default_operator;
00208 $lastoper = '';
00209 $i++;
00210 }
00211 }
00212 }
00213 }
00214 }
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225 function split($origSword, $specchars='+-', $delchars='+.,-') {
00226 $sword = $origSword;
00227 $specs = '['.$this->quotemeta($specchars).']';
00228
00229
00230 while ($sword) {
00231 if (preg_match('/^"/',$sword)) { // There was a double-quote and we will then look for the ending quote.
00232 $sword = preg_replace('/^"/','',$sword);
00233 preg_match('/^[^"]*/',$sword,$reg); // Removes everything till next double-quote
00234 $value[] = $reg[0]; // reg[0] is the value, should not be trimmed
00235 $sword = preg_replace('/^'.$this->quotemeta($reg[0]).'/','',$sword);
00236 $sword = trim(preg_replace('/^"/','',$sword));
00237 } elseif (preg_match('/^'.$specs.'/',$sword,$reg)) {
00238 $value[] = $reg[0];
00239 $sword = trim(preg_replace('/^'.$specs.'/','',$sword));
00240 } elseif (preg_match('/[\+\-]/',$sword)) {
00241
00242
00243 $a_sword = explode(' ',$sword);
00244 $word = array_shift($a_sword);
00245 $word = rtrim($word, $delchars);
00246 $value[] = $word;
00247 $sword = implode(' ',$a_sword);
00248 } else {
00249
00250 preg_match('/^[^ '.$this->quotemeta($specchars).']*/',$sword,$reg);
00251 $word = rtrim(trim($reg[0]), $delchars);
00252 $value[] = $word;
00253 $sword = trim(preg_replace('/^'.$this->quotemeta($reg[0]).'/','',$sword));
00254 }
00255 }
00256
00257 return $value;
00258 }
00259
00260
00261
00262
00263
00264
00265
00266
00267 function quotemeta($str) {
00268 $str = str_replace('|','\|',quotemeta($str));
00269 #$str = str_replace('-','\-',$str); // Breaks "-" which should NOT have a slash before it inside of [ ] in a regex.
00270 return $str;
00271 }
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283 function build_search_query($endClause) {
00284
00285 if (is_array($this->tables)) {
00286 $tables = $this->tables;
00287 $primary_table = '';
00288
00289
00290 foreach($tables as $key => $val) {
00291 if ($tables[$key]['primary_key']) {$primary_table = $key;}
00292 }
00293
00294 if ($primary_table) {
00295
00296
00297 $this->queryParts = array(
00298 'SELECT' => '',
00299 'FROM' => '',
00300 'WHERE' => '',
00301 'GROUPBY' => '',
00302 'ORDERBY' => '',
00303 'LIMIT' => '',
00304 );
00305
00306
00307 $fieldArray = array();
00308 $tableArray = array();
00309 foreach($tables as $key => $val) {
00310 $tableArray[] = $key;
00311 $resultfields = $tables[$key]['resultfields'];
00312 if (is_array($resultfields)) {
00313 foreach($resultfields as $key2 => $val2) {
00314 $fieldArray[] = $key.'.'.$val2;
00315 }
00316 }
00317 }
00318 $this->queryParts['SELECT'] = implode(',',$fieldArray);
00319 $this->queryParts['FROM'] = implode(',',$tableArray);
00320
00321
00322 $whereArray = array();
00323
00324 $primary_table_and_key = $primary_table.'.'.$tables[$primary_table]['primary_key'];
00325 $primKeys = Array();
00326 foreach($tables as $key => $val) {
00327 $fkey = $tables[$key]['fkey'];
00328 if ($fkey) {
00329 $primKeys[] = $key.'.'.$fkey.'='.$primary_table_and_key;
00330 }
00331 }
00332 if (count($primKeys)) {
00333 $whereArray[] = '('.implode(' OR ',$primKeys).')';
00334 }
00335
00336
00337 if (trim($endClause)) {
00338 $whereArray[] = trim($endClause);
00339 }
00340
00341
00342 $query_part = $this->build_search_query_for_searchwords();
00343 if (!$query_part) {
00344 $query_part = '(0!=0)';
00345 }
00346 $whereArray[] = '('.$query_part.')';
00347
00348
00349 $this->queryParts['WHERE'] = implode(' AND ',$whereArray);
00350
00351
00352 if ($this->group_by) {
00353 if ($this->group_by == 'PRIMARY_KEY') {
00354 $this->queryParts['GROUPBY'] = $primary_table_and_key;
00355 } else {
00356 $this->queryParts['GROUPBY'] = $this->group_by;
00357 }
00358 }
00359 }
00360 }
00361 }
00362
00363
00364
00365
00366
00367
00368
00369 function build_search_query_for_searchwords() {
00370
00371 if (is_array($this->sword_array)) {
00372 $main_query_part = array();
00373
00374 foreach($this->sword_array as $key => $val) {
00375 $s_sword = $this->sword_array[$key]['sword'];
00376
00377
00378 $sub_query_part = array();
00379
00380 $this->listOfSearchFields='';
00381 foreach($this->tables as $key3 => $val3) {
00382 $searchfields = $this->tables[$key3]['searchfields'];
00383 if (is_array($searchfields)) {
00384 foreach($searchfields as $key2 => $val2) {
00385 $this->listOfSearchFields.= $key3.'.'.$val2.',';
00386 $sub_query_part[] = $key3.'.'.$val2.' LIKE \'%'.$GLOBALS['TYPO3_DB']->quoteStr($s_sword, $key3).'%\'';
00387 }
00388 }
00389 }
00390
00391 if (count($sub_query_part)) {
00392 $main_query_part[] = $this->sword_array[$key]['oper'];
00393 $main_query_part[] = '('.implode(' OR ',$sub_query_part).')';
00394 }
00395 }
00396
00397 if (count($main_query_part)) {
00398 unset($main_query_part[0]);
00399 return implode(' ',$main_query_part);
00400 }
00401 }
00402 }
00403
00404
00405
00406
00407
00408
00409
00410
00411 function get_operator($operator) {
00412 $operator = trim($operator);
00413 $op_array = $this->operator_translate_table;
00414 if ($this->operator_translate_table_caseinsensitive) {
00415 $operator = strtolower($operator);
00416 }
00417 foreach ($op_array as $key => $val) {
00418 $item = $op_array[$key][0];
00419 if ($this->operator_translate_table_caseinsensitive) {
00420 $item = strtolower($item);
00421 }
00422 if ($operator==$item) {
00423 return $op_array[$key][1];
00424 }
00425 }
00426 }
00427
00428
00429
00430
00431
00432
00433 function count_query() {
00434 if (is_array($this->queryParts)) {
00435 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery($this->queryParts['SELECT'], $this->queryParts['FROM'], $this->queryParts['WHERE'], $this->queryParts['GROUPBY']);
00436 $this->res_count = $GLOBALS['TYPO3_DB']->sql_num_rows($res);
00437 return TRUE;
00438 }
00439 }
00440
00441
00442
00443
00444
00445
00446 function execute_query() {
00447 if (is_array($this->queryParts)) {
00448 $this->result = $GLOBALS['TYPO3_DB']->exec_SELECT_queryArray($this->queryParts);
00449 return TRUE;
00450 }
00451 }
00452
00453
00454
00455
00456
00457
00458
00459 function get_searchwords() {
00460 $SWORD_PARAMS = '';
00461 if (is_array($this->sword_array)) {
00462 foreach($this->sword_array as $key => $val) {
00463 $SWORD_PARAMS.= '&sword_list[]='.rawurlencode($val['sword']);
00464 }
00465 }
00466 return $SWORD_PARAMS;
00467 }
00468
00469
00470
00471
00472
00473
00474 function get_searchwordsArray() {
00475 if (is_array($this->sword_array)) {
00476 foreach($this->sword_array as $key => $val) {
00477 $swords[] = $val['sword'];
00478 }
00479 }
00480 return $swords;
00481 }
00482 }
00483
00484
00485
00486
00487 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['tslib/class.tslib_search.php']) {
00488 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['tslib/class.tslib_search.php']);
00489 }
00490
00491 ?>