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