TYPO3  7.6
QueryView.php
Go to the documentation of this file.
1 <?php
2 namespace TYPO3\CMS\Core\Database;
3 
4 /*
5  * This file is part of the TYPO3 CMS project.
6  *
7  * It is free software; you can redistribute it and/or modify it under
8  * the terms of the GNU General Public License, either version 2
9  * of the License, or any later version.
10  *
11  * For the full copyright and license information, please read the
12  * LICENSE.txt file that was distributed with this source code.
13  *
14  * The TYPO3 project - inspiring people to share!
15  */
16 
21 
26 class QueryView
27 {
31  public $storeList = 'search_query_smallparts,search_result_labels,labels_noprefix,show_deleted,queryConfig,queryTable,queryFields,queryLimit,queryOrder,queryOrderDesc,queryOrder2,queryOrder2Desc,queryGroup,search_query_makeQuery';
32 
36  public $downloadScript = 'index.php';
37 
41  public $formW = 48;
42 
46  public $noDownloadB = 0;
47 
51  public $hookArray = array();
52 
56  protected $formName = '';
57 
61  protected $iconFactory;
62 
66  public function __construct()
67  {
68  $GLOBALS['LANG']->includeLLFile('EXT:lang/locallang_t3lib_fullsearch.xlf');
69  $this->iconFactory = GeneralUtility::makeInstance(IconFactory::class);
70  }
71 
77  public function form()
78  {
79  return '
80  <div class="form-group">
81  <input placeholder="Search Word" class="form-control" type="search" name="SET[sword]" value="' . htmlspecialchars($GLOBALS['SOBE']->MOD_SETTINGS['sword']) . '">
82  </div>
83  <div class="form-group">
84  <input class="btn btn-default" type="submit" name="submit" value="Search All Records">
85  </div>
86  ';
87  }
88 
94  public function makeStoreControl()
95  {
96  // Load/Save
97  $storeArray = $this->initStoreArray();
98 
99  $opt = array();
100  foreach ($storeArray as $k => $v) {
101  $opt[] = '<option value="' . $k . '">' . htmlspecialchars($v) . '</option>';
102  }
103  // Actions:
104  if (\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::isLoaded('sys_action') && $GLOBALS['BE_USER']->isAdmin()) {
105  $rows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('*', 'sys_action', 'type=2', '', 'title');
106  $opt[] = '<option value="0">__Save to Action:__</option>';
107  foreach ($rows as $row) {
108  $opt[] = '<option value="-' . $row['uid'] . '">' . htmlspecialchars(($row['title'] . ' [' . $row['uid'] . ']')) . '</option>';
109  }
110  }
111  return '<div class="load-queries">
112  <div class="form-inline">
113  <div class="form-group">
114  <select class="form-control" 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>
115  <input class="btn btn-default" type="submit" name="storeControl[LOAD]" value="Load">
116  </div>
117  </div>
118  <div class="form-inline">
119  <div class="form-group">
120  <input name="storeControl[title]" value="" type="text" max="80" class="form-control">
121  <input class="btn btn-default" 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?\');">
122  <input class="btn btn-default" type="submit" name="storeControl[REMOVE]" value="Remove">
123  </div>
124  </div>
125  </div>';
126  }
127 
133  public function initStoreArray()
134  {
135  $storeArray = array(
136  '0' => '[New]'
137  );
138  $savedStoreArray = unserialize($GLOBALS['SOBE']->MOD_SETTINGS['storeArray']);
139  if (is_array($savedStoreArray)) {
140  $storeArray = array_merge($storeArray, $savedStoreArray);
141  }
142  return $storeArray;
143  }
144 
152  public function cleanStoreQueryConfigs($storeQueryConfigs, $storeArray)
153  {
154  if (is_array($storeQueryConfigs)) {
155  foreach ($storeQueryConfigs as $k => $v) {
156  if (!isset($storeArray[$k])) {
157  unset($storeQueryConfigs[$k]);
158  }
159  }
160  }
161  return $storeQueryConfigs;
162  }
163 
171  public function addToStoreQueryConfigs($storeQueryConfigs, $index)
172  {
173  $keyArr = explode(',', $this->storeList);
174  $storeQueryConfigs[$index] = array();
175  foreach ($keyArr as $k) {
176  $storeQueryConfigs[$index][$k] = $GLOBALS['SOBE']->MOD_SETTINGS[$k];
177  }
178  return $storeQueryConfigs;
179  }
180 
187  public function saveQueryInAction($uid)
188  {
189  if (\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::isLoaded('sys_action')) {
190  $keyArr = explode(',', $this->storeList);
191  $saveArr = array();
192  foreach ($keyArr as $k) {
193  $saveArr[$k] = $GLOBALS['SOBE']->MOD_SETTINGS[$k];
194  }
195  $qOK = 0;
196  // Show query
197  if ($saveArr['queryTable']) {
199  $qGen = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Database\QueryGenerator::class);
200  $qGen->init('queryConfig', $saveArr['queryTable']);
201  $qGen->makeSelectorTable($saveArr);
202  $qGen->enablePrefix = 1;
203  $qString = $qGen->getQuery($qGen->queryConfig);
204  $qCount = $GLOBALS['TYPO3_DB']->SELECTquery('count(*)', $qGen->table, $qString . BackendUtility::deleteClause($qGen->table));
205  $qSelect = $qGen->getSelectQuery($qString);
206  $res = @$GLOBALS['TYPO3_DB']->sql_query($qCount);
207  if (!$GLOBALS['TYPO3_DB']->sql_error()) {
208  $GLOBALS['TYPO3_DB']->sql_free_result($res);
209  $dA = array();
210  $dA['t2_data'] = serialize(array(
211  'qC' => $saveArr,
212  'qCount' => $qCount,
213  'qSelect' => $qSelect,
214  'qString' => $qString
215  ));
216  $GLOBALS['TYPO3_DB']->exec_UPDATEquery('sys_action', 'uid=' . (int)$uid, $dA);
217  $qOK = 1;
218  }
219  }
220  return $qOK;
221  }
222  }
223 
232  public function loadStoreQueryConfigs($storeQueryConfigs, $storeIndex, $writeArray)
233  {
234  if ($storeQueryConfigs[$storeIndex]) {
235  $keyArr = explode(',', $this->storeList);
236  foreach ($keyArr as $k) {
237  $writeArray[$k] = $storeQueryConfigs[$storeIndex][$k];
238  }
239  }
240  return $writeArray;
241  }
242 
248  public function procesStoreControl()
249  {
250  $storeArray = $this->initStoreArray();
251  $storeQueryConfigs = unserialize($GLOBALS['SOBE']->MOD_SETTINGS['storeQueryConfigs']);
252  $storeControl = GeneralUtility::_GP('storeControl');
253  $storeIndex = (int)$storeControl['STORE'];
254  $saveStoreArray = 0;
255  $writeArray = array();
256  if (is_array($storeControl)) {
257  $msg = '';
258  if ($storeControl['LOAD']) {
259  if ($storeIndex > 0) {
260  $writeArray = $this->loadStoreQueryConfigs($storeQueryConfigs, $storeIndex, $writeArray);
261  $saveStoreArray = 1;
262  $flashMessage = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Messaging\FlashMessage::class, sprintf($GLOBALS['LANG']->getLL('query_loaded'), htmlspecialchars($storeArray[$storeIndex])));
263  } elseif ($storeIndex < 0 && \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::isLoaded('sys_action')) {
264  $actionRecord = BackendUtility::getRecord('sys_action', abs($storeIndex));
265  if (is_array($actionRecord)) {
266  $dA = unserialize($actionRecord['t2_data']);
267  $dbSC = array();
268  if (is_array($dA['qC'])) {
269  $dbSC[0] = $dA['qC'];
270  }
271  $writeArray = $this->loadStoreQueryConfigs($dbSC, '0', $writeArray);
272  $saveStoreArray = 1;
273  $flashMessage = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Messaging\FlashMessage::class, sprintf($GLOBALS['LANG']->getLL('query_from_action_loaded'), htmlspecialchars($actionRecord['title'])));
274  }
275  }
276  } elseif ($storeControl['SAVE']) {
277  if ($storeIndex < 0) {
278  $qOK = $this->saveQueryInAction(abs($storeIndex));
279  if ($qOK) {
280  $flashMessage = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Messaging\FlashMessage::class, $GLOBALS['LANG']->getLL('query_saved'));
281  } else {
282  $flashMessage = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Messaging\FlashMessage::class, $GLOBALS['LANG']->getLL('query_notsaved'), '', \TYPO3\CMS\Core\Messaging\FlashMessage::ERROR);
283  }
284  } else {
285  if (trim($storeControl['title'])) {
286  if ($storeIndex > 0) {
287  $storeArray[$storeIndex] = $storeControl['title'];
288  } else {
289  $storeArray[] = $storeControl['title'];
290  end($storeArray);
291  $storeIndex = key($storeArray);
292  }
293  $storeQueryConfigs = $this->addToStoreQueryConfigs($storeQueryConfigs, $storeIndex);
294  $saveStoreArray = 1;
295  $flashMessage = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Messaging\FlashMessage::class, $GLOBALS['LANG']->getLL('query_saved'));
296  }
297  }
298  } elseif ($storeControl['REMOVE']) {
299  if ($storeIndex > 0) {
300  $flashMessage = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Messaging\FlashMessage::class, sprintf($GLOBALS['LANG']->getLL('query_removed'), htmlspecialchars($storeArray[$storeControl['STORE']])));
301  // Removing
302  unset($storeArray[$storeControl['STORE']]);
303  $saveStoreArray = 1;
304  }
305  }
306  if ($flashMessage) {
307  $msg = $flashMessage->render();
308  }
309  }
310  if ($saveStoreArray) {
311  // Making sure, index 0 is not set!
312  unset($storeArray[0]);
313  $writeArray['storeArray'] = serialize($storeArray);
314  $writeArray['storeQueryConfigs'] = serialize($this->cleanStoreQueryConfigs($storeQueryConfigs, $storeArray));
315  $GLOBALS['SOBE']->MOD_SETTINGS = BackendUtility::getModuleData($GLOBALS['SOBE']->MOD_MENU, $writeArray, $GLOBALS['SOBE']->MCONF['name'], 'ses');
316  }
317  return $msg;
318  }
319 
325  public function queryMaker()
326  {
327  $output = '';
328  if (is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['t3lib_fullsearch'])) {
329  $this->hookArray = $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['t3lib_fullsearch'];
330  }
331  $msg = $this->procesStoreControl();
332  if (!$GLOBALS['BE_USER']->userTS['mod.']['dbint.']['disableStoreControl']) {
333  $output .= '<h2>Load/Save Query</h2><div>' . $this->makeStoreControl() . '</div>';
334  if ($msg) {
335  $output .= '<br />' . $msg;
336  }
337  $output .= '<div style="padding-top: 20px;"></div>';
338  }
339  // Query Maker:
340  $qGen = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Database\QueryGenerator::class);
341  $qGen->init('queryConfig', $GLOBALS['SOBE']->MOD_SETTINGS['queryTable']);
342  if ($this->formName) {
343  $qGen->setFormName($this->formName);
344  }
345  $tmpCode = $qGen->makeSelectorTable($GLOBALS['SOBE']->MOD_SETTINGS);
346  $output .= '<div id="query"></div>' . '<h2>Make query</h2><div>' . $tmpCode . '</div>';
347  $mQ = $GLOBALS['SOBE']->MOD_SETTINGS['search_query_makeQuery'];
348  // Make form elements:
349  if ($qGen->table && is_array($GLOBALS['TCA'][$qGen->table])) {
350  if ($mQ) {
351  // Show query
352  $qGen->enablePrefix = 1;
353  $qString = $qGen->getQuery($qGen->queryConfig);
354  switch ($mQ) {
355  case 'count':
356  $qExplain = $GLOBALS['TYPO3_DB']->SELECTquery('count(*)', $qGen->table, $qString . BackendUtility::deleteClause($qGen->table));
357  break;
358  default:
359  $qExplain = $qGen->getSelectQuery($qString);
360  if ($mQ == 'explain') {
361  $qExplain = 'EXPLAIN ' . $qExplain;
362  }
363  }
364  if (!$GLOBALS['BE_USER']->userTS['mod.']['dbint.']['disableShowSQLQuery']) {
365  $output .= '<h2>SQL query</h2><div>' . $this->tableWrap(htmlspecialchars($qExplain)) . '</div>';
366  }
367  $res = @$GLOBALS['TYPO3_DB']->sql_query($qExplain);
368  if ($GLOBALS['TYPO3_DB']->sql_error()) {
369  $out = '<BR><strong>Error:</strong><BR><font color="red"><strong>' . $GLOBALS['TYPO3_DB']->sql_error() . '</strong></font>';
370  $output .= '<h2>SQL error</h2><div>' . $out . '</div>';
371  } else {
372  $cPR = $this->getQueryResultCode($mQ, $res, $qGen->table);
373  $GLOBALS['TYPO3_DB']->sql_free_result($res);
374  $output .= '<h2>' . $cPR['header'] . '</h2><div>' . $cPR['content'] . '</div>';
375  }
376  }
377  }
378  return '<div class="query-builder">' . $output . '</div>';
379  }
380 
389  public function getQueryResultCode($mQ, $res, $table)
390  {
391  $out = '';
392  $cPR = array();
393  switch ($mQ) {
394  case 'count':
395  $row = $GLOBALS['TYPO3_DB']->sql_fetch_row($res);
396  $cPR['header'] = 'Count';
397  $cPR['content'] = '<BR><strong>' . $row[0] . '</strong> records selected.';
398  break;
399  case 'all':
400  $rowArr = array();
401  while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
402  $rowArr[] = $this->resultRowDisplay($row, $GLOBALS['TCA'][$table], $table);
403  $lrow = $row;
404  }
405  if (is_array($this->hookArray['beforeResultTable'])) {
406  foreach ($this->hookArray['beforeResultTable'] as $_funcRef) {
407  $out .= GeneralUtility::callUserFunction($_funcRef, $GLOBALS['SOBE']->MOD_SETTINGS, $this);
408  }
409  }
410  if (!empty($rowArr)) {
411  $out .= '<table class="table table-striped table-hover">' . $this->resultRowTitles($lrow, $GLOBALS['TCA'][$table], $table) . implode(LF, $rowArr) . '</table>';
412  }
413  if (!$out) {
414  $out = '<div class="alert-info">No rows selected!</div>';
415  }
416  $cPR['header'] = 'Result';
417  $cPR['content'] = $out;
418  break;
419  case 'csv':
420  $rowArr = array();
421  $first = 1;
422  while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
423  if ($first) {
424  $rowArr[] = $this->csvValues(array_keys($row), ',', '');
425  $first = 0;
426  }
427  $rowArr[] = $this->csvValues($row, ',', '"', $GLOBALS['TCA'][$table], $table);
428  }
429  if (!empty($rowArr)) {
430  $out .= '<textarea name="whatever" rows="20" wrap="off"' . $GLOBALS['SOBE']->getModuleTemplate()->formWidth($this->formW) . ' class="text-monospace">' . htmlspecialchars(implode(LF, $rowArr)) . '</textarea>';
431  if (!$this->noDownloadB) {
432  $out .= '<br><input class="btn btn-default" type="submit" name="download_file" value="Click to download file" onClick="window.location.href=\'' . $this->downloadScript . '\';">';
433  }
434  // Downloads file:
435  if (GeneralUtility::_GP('download_file')) {
436  $filename = 'TYPO3_' . $table . '_export_' . date('dmy-Hi') . '.csv';
437  $mimeType = 'application/octet-stream';
438  header('Content-Type: ' . $mimeType);
439  header('Content-Disposition: attachment; filename=' . $filename);
440  echo implode(CRLF, $rowArr);
441  die;
442  }
443  }
444  if (!$out) {
445  $out = '<em>No rows selected!</em>';
446  }
447  $cPR['header'] = 'Result';
448  $cPR['content'] = $out;
449  break;
450  case 'explain':
451 
452  default:
453  while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
454  $out .= '<br />' . \TYPO3\CMS\Core\Utility\DebugUtility::viewArray($row);
455  }
456  $cPR['header'] = 'Explain SQL query';
457  $cPR['content'] = $out;
458  }
459  return $cPR;
460  }
461 
472  public function csvValues($row, $delim = ',', $quote = '"', $conf = array(), $table = '')
473  {
474  $valueArray = $row;
475  if ($GLOBALS['SOBE']->MOD_SETTINGS['search_result_labels'] && $table) {
476  foreach ($valueArray as $key => $val) {
477  $valueArray[$key] = $this->getProcessedValueExtra($table, $key, $val, $conf, ';');
478  }
479  }
480  return GeneralUtility::csvValues($valueArray, $delim, $quote);
481  }
482 
489  public function tableWrap($str)
490  {
491  return '<pre>' . $str . '</pre>';
492  }
493 
499  public function search()
500  {
501  $SET = $GLOBALS['SOBE']->MOD_SETTINGS;
502  $swords = $SET['sword'];
503  $out = '';
504  $limit = 200;
505  if ($swords) {
506  foreach ($GLOBALS['TCA'] as $table => $value) {
507  // Get fields list
508  $conf = $GLOBALS['TCA'][$table];
509  // Avoid querying tables with no columns
510  if (empty($conf['columns'])) {
511  continue;
512  }
513  $fieldsInDatabase = $GLOBALS['TYPO3_DB']->admin_get_fields($table);
514  $list = array_intersect(array_keys($conf['columns']), array_keys($fieldsInDatabase));
515  // Get query
516  $qp = $GLOBALS['TYPO3_DB']->searchQuery(array($swords), $list, $table);
517  // Count:
518  $count = $GLOBALS['TYPO3_DB']->exec_SELECTcountRows('*', $table, $qp . BackendUtility::deleteClause($table));
519  if ($count) {
520  $rowArr = array();
521  $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid,' . $conf['ctrl']['label'], $table, $qp . BackendUtility::deleteClause($table), '', '', $limit);
522  while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
523  $rowArr[] = $this->resultRowDisplay($row, $conf, $table);
524  $lrow = $row;
525  }
526  $GLOBALS['TYPO3_DB']->sql_free_result($res);
527  $out .= '<div class="panel panel-default">
528  <div class="panel-heading">' . $GLOBALS['LANG']->sL($conf['ctrl']['title'], true) . ' (' . $count . ')</div>
529  <table class="table table-striped table-hover">' .
530  $this->resultRowTitles($lrow, $conf, $table) .
531  implode(LF, $rowArr) .
532  '</table>
533  </div>';
534  }
535  }
536  }
537  return $out;
538  }
539 
548  public function resultRowDisplay($row, $conf, $table)
549  {
550  $SET = $GLOBALS['SOBE']->MOD_SETTINGS;
551  $out = '<tr>';
552  foreach ($row as $fieldName => $fieldValue) {
553  if (GeneralUtility::inList($SET['queryFields'], $fieldName) || !$SET['queryFields'] && $fieldName != 'pid' && $fieldName != 'deleted') {
554  if ($SET['search_result_labels']) {
555  $fVnew = $this->getProcessedValueExtra($table, $fieldName, $fieldValue, $conf, '<br />');
556  } else {
557  $fVnew = htmlspecialchars($fieldValue);
558  }
559  $out .= '<td>' . $fVnew . '</td>';
560  }
561  }
562  $out .= '<td><div class="btn-group">';
563  if (!$row['deleted']) {
564  $url = BackendUtility::getModuleUrl('record_edit', [
565  'edit' => [
566  $table => [
567  $row['uid'] => 'edit'
568  ]
569  ],
570  'returnUrl' => GeneralUtility::getIndpEnv('REQUEST_URI') . GeneralUtility::implodeArrayForUrl('SET', (array)GeneralUtility::_POST('SET'))
571  ]);
572  $out .= '<a class="btn btn-default" href="#" onClick="top.launchView(\'' . $table . '\',' . $row['uid'] . ',\'' . $GLOBALS['BACK_PATH'] . '\');return false;">' . $this->iconFactory->getIcon('actions-document-info', Icon::SIZE_SMALL)->render() . '</a>';
573  $out .= '<a class="btn btn-default" href="' . htmlspecialchars($url) . '">' . $this->iconFactory->getIcon('actions-document-open', Icon::SIZE_SMALL)->render() . '</a>';
574  } else {
575  $out .= '<a class="btn btn-default" href="' . GeneralUtility::linkThisUrl(BackendUtility::getModuleUrl('tce_db'), array(
576  ('cmd[' . $table . '][' . $row['uid'] . '][undelete]') => '1',
577  'redirect' => GeneralUtility::linkThisScript(array())
578  )) . '" title="' . $GLOBALS['LANG']->getLL('undelete_only', true) . '">';
579  $out .= $this->iconFactory->getIcon('actions-edit-restore', Icon::SIZE_SMALL)->render() . '</a>';
580  $formEngineParameters = array(
581  'edit[' . $table . '][' . $row['uid'] . ']' => 'edit',
582  'returnUrl' => GeneralUtility::linkThisScript(array())
583  );
584  $redirectUrl = BackendUtility::getModuleUrl('record_edit', $formEngineParameters);
585  $out .= '<a class="btn btn-default" href="' . GeneralUtility::linkThisUrl(BackendUtility::getModuleUrl('tce_db'), array(
586  ('cmd[' . $table . '][' . $row['uid'] . '][undelete]') => '1',
587  'redirect' => $redirectUrl
588  )) . '" title="' . $GLOBALS['LANG']->getLL('undelete_and_edit', true) . '">';
589  $out .= $this->iconFactory->getIcon('actions-edit-restore-edit', Icon::SIZE_SMALL)->render() . '</a>';
590  }
591  $_params = array($table => $row);
592  if (is_array($this->hookArray['additionalButtons'])) {
593  foreach ($this->hookArray['additionalButtons'] as $_funcRef) {
594  $out .= GeneralUtility::callUserFunction($_funcRef, $_params, $this);
595  }
596  }
597  $out .= '</div></td>
598  </tr>
599  ';
600  return $out;
601  }
602 
613  public function getProcessedValueExtra($table, $fieldName, $fieldValue, $conf, $splitString)
614  {
615  $out = '';
616  // Analysing the fields in the table.
617  if (is_array($GLOBALS['TCA'][$table])) {
618  $fC = $GLOBALS['TCA'][$table]['columns'][$fieldName];
619  $fields = $fC['config'];
620  $fields['exclude'] = $fC['exclude'];
621  if (is_array($fC) && $fC['label']) {
622  $fields['label'] = preg_replace('/:$/', '', trim($GLOBALS['LANG']->sL($fC['label'])));
623  switch ($fields['type']) {
624  case 'input':
625  if (preg_match('/int|year/i', $fields['eval'])) {
626  $fields['type'] = 'number';
627  } elseif (preg_match('/time/i', $fields['eval'])) {
628  $fields['type'] = 'time';
629  } elseif (preg_match('/date/i', $fields['eval'])) {
630  $fields['type'] = 'date';
631  } else {
632  $fields['type'] = 'text';
633  }
634  break;
635  case 'check':
636  if (!$fields['items']) {
637  $fields['type'] = 'boolean';
638  } else {
639  $fields['type'] = 'binary';
640  }
641  break;
642  case 'radio':
643  $fields['type'] = 'multiple';
644  break;
645  case 'select':
646  $fields['type'] = 'multiple';
647  if ($fields['foreign_table']) {
648  $fields['type'] = 'relation';
649  }
650  if ($fields['special']) {
651  $fields['type'] = 'text';
652  }
653  break;
654  case 'group':
655  $fields['type'] = 'files';
656  if ($fields['internal_type'] == 'db') {
657  $fields['type'] = 'relation';
658  }
659  break;
660  case 'user':
661  case 'flex':
662  case 'passthrough':
663  case 'none':
664  case 'text':
665  default:
666  $fields['type'] = 'text';
667  }
668  } else {
669  $fields['label'] = '[FIELD: ' . $fieldName . ']';
670  switch ($fieldName) {
671  case 'pid':
672  $fields['type'] = 'relation';
673  $fields['allowed'] = 'pages';
674  break;
675  case 'cruser_id':
676  $fields['type'] = 'relation';
677  $fields['allowed'] = 'be_users';
678  break;
679  case 'tstamp':
680 
681  case 'crdate':
682  $fields['type'] = 'time';
683  break;
684  default:
685  $fields['type'] = 'number';
686  }
687  }
688  }
689  switch ($fields['type']) {
690  case 'date':
691  if ($fieldValue != -1) {
692  $out = strftime('%e-%m-%Y', $fieldValue);
693  }
694  break;
695  case 'time':
696  if ($fieldValue != -1) {
697  if ($splitString == '<br />') {
698  $out = strftime('%H:%M' . $splitString . '%e-%m-%Y', $fieldValue);
699  } else {
700  $out = strftime('%H:%M %e-%m-%Y', $fieldValue);
701  }
702  }
703  break;
704  case 'multiple':
705  case 'binary':
706  case 'relation':
707  $out = $this->makeValueList($fieldName, $fieldValue, $fields, $table, $splitString);
708  break;
709  case 'boolean':
710  $out = $fieldValue ? 'True' : 'False';
711  break;
712  case 'files':
713  default:
714  $out = htmlspecialchars($fieldValue);
715  }
716  return $out;
717  }
718 
728  public function getTreeList($id, $depth, $begin = 0, $perms_clause)
729  {
730  $depth = (int)$depth;
731  $begin = (int)$begin;
732  $id = (int)$id;
733  if ($id < 0) {
734  $id = abs($id);
735  }
736  if ($begin == 0) {
737  $theList = $id;
738  } else {
739  $theList = '';
740  }
741  if ($id && $depth > 0) {
742  $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid', 'pages', 'pid=' . $id . ' ' . BackendUtility::deleteClause('pages') . ' AND ' . $perms_clause);
743  while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
744  if ($begin <= 0) {
745  $theList .= ',' . $row['uid'];
746  }
747  if ($depth > 1) {
748  $theList .= $this->getTreeList($row['uid'], $depth - 1, $begin - 1, $perms_clause);
749  }
750  }
751  $GLOBALS['TYPO3_DB']->sql_free_result($res);
752  }
753  return $theList;
754  }
755 
766  public function makeValueList($fieldName, $fieldValue, $conf, $table, $splitString)
767  {
768  $fieldSetup = $conf;
769  $out = '';
770  if ($fieldSetup['type'] == 'files') {
771  $d = dir(PATH_site . $fieldSetup['uploadfolder']);
772  while (false !== ($entry = $d->read())) {
773  if ($entry == '.' || $entry == '..') {
774  continue;
775  }
776  $fileArray[] = $entry;
777  }
778  $d->close();
779  natcasesort($fileArray);
780  foreach ($fileArray as $fileName) {
781  if (GeneralUtility::inList($fieldValue, $fileName) || $fieldValue == $fileName) {
782  if (!$out) {
783  $out = htmlspecialchars($fileName);
784  } else {
785  $out .= $splitString . htmlspecialchars($fileName);
786  }
787  }
788  }
789  }
790  if ($fieldSetup['type'] == 'multiple') {
791  foreach ($fieldSetup['items'] as $key => $val) {
792  if (substr($val[0], 0, 4) == 'LLL:') {
793  $value = $GLOBALS['LANG']->sL($val[0]);
794  } else {
795  $value = $val[0];
796  }
797  if (GeneralUtility::inList($fieldValue, $val[1]) || $fieldValue == $val[1]) {
798  if (!$out) {
799  $out = htmlspecialchars($value);
800  } else {
801  $out .= $splitString . htmlspecialchars($value);
802  }
803  }
804  }
805  }
806  if ($fieldSetup['type'] == 'binary') {
807  foreach ($fieldSetup['items'] as $Key => $val) {
808  if (substr($val[0], 0, 4) == 'LLL:') {
809  $value = $GLOBALS['LANG']->sL($val[0]);
810  } else {
811  $value = $val[0];
812  }
813  if (!$out) {
814  $out = htmlspecialchars($value);
815  } else {
816  $out .= $splitString . htmlspecialchars($value);
817  }
818  }
819  }
820  if ($fieldSetup['type'] == 'relation') {
821  if ($fieldSetup['items']) {
822  foreach ($fieldSetup['items'] as $key => $val) {
823  if (substr($val[0], 0, 4) == 'LLL:') {
824  $value = $GLOBALS['LANG']->sL($val[0]);
825  } else {
826  $value = $val[0];
827  }
828  if (GeneralUtility::inList($fieldValue, $value) || $fieldValue == $value) {
829  if (!$out) {
830  $out = htmlspecialchars($value);
831  } else {
832  $out .= $splitString . htmlspecialchars($value);
833  }
834  }
835  }
836  }
837  if (stristr($fieldSetup['allowed'], ',')) {
838  $from_table_Arr = explode(',', $fieldSetup['allowed']);
839  $useTablePrefix = 1;
840  if (!$fieldSetup['prepend_tname']) {
841  $checkres = $GLOBALS['TYPO3_DB']->exec_SELECTquery($fieldName, $table, 'uid ' . BackendUtility::deleteClause($table), ($groupBy = ''), ($orderBy = ''), ($limit = ''));
842  if ($checkres) {
843  while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($checkres)) {
844  if (stristr($row[$fieldName], ',')) {
845  $checkContent = explode(',', $row[$fieldName]);
846  foreach ($checkContent as $singleValue) {
847  if (!stristr($singleValue, '_')) {
848  $dontPrefixFirstTable = 1;
849  }
850  }
851  } else {
852  $singleValue = $row[$fieldName];
853  if ($singleValue !== '' && !stristr($singleValue, '_')) {
854  $dontPrefixFirstTable = 1;
855  }
856  }
857  }
858  $GLOBALS['TYPO3_DB']->sql_free_result($checkres);
859  }
860  }
861  } else {
862  $from_table_Arr[0] = $fieldSetup['allowed'];
863  }
864  if ($fieldSetup['prepend_tname']) {
865  $useTablePrefix = 1;
866  }
867  if ($fieldSetup['foreign_table']) {
868  $from_table_Arr[0] = $fieldSetup['foreign_table'];
869  }
870  $counter = 0;
871  foreach ($from_table_Arr as $from_table) {
872  if ($useTablePrefix && !$dontPrefixFirstTable && $counter != 1 || $counter == 1) {
873  $tablePrefix = $from_table . '_';
874  }
875  $counter = 1;
876  if (is_array($GLOBALS['TCA'][$from_table])) {
877  $labelField = $GLOBALS['TCA'][$from_table]['ctrl']['label'];
878  $altLabelField = $GLOBALS['TCA'][$from_table]['ctrl']['label_alt'];
879  if ($GLOBALS['TCA'][$from_table]['columns'][$labelField]['config']['items']) {
880  foreach ($GLOBALS['TCA'][$from_table]['columns'][$labelField]['config']['items'] as $labelArray) {
881  if (substr($labelArray[0], 0, 4) == 'LLL:') {
882  $labelFieldSelect[$labelArray[1]] = $GLOBALS['LANG']->sL($labelArray[0]);
883  } else {
884  $labelFieldSelect[$labelArray[1]] = $labelArray[0];
885  }
886  }
887  $useSelectLabels = 1;
888  }
889  if ($GLOBALS['TCA'][$from_table]['columns'][$altLabelField]['config']['items']) {
890  foreach ($GLOBALS['TCA'][$from_table]['columns'][$altLabelField]['config']['items'] as $altLabelArray) {
891  if (substr($altLabelArray[0], 0, 4) == 'LLL:') {
892  $altLabelFieldSelect[$altLabelArray[1]] = $GLOBALS['LANG']->sL($altLabelArray[0]);
893  } else {
894  $altLabelFieldSelect[$altLabelArray[1]] = $altLabelArray[0];
895  }
896  }
897  $useAltSelectLabels = 1;
898  }
899  $altLabelFieldSelect = $altLabelField ? ',' . $altLabelField : '';
900  $select_fields = 'uid,' . $labelField . $altLabelFieldSelect;
901  if (!$GLOBALS['BE_USER']->isAdmin() && $GLOBALS['TYPO3_CONF_VARS']['BE']['lockBeUserToDBmounts']) {
902  $webMounts = $GLOBALS['BE_USER']->returnWebmounts();
903  $perms_clause = $GLOBALS['BE_USER']->getPagePermsClause(1);
904  $webMountPageTree = '';
905  foreach ($webMounts as $key => $val) {
906  if ($webMountPageTree) {
907  $webMountPageTreePrefix = ',';
908  }
909  $webMountPageTree .= $webMountPageTreePrefix . $this->getTreeList($val, 999, ($begin = 0), $perms_clause);
910  }
911  if ($from_table == 'pages') {
912  $where_clause = 'uid IN (' . $webMountPageTree . ') ' . BackendUtility::deleteClause($from_table) . ' AND ' . $perms_clause;
913  } else {
914  $where_clause = 'pid IN (' . $webMountPageTree . ') ' . BackendUtility::deleteClause($from_table);
915  }
916  } else {
917  $where_clause = 'uid' . BackendUtility::deleteClause($from_table);
918  }
919  $orderBy = 'uid';
920  if (!$this->tableArray[$from_table]) {
921  $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery($select_fields, $from_table, $where_clause, ($groupBy = ''), $orderBy, ($limit = ''));
922  $this->tableArray[$from_table] = array();
923  }
924  if ($res) {
925  while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
926  $this->tableArray[$from_table][] = $row;
927  }
928  $GLOBALS['TYPO3_DB']->sql_free_result($res);
929  }
930  foreach ($this->tableArray[$from_table] as $key => $val) {
931  $GLOBALS['SOBE']->MOD_SETTINGS['labels_noprefix'] = $GLOBALS['SOBE']->MOD_SETTINGS['labels_noprefix'] == 1 ? 'on' : $GLOBALS['SOBE']->MOD_SETTINGS['labels_noprefix'];
932  $prefixString = $GLOBALS['SOBE']->MOD_SETTINGS['labels_noprefix'] == 'on' ? '' : ' [' . $tablePrefix . $val['uid'] . '] ';
933  if (GeneralUtility::inList($fieldValue, $tablePrefix . $val['uid']) || $fieldValue == $tablePrefix . $val['uid']) {
934  if ($useSelectLabels) {
935  if (!$out) {
936  $out = htmlspecialchars($prefixString . $labelFieldSelect[$val[$labelField]]);
937  } else {
938  $out .= $splitString . htmlspecialchars(($prefixString . $labelFieldSelect[$val[$labelField]]));
939  }
940  } elseif ($val[$labelField]) {
941  if (!$out) {
942  $out = htmlspecialchars($prefixString . $val[$labelField]);
943  } else {
944  $out .= $splitString . htmlspecialchars(($prefixString . $val[$labelField]));
945  }
946  } elseif ($useAltSelectLabels) {
947  if (!$out) {
948  $out = htmlspecialchars($prefixString . $altLabelFieldSelect[$val[$altLabelField]]);
949  } else {
950  $out .= $splitString . htmlspecialchars(($prefixString . $altLabelFieldSelect[$val[$altLabelField]]));
951  }
952  } else {
953  if (!$out) {
954  $out = htmlspecialchars($prefixString . $val[$altLabelField]);
955  } else {
956  $out .= $splitString . htmlspecialchars(($prefixString . $val[$altLabelField]));
957  }
958  }
959  }
960  }
961  }
962  }
963  }
964  return $out;
965  }
966 
975  public function resultRowTitles($row, $conf, $table)
976  {
977  $SET = $GLOBALS['SOBE']->MOD_SETTINGS;
978  $tableHeader = array();
979  // Start header row
980  $tableHeader[] = '<thead><tr>';
981  // Iterate over given columns
982  foreach ($row as $fieldName => $fieldValue) {
983  if (GeneralUtility::inList($SET['queryFields'], $fieldName) || !$SET['queryFields'] && $fieldName != 'pid' && $fieldName != 'deleted') {
984  if ($GLOBALS['SOBE']->MOD_SETTINGS['search_result_labels']) {
985  $title = $GLOBALS['LANG']->sL($conf['columns'][$fieldName]['label'] ? $conf['columns'][$fieldName]['label'] : $fieldName, true);
986  } else {
987  $title = $GLOBALS['LANG']->sL($fieldName, true);
988  }
989  $tableHeader[] = '<th>' . $title . '</th>';
990  }
991  }
992  // Add empty icon column
993  $tableHeader[] = '<th></th>';
994  // Close header row
995  $tableHeader[] = '</tr></thead>';
996  return implode(LF, $tableHeader);
997  }
998 
1007  public function csvRowTitles($row, $conf, $table)
1008  {
1009  $out = '';
1010  $SET = $GLOBALS['SOBE']->MOD_SETTINGS;
1011  foreach ($row as $fieldName => $fieldValue) {
1012  if (GeneralUtility::inList($SET['queryFields'], $fieldName) || !$SET['queryFields'] && $fieldName != 'pid') {
1013  if (!$out) {
1014  if ($GLOBALS['SOBE']->MOD_SETTINGS['search_result_labels']) {
1015  $out = $GLOBALS['LANG']->sL($conf['columns'][$fieldName]['label'] ? $conf['columns'][$fieldName]['label'] : $fieldName, true);
1016  } else {
1017  $out = $GLOBALS['LANG']->sL($fieldName, true);
1018  }
1019  } else {
1020  if ($GLOBALS['SOBE']->MOD_SETTINGS['search_result_labels']) {
1021  $out .= ',' . $GLOBALS['LANG']->sL(($conf['columns'][$fieldName]['label'] ? $conf['columns'][$fieldName]['label'] : $fieldName), true);
1022  } else {
1023  $out .= ',' . $GLOBALS['LANG']->sL($fieldName, true);
1024  }
1025  }
1026  }
1027  }
1028  return $out;
1029  }
1030 
1037  public function setFormName($formName)
1038  {
1039  $this->formName = trim($formName);
1040  }
1041 }