* Merging all changes from TYPO3_4-0 branch back into HEAD
[Packages/TYPO3.CMS.git] / t3lib / class.t3lib_fullsearch.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 1999-2006 Kasper Skaarhoj (kasperYYYY@typo3.com)
6 * All rights reserved
7 *
8 * This script is part of the TYPO3 project. The TYPO3 project is
9 * free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * The GNU General Public License can be found at
15 * http://www.gnu.org/copyleft/gpl.html.
16 * A copy is found in the textfile GPL.txt and important notices to the license
17 * from the author is found in LICENSE.txt distributed with these scripts.
18 *
19 *
20 * This script is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * This copyright notice MUST APPEAR in all copies of the script!
26 ***************************************************************/
27 /**
28 * Class used in module tools/dbint (advanced search) and which may hold code specific for that module
29 * However the class has a general principle in it which may be used in the web/export module.
30 *
31 * $Id$
32 *
33 * @author Kasper Skaarhoj <kasperYYYY@typo3.com>
34 * @coauthor Jo Hasenau <info@cybercraft.de>
35 */
36 /**
37 * [CLASS/FUNCTION INDEX of SCRIPT]
38 *
39 *
40 *
41 * 88: class t3lib_fullsearch
42 * 103: function form()
43 * 117: function makeStoreControl()
44 * 156: function initStoreArray()
45 * 176: function cleanStoreQueryConfigs($storeQueryConfigs,$storeArray)
46 * 193: function addToStoreQueryConfigs($storeQueryConfigs,$index)
47 * 209: function saveQueryInAction($uid)
48 * 256: function loadStoreQueryConfigs($storeQueryConfigs,$storeIndex,$writeArray)
49 * 272: function procesStoreControl()
50 * 344: function queryMaker()
51 * 414: function getQueryResultCode($mQ,$res,$table)
52 * 534: function csvValues($row, $delim=',', $quote='"', $conf=array(), $table='')
53 * 550: function tableWrap($str)
54 * 559: function search()
55 * 614: function resultRowDisplay($row,$conf,$table)
56 * 662: function getProcessedValueExtra($table, $fN, $fV, $conf, $splitString)
57 * 781: function getTreeList($id, $depth, $begin = 0, $perms_clause)
58 * 818: function makeValueList($fN, $fV, $conf, $table, $splitString)
59 * 1028: function resultRowTitles($row,$conf,$table)
60 * 1058: function csvRowTitles($row, $conf, $table)
61 *
62 * TOTAL FUNCTIONS: 19
63 * (This index is automatically created/updated by the extension "extdeveval")
64 *
65 */
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80 /**
81 * Class used in module tools/dbint (advanced search) and which may hold code specific for that module
82 * However the class has a general principle in it which may be used in the web/export module.
83 *
84 * @author Kasper Skaarhoj <kasperYYYY@typo3.com>
85 * @package TYPO3
86 * @subpackage t3lib
87 */
88 class t3lib_fullsearch {
89 var $storeList = 'search_query_smallparts,search_result_labels,labels_noprefix,show_deleted,queryConfig,queryTable,queryFields,queryLimit,queryOrder,queryOrderDesc,queryOrder2,queryOrder2Desc,queryGroup,search_query_makeQuery';
90 var $downloadScript = 'index.php';
91 var $formW=48;
92 var $noDownloadB=0;
93
94
95
96
97
98 /**
99 * [Describe function...]
100 *
101 * @return [type] ...
102 */
103 function form() {
104 $out='
105 Search Word:<BR>
106 <input type="text" name="SET[sword]" value="'.htmlspecialchars($GLOBALS['SOBE']->MOD_SETTINGS['sword']).'"'.$GLOBALS['TBE_TEMPLATE']->formWidth(20).'><input type="submit" name="submit" value="Search All Records">
107 ';
108
109 return $out;
110 }
111
112 /**
113 * [Describe function...]
114 *
115 * @return [type] ...
116 */
117 function makeStoreControl() {
118 // Load/Save
119 $storeArray = $this->initStoreArray();
120 $cur='';
121
122 // Store Array:
123 $opt=array();
124 reset($storeArray);
125 while(list($k,$v)=each($storeArray)) {
126 $opt[]='<option value="'.$k.'"'.(!strcmp($cur,$v)?' selected':'').'>'.htmlspecialchars($v).'</option>';
127 }
128
129 // Actions:
130 if (t3lib_extMgm::isLoaded('sys_action') && $GLOBALS['BE_USER']->isAdmin()) {
131 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', 'sys_action', 'type=2', '', 'title');
132 if ($GLOBALS['TYPO3_DB']->sql_num_rows($res)) {
133 $opt[]='<option value="0">__Save to Action:__</option>';
134 while($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
135 $opt[]='<option value="-'.$row['uid'].'"'.(!strcmp($cur,'-'.$row['uid'])?' selected':'').'>'.htmlspecialchars($row['title'].' ['.$row['uid'].']').'</option>';
136 }
137 }
138 $GLOBALS['TYPO3_DB']->sql_free_result($res);
139 }
140
141 $TDparams=' nowrap="nowrap" class="bgColor4"';
142 $tmpCode='
143 <table border="0" cellpadding="3" cellspacing="1">
144 <tr'.$TDparams.'><td><select name="storeControl[STORE]" onChange="document.forms[0][\'storeControl[title]\'].value= this.options[this.selectedIndex].value!=0 ? this.options[this.selectedIndex].text : \'\';">'.implode(chr(10),$opt).'</select><input type="submit" name="storeControl[LOAD]" value="Load"></td></tr>
145 <tr'.$TDparams.'><td nowrap><input name="storeControl[title]" value="" type="text" max="80"'.$GLOBALS['SOBE']->doc->formWidth().'><input type="submit" name="storeControl[SAVE]" value="Save" onClick="if (document.forms[0][\'storeControl[STORE]\'].options[document.forms[0][\'storeControl[STORE]\'].selectedIndex].value<0) return confirm(\'Are you sure you want to overwrite the existing query in this action?\');"><input type="submit" name="storeControl[REMOVE]" value="Remove"></td></tr>
146 </table>
147 ';
148 return $tmpCode;
149 }
150
151 /**
152 * [Describe function...]
153 *
154 * @return [type] ...
155 */
156 function initStoreArray() {
157 $storeArray=array(
158 '0' => '[New]'
159 );
160
161 $savedStoreArray = unserialize($GLOBALS['SOBE']->MOD_SETTINGS['storeArray']);
162
163 if (is_array($savedStoreArray)) {
164 $storeArray = array_merge($storeArray,$savedStoreArray);
165 }
166 return $storeArray;
167 }
168
169 /**
170 * [Describe function...]
171 *
172 * @param [type] $storeQueryConfigs: ...
173 * @param [type] $storeArray: ...
174 * @return [type] ...
175 */
176 function cleanStoreQueryConfigs($storeQueryConfigs,$storeArray) {
177 if (is_array($storeQueryConfigs)) {
178 reset($storeQueryConfigs);
179 while(list($k,$v)=each($storeQueryConfigs)) {
180 if (!isset($storeArray[$k])) unset($storeQueryConfigs[$k]);
181 }
182 }
183 return $storeQueryConfigs;
184 }
185
186 /**
187 * [Describe function...]
188 *
189 * @param [type] $storeQueryConfigs: ...
190 * @param [type] $index: ...
191 * @return [type] ...
192 */
193 function addToStoreQueryConfigs($storeQueryConfigs,$index) {
194 $keyArr = explode(',',$this->storeList);
195 reset($keyArr);
196 $storeQueryConfigs[$index]=array();
197 while(list(,$k)=each($keyArr)) {
198 $storeQueryConfigs[$index][$k]=$GLOBALS['SOBE']->MOD_SETTINGS[$k];
199 }
200 return $storeQueryConfigs;
201 }
202
203 /**
204 * [Describe function...]
205 *
206 * @param [type] $uid: ...
207 * @return [type] ...
208 */
209 function saveQueryInAction($uid) {
210 if (t3lib_extMgm::isLoaded('sys_action')) {
211 $keyArr = explode(',',$this->storeList);
212 reset($keyArr);
213 $saveArr=array();
214 while(list(,$k)=each($keyArr)) {
215 $saveArr[$k]=$GLOBALS['SOBE']->MOD_SETTINGS[$k];
216 }
217
218 $qOK = 0;
219 // Show query
220 if ($saveArr['queryTable']) {
221 $qGen = t3lib_div::makeInstance('t3lib_queryGenerator');
222 $qGen->init('queryConfig',$saveArr['queryTable']);
223 $qGen->makeSelectorTable($saveArr);
224
225 $qGen->enablePrefix=1;
226 $qString = $qGen->getQuery($qGen->queryConfig);
227 $qCount = $GLOBALS['TYPO3_DB']->SELECTquery('count(*)', $qGen->table, $qString.t3lib_BEfunc::deleteClause($qGen->table));
228 $qSelect = $qGen->getSelectQuery($qString);
229
230 $res = @$GLOBALS['TYPO3_DB']->sql(TYPO3_db,$qCount);
231 if (!$GLOBALS['TYPO3_DB']->sql_error()) {
232 $dA = array();
233 $dA['t2_data'] = serialize(array(
234 'qC'=>$saveArr,
235 'qCount' => $qCount,
236 'qSelect' => $qSelect,
237 'qString' => $qString
238 ));
239 $GLOBALS['TYPO3_DB']->exec_UPDATEquery('sys_action', 'uid='.intval($uid), $dA);
240 $qOK=1;
241 }
242 }
243
244 return $qOK;
245 }
246 }
247
248 /**
249 * [Describe function...]
250 *
251 * @param [type] $storeQueryConfigs: ...
252 * @param [type] $storeIndex: ...
253 * @param [type] $writeArray: ...
254 * @return [type] ...
255 */
256 function loadStoreQueryConfigs($storeQueryConfigs,$storeIndex,$writeArray) {
257 if ($storeQueryConfigs[$storeIndex]) {
258 $keyArr = explode(',',$this->storeList);
259 reset($keyArr);
260 while(list(,$k)=each($keyArr)) {
261 $writeArray[$k]=$storeQueryConfigs[$storeIndex][$k];
262 }
263 }
264 return $writeArray;
265 }
266
267 /**
268 * [Describe function...]
269 *
270 * @return [type] ...
271 */
272 function procesStoreControl() {
273 $storeArray = $this->initStoreArray();
274 $storeQueryConfigs = unserialize($GLOBALS['SOBE']->MOD_SETTINGS['storeQueryConfigs']);
275
276 $storeControl = t3lib_div::_GP('storeControl');
277 $storeIndex = intval($storeControl['STORE']);
278 $saveStoreArray=0;
279 $writeArray=array();
280 if (is_array($storeControl)) {
281 if ($storeControl['LOAD']) {
282 if ($storeIndex>0) {
283 $writeArray=$this->loadStoreQueryConfigs($storeQueryConfigs,$storeIndex,$writeArray);
284 $saveStoreArray=1;
285 $msg="'".htmlspecialchars($storeArray[$storeIndex])."' query loaded!";
286 } elseif ($storeIndex<0 && t3lib_extMgm::isLoaded('sys_action')) {
287 $actionRecord=t3lib_BEfunc::getRecord('sys_action',abs($storeIndex));
288 if (is_array($actionRecord)) {
289 $dA = unserialize($actionRecord['t2_data']);
290 $dbSC=array();
291 if (is_array($dA['qC'])) {
292 $dbSC[0] = $dA['qC'];
293 }
294 $writeArray=$this->loadStoreQueryConfigs($dbSC,'0',$writeArray);
295 $saveStoreArray=1;
296 $acTitle=htmlspecialchars($actionRecord['title']);
297 $msg="Query from action '".$acTitle."' loaded!";
298 }
299 }
300 } elseif ($storeControl['SAVE']) {
301 if ($storeIndex<0) {
302 $qOK = $this->saveQueryInAction(abs($storeIndex));
303 if ($qOK) {
304 $msg='Query OK and saved.';
305 } else {
306 $msg='No query saved!';
307 }
308 } else {
309 if (trim($storeControl['title'])) {
310 if ($storeIndex>0) {
311 $storeArray[$storeIndex]=$storeControl['title'];
312 } else {
313 $storeArray[]=$storeControl['title'];
314 end($storeArray);
315 $storeIndex=key($storeArray);
316 }
317 $storeQueryConfigs=$this->addToStoreQueryConfigs($storeQueryConfigs,$storeIndex);
318 $saveStoreArray=1;
319 $msg="'".htmlspecialchars($storeArray[$storeIndex])."' query saved!";
320 }
321 }
322 } elseif ($storeControl['REMOVE']) {
323 if ($storeIndex>0) {
324 $msg="'".$storeArray[$storeControl['STORE']]."' query entry removed!";
325 unset($storeArray[$storeControl['STORE']]); // Removing
326 $saveStoreArray=1;
327 }
328 }
329 }
330 if ($saveStoreArray) {
331 unset($storeArray[0]); // making sure, index 0 is not set!
332 $writeArray['storeArray']=serialize($storeArray);
333 $writeArray['storeQueryConfigs']=serialize($this->cleanStoreQueryConfigs($storeQueryConfigs,$storeArray));
334 $GLOBALS['SOBE']->MOD_SETTINGS = t3lib_BEfunc::getModuleData($GLOBALS['SOBE']->MOD_MENU, $writeArray, $GLOBALS['SOBE']->MCONF['name'], 'ses');
335 }
336 return $msg;
337 }
338
339 /**
340 * [Describe function...]
341 *
342 * @return [type] ...
343 */
344 function queryMaker() {
345 global $TCA;
346
347 if (is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['t3lib_fullsearch'])) {
348 $this->hookArray = $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['t3lib_fullsearch'];
349 }
350 $msg=$this->procesStoreControl();
351
352 if (!$GLOBALS['BE_USER']->userTS['mod.']['dbint.']['disableStoreControl']) {
353 $output.= $GLOBALS['SOBE']->doc->section('Load/Save Query',$this->makeStoreControl(),0,1);
354 if ($msg) {
355 $output.= $GLOBALS['SOBE']->doc->section('','<font color=red><strong>'.$msg.'</strong></font>');
356 }
357 $output.= $GLOBALS['SOBE']->doc->spacer(20);
358 }
359
360
361 // Query Maker:
362 $qGen = t3lib_div::makeInstance('t3lib_queryGenerator');
363 $qGen->init('queryConfig',$GLOBALS['SOBE']->MOD_SETTINGS['queryTable']);
364 $tmpCode=$qGen->makeSelectorTable($GLOBALS['SOBE']->MOD_SETTINGS);
365 $output.= $GLOBALS['SOBE']->doc->section('Make query',$tmpCode,0,1);
366
367 $mQ = $GLOBALS['SOBE']->MOD_SETTINGS['search_query_makeQuery'];
368
369 // Make form elements:
370 if ($qGen->table && is_array($TCA[$qGen->table])) {
371 if ($mQ) {
372 // Show query
373 $qGen->enablePrefix=1;
374 $qString = $qGen->getQuery($qGen->queryConfig);
375 // debug($qGen->queryConfig);
376
377 switch($mQ) {
378 case 'count':
379 $qExplain = $GLOBALS['TYPO3_DB']->SELECTquery('count(*)', $qGen->table, $qString.t3lib_BEfunc::deleteClause($qGen->table));
380 break;
381 default:
382 $qExplain = $qGen->getSelectQuery($qString);
383 if ($mQ=='explain') {
384 $qExplain='EXPLAIN '.$qExplain;
385 }
386 break;
387 }
388
389 if (!$GLOBALS['BE_USER']->userTS['mod.']['dbint.']['disableShowSQLQuery']) {
390 $output.= $GLOBALS['SOBE']->doc->section('SQL query',$this->tableWrap(htmlspecialchars($qExplain)),0,1);
391 }
392
393 $res = @$GLOBALS['TYPO3_DB']->sql(TYPO3_db,$qExplain);
394 if ($GLOBALS['TYPO3_DB']->sql_error()) {
395 $out.='<BR><strong>Error:</strong><BR><font color="red"><strong>'.$GLOBALS['TYPO3_DB']->sql_error().'</strong></font>';
396 $output.= $GLOBALS['SOBE']->doc->section('SQL error',$out,0,1);
397 } else {
398 $cPR = $this->getQueryResultCode($mQ,$res,$qGen->table);
399 $output.=$GLOBALS['SOBE']->doc->section($cPR['header'],$cPR['content'],0,1);
400 }
401 }
402 }
403 return $output;
404 }
405
406 /**
407 * [Describe function...]
408 *
409 * @param [type] $mQ: ...
410 * @param [type] $res: ...
411 * @param [type] $table: ...
412 * @return [type] ...
413 */
414 function getQueryResultCode($mQ,$res,$table) {
415 global $TCA;
416 $output='';
417 $cPR=array();
418 switch($mQ) {
419 case 'count':
420 $row = $GLOBALS['TYPO3_DB']->sql_fetch_row($res);
421 $cPR['header']='Count';
422 $cPR['content']='<BR><strong>'.$row[0]. '</strong> records selected.';
423 break;
424 case 'all':
425 $rowArr=array();
426 while($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
427 $rowArr[]=$this->resultRowDisplay($row,$TCA[$table],$table);
428 $lrow=$row;
429 }
430 if (is_array($this->hookArray['beforeResultTable'])) {
431 foreach ($this->hookArray['beforeResultTable'] as $_funcRef) {
432 $out.=t3lib_div::callUserFunction($_funcRef, $GLOBALS['SOBE']->MOD_SETTINGS, $this);
433 }
434 }
435 if (count($rowArr)) {
436 $out.='<table border="0" cellpadding="2" cellspacing="1" width="100%">'.$this->resultRowTitles($lrow, $TCA[$table], $table).implode(chr(10), $rowArr).'</table>';
437 }
438 if (!$out) $out='<em>No rows selected!</em>';
439 $cPR['header']='Result';
440 $cPR['content']=$out;
441 break;
442 case 'csv':
443 $rowArr=array();
444 $first=1;
445 while($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
446 if ($first) {
447 $rowArr[]=$this->csvValues(array_keys($row),',','');
448 $first=0;
449 }
450 $rowArr[]=$this->csvValues($row, ',', '"', $TCA[$table], $table);
451 }
452 if (count($rowArr)) {
453 $out.='<textarea name="whatever" rows="20" wrap="off"'.$GLOBALS['SOBE']->doc->formWidthText($this->formW,'','off').' class="fixed-font">'.t3lib_div::formatForTextarea(implode(chr(10),$rowArr)).'</textarea>';
454 if (!$this->noDownloadB) {
455 $out.='<BR><input type="submit" name="download_file" value="Click to download file" onClick="window.location.href=\''.$this->downloadScript.'\';">'; // document.forms[0].target=\'_blank\';
456 }
457 // Downloads file:
458 if (t3lib_div::_GP('download_file')) {
459 $filename='TYPO3_'.$table.'_export_'.date('dmy-Hi').'.csv';
460 $mimeType = 'application/octet-stream';
461 header('Content-Type: '.$mimeType);
462 header('Content-Disposition: attachment; filename='.$filename);
463 echo implode(chr(13).chr(10),$rowArr);
464 exit;
465 }
466 }
467 if (!$out) $out='<em>No rows selected!</em>';
468 $cPR['header']='Result';
469 $cPR['content']=$out;
470 break;
471 case 'xml':
472 $className=t3lib_div::makeInstanceClassName('t3lib_xml');
473 $xmlObj = new $className('typo3_export');
474 $xmlObj->includeNonEmptyValues=1;
475 $xmlObj->renderHeader();
476 $first=1;
477 while($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
478 if ($first) {
479 $xmlObj->setRecFields($table,implode(',',array_keys($row)));
480 // debug($xmlObj->XML_recFields);
481 $first=0;
482 }
483 $valueArray = $row;
484 if ($GLOBALS['SOBE']->MOD_SETTINGS['search_result_labels']) {
485 foreach ($valueArray as $key => $val) {
486 $valueArray[$key] = $this->getProcessedValueExtra($table, $key, $val, $conf, ',');
487 }
488 }
489 $xmlObj->addRecord($table, $valueArray);
490 }
491 $xmlObj->renderFooter();
492 if ($GLOBALS['TYPO3_DB']->sql_num_rows($res)) {
493 $xmlData=$xmlObj->getResult();
494 $out.='<textarea name="whatever" rows="20" wrap="off"'.$GLOBALS['SOBE']->doc->formWidthText($this->formW,'','off').' class="fixed-font">'.t3lib_div::formatForTextarea($xmlData).'</textarea>';
495 if (!$this->noDownloadB) {
496 $out.='<BR><input type="submit" name="download_file" value="Click to download file" onClick="window.location.href=\''.$this->downloadScript.'\';">'; // document.forms[0].target=\'_blank\';
497 }
498 // Downloads file:
499 if (t3lib_div::_GP('download_file')) {
500 $filename='TYPO3_'.$table.'_export_'.date('dmy-Hi').'.xml';
501 $mimeType = 'application/octet-stream';
502 header('Content-Type: '.$mimeType);
503 header('Content-Disposition: attachment; filename='.$filename);
504 echo $xmlData;
505 exit;
506 }
507 }
508 if (!$out) $out='<em>No rows selected!</em>';
509 $cPR['header']='Result';
510 $cPR['content']=$out;
511 break;
512 case 'explain':
513 default:
514 while($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
515 $out.='<BR>'.t3lib_div::view_array($row);
516 }
517 $cPR['header']='Explain SQL query';
518 $cPR['content']=$out;
519 break;
520 }
521 return $cPR;
522 }
523
524 /**
525 * [Describe function...]
526 *
527 * @param [type] $row: ...
528 * @param [type] $delim: ...
529 * @param [type] $quote: ...
530 * @param [type] $conf: ...
531 * @param [type] $table: ...
532 * @return [type] ...
533 */
534 function csvValues($row, $delim=',', $quote='"', $conf=array(), $table='') {
535 $valueArray = $row;
536 if ($GLOBALS['SOBE']->MOD_SETTINGS['search_result_labels'] && $table) {
537 foreach ($valueArray as $key => $val) {
538 $valueArray[$key] = $this->getProcessedValueExtra($table, $key, $val, $conf, ';');
539 }
540 }
541 return t3lib_div::csvValues($valueArray, $delim, $quote);
542 }
543
544 /**
545 * [Describe function...]
546 *
547 * @param [type] $str: ...
548 * @return [type] ...
549 */
550 function tableWrap($str) {
551 return '<table border="0" cellpadding="10" cellspacing="0" class="bgColor4"><tr><td nowrap><pre>'.$str.'</pre></td></tr></table>';
552 }
553
554 /**
555 * [Describe function...]
556 *
557 * @return [type] ...
558 */
559 function search() {
560 global $TCA;
561 $SET = $GLOBALS['SOBE']->MOD_SETTINGS;
562 $swords = $SET['sword'];
563
564 $limit=200;
565 $showAlways=0;
566 if ($swords) {
567 reset($TCA);
568 while(list($table)=each($TCA)) {
569 // Get fields list
570 t3lib_div::loadTCA($table);
571 $conf=$TCA[$table];
572
573 reset($conf['columns']);
574 $list=array();
575 while(list($field,)=each($conf['columns'])) {
576 $list[]=$field;
577 }
578 // Get query
579 $qp = $GLOBALS['TYPO3_DB']->searchQuery(array($swords), $list, $table);
580
581 // Count:
582 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('count(*)', $table, $qp.t3lib_BEfunc::deleteClause($table));
583 list($count) = $GLOBALS['TYPO3_DB']->sql_fetch_row($res);
584 if($count || $showAlways) {
585 // Output header:
586 $out.='<strong>TABLE:</strong> '.$GLOBALS['LANG']->sL($conf['ctrl']['title']).'<BR>';
587 $out.='<strong>Results:</strong> '.$count.'<BR>';
588
589 // Show to limit
590 if ($count) {
591 $rowArr = array();
592 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid,'.$conf['ctrl']['label'], $table, $qp.t3lib_BEfunc::deleteClause($table), '', '', $limit);
593 while($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
594 $rowArr[]=$this->resultRowDisplay($row,$conf,$table);
595 $lrow=$row;
596 }
597 $out.='<table border="0" cellpadding="2" cellspacing="1">'.$this->resultRowTitles($lrow,$conf,$table).implode(chr(10),$rowArr).'</table>';
598 }
599 $out.='<HR>';
600 }
601 }
602 }
603 return $out;
604 }
605
606 /**
607 * [Describe function...]
608 *
609 * @param [type] $row: ...
610 * @param [type] $conf: ...
611 * @param [type] $table: ...
612 * @return [type] ...
613 */
614 function resultRowDisplay($row,$conf,$table) {
615 $tce = t3lib_div::makeInstance('t3lib_TCEmain');
616 $SET = $GLOBALS['SOBE']->MOD_SETTINGS;
617 $out='<tr class="bgColor4">';
618 reset($row);
619 while(list($fN,$fV)=each($row)) {
620 if (t3lib_div::inList($SET['queryFields'], $fN) || (!$SET['queryFields'] && $fN!='pid' && $fN!='deleted')) {
621 if ($SET['search_result_labels']) {
622 $fVnew = $this->getProcessedValueExtra($table, $fN, $fV, $conf, '<br />');
623 } else {
624 $fVnew = $fV;
625 }
626 $out.='<td'.$TDparams.'>'.$fVnew.'</td>';
627 }
628 }
629 $params = '&edit['.$table.']['.$row['uid'].']=edit';
630 $out.='<td nowrap>';
631 if (!$row['deleted']) {
632 $out .= '<a href="#" onClick="top.launchView(\''.$table.'\','.$row['uid'].',\''.$GLOBALS['BACK_PATH'].'\');return false;"><img src="'.$GLOBALS['BACK_PATH'].'gfx/zoom2.gif" width="12" height="12" alt="" /></a>';
633 $out .= '<a href="#" onClick="'.t3lib_BEfunc::editOnClick($params, $GLOBALS['BACK_PATH'], t3lib_div::getIndpEnv('REQUEST_URI').t3lib_div::implodeArrayForUrl('SET', t3lib_div::_POST('SET'))).'"><img src="'.$GLOBALS['BACK_PATH'].'gfx/edit2.gif" width="11" height="12" border="0" alt=""></a>';
634 } else {
635 $out.= '<a href="'.t3lib_div::linkThisUrl($GLOBALS['BACK_PATH'].'tce_db.php', array('cmd['.$table.']['.$row['uid'].'][undelete]' => '1', 'redirect' => t3lib_div::linkThisScript(array()))).'">';
636 $out.= '<img src="'.$GLOBALS['BACK_PATH'].'gfx/undelete.gif" width="13" height="12" border="0" alt="undelete" only></A>';
637 $out.= '<a href="'.t3lib_div::linkThisUrl($GLOBALS['BACK_PATH'].'tce_db.php', array('cmd['.$table.']['.$row['uid'].'][undelete]' => '1', 'redirect' => t3lib_div::linkThisUrl('alt_doc.php', array('edit['.$table.']['.$row['uid'].']' => 'edit', 'returnUrl' => t3lib_div::linkThisScript(array()))))).'">';
638 $out.= '<img src="'.$GLOBALS['BACK_PATH'].'gfx/undelete_and_edit.gif" width="13" height="12" border="0" alt="undelete and edit">';
639 }
640 $_params = array($table=>$row);
641 if (is_array($this->hookArray['additionalButtons'])) {
642 foreach ($this->hookArray['additionalButtons'] as $_funcRef) {
643 $out.=t3lib_div::callUserFunction($_funcRef, $_params, $this);
644 }
645 }
646 $out.='</td>
647 </tr>
648 ';
649 return $out;
650 }
651
652 /**
653 * [Describe function...]
654 *
655 * @param [type] $table: ...
656 * @param [type] $fN: ...
657 * @param [type] $fV: ...
658 * @param [type] $conf: ...
659 * @param [type] $splitString: ...
660 * @return [type] ...
661 */
662 function getProcessedValueExtra($table, $fN, $fV, $conf, $splitString) {
663 global $TCA;
664 // Analysing the fields in the table.
665 if (is_array($TCA[$table])) {
666 t3lib_div::loadTCA($table);
667 $fC = $TCA[$table]['columns'][$fN];
668 $fields = $fC['config'];
669 $fields['exclude'] = $fC['exclude'];
670 if (is_array($fC) && $fC['label']) {
671 $fields['label'] = ereg_replace(":$", '', trim($GLOBALS['LANG']->sL($fC['label'])));
672
673 switch ($fields['type']) {
674 case 'input':
675 if (eregi('int|year', $fields['eval'])) {
676 $fields['type'] = 'number';
677 } elseif (eregi('time', $fields['eval'])) {
678 $fields['type'] = 'time';
679 } elseif (eregi('date', $fields['eval'])) {
680 $fields['type'] = 'date';
681 } else {
682 $fields['type'] = 'text';
683 }
684 break;
685 case 'check':
686 if (!$fields['items']) {
687 $fields['type'] = 'boolean';
688 } else {
689 $fields['type'] = 'binary';
690 }
691 break;
692 case 'radio':
693 $fields['type'] = 'multiple';
694 break;
695 case 'select':
696 $fields['type'] = 'multiple';
697 if ($fields['foreign_table']) {
698 $fields['type'] = 'relation';
699 }
700 if ($fields['special']) {
701 $fields['type'] = 'text';
702 }
703 break;
704 case 'group':
705 $fields['type'] = 'files';
706 if ($fields['internal_type']=='db') {
707 $fields['type'] = 'relation';
708 }
709 break;
710 case 'user':
711 case 'flex':
712 case 'passthrough':
713 case 'none':
714 case 'text':
715 default:
716 $fields['type'] = 'text';
717 break;
718 }
719 } else {
720 $fields['label'] = '[FIELD: '.$fN.']';
721 switch ($fN) {
722 case 'pid':
723 $fields['type'] = 'relation';
724 $fields['allowed'] = 'pages';
725 break;
726 case 'cruser_id':
727 $fields['type'] = 'relation';
728 $fields['allowed'] = 'be_users';
729 break;
730 case 'tstamp':
731 case 'crdate':
732 $fields['type'] = 'time';
733 break;
734 default:
735 $fields['type'] = 'number';
736 break;
737 }
738 }
739 }
740
741 switch ($fields['type']) {
742 case 'date':
743 if ($fV != -1) {
744 $out = strftime('%e-%m-%Y', $fV);
745 }
746 break;
747 case 'time':
748 if ($fV != -1) {
749 if ($splitString=='<br />') {
750 $out = strftime('%H:%M'.$splitString.'%e-%m-%Y', $fV);
751 } else {
752 $out = strftime('%H:%M %e-%m-%Y', $fV);
753 }
754 }
755 break;
756 case 'multiple':
757 case 'binary':
758 case 'relation':
759 $out = $this->makeValueList($fN, $fV, $fields, $table, $splitString);
760 break;
761 case 'boolean':
762 $out = $fV ? 'True' : 'False';
763 break;
764 case 'files':
765 default:
766 $out = htmlspecialchars($fV);
767 break;
768 }
769 return $out;
770 }
771
772 /*
773 * [Describe function...]
774 *
775 * @param [type] $qString: ...
776 * @param [type] $depth: ...
777 * @param [type] $begin: ...
778 * @param [type] $perms_clause: ...
779 * @return [type] ...
780 */
781 function getTreeList($id, $depth, $begin = 0, $perms_clause) {
782 $depth = intval($depth);
783 $begin = intval($begin);
784 $id = intval($id);
785 if ($begin == 0) {
786 $theList = $id;
787 } else {
788 $theList = '';
789 }
790 if ($id && $depth > 0) {
791 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
792 'uid',
793 'pages',
794 'pid='.$id.' '.t3lib_BEfunc::deleteClause('pages').' AND '.$perms_clause
795 );
796 while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
797 if ($begin <= 0) {
798 $theList .= ','.$row['uid'];
799 }
800 if ($depth > 1) {
801 $theList .= $this->getTreeList($row['uid'], $depth-1, $begin-1, $perms_clause);
802 }
803 }
804 }
805 return $theList;
806 }
807
808 /**
809 * [Describe function...]
810 *
811 * @param [type] $fN: ...
812 * @param [type] $fV: ...
813 * @param [type] $conf: ...
814 * @param [type] $table: ...
815 * @param [type] $splitString: ...
816 * @return [type] ...
817 */
818 function makeValueList($fN, $fV, $conf, $table, $splitString) {
819 $fieldSetup = $conf;
820 if ($fieldSetup['type'] == 'files') {
821 $d = dir(t3lib_div::getIndpEnv(TYPO3_DOCUMENT_ROOT).'/'.$fieldSetup['uploadfolder']);
822 while (false !== ($entry = $d->read())) {
823 if ($entry == '.' || $entry == '..') {
824 continue;
825 }
826 $fileArray[] = $entry;
827 }
828 $d->close();
829 natcasesort($fileArray);
830 while (list(, $fileName) = each($fileArray)) {
831 if (t3lib_div::inList($fV, $fileName) || $fV == $fileName) {
832 if (!$out) {
833 $out = htmlspecialchars($fileName);
834 } else {
835 $out .= $splitString.htmlspecialchars($fileName);
836 }
837 }
838 }
839 }
840 if ($fieldSetup['type'] == 'multiple') {
841 foreach ($fieldSetup['items'] as $key => $val) {
842 if (substr($val[0], 0, 4) == 'LLL:') {
843 $value = $GLOBALS['LANG']->sL($val[0]);
844 } else {
845 $value = $val[0];
846 }
847 if (t3lib_div::inList($fV, $val[1]) || $fV == $val[1]) {
848 if (!$out) {
849 $out = htmlspecialchars($value);
850 } else {
851 $out .= $splitString.htmlspecialchars($value);
852 }
853 }
854 }
855 }
856 if ($fieldSetup['type'] == 'binary') {
857 foreach($fieldSetup['items'] as $Key => $val) {
858 if (substr($val[0], 0, 4) == 'LLL:') {
859 $value = $GLOBALS['LANG']->sL($val[0]);
860 } else {
861 $value = $val[0];
862 }
863 if (!$out) {
864 $out = htmlspecialchars($value);
865 } else {
866 $out .= $splitString.htmlspecialchars($value);
867 }
868 }
869 }
870 if ($fieldSetup['type']=='relation') {
871 if ($fieldSetup['items']) {
872 foreach($fieldSetup['items'] as $key => $val) {
873 if (substr($val[0], 0, 4) == 'LLL:') {
874 $value = $GLOBALS['LANG']->sL($val[0]);
875 } else {
876 $value = $val[0];
877 }
878 if (t3lib_div::inList($fV, $value) || $fV == $value) {
879 if (!$out) {
880 $out = htmlspecialchars($value);
881 } else {
882 $out .= $splitString.htmlspecialchars($value);
883 }
884 }
885 }
886 }
887 global $TCA;
888 if (stristr($fieldSetup['allowed'], ',')) {
889 $from_table_Arr = explode(',', $fieldSetup['allowed']);
890 $useTablePrefix = 1;
891 if (!$fieldSetup['prepend_tname']) {
892 $checkres = $GLOBALS['TYPO3_DB']->exec_SELECTquery($fN, $table, 'uid '.t3lib_BEfunc::deleteClause($table), $groupBy = '', $orderBy = '', $limit = '');
893 if ($checkres) {
894 while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($checkres)) {
895 if (stristr($row[$fN], ',')) {
896 $checkContent = explode(',', $row[$fN]);
897 foreach($checkContent as $singleValue) {
898 if (!stristr($singleValue, '_')) {
899 $dontPrefixFirstTable = 1;
900 }
901 }
902 } else {
903 $singleValue = $row[$fN];
904 if (strlen($singleValue) && !stristr($singleValue, '_')) {
905 $dontPrefixFirstTable = 1;
906 }
907 }
908 }
909 }
910 }
911 } else {
912 $from_table_Arr[0] = $fieldSetup['allowed'];
913 }
914 if ($fieldSetup['prepend_tname']) {
915 $useTablePrefix = 1;
916 }
917 if ($fieldSetup['foreign_table']) {
918 $from_table_Arr[0] = $fieldSetup['foreign_table'];
919 }
920 $counter = 0;
921 foreach($from_table_Arr as $from_table) {
922 if (($useTablePrefix && !$dontPrefixFirstTable && $counter != 1) || $counter == 1) {
923 $tablePrefix = $from_table.'_';
924 }
925 $counter = 1;
926 if (is_array($TCA[$from_table])) {
927 t3lib_div::loadTCA($from_table);
928 $labelField = $TCA[$from_table]['ctrl']['label'];
929 $altLabelField = $TCA[$from_table]['ctrl']['label_alt'];
930 if ($TCA[$from_table]['columns'][$labelField]['config']['items']) {
931 reset($TCA[$from_table]['columns'][$labelField]['config']['items']);
932 while (list(, $labelArray) = each($TCA[$from_table]['columns'][$labelField]['config']['items'])) {
933 if (substr($labelArray[0], 0, 4) == 'LLL:') {
934 $labelFieldSelect[$labelArray[1]] = $GLOBALS['LANG']->sL($labelArray[0]);
935 } else {
936 $labelFieldSelect[$labelArray[1]] = $labelArray[0];
937 }
938 }
939 $useSelectLabels = 1;
940 }
941 if ($TCA[$from_table]['columns'][$altLabelField]['config']['items']) {
942 reset($TCA[$from_table]['columns'][$altLabelField]['config']['items']);
943 foreach($TCA[$from_table]['columns'][$altLabelField]['config']['items'] as $altLabelArray) {
944 if (substr($altLabelArray[0], 0, 4) == 'LLL:') {
945 $altLabelFieldSelect[$altLabelArray[1]] = $GLOBALS['LANG']->sL($altLabelArray[0]);
946 } else {
947 $altLabelFieldSelect[$altLabelArray[1]] = $altLabelArray[0];
948 }
949 }
950 $useAltSelectLabels = 1;
951 }
952 $altLabelFieldSelect = $altLabelField ? ','.$altLabelField : '';
953 $select_fields = 'uid,'.$labelField.$altLabelFieldSelect;
954 if (!$GLOBALS['BE_USER']->isAdmin() && $GLOBALS['TYPO3_CONF_VARS']['BE']['lockBeUserToDBmounts']) {
955 $webMounts = $GLOBALS['BE_USER']->returnWebmounts();
956 $perms_clause = $GLOBALS['BE_USER']->getPagePermsClause(1);
957 foreach($webMounts as $key => $val) {
958 if ($webMountPageTree) {
959 $webMountPageTreePrefix = ',';
960 }
961 $webMountPageTree .= $webMountPageTreePrefix.$this->getTreeList($val, 999, $begin = 0, $perms_clause);
962 }
963 if ($from_table == 'pages') {
964 $where_clause = 'uid IN ('.$webMountPageTree.') '.t3lib_BEfunc::deleteClause($from_table).' AND '.$perms_clause;
965 } else {
966 $where_clause = 'pid IN ('.$webMountPageTree.') '.t3lib_BEfunc::deleteClause($from_table);
967 }
968 } else {
969 $where_clause = 'uid'.t3lib_BEfunc::deleteClause($from_table);
970 }
971 $orderBy = 'uid';
972 if (!$this->tableArray[$from_table]) {
973 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery($select_fields, $from_table, $where_clause, $groupBy = '', $orderBy, $limit = '');
974 $this->tableArray[$from_table] = array();
975 }
976 if ($res) {
977 while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
978 $this->tableArray[$from_table][] = $row;
979 }
980 }
981 reset($this->tableArray[$from_table]);
982 foreach ($this->tableArray[$from_table] as $key => $val) {
983 $GLOBALS['SOBE']->MOD_SETTINGS['labels_noprefix'] = $GLOBALS['SOBE']->MOD_SETTINGS['labels_noprefix'] == 1 ? 'on' :
984 $GLOBALS['SOBE']->MOD_SETTINGS['labels_noprefix'];
985 $prefixString = $GLOBALS['SOBE']->MOD_SETTINGS['labels_noprefix'] == 'on' ? '' : ' ['.$tablePrefix.$val['uid'].'] ';
986 if (t3lib_div::inList($fV, $tablePrefix.$val['uid']) || $fV == $tablePrefix.$val['uid']) {
987 if ($useSelectLabels) {
988 if (!$out) {
989 $out = htmlspecialchars($prefixString.$labelFieldSelect[$val[$labelField]]);
990 } else {
991 $out .= $splitString.htmlspecialchars($prefixString.$labelFieldSelect[$val[$labelField]]);
992 }
993 } elseif ($val[$labelField]) {
994 if (!$out) {
995 $out = htmlspecialchars($prefixString.$val[$labelField]);
996 } else {
997 $out .= $splitString.htmlspecialchars($prefixString.$val[$labelField]);
998 }
999 } elseif ($useAltSelectLabels) {
1000 if (!$out) {
1001 $out = htmlspecialchars($prefixString.$altLabelFieldSelect[$val[$altLabelField]]);
1002 } else {
1003 $out .= $splitString.htmlspecialchars($prefixString.$altLabelFieldSelect[$val[$altLabelField]]);
1004 }
1005 } else {
1006 if (!$out) {
1007 $out = htmlspecialchars($prefixString.$val[$altLabelField]);
1008 } else {
1009 $out .= $splitString.htmlspecialchars($prefixString.$val[$altLabelField]);
1010 }
1011 }
1012 }
1013 }
1014 }
1015 }
1016 }
1017 return $out;
1018 }
1019
1020 /**
1021 * [Describe function...]
1022 *
1023 * @param [type] $row: ...
1024 * @param [type] $conf: ...
1025 * @param [type] $table: ...
1026 * @return [type] ...
1027 */
1028 function resultRowTitles($row,$conf,$table) {
1029 $SET = $GLOBALS['SOBE']->MOD_SETTINGS;
1030 $out='<tr class="bgColor5">';
1031 reset($row);
1032 while(list($fN,$fV)=each($row)) {
1033 if (t3lib_div::inList($SET['queryFields'], $fN) || (!$SET['queryFields'] && $fN!='pid' && $fN!='deleted')) {
1034 if (strlen($fV) < 50) $TDparams = ' nowrap';
1035 else $TDparams = '';
1036
1037 if ($GLOBALS['SOBE']->MOD_SETTINGS['search_result_labels']) {
1038 $out.='<td'.$TDparams.'><strong>'.$GLOBALS['LANG']->sL($conf['columns'][$fN]['label']?$conf['columns'][$fN]['label']:$fN,1).'</strong></td>';
1039 } else {
1040 $out.='<td'.$TDparams.'><strong>'.$GLOBALS['LANG']->sL($fN, 1).'</strong></td>';
1041 }
1042 }
1043 }
1044 $out.='<td nowrap></td>
1045 </tr>
1046 ';
1047 return $out;
1048 }
1049
1050 /**
1051 * [Describe function...]
1052 *
1053 * @param [type] $row: ...
1054 * @param [type] $conf: ...
1055 * @param [type] $table: ...
1056 * @return [type] ...
1057 */
1058 function csvRowTitles($row, $conf, $table) {
1059 $SET = $GLOBALS['SOBE']->MOD_SETTINGS;
1060 foreach ($row as $fN => $fV) {
1061 if (t3lib_div::inList($SET['queryFields'], $fN) || (!$SET['queryFields'] && $fN!='pid')) {
1062 if (!$out) {
1063 if ($GLOBALS['SOBE']->MOD_SETTINGS['search_result_labels']) {
1064 $out = $GLOBALS['LANG']->sL($conf['columns'][$fN]['label']?$conf['columns'][$fN]['label']:$fN, 1);
1065 } else {
1066 $out = $GLOBALS['LANG']->sL($fN, 1);
1067 }
1068 } else {
1069 if ($GLOBALS['SOBE']->MOD_SETTINGS['search_result_labels']) {
1070 $out.= ','.$GLOBALS['LANG']->sL($conf['columns'][$fN]['label']?$conf['columns'][$fN]['label']:$fN, 1);
1071 } else {
1072 $out.= ','.$GLOBALS['LANG']->sL($fN, 1);
1073 }
1074 }
1075 }
1076 }
1077 return $out;
1078 }
1079 }
1080
1081 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_fullsearch.php']) {
1082 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_fullsearch.php']);
1083 }
1084 ?>