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