‪TYPO3CMS  9.5
QueryGenerator.php
Go to the documentation of this file.
1 <?php
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 
28 
33 {
37  public ‪$lang = [
38  'OR' => 'or',
39  'AND' => 'and',
40  'comparison' => [
41  // Type = text offset = 0
42  '0_' => 'contains',
43  '1_' => 'does not contain',
44  '2_' => 'starts with',
45  '3_' => 'does not start with',
46  '4_' => 'ends with',
47  '5_' => 'does not end with',
48  '6_' => 'equals',
49  '7_' => 'does not equal',
50  // Type = number , offset = 32
51  '32_' => 'equals',
52  '33_' => 'does not equal',
53  '34_' => 'is greater than',
54  '35_' => 'is less than',
55  '36_' => 'is between',
56  '37_' => 'is not between',
57  '38_' => 'is in list',
58  '39_' => 'is not in list',
59  '40_' => 'binary AND equals',
60  '41_' => 'binary AND does not equal',
61  '42_' => 'binary OR equals',
62  '43_' => 'binary OR does not equal',
63  // Type = multiple, relation, files , offset = 64
64  '64_' => 'equals',
65  '65_' => 'does not equal',
66  '66_' => 'contains',
67  '67_' => 'does not contain',
68  '68_' => 'is in list',
69  '69_' => 'is not in list',
70  '70_' => 'binary AND equals',
71  '71_' => 'binary AND does not equal',
72  '72_' => 'binary OR equals',
73  '73_' => 'binary OR does not equal',
74  // Type = date,time offset = 96
75  '96_' => 'equals',
76  '97_' => 'does not equal',
77  '98_' => 'is greater than',
78  '99_' => 'is less than',
79  '100_' => 'is between',
80  '101_' => 'is not between',
81  '102_' => 'binary AND equals',
82  '103_' => 'binary AND does not equal',
83  '104_' => 'binary OR equals',
84  '105_' => 'binary OR does not equal',
85  // Type = boolean, offset = 128
86  '128_' => 'is True',
87  '129_' => 'is False',
88  // Type = binary , offset = 160
89  '160_' => 'equals',
90  '161_' => 'does not equal',
91  '162_' => 'contains',
92  '163_' => 'does not contain'
93  ]
94  ];
95 
99  public ‪$compSQL = [
100  // Type = text offset = 0
101  '0' => '#FIELD# LIKE \'%#VALUE#%\'',
102  '1' => '#FIELD# NOT LIKE \'%#VALUE#%\'',
103  '2' => '#FIELD# LIKE \'#VALUE#%\'',
104  '3' => '#FIELD# NOT LIKE \'#VALUE#%\'',
105  '4' => '#FIELD# LIKE \'%#VALUE#\'',
106  '5' => '#FIELD# NOT LIKE \'%#VALUE#\'',
107  '6' => '#FIELD# = \'#VALUE#\'',
108  '7' => '#FIELD# != \'#VALUE#\'',
109  // Type = number, offset = 32
110  '32' => '#FIELD# = \'#VALUE#\'',
111  '33' => '#FIELD# != \'#VALUE#\'',
112  '34' => '#FIELD# > #VALUE#',
113  '35' => '#FIELD# < #VALUE#',
114  '36' => '#FIELD# >= #VALUE# AND #FIELD# <= #VALUE1#',
115  '37' => 'NOT (#FIELD# >= #VALUE# AND #FIELD# <= #VALUE1#)',
116  '38' => '#FIELD# IN (#VALUE#)',
117  '39' => '#FIELD# NOT IN (#VALUE#)',
118  '40' => '(#FIELD# & #VALUE#)=#VALUE#',
119  '41' => '(#FIELD# & #VALUE#)!=#VALUE#',
120  '42' => '(#FIELD# | #VALUE#)=#VALUE#',
121  '43' => '(#FIELD# | #VALUE#)!=#VALUE#',
122  // Type = multiple, relation, files , offset = 64
123  '64' => '#FIELD# = \'#VALUE#\'',
124  '65' => '#FIELD# != \'#VALUE#\'',
125  '66' => '#FIELD# LIKE \'%#VALUE#%\' AND #FIELD# LIKE \'%#VALUE1#%\'',
126  '67' => '(#FIELD# NOT LIKE \'%#VALUE#%\' OR #FIELD# NOT LIKE \'%#VALUE1#%\')',
127  '68' => '#FIELD# IN (#VALUE#)',
128  '69' => '#FIELD# NOT IN (#VALUE#)',
129  '70' => '(#FIELD# & #VALUE#)=#VALUE#',
130  '71' => '(#FIELD# & #VALUE#)!=#VALUE#',
131  '72' => '(#FIELD# | #VALUE#)=#VALUE#',
132  '73' => '(#FIELD# | #VALUE#)!=#VALUE#',
133  // Type = date, offset = 32
134  '96' => '#FIELD# = \'#VALUE#\'',
135  '97' => '#FIELD# != \'#VALUE#\'',
136  '98' => '#FIELD# > #VALUE#',
137  '99' => '#FIELD# < #VALUE#',
138  '100' => '#FIELD# >= #VALUE# AND #FIELD# <= #VALUE1#',
139  '101' => 'NOT (#FIELD# >= #VALUE# AND #FIELD# <= #VALUE1#)',
140  '102' => '(#FIELD# & #VALUE#)=#VALUE#',
141  '103' => '(#FIELD# & #VALUE#)!=#VALUE#',
142  '104' => '(#FIELD# | #VALUE#)=#VALUE#',
143  '105' => '(#FIELD# | #VALUE#)!=#VALUE#',
144  // Type = boolean, offset = 128
145  '128' => '#FIELD# = \'1\'',
146  '129' => '#FIELD# != \'1\'',
147  // Type = binary = 160
148  '160' => '#FIELD# = \'#VALUE#\'',
149  '161' => '#FIELD# != \'#VALUE#\'',
150  '162' => '(#FIELD# & #VALUE#)=#VALUE#',
151  '163' => '(#FIELD# & #VALUE#)=0'
152  ];
153 
157  public ‪$comp_offsets = [
158  'text' => 0,
159  'number' => 1,
160  'multiple' => 2,
161  'relation' => 2,
162  'files' => 2,
163  'date' => 3,
164  'time' => 3,
165  'boolean' => 4,
166  'binary' => 5
167  ];
168 
172  public ‪$noWrap = ' nowrap';
173 
179  public ‪$name;
180 
186  public ‪$table;
187 
191  public ‪$tableArray;
192 
198  public ‪$fieldList;
199 
205  public ‪$fields = [];
206 
210  public ‪$extFieldLists = [];
211 
217  public ‪$queryConfig = [];
218 
222  public ‪$enablePrefix = false;
223 
227  public ‪$enableQueryParts = false;
228 
232  protected ‪$formName = '';
233 
237  protected ‪$limitBegin;
238 
242  protected ‪$limitLength;
243 
247  protected ‪$fieldName;
248 
254  public function ‪makeFieldList()
255  {
256  $fieldListArr = [];
257  if (is_array(‪$GLOBALS['TCA'][$this->table])) {
258  $fieldListArr = array_keys(‪$GLOBALS['TCA'][$this->table]['columns']);
259  $fieldListArr[] = 'uid';
260  $fieldListArr[] = 'pid';
261  $fieldListArr[] = 'deleted';
262  if (‪$GLOBALS['TCA'][$this->table]['ctrl']['tstamp']) {
263  $fieldListArr[] = ‪$GLOBALS['TCA'][‪$this->table]['ctrl']['tstamp'];
264  }
265  if (‪$GLOBALS['TCA'][$this->table]['ctrl']['crdate']) {
266  $fieldListArr[] = ‪$GLOBALS['TCA'][‪$this->table]['ctrl']['crdate'];
267  }
268  if (‪$GLOBALS['TCA'][$this->table]['ctrl']['cruser_id']) {
269  $fieldListArr[] = ‪$GLOBALS['TCA'][‪$this->table]['ctrl']['cruser_id'];
270  }
271  if (‪$GLOBALS['TCA'][$this->table]['ctrl']['sortby']) {
272  $fieldListArr[] = ‪$GLOBALS['TCA'][‪$this->table]['ctrl']['sortby'];
273  }
274  }
275  return implode(',', $fieldListArr);
276  }
277 
285  public function ‪init(‪$name, ‪$table, ‪$fieldList = '')
286  {
287  // Analysing the fields in the table.
288  if (is_array(‪$GLOBALS['TCA'][‪$table])) {
289  $this->name = ‪$name;
290  $this->table = ‪$table;
291  $this->fieldList = ‪$fieldList ? ‪$fieldList : $this->‪makeFieldList();
292  $fieldArr = GeneralUtility::trimExplode(',', $this->fieldList, true);
293  foreach ($fieldArr as ‪$fieldName) {
294  $fC = ‪$GLOBALS['TCA'][‪$this->table]['columns'][‪$fieldName];
295  $this->fields[‪$fieldName] = $fC['config'];
296  $this->fields[‪$fieldName]['exclude'] = $fC['exclude'];
297  if ($this->fields[‪$fieldName]['type'] === 'user' && !isset($this->fields[‪$fieldName]['type']['userFunc'])
298  || $this->fields[‪$fieldName]['type'] === 'none'
299  ) {
300  // Do not list type=none "virtual" fields or query them from db,
301  // and if type is user without defined userFunc
302  unset($this->fields[‪$fieldName]);
303  continue;
304  }
305  if (is_array($fC) && $fC['label']) {
306  $this->fields[‪$fieldName]['label'] = rtrim(trim($this->‪getLanguageService()->sL($fC['label'])), ':');
307  switch ($this->fields[‪$fieldName]['type']) {
308  case 'input':
309  if (preg_match('/int|year/i', $this->fields[‪$fieldName]['eval'])) {
310  $this->fields[‪$fieldName]['type'] = 'number';
311  } elseif (preg_match('/time/i', $this->fields[‪$fieldName]['eval'])) {
312  $this->fields[‪$fieldName]['type'] = 'time';
313  } elseif (preg_match('/date/i', $this->fields[‪$fieldName]['eval'])) {
314  $this->fields[‪$fieldName]['type'] = 'date';
315  } else {
316  $this->fields[‪$fieldName]['type'] = 'text';
317  }
318  break;
319  case 'check':
320  if (!$this->fields[‪$fieldName]['items'] || count($this->fields[‪$fieldName]['items']) <= 1) {
321  $this->fields[‪$fieldName]['type'] = 'boolean';
322  } else {
323  $this->fields[‪$fieldName]['type'] = 'binary';
324  }
325  break;
326  case 'radio':
327  $this->fields[‪$fieldName]['type'] = 'multiple';
328  break;
329  case 'select':
330  $this->fields[‪$fieldName]['type'] = 'multiple';
331  if ($this->fields[‪$fieldName]['foreign_table']) {
332  $this->fields[‪$fieldName]['type'] = 'relation';
333  }
334  if ($this->fields[‪$fieldName]['special']) {
335  $this->fields[‪$fieldName]['type'] = 'text';
336  }
337  break;
338  case 'group':
339  $this->fields[‪$fieldName]['type'] = 'files';
340  if ($this->fields[‪$fieldName]['internal_type'] === 'db') {
341  $this->fields[‪$fieldName]['type'] = 'relation';
342  }
343  break;
344  case 'user':
345  case 'flex':
346  case 'passthrough':
347  case 'none':
348  case 'text':
349  default:
350  $this->fields[‪$fieldName]['type'] = 'text';
351  }
352  } else {
353  $this->fields[‪$fieldName]['label'] = '[FIELD: ' . ‪$fieldName . ']';
354  switch (‪$fieldName) {
355  case 'pid':
356  $this->fields[‪$fieldName]['type'] = 'relation';
357  $this->fields[‪$fieldName]['allowed'] = 'pages';
358  break;
359  case 'cruser_id':
360  $this->fields[‪$fieldName]['type'] = 'relation';
361  $this->fields[‪$fieldName]['allowed'] = 'be_users';
362  break;
363  case 'tstamp':
364  case 'crdate':
365  $this->fields[‪$fieldName]['type'] = 'time';
366  break;
367  case 'deleted':
368  $this->fields[‪$fieldName]['type'] = 'boolean';
369  break;
370  default:
371  $this->fields[‪$fieldName]['type'] = 'number';
372  }
373  }
374  }
375  }
376  /* // EXAMPLE:
377  $this->queryConfig = array(
378  array(
379  'operator' => 'AND',
380  'type' => 'FIELD_spaceBefore',
381  ),
382  array(
383  'operator' => 'AND',
384  'type' => 'FIELD_records',
385  'negate' => 1,
386  'inputValue' => 'foo foo'
387  ),
388  array(
389  'type' => 'newlevel',
390  'nl' => array(
391  array(
392  'operator' => 'AND',
393  'type' => 'FIELD_spaceBefore',
394  'negate' => 1,
395  'inputValue' => 'foo foo'
396  ),
397  array(
398  'operator' => 'AND',
399  'type' => 'FIELD_records',
400  'negate' => 1,
401  'inputValue' => 'foo foo'
402  )
403  )
404  ),
405  array(
406  'operator' => 'OR',
407  'type' => 'FIELD_maillist',
408  )
409  );
410  */
411  $this->‪initUserDef();
412  }
413 
421  public function ‪setAndCleanUpExternalLists(‪$name, $list, $force = '')
422  {
423  ‪$fields = array_unique(GeneralUtility::trimExplode(',', $list . ',' . $force, true));
424  $reList = [];
425  foreach (‪$fields as ‪$fieldName) {
426  if ($this->fields[‪$fieldName]) {
427  $reList[] = ‪$fieldName;
428  }
429  }
430  $this->extFieldLists[‪$name] = implode(',', $reList);
431  }
432 
438  public function ‪procesData($qC = '')
439  {
440  $this->queryConfig = $qC;
441  $POST = GeneralUtility::_POST();
442  // If delete...
443  if ($POST['qG_del']) {
444  // Initialize array to work on, save special parameters
445  $ssArr = $this->‪getSubscript($POST['qG_del']);
446  $workArr = &‪$this->queryConfig;
447  $ssArrSize = count($ssArr) - 1;
448  $i = 0;
449  for (; $i < $ssArrSize; $i++) {
450  $workArr = &$workArr[$ssArr[$i]];
451  }
452  // Delete the entry and move the other entries
453  unset($workArr[$ssArr[$i]]);
454  $workArrSize = count($workArr);
455  for ($j = $ssArr[$i]; $j < $workArrSize; $j++) {
456  $workArr[$j] = $workArr[$j + 1];
457  unset($workArr[$j + 1]);
458  }
459  }
460  // If insert...
461  if ($POST['qG_ins']) {
462  // Initialize array to work on, save special parameters
463  $ssArr = $this->‪getSubscript($POST['qG_ins']);
464  $workArr = &‪$this->queryConfig;
465  $ssArrSize = count($ssArr) - 1;
466  $i = 0;
467  for (; $i < $ssArrSize; $i++) {
468  $workArr = &$workArr[$ssArr[$i]];
469  }
470  // Move all entries above position where new entry is to be inserted
471  $workArrSize = count($workArr);
472  for ($j = $workArrSize; $j > $ssArr[$i]; $j--) {
473  $workArr[$j] = $workArr[$j - 1];
474  }
475  // Clear new entry position
476  unset($workArr[$ssArr[$i] + 1]);
477  $workArr[$ssArr[$i] + 1]['type'] = 'FIELD_';
478  }
479  // If move up...
480  if ($POST['qG_up']) {
481  // Initialize array to work on
482  $ssArr = $this->‪getSubscript($POST['qG_up']);
483  $workArr = &‪$this->queryConfig;
484  $ssArrSize = count($ssArr) - 1;
485  $i = 0;
486  for (; $i < $ssArrSize; $i++) {
487  $workArr = &$workArr[$ssArr[$i]];
488  }
489  // Swap entries
490  $qG_tmp = $workArr[$ssArr[$i]];
491  $workArr[$ssArr[$i]] = $workArr[$ssArr[$i] - 1];
492  $workArr[$ssArr[$i] - 1] = $qG_tmp;
493  }
494  // If new level...
495  if ($POST['qG_nl']) {
496  // Initialize array to work on
497  $ssArr = $this->‪getSubscript($POST['qG_nl']);
498  $workArr = &‪$this->queryConfig;
499  $ssArraySize = count($ssArr) - 1;
500  $i = 0;
501  for (; $i < $ssArraySize; $i++) {
502  $workArr = &$workArr[$ssArr[$i]];
503  }
504  // Do stuff:
505  $tempEl = $workArr[$ssArr[$i]];
506  if (is_array($tempEl)) {
507  if ($tempEl['type'] !== 'newlevel') {
508  $workArr[$ssArr[$i]] = [
509  'type' => 'newlevel',
510  'operator' => $tempEl['operator'],
511  'nl' => [$tempEl]
512  ];
513  }
514  }
515  }
516  // If collapse level...
517  if ($POST['qG_remnl']) {
518  // Initialize array to work on
519  $ssArr = $this->‪getSubscript($POST['qG_remnl']);
520  $workArr = &‪$this->queryConfig;
521  $ssArrSize = count($ssArr) - 1;
522  $i = 0;
523  for (; $i < $ssArrSize; $i++) {
524  $workArr = &$workArr[$ssArr[$i]];
525  }
526  // Do stuff:
527  $tempEl = $workArr[$ssArr[$i]];
528  if (is_array($tempEl)) {
529  if ($tempEl['type'] === 'newlevel') {
530  $a1 = array_slice($workArr, 0, $ssArr[$i]);
531  $a2 = array_slice($workArr, $ssArr[$i]);
532  array_shift($a2);
533  $a3 = $tempEl['nl'];
534  $a3[0]['operator'] = $tempEl['operator'];
535  $workArr = array_merge($a1, $a3, $a2);
536  }
537  }
538  }
539  }
540 
547  public function ‪cleanUpQueryConfig(‪$queryConfig)
548  {
549  // Since we don't traverse the array using numeric keys in the upcoming while-loop make sure it's fresh and clean before displaying
550  if (is_array(‪$queryConfig)) {
551  ksort(‪$queryConfig);
552  } else {
553  // queryConfig should never be empty!
554  if (!isset(‪$queryConfig[0]) || empty(‪$queryConfig[0]['type'])) {
555  // Make sure queryConfig is an array
556  ‪$queryConfig = [];
557  ‪$queryConfig[0] = ['type' => 'FIELD_'];
558  }
559  }
560  // Traverse:
561  foreach (‪$queryConfig as $key => $conf) {
562  ‪$fieldName = '';
563  if (strpos($conf['type'], 'FIELD_') === 0) {
564  ‪$fieldName = substr($conf['type'], 6);
565  $fieldType = $this->fields[‪$fieldName]['type'];
566  } elseif ($conf['type'] === 'newlevel') {
567  $fieldType = $conf['type'];
568  } else {
569  $fieldType = 'ignore';
570  }
571  switch ($fieldType) {
572  case 'newlevel':
573  if (!‪$queryConfig[$key]['nl']) {
574  ‪$queryConfig[$key]['nl'][0]['type'] = 'FIELD_';
575  }
576  ‪$queryConfig[$key]['nl'] = $this->‪cleanUpQueryConfig(‪$queryConfig[$key]['nl']);
577  break;
578  case 'userdef':
579  ‪$queryConfig[$key] = $this->‪userDefCleanUp(‪$queryConfig[$key]);
580  break;
581  case 'ignore':
582  default:
583  $verifiedName = $this->‪verifyType($fieldName);
584  ‪$queryConfig[$key]['type'] = 'FIELD_' . $this->‪verifyType($verifiedName);
585  if ($conf['comparison'] >> 5 != $this->comp_offsets[$fieldType]) {
586  $conf['comparison'] = $this->comp_offsets[$fieldType] << 5;
587  }
588  ‪$queryConfig[$key]['comparison'] = $this->‪verifyComparison($conf['comparison'], $conf['negate'] ? 1 : 0);
589  ‪$queryConfig[$key]['inputValue'] = $this->‪cleanInputVal(‪$queryConfig[$key]);
590  ‪$queryConfig[$key]['inputValue1'] = $this->‪cleanInputVal(‪$queryConfig[$key], 1);
591  }
592  }
593  return ‪$queryConfig;
594  }
595 
604  public function ‪getFormElements($subLevel = 0, ‪$queryConfig = '', $parent = '')
605  {
606  $codeArr = [];
607  if (!is_array(‪$queryConfig)) {
609  }
610  $c = 0;
611  $arrCount = 0;
612  $loopCount = 0;
613  foreach (‪$queryConfig as $key => $conf) {
614  ‪$fieldName = '';
615  $subscript = $parent . '[' . $key . ']';
616  $lineHTML = [];
617  $lineHTML[] = $this->‪mkOperatorSelect($this->name . $subscript, $conf['operator'], $c, $conf['type'] !== 'FIELD_');
618  if (strpos($conf['type'], 'FIELD_') === 0) {
619  ‪$fieldName = substr($conf['type'], 6);
620  $this->fieldName = ‪$fieldName;
621  $fieldType = $this->fields[‪$fieldName]['type'];
622  if ($conf['comparison'] >> 5 != $this->comp_offsets[$fieldType]) {
623  $conf['comparison'] = $this->comp_offsets[$fieldType] << 5;
624  }
625  //nasty nasty...
626  //make sure queryConfig contains _actual_ comparevalue.
627  //mkCompSelect don't care, but getQuery does.
628  ‪$queryConfig[$key]['comparison'] += isset($conf['negate']) - $conf['comparison'] % 2;
629  } elseif ($conf['type'] === 'newlevel') {
630  $fieldType = $conf['type'];
631  } else {
632  $fieldType = 'ignore';
633  }
634  $fieldPrefix = htmlspecialchars($this->name . $subscript);
635  switch ($fieldType) {
636  case 'ignore':
637  break;
638  case 'newlevel':
639  if (!‪$queryConfig[$key]['nl']) {
640  ‪$queryConfig[$key]['nl'][0]['type'] = 'FIELD_';
641  }
642  $lineHTML[] = '<input type="hidden" name="' . $fieldPrefix . '[type]" value="newlevel">';
643  $codeArr[$arrCount]['sub'] = $this->‪getFormElements($subLevel + 1, ‪$queryConfig[$key]['nl'], $subscript . '[nl]');
644  break;
645  case 'userdef':
646  $lineHTML[] = $this->‪userDef($fieldPrefix, $conf, ‪$fieldName, $fieldType);
647  break;
648  case 'date':
649  $lineHTML[] = '<div class="form-inline">';
650  $lineHTML[] = $this->‪makeComparisonSelector($subscript, ‪$fieldName, $conf);
651  if ($conf['comparison'] === 100 || $conf['comparison'] === 101) {
652  // between
653  $lineHTML[] = $this->‪getDateTimePickerField($fieldPrefix . '[inputValue]', $conf['inputValue'], 'date');
654  $lineHTML[] = $this->‪getDateTimePickerField($fieldPrefix . '[inputValue1]', $conf['inputValue1'], 'date');
655  } else {
656  $lineHTML[] = $this->‪getDateTimePickerField($fieldPrefix . '[inputValue]', $conf['inputValue'], 'date');
657  }
658  $lineHTML[] = '</div>';
659  break;
660  case 'time':
661  $lineHTML[] = '<div class="form-inline">';
662  $lineHTML[] = $this->‪makeComparisonSelector($subscript, ‪$fieldName, $conf);
663  if ($conf['comparison'] === 100 || $conf['comparison'] === 101) {
664  // between:
665  $lineHTML[] = $this->‪getDateTimePickerField($fieldPrefix . '[inputValue]', $conf['inputValue'], 'datetime');
666  $lineHTML[] = $this->‪getDateTimePickerField($fieldPrefix . '[inputValue1]', $conf['inputValue1'], 'datetime');
667  } else {
668  $lineHTML[] = $this->‪getDateTimePickerField($fieldPrefix . '[inputValue]', $conf['inputValue'], 'datetime');
669  }
670  $lineHTML[] = '</div>';
671  break;
672  case 'multiple':
673  case 'binary':
674  case 'relation':
675  $lineHTML[] = '<div class="form-inline">';
676  $lineHTML[] = $this->‪makeComparisonSelector($subscript, ‪$fieldName, $conf);
677  if ($conf['comparison'] === 68 || $conf['comparison'] === 69 || $conf['comparison'] === 162 || $conf['comparison'] === 163) {
678  $lineHTML[] = '<select class="form-control" name="' . $fieldPrefix . '[inputValue]' . '[]" multiple="multiple">';
679  } elseif ($conf['comparison'] === 66 || $conf['comparison'] === 67) {
680  if (is_array($conf['inputValue'])) {
681  $conf['inputValue'] = implode(',', $conf['inputValue']);
682  }
683  $lineHTML[] = '<input class="form-control t3js-clearable" type="text" value="' . htmlspecialchars($conf['inputValue']) . '" name="' . $fieldPrefix . '[inputValue]">';
684  } elseif ($conf['comparison'] === 64) {
685  if (is_array($conf['inputValue'])) {
686  $conf['inputValue'] = $conf['inputValue'][0];
687  }
688  $lineHTML[] = '<select class="form-control t3js-submit-change" name="' . $fieldPrefix . '[inputValue]">';
689  } else {
690  $lineHTML[] = '<select class="form-control t3js-submit-change" name="' . $fieldPrefix . '[inputValue]' . '">';
691  }
692  if ($conf['comparison'] != 66 && $conf['comparison'] != 67) {
693  $lineHTML[] = $this->‪makeOptionList($fieldName, $conf, $this->table);
694  $lineHTML[] = '</select>';
695  }
696  $lineHTML[] = '</div>';
697  break;
698  case 'files':
699  $lineHTML[] = '<div class="form-inline">';
700  $lineHTML[] = $this->‪makeComparisonSelector($subscript, ‪$fieldName, $conf);
701  if ($conf['comparison'] === 68 || $conf['comparison'] === 69) {
702  $lineHTML[] = '<select class="form-control" name="' . $fieldPrefix . '[inputValue]' . '[]" multiple="multiple">';
703  } else {
704  $lineHTML[] = '<select class="form-control t3js-submit-change" name="' . $fieldPrefix . '[inputValue]' . '">';
705  }
706  $lineHTML[] = '<option value=""></option>' . $this->‪makeOptionList($fieldName, $conf, $this->table);
707  $lineHTML[] = '</select>';
708  if ($conf['comparison'] === 66 || $conf['comparison'] === 67) {
709  $lineHTML[] = ' + <input class="form-control t3js-clearable" type="text" value="' . htmlspecialchars($conf['inputValue1']) . '" name="' . $fieldPrefix . '[inputValue1]' . '">';
710  }
711  $lineHTML[] = '</div>';
712  break;
713  case 'boolean':
714  $lineHTML[] = '<div class="form-inline">';
715  $lineHTML[] = $this->‪makeComparisonSelector($subscript, ‪$fieldName, $conf);
716  $lineHTML[] = '<input type="hidden" value="1" name="' . $fieldPrefix . '[inputValue]' . '">';
717  $lineHTML[] = '</div>';
718  break;
719  default:
720  $lineHTML[] = '<div class="form-inline">';
721  $lineHTML[] = $this->‪makeComparisonSelector($subscript, ‪$fieldName, $conf);
722  if ($conf['comparison'] === 37 || $conf['comparison'] === 36) {
723  // between:
724  $lineHTML[] = '<input class="form-control t3js-clearable" type="text" value="' . htmlspecialchars($conf['inputValue']) . '" name="' . $fieldPrefix . '[inputValue]' . '">';
725  $lineHTML[] = '<input class="form-control t3js-clearable" type="text" value="' . htmlspecialchars($conf['inputValue1']) . '" name="' . $fieldPrefix . '[inputValue1]' . '">';
726  } else {
727  $lineHTML[] = '<input class="form-control t3js-clearable" type="text" value="' . htmlspecialchars($conf['inputValue']) . '" name="' . $fieldPrefix . '[inputValue]' . '">';
728  }
729  $lineHTML[] = '</div>';
730  }
731  if ($fieldType !== 'ignore') {
732  $lineHTML[] = '<div class="btn-group action-button-group">';
733  $lineHTML[] = $this->‪updateIcon();
734  if ($loopCount) {
735  $lineHTML[] = '<button class="btn btn-default" title="Remove condition" name="qG_del' . htmlspecialchars($subscript) . '"><i class="fa fa-trash fa-fw"></i></button>';
736  }
737  $lineHTML[] = '<button class="btn btn-default" title="Add condition" name="qG_ins' . htmlspecialchars($subscript) . '"><i class="fa fa-plus fa-fw"></i></button>';
738  if ($c != 0) {
739  $lineHTML[] = '<button class="btn btn-default" title="Move up" name="qG_up' . htmlspecialchars($subscript) . '"><i class="fa fa-chevron-up fa-fw"></i></button>';
740  }
741  if ($c != 0 && $fieldType !== 'newlevel') {
742  $lineHTML[] = '<button class="btn btn-default" title="New level" name="qG_nl' . htmlspecialchars($subscript) . '"><i class="fa fa-chevron-right fa-fw"></i></button>';
743  }
744  if ($fieldType === 'newlevel') {
745  $lineHTML[] = '<button class="btn btn-default" title="Collapse new level" name="qG_remnl' . htmlspecialchars($subscript) . '"><i class="fa fa-chevron-left fa-fw"></i></button>';
746  }
747  $lineHTML[] = '</div>';
748  $codeArr[$arrCount]['html'] = implode(LF, $lineHTML);
749  $codeArr[$arrCount]['query'] = $this->‪getQuerySingle($conf, $c > 0 ? 0 : 1);
750  $arrCount++;
751  $c++;
752  }
753  $loopCount = 1;
754  }
755  $this->queryConfig = ‪$queryConfig;
756  return $codeArr;
757  }
758 
766  protected function ‪makeComparisonSelector($subscript, ‪$fieldName, $conf)
767  {
768  $fieldPrefix = $this->name . $subscript;
769  $lineHTML = [];
770  $lineHTML[] = $this->‪mkTypeSelect($fieldPrefix . '[type]', ‪$fieldName);
771  $lineHTML[] = ' <div class="input-group">';
772  $lineHTML[] = $this->‪mkCompSelect($fieldPrefix . '[comparison]', $conf['comparison'], $conf['negate'] ? 1 : 0);
773  $lineHTML[] = ' <div class="input-group-addon">';
774  $lineHTML[] = ' <input type="checkbox" class="checkbox t3js-submit-click"' . ($conf['negate'] ? ' checked' : '') . ' name="' . htmlspecialchars($fieldPrefix) . '[negate]' . '">';
775  $lineHTML[] = ' </div>';
776  $lineHTML[] = ' </div>';
777  return implode(LF, $lineHTML);
778  }
779 
788  public function ‪makeOptionList(‪$fieldName, $conf, ‪$table)
789  {
790  $out = [];
791  $fieldSetup = $this->fields[‪$fieldName];
792  $languageService = $this->‪getLanguageService();
793  if ($fieldSetup['type'] === 'files') {
794  if ($conf['comparison'] === 66 || $conf['comparison'] === 67) {
795  $fileExtArray = explode(',', $fieldSetup['allowed']);
796  natcasesort($fileExtArray);
797  foreach ($fileExtArray as $fileExt) {
798  if (GeneralUtility::inList($conf['inputValue'], $fileExt)) {
799  $out[] = '<option value="' . htmlspecialchars($fileExt) . '" selected>.' . htmlspecialchars($fileExt) . '</option>';
800  } else {
801  $out[] = '<option value="' . htmlspecialchars($fileExt) . '">.' . htmlspecialchars($fileExt) . '</option>';
802  }
803  }
804  }
805  $d = dir(‪Environment::getPublicPath() . '/' . $fieldSetup['uploadfolder']);
806  while (false !== ($entry = $d->read())) {
807  if ($entry === '.' || $entry === '..') {
808  continue;
809  }
810  $fileArray[] = $entry;
811  }
812  $d->close();
813  natcasesort($fileArray);
814  foreach ($fileArray as $fileName) {
815  if (GeneralUtility::inList($conf['inputValue'], $fileName)) {
816  $out[] = '<option value="' . htmlspecialchars($fileName) . '" selected>' . htmlspecialchars($fileName) . '</option>';
817  } else {
818  $out[] = '<option value="' . htmlspecialchars($fileName) . '">' . htmlspecialchars($fileName) . '</option>';
819  }
820  }
821  }
822  if ($fieldSetup['type'] === 'multiple') {
823  $optGroupOpen = false;
824  foreach ($fieldSetup['items'] as $key => $val) {
825  if (strpos($val[0], 'LLL:') === 0) {
826  $value = $languageService->sL($val[0]);
827  } else {
828  $value = $val[0];
829  }
830  if ($val[1] === '--div--') {
831  if ($optGroupOpen) {
832  $out[] = '</optgroup>';
833  }
834  $optGroupOpen = true;
835  $out[] = '<optgroup label="' . htmlspecialchars($value) . '">';
836  } elseif (GeneralUtility::inList($conf['inputValue'], $val[1])) {
837  $out[] = '<option value="' . htmlspecialchars($val[1]) . '" selected>' . htmlspecialchars($value) . '</option>';
838  } else {
839  $out[] = '<option value="' . htmlspecialchars($val[1]) . '">' . htmlspecialchars($value) . '</option>';
840  }
841  }
842  if ($optGroupOpen) {
843  $out[] = '</optgroup>';
844  }
845  }
846  if ($fieldSetup['type'] === 'binary') {
847  foreach ($fieldSetup['items'] as $key => $val) {
848  if (strpos($val[0], 'LLL:') === 0) {
849  $value = $languageService->sL($val[0]);
850  } else {
851  $value = $val[0];
852  }
853  if (GeneralUtility::inList($conf['inputValue'], pow(2, $key))) {
854  $out[] = '<option value="' . pow(2, $key) . '" selected>' . htmlspecialchars($value) . '</option>';
855  } else {
856  $out[] = '<option value="' . pow(2, $key) . '">' . htmlspecialchars($value) . '</option>';
857  }
858  }
859  }
860  if ($fieldSetup['type'] === 'relation') {
861  $useTablePrefix = 0;
862  $dontPrefixFirstTable = 0;
863  if ($fieldSetup['items']) {
864  foreach ($fieldSetup['items'] as $key => $val) {
865  if (strpos($val[0], 'LLL:') === 0) {
866  $value = $languageService->sL($val[0]);
867  } else {
868  $value = $val[0];
869  }
870  if (GeneralUtility::inList($conf['inputValue'], $val[1])) {
871  $out[] = '<option value="' . htmlspecialchars($val[1]) . '" selected>' . htmlspecialchars($value) . '</option>';
872  } else {
873  $out[] = '<option value="' . htmlspecialchars($val[1]) . '">' . htmlspecialchars($value) . '</option>';
874  }
875  }
876  }
877  if (stristr($fieldSetup['allowed'], ',')) {
878  $from_table_Arr = explode(',', $fieldSetup['allowed']);
879  $useTablePrefix = 1;
880  if (!$fieldSetup['prepend_tname']) {
881  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable(‪$table);
882  $queryBuilder->getRestrictions()->removeAll()->add(GeneralUtility::makeInstance(DeletedRestriction::class));
883  $statement = $queryBuilder->select(‪$fieldName)
884  ->from(‪$table)
885  ->execute();
886  while ($row = $statement->fetch()) {
887  if (stristr($row[‪$fieldName], ',')) {
888  $checkContent = explode(',', $row[‪$fieldName]);
889  foreach ($checkContent as $singleValue) {
890  if (!stristr($singleValue, '_')) {
891  $dontPrefixFirstTable = 1;
892  }
893  }
894  } else {
895  $singleValue = $row[‪$fieldName];
896  if ($singleValue !== '' && !stristr($singleValue, '_')) {
897  $dontPrefixFirstTable = 1;
898  }
899  }
900  }
901  }
902  } else {
903  $from_table_Arr[0] = $fieldSetup['allowed'];
904  }
905  if ($fieldSetup['prepend_tname']) {
906  $useTablePrefix = 1;
907  }
908  if ($fieldSetup['foreign_table']) {
909  $from_table_Arr[0] = $fieldSetup['foreign_table'];
910  }
911  $counter = 0;
912  $tablePrefix = '';
913  $backendUserAuthentication = $this->‪getBackendUserAuthentication();
914  $module = $this->‪getModule();
915  $outArray = [];
916  $labelFieldSelect = [];
917  foreach ($from_table_Arr as $from_table) {
918  $useSelectLabels = false;
919  $useAltSelectLabels = false;
920  if ($useTablePrefix && !$dontPrefixFirstTable && $counter != 1 || $counter === 1) {
921  $tablePrefix = $from_table . '_';
922  }
923  $counter = 1;
924  if (is_array(‪$GLOBALS['TCA'][$from_table])) {
925  $labelField = ‪$GLOBALS['TCA'][$from_table]['ctrl']['label'];
926  $altLabelField = ‪$GLOBALS['TCA'][$from_table]['ctrl']['label_alt'];
927  if (‪$GLOBALS['TCA'][$from_table]['columns'][$labelField]['config']['items']) {
928  foreach (‪$GLOBALS['TCA'][$from_table]['columns'][$labelField]['config']['items'] as $labelArray) {
929  if (strpos($labelArray[0], 'LLL:') === 0) {
930  $labelFieldSelect[$labelArray[1]] = $languageService->sL($labelArray[0]);
931  } else {
932  $labelFieldSelect[$labelArray[1]] = $labelArray[0];
933  }
934  }
935  $useSelectLabels = true;
936  }
937  $altLabelFieldSelect = [];
938  if (‪$GLOBALS['TCA'][$from_table]['columns'][$altLabelField]['config']['items']) {
939  foreach (‪$GLOBALS['TCA'][$from_table]['columns'][$altLabelField]['config']['items'] as $altLabelArray) {
940  if (strpos($altLabelArray[0], 'LLL:') === 0) {
941  $altLabelFieldSelect[$altLabelArray[1]] = $languageService->sL($altLabelArray[0]);
942  } else {
943  $altLabelFieldSelect[$altLabelArray[1]] = $altLabelArray[0];
944  }
945  }
946  $useAltSelectLabels = true;
947  }
948 
949  if (!$this->tableArray[$from_table]) {
950  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($from_table);
951  if ($module->MOD_SETTINGS['show_deleted']) {
952  $queryBuilder->getRestrictions()->removeAll();
953  } else {
954  $queryBuilder->getRestrictions()->removeAll()->add(GeneralUtility::makeInstance(DeletedRestriction::class));
955  }
956  $selectFields = ['uid', $labelField];
957  if ($altLabelField) {
958  $selectFields[] = $altLabelField;
959  }
960  $queryBuilder->select(...$selectFields)
961  ->from($from_table)
962  ->orderBy('uid');
963  if (!$backendUserAuthentication->isAdmin() && ‪$GLOBALS['TYPO3_CONF_VARS']['BE']['lockBeUserToDBmounts']) {
964  $webMounts = $backendUserAuthentication->returnWebmounts();
965  $perms_clause = $backendUserAuthentication->getPagePermsClause(‪Permission::PAGE_SHOW);
966  $webMountPageTree = '';
967  $webMountPageTreePrefix = '';
968  foreach ($webMounts as $webMount) {
969  if ($webMountPageTree) {
970  $webMountPageTreePrefix = ',';
971  }
972  $webMountPageTree .= $webMountPageTreePrefix
973  . $this->‪getTreeList($webMount, 999, 0, $perms_clause);
974  }
975  if ($from_table === 'pages') {
976  $queryBuilder->where(
978  $queryBuilder->expr()->in(
979  'uid',
980  $queryBuilder->createNamedParameter(
981  GeneralUtility::intExplode(',', $webMountPageTree),
982  Connection::PARAM_INT_ARRAY
983  )
984  )
985  );
986  } else {
987  $queryBuilder->where(
988  $queryBuilder->expr()->in(
989  'pid',
990  $queryBuilder->createNamedParameter(
991  GeneralUtility::intExplode(',', $webMountPageTree),
992  Connection::PARAM_INT_ARRAY
993  )
994  )
995  );
996  }
997  }
998  $statement = $queryBuilder->execute();
999  $this->tableArray[$from_table] = [];
1000  while ($row = $statement->fetch()) {
1001  $this->tableArray[$from_table][] = $row;
1002  }
1003  }
1004 
1005  foreach ($this->tableArray[$from_table] as $key => $val) {
1006  if ($useSelectLabels) {
1007  $outArray[$tablePrefix . $val['uid']] = htmlspecialchars($labelFieldSelect[$val[$labelField]]);
1008  } elseif ($val[$labelField]) {
1009  $outArray[$tablePrefix . $val['uid']] = htmlspecialchars($val[$labelField]);
1010  } elseif ($useAltSelectLabels) {
1011  $outArray[$tablePrefix . $val['uid']] = htmlspecialchars($altLabelFieldSelect[$val[$altLabelField]]);
1012  } else {
1013  $outArray[$tablePrefix . $val['uid']] = htmlspecialchars($val[$altLabelField]);
1014  }
1015  }
1016  if ($module->MOD_SETTINGS['options_sortlabel'] && is_array($outArray)) {
1017  natcasesort($outArray);
1018  }
1019  }
1020  }
1021  foreach ($outArray as $key2 => $val2) {
1022  if (GeneralUtility::inList($conf['inputValue'], $key2)) {
1023  $out[] = '<option value="' . htmlspecialchars($key2) . '" selected>[' . htmlspecialchars($key2) . '] ' . htmlspecialchars($val2) . '</option>';
1024  } else {
1025  $out[] = '<option value="' . htmlspecialchars($key2) . '">[' . htmlspecialchars($key2) . '] ' . htmlspecialchars($val2) . '</option>';
1026  }
1027  }
1028  }
1029  return implode(LF, $out);
1030  }
1031 
1039  public function ‪printCodeArray($codeArr, $recursionLevel = 0)
1040  {
1041  $indent = 'row-group';
1042  if ($recursionLevel) {
1043  $indent = 'row-group indent indent-' . (int)$recursionLevel;
1044  }
1045  $out = [];
1046  foreach ($codeArr as $k => $v) {
1047  $out[] = '<div class="' . $indent . '">';
1048  $out[] = $v['html'];
1049 
1050  if ($this->enableQueryParts) {
1051  $out[] = '<pre>';
1052  $out[] = htmlspecialchars($v['query']);
1053  $out[] = '</pre>';
1054  }
1055  if (is_array($v['sub'])) {
1056  $out[] = '<div class="' . $indent . '">';
1057  $out[] = $this->‪printCodeArray($v['sub'], $recursionLevel + 1);
1058  $out[] = '</div>';
1059  }
1060 
1061  $out[] = '</div>';
1062  }
1063  return implode(LF, $out);
1064  }
1065 
1075  public function ‪mkOperatorSelect(‪$name, $op, $draw, $submit)
1076  {
1077  $out = [];
1078  if ($draw) {
1079  $out[] = '<select class="form-control from-control-operator' . ($submit ? ' t3js-submit-change' : '') . '" name="' . htmlspecialchars(‪$name) . '[operator]">';
1080  $out[] = ' <option value="AND"' . (!$op || $op === 'AND' ? ' selected' : '') . '>' . htmlspecialchars($this->lang['AND']) . '</option>';
1081  $out[] = ' <option value="OR"' . ($op === 'OR' ? ' selected' : '') . '>' . htmlspecialchars($this->lang['OR']) . '</option>';
1082  $out[] = '</select>';
1083  } else {
1084  $out[] = '<input type="hidden" value="' . htmlspecialchars($op) . '" name="' . htmlspecialchars(‪$name) . '[operator]">';
1085  }
1086  return implode(LF, $out);
1087  }
1088 
1097  public function ‪mkTypeSelect(‪$name, ‪$fieldName, $prepend = 'FIELD_')
1098  {
1099  $out = [];
1100  $out[] = '<select class="form-control t3js-submit-change" name="' . htmlspecialchars(‪$name) . '">';
1101  $out[] = '<option value=""></option>';
1102  foreach ($this->fields as $key => $value) {
1103  if (!$value['exclude'] || $this->‪getBackendUserAuthentication()->check('non_exclude_fields', $this->table . ':' . $key)) {
1104  $label = $this->fields[$key]['label'];
1105  $out[] = '<option value="' . htmlspecialchars($prepend . $key) . '"' . ($key === ‪$fieldName ? ' selected' : '') . '>' . htmlspecialchars($label) . '</option>';
1106  }
1107  }
1108  $out[] = '</select>';
1109  return implode(LF, $out);
1110  }
1111 
1118  public function ‪verifyType(‪$fieldName)
1119  {
1120  $first = '';
1121  foreach ($this->fields as $key => $value) {
1122  if (!$first) {
1123  $first = $key;
1124  }
1125  if ($key === ‪$fieldName) {
1126  return $key;
1127  }
1128  }
1129  return $first;
1130  }
1131 
1139  public function ‪verifyComparison($comparison, $neg)
1140  {
1141  $compOffSet = $comparison >> 5;
1142  $first = -1;
1143  for ($i = 32 * $compOffSet + $neg; $i < 32 * ($compOffSet + 1); $i += 2) {
1144  if ($first === -1) {
1145  $first = $i;
1146  }
1147  if ($i >> 1 === $comparison >> 1) {
1148  return $i;
1149  }
1150  }
1151  return $first;
1152  }
1153 
1162  {
1163  $out = [];
1164  $out[] = '<div class="input-group">';
1165  $out[] = ' <div class="input-group-addon">';
1166  $out[] = ' <span class="input-group-btn">';
1167  $out[] = $this->‪updateIcon();
1168  $out[] = ' </span>';
1169  $out[] = ' </div>';
1170  $out[] = ' <input type="text" class="form-control t3js-clearable" value="' . htmlspecialchars(‪$fieldName) . '" name="' . htmlspecialchars(‪$name) . '">';
1171  $out[] = '</div>';
1172 
1173  $out[] = '<select class="form-control t3js-addfield" name="_fieldListDummy" size="5" data-field="' . htmlspecialchars(‪$name) . '">';
1174  foreach ($this->fields as $key => $value) {
1175  if (!$value['exclude'] || $this->‪getBackendUserAuthentication()->check('non_exclude_fields', $this->table . ':' . $key)) {
1176  $label = $this->fields[$key]['label'];
1177  $out[] = '<option value="' . htmlspecialchars($key) . '"' . ($key === ‪$fieldName ? ' selected' : '') . '>' . htmlspecialchars($label) . '</option>';
1178  }
1179  }
1180  $out[] = '</select>';
1181  return implode(LF, $out);
1182  }
1183 
1191  public function ‪mkTableSelect(‪$name, $cur)
1192  {
1193  $out = [];
1194  $out[] = '<select class="form-control t3js-submit-change" name="' . ‪$name . '">';
1195  $out[] = '<option value=""></option>';
1196  foreach (‪$GLOBALS['TCA'] as $tN => $value) {
1197  if ($this->‪getBackendUserAuthentication()->check('tables_select', $tN)) {
1198  $out[] = '<option value="' . htmlspecialchars($tN) . '"' . ($tN === $cur ? ' selected' : '') . '>' . htmlspecialchars($this->‪getLanguageService()->‪sL(‪$GLOBALS['TCA'][$tN]['ctrl']['title'])) . '</option>';
1199  }
1200  }
1201  $out[] = '</select>';
1202  return implode(LF, $out);
1203  }
1204 
1213  public function ‪mkCompSelect(‪$name, $comparison, $neg)
1214  {
1215  $compOffSet = $comparison >> 5;
1216  $out = [];
1217  $out[] = '<select class="form-control t3js-submit-change" name="' . ‪$name . '">';
1218  for ($i = 32 * $compOffSet + $neg; $i < 32 * ($compOffSet + 1); $i += 2) {
1219  if ($this->lang['comparison'][$i . '_']) {
1220  $out[] = '<option value="' . $i . '"' . ($i >> 1 === $comparison >> 1 ? ' selected' : '') . '>' . htmlspecialchars($this->lang['comparison'][$i . '_']) . '</option>';
1221  }
1222  }
1223  $out[] = '</select>';
1224  return implode(LF, $out);
1225  }
1226 
1233  public function ‪getSubscript($arr): array
1234  {
1235  $retArr = [];
1236  while (\is_array($arr)) {
1237  reset($arr);
1238  $key = key($arr);
1239  $retArr[] = $key;
1240  if (isset($arr[$key])) {
1241  $arr = $arr[$key];
1242  } else {
1243  break;
1244  }
1245  }
1246  return $retArr;
1247  }
1248 
1252  public function ‪initUserDef()
1253  {
1254  }
1255 
1266  public function ‪userDef($fieldPrefix, $conf, ‪$fieldName, $fieldType)
1267  {
1268  return '';
1269  }
1270 
1277  public function ‪userDefCleanUp(‪$queryConfig)
1278  {
1279  return ‪$queryConfig;
1280  }
1281 
1289  public function ‪getQuery(‪$queryConfig, $pad = '')
1290  {
1291  $qs = '';
1292  // Since we don't traverse the array using numeric keys in the upcoming whileloop make sure it's fresh and clean
1293  ksort(‪$queryConfig);
1294  $first = 1;
1295  foreach (‪$queryConfig as $key => $conf) {
1296  $conf = $this->‪convertIso8601DatetimeStringToUnixTimestamp($conf);
1297  switch ($conf['type']) {
1298  case 'newlevel':
1299  $qs .= LF . $pad . trim($conf['operator']) . ' (' . $this->‪getQuery(
1300  ‪$queryConfig[$key]['nl'],
1301  $pad . ' '
1302  ) . LF . $pad . ')';
1303  break;
1304  case 'userdef':
1305  $qs .= LF . $pad . $this->‪getUserDefQuery($conf, $first);
1306  break;
1307  default:
1308  $qs .= LF . $pad . $this->‪getQuerySingle($conf, $first);
1309  }
1310  $first = 0;
1311  }
1312  return $qs;
1313  }
1314 
1321  protected function ‪convertIso8601DatetimeStringToUnixTimestamp(array $conf): array
1322  {
1323  if ($this->‪isDateOfIso8601Format($conf['inputValue'])) {
1324  $conf['inputValue'] = strtotime($conf['inputValue']);
1325  if ($this->‪isDateOfIso8601Format($conf['inputValue1'])) {
1326  $conf['inputValue1'] = strtotime($conf['inputValue1']);
1327  }
1328  }
1329 
1330  return $conf;
1331  }
1332 
1339  protected function ‪isDateOfIso8601Format($date): bool
1340  {
1341  if (!is_int($date) && !is_string($date)) {
1342  return false;
1343  }
1344  $format = 'Y-m-d\\TH:i:s\\Z';
1345  $formattedDate = \DateTime::createFromFormat($format, $date);
1346  return $formattedDate && $formattedDate->format($format) === $date;
1347  }
1348 
1356  public function ‪getQuerySingle($conf, $first)
1357  {
1358  $qs = '';
1359  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($this->table);
1360  $prefix = $this->enablePrefix ? $this->table . '.' : '';
1361  if (!$first) {
1362  // Is it OK to insert the AND operator if none is set?
1363  $operator = strtoupper(trim($conf['operator']));
1364  if (!in_array($operator, ['AND', 'OR'], true)) {
1365  $operator = 'AND';
1366  }
1367  $qs .= $operator . ' ';
1368  }
1369  $qsTmp = str_replace('#FIELD#', $prefix . trim(substr($conf['type'], 6)), $this->compSQL[$conf['comparison']]);
1370  $inputVal = $this->‪cleanInputVal($conf);
1371  if ($conf['comparison'] === 68 || $conf['comparison'] === 69) {
1372  $inputVal = explode(',', $inputVal);
1373  foreach ($inputVal as $key => $fileName) {
1374  $inputVal[$key] = $queryBuilder->quote($fileName);
1375  }
1376  $inputVal = implode(',', $inputVal);
1377  $qsTmp = str_replace('#VALUE#', $inputVal, $qsTmp);
1378  } elseif ($conf['comparison'] === 162 || $conf['comparison'] === 163) {
1379  $inputValArray = explode(',', $inputVal);
1380  $inputVal = 0;
1381  foreach ($inputValArray as $fileName) {
1382  $inputVal += (int)$fileName;
1383  }
1384  $qsTmp = str_replace('#VALUE#', $inputVal, $qsTmp);
1385  } else {
1386  if (is_array($inputVal)) {
1387  $inputVal = $inputVal[0];
1388  }
1389  $qsTmp = str_replace('#VALUE#', trim($queryBuilder->quote($inputVal), '\''), $qsTmp);
1390  }
1391  if ($conf['comparison'] === 37 || $conf['comparison'] === 36 || $conf['comparison'] === 66 || $conf['comparison'] === 67 || $conf['comparison'] === 100 || $conf['comparison'] === 101) {
1392  // between:
1393  $inputVal = $this->‪cleanInputVal($conf, '1');
1394  $qsTmp = str_replace('#VALUE1#', trim($queryBuilder->quote($inputVal), '\''), $qsTmp);
1395  }
1396  $qs .= trim($qsTmp);
1397  return $qs;
1398  }
1399 
1407  public function ‪cleanInputVal($conf, $suffix = '')
1408  {
1409  if ($conf['comparison'] >> 5 === 0 || ($conf['comparison'] === 32 || $conf['comparison'] === 33 || $conf['comparison'] === 64 || $conf['comparison'] === 65 || $conf['comparison'] === 66 || $conf['comparison'] === 67 || $conf['comparison'] === 96 || $conf['comparison'] === 97)) {
1410  $inputVal = $conf['inputValue' . $suffix];
1411  } elseif ($conf['comparison'] === 39 || $conf['comparison'] === 38) {
1412  // in list:
1413  $inputVal = implode(',', GeneralUtility::intExplode(',', $conf['inputValue' . $suffix]));
1414  } elseif ($conf['comparison'] === 68 || $conf['comparison'] === 69 || $conf['comparison'] === 162 || $conf['comparison'] === 163) {
1415  // in list:
1416  if (is_array($conf['inputValue' . $suffix])) {
1417  $inputVal = implode(',', $conf['inputValue' . $suffix]);
1418  } elseif ($conf['inputValue' . $suffix]) {
1419  $inputVal = $conf['inputValue' . $suffix];
1420  } else {
1421  $inputVal = 0;
1422  }
1423  } elseif (!is_array($conf['inputValue' . $suffix]) && strtotime($conf['inputValue' . $suffix])) {
1424  $inputVal = $conf['inputValue' . $suffix];
1425  } elseif (!is_array($conf['inputValue' . $suffix]) && ‪MathUtility::canBeInterpretedAsInteger($conf['inputValue' . $suffix])) {
1426  $inputVal = (int)$conf['inputValue' . $suffix];
1427  } else {
1428  // TODO: Six eyes looked at this code and nobody understood completely what is going on here and why we
1429  // fallback to float casting, the whole class smells like it needs a refactoring.
1430  $inputVal = (float)$conf['inputValue' . $suffix];
1431  }
1432  return $inputVal;
1433  }
1434 
1441  public function ‪getUserDefQuery($qcArr, $first)
1442  {
1443  }
1444 
1450  public function ‪updateIcon()
1451  {
1452  return '<button class="btn btn-default" title="Update" name="just_update"><i class="fa fa-refresh fa-fw"></i></button>';
1453  }
1454 
1460  public function ‪getLabelCol()
1461  {
1462  return ‪$GLOBALS['TCA'][‪$this->table]['ctrl']['label'];
1463  }
1464 
1472  public function ‪makeSelectorTable($modSettings, $enableList = 'table,fields,query,group,order,limit')
1473  {
1474  $out = [];
1475  $enableArr = explode(',', $enableList);
1476  $userTsConfig = $this->‪getBackendUserAuthentication()->‪getTSConfig();
1477 
1478  // Make output
1479  if (in_array('table', $enableArr) && !$userTsConfig['mod.']['dbint.']['disableSelectATable']) {
1480  $out[] = '<div class="form-group">';
1481  $out[] = ' <label for="SET[queryTable]">Select a table:</label>';
1482  $out[] = $this->‪mkTableSelect('SET[queryTable]', $this->table);
1483  $out[] = '</div>';
1484  }
1485  if ($this->table) {
1486  // Init fields:
1487  $this->‪setAndCleanUpExternalLists('queryFields', $modSettings['queryFields'], 'uid,' . $this->‪getLabelCol());
1488  $this->‪setAndCleanUpExternalLists('queryGroup', $modSettings['queryGroup']);
1489  $this->‪setAndCleanUpExternalLists('queryOrder', $modSettings['queryOrder'] . ',' . $modSettings['queryOrder2']);
1490  // Limit:
1491  $this->extFieldLists['queryLimit'] = $modSettings['queryLimit'];
1492  if (!$this->extFieldLists['queryLimit']) {
1493  $this->extFieldLists['queryLimit'] = 100;
1494  }
1495  $parts = GeneralUtility::intExplode(',', $this->extFieldLists['queryLimit']);
1496  if ($parts[1]) {
1497  $this->limitBegin = $parts[0];
1498  $this->limitLength = $parts[1];
1499  } else {
1500  $this->limitLength = $this->extFieldLists['queryLimit'];
1501  }
1502  $this->extFieldLists['queryLimit'] = implode(',', array_slice($parts, 0, 2));
1503  // Insert Descending parts
1504  if ($this->extFieldLists['queryOrder']) {
1505  $descParts = explode(',', $modSettings['queryOrderDesc'] . ',' . $modSettings['queryOrder2Desc']);
1506  $orderParts = explode(',', $this->extFieldLists['queryOrder']);
1507  $reList = [];
1508  foreach ($orderParts as $kk => $vv) {
1509  $reList[] = $vv . ($descParts[$kk] ? ' DESC' : '');
1510  }
1511  $this->extFieldLists['queryOrder_SQL'] = implode(',', $reList);
1512  }
1513  // Query Generator:
1514  $this->‪procesData($modSettings['queryConfig'] ? unserialize($modSettings['queryConfig'], ['allowed_classes' => false]) : '');
1515  $this->queryConfig = $this->‪cleanUpQueryConfig($this->queryConfig);
1516  $this->enableQueryParts = (bool)$modSettings['search_query_smallparts'];
1517  $codeArr = $this->‪getFormElements();
1518  $queryCode = $this->‪printCodeArray($codeArr);
1519  if (in_array('fields', $enableArr) && !$userTsConfig['mod.']['dbint.']['disableSelectFields']) {
1520  $out[] = '<div class="form-group form-group-with-button-addon">';
1521  $out[] = ' <label for="SET[queryFields]">Select fields:</label>';
1522  $out[] = $this->‪mkFieldToInputSelect('SET[queryFields]', $this->extFieldLists['queryFields']);
1523  $out[] = '</div>';
1524  }
1525  if (in_array('query', $enableArr) && !$userTsConfig['mod.']['dbint.']['disableMakeQuery']) {
1526  $out[] = '<div class="form-group">';
1527  $out[] = ' <label>Make Query:</label>';
1528  $out[] = $queryCode;
1529  $out[] = '</div>';
1530  }
1531  if (in_array('group', $enableArr) && !$userTsConfig['mod.']['dbint.']['disableGroupBy']) {
1532  $out[] = '<div class="form-group form-inline">';
1533  $out[] = ' <label for="SET[queryGroup]">Group By:</label>';
1534  $out[] = $this->‪mkTypeSelect('SET[queryGroup]', $this->extFieldLists['queryGroup'], '');
1535  $out[] = '</div>';
1536  }
1537  if (in_array('order', $enableArr) && !$userTsConfig['mod.']['dbint.']['disableOrderBy']) {
1538  $module = $this->‪getModule();
1539  $orderByArr = explode(',', $this->extFieldLists['queryOrder']);
1540  $orderBy = [];
1541  $orderBy[] = $this->‪mkTypeSelect('SET[queryOrder]', $orderByArr[0], '');
1542  $orderBy[] = '<div class="checkbox">';
1543  $orderBy[] = ' <label for="checkQueryOrderDesc">';
1544  $orderBy[] = ‪BackendUtility::getFuncCheck($module->id, 'SET[queryOrderDesc]', $modSettings['queryOrderDesc'], '', '', 'id="checkQueryOrderDesc"') . ' Descending';
1545  $orderBy[] = ' </label>';
1546  $orderBy[] = '</div>';
1547 
1548  if ($orderByArr[0]) {
1549  $orderBy[] = $this->‪mkTypeSelect('SET[queryOrder2]', $orderByArr[1], '');
1550  $orderBy[] = '<div class="checkbox">';
1551  $orderBy[] = ' <label for="checkQueryOrder2Desc">';
1552  $orderBy[] = ‪BackendUtility::getFuncCheck($module->id, 'SET[queryOrder2Desc]', $modSettings['queryOrder2Desc'], '', '', 'id="checkQueryOrder2Desc"') . ' Descending';
1553  $orderBy[] = ' </label>';
1554  $orderBy[] = '</div>';
1555  }
1556  $out[] = '<div class="form-group form-inline">';
1557  $out[] = ' <label>Order By:</label>';
1558  $out[] = implode(LF, $orderBy);
1559  $out[] = '</div>';
1560  }
1561  if (in_array('limit', $enableArr) && !$userTsConfig['mod.']['dbint.']['disableLimit']) {
1562  $limit = [];
1563  $limit[] = '<div class="input-group">';
1564  $limit[] = ' <div class="input-group-addon">';
1565  $limit[] = ' <span class="input-group-btn">';
1566  $limit[] = $this->‪updateIcon();
1567  $limit[] = ' </span>';
1568  $limit[] = ' </div>';
1569  $limit[] = ' <input type="text" class="form-control" value="' . htmlspecialchars($this->extFieldLists['queryLimit']) . '" name="SET[queryLimit]" id="queryLimit">';
1570  $limit[] = '</div>';
1571 
1572  $prevLimit = $this->limitBegin - $this->limitLength < 0 ? 0 : $this->limitBegin - ‪$this->limitLength;
1573  $prevButton = '';
1574  $nextButton = '';
1575 
1576  if ($this->limitBegin) {
1577  $prevButton = '<input type="button" class="btn btn-default" value="previous ' . htmlspecialchars($this->limitLength) . '" data-value="' . htmlspecialchars($prevLimit . ',' . $this->limitLength) . '">';
1578  }
1579  if (!$this->limitLength) {
1580  $this->limitLength = 100;
1581  }
1582 
1583  $nextLimit = $this->limitBegin + ‪$this->limitLength;
1584  if ($nextLimit < 0) {
1585  $nextLimit = 0;
1586  }
1587  if ($nextLimit) {
1588  $nextButton = '<input type="button" class="btn btn-default" value="next ' . htmlspecialchars($this->limitLength) . '" data-value="' . htmlspecialchars($nextLimit . ',' . $this->limitLength) . '">';
1589  }
1590 
1591  $out[] = '<div class="form-group form-group-with-button-addon">';
1592  $out[] = ' <label>Limit:</label>';
1593  $out[] = ' <div class="form-inline">';
1594  $out[] = implode(LF, $limit);
1595  $out[] = ' <div class="input-group">';
1596  $out[] = ' <div class="btn-group t3js-limit-submit">';
1597  $out[] = $prevButton;
1598  $out[] = $nextButton;
1599  $out[] = ' </div>';
1600  $out[] = ' <div class="btn-group t3js-limit-submit">';
1601  $out[] = ' <input type="button" class="btn btn-default" data-value="10" value="10">';
1602  $out[] = ' <input type="button" class="btn btn-default" data-value="20" value="20">';
1603  $out[] = ' <input type="button" class="btn btn-default" data-value="50" value="50">';
1604  $out[] = ' <input type="button" class="btn btn-default" data-value="100" value="100">';
1605  $out[] = ' </div>';
1606  $out[] = ' </div>';
1607  $out[] = ' </div>';
1608  $out[] = '</div>';
1609  }
1610  }
1611  return implode(LF, $out);
1612  }
1613 
1623  public function ‪getTreeList($id, $depth, $begin = 0, $permClause = '')
1624  {
1625  $depth = (int)$depth;
1626  $begin = (int)$begin;
1627  $id = (int)$id;
1628  if ($id < 0) {
1629  $id = abs($id);
1630  }
1631  if ($begin === 0) {
1632  $theList = $id;
1633  } else {
1634  $theList = '';
1635  }
1636  if ($id && $depth > 0) {
1637  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('pages');
1638  $queryBuilder->getRestrictions()->removeAll()->add(GeneralUtility::makeInstance(DeletedRestriction::class));
1639  $queryBuilder->select('uid')
1640  ->from('pages')
1641  ->where(
1642  $queryBuilder->expr()->eq('pid', $queryBuilder->createNamedParameter($id, \PDO::PARAM_INT)),
1643  $queryBuilder->expr()->eq('sys_language_uid', 0)
1644  )
1645  ->orderBy('uid');
1646  if ($permClause !== '') {
1647  $queryBuilder->andWhere(‪QueryHelper::stripLogicalOperatorPrefix($permClause));
1648  }
1649  $statement = $queryBuilder->execute();
1650  while ($row = $statement->fetch()) {
1651  if ($begin <= 0) {
1652  $theList .= ',' . $row['uid'];
1653  }
1654  if ($depth > 1) {
1655  $theSubList = $this->‪getTreeList($row['uid'], $depth - 1, $begin - 1, $permClause);
1656  if (!empty($theList) && !empty($theSubList) && ($theSubList[0] !== ',')) {
1657  $theList .= ',';
1658  }
1659  $theList .= $theSubList;
1660  }
1661  }
1662  }
1663  return $theList;
1664  }
1665 
1672  public function ‪getSelectQuery($qString = ''): string
1673  {
1674  $backendUserAuthentication = $this->‪getBackendUserAuthentication();
1675  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($this->table);
1676  if ($this->‪getModule()->MOD_SETTINGS['show_deleted']) {
1677  $queryBuilder->getRestrictions()->removeAll();
1678  } else {
1679  $queryBuilder->getRestrictions()->removeAll()->add(GeneralUtility::makeInstance(DeletedRestriction::class));
1680  }
1681  ‪$fieldList = GeneralUtility::trimExplode(
1682  ',',
1683  $this->extFieldLists['queryFields']
1684  . ',pid'
1685  . (‪$GLOBALS['TCA'][$this->table]['ctrl']['delete'] ? ',' . ‪$GLOBALS['TCA'][$this->table]['ctrl']['delete'] : '')
1686  );
1687  $queryBuilder->select(...‪$fieldList)
1688  ->from($this->table);
1689 
1690  if ($this->extFieldLists['queryGroup']) {
1691  $queryBuilder->groupBy(...‪QueryHelper::parseGroupBy($this->extFieldLists['queryGroup']));
1692  }
1693  if ($this->extFieldLists['queryOrder']) {
1694  foreach (‪QueryHelper::parseOrderBy($this->extFieldLists['queryOrder_SQL']) as $orderPair) {
1695  list(‪$fieldName, $order) = $orderPair;
1696  $queryBuilder->addOrderBy(‪$fieldName, $order);
1697  }
1698  }
1699  if ($this->extFieldLists['queryLimit']) {
1700  $queryBuilder->setMaxResults((int)$this->extFieldLists['queryLimit']);
1701  }
1702 
1703  if (!$backendUserAuthentication->isAdmin() && ‪$GLOBALS['TYPO3_CONF_VARS']['BE']['lockBeUserToDBmounts']) {
1704  $webMounts = $backendUserAuthentication->returnWebmounts();
1705  $perms_clause = $backendUserAuthentication->getPagePermsClause(‪Permission::PAGE_SHOW);
1706  $webMountPageTree = '';
1707  $webMountPageTreePrefix = '';
1708  foreach ($webMounts as $webMount) {
1709  if ($webMountPageTree) {
1710  $webMountPageTreePrefix = ',';
1711  }
1712  $webMountPageTree .= $webMountPageTreePrefix
1713  . $this->‪getTreeList($webMount, 999, $begin = 0, $perms_clause);
1714  }
1715  // createNamedParameter() is not used here because the SQL fragment will only include
1716  // the :dcValueX placeholder when the query is returned as a string. The value for the
1717  // placeholder would be lost in the process.
1718  if ($this->table === 'pages') {
1719  $queryBuilder->where(
1721  $queryBuilder->expr()->in(
1722  'uid',
1723  GeneralUtility::intExplode(',', $webMountPageTree)
1724  )
1725  );
1726  } else {
1727  $queryBuilder->where(
1728  $queryBuilder->expr()->in(
1729  'pid',
1730  GeneralUtility::intExplode(',', $webMountPageTree)
1731  )
1732  );
1733  }
1734  }
1735  if (!$qString) {
1736  $qString = $this->‪getQuery($this->queryConfig);
1737  }
1738  $queryBuilder->andWhere(‪QueryHelper::stripLogicalOperatorPrefix($qString));
1739 
1740  return $queryBuilder->getSQL();
1741  }
1742 
1750  protected function ‪getDateTimePickerField(‪$name, $timestamp, $type)
1751  {
1752  $value = strtotime($timestamp) ? date(‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['hhmm'] . ' ' . ‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy'], strtotime($timestamp)) : '';
1753  $id = ‪StringUtility::getUniqueId('dt_');
1754  $html = [];
1755  $html[] = '<div class="input-group" id="' . $id . '-wrapper">';
1756  $html[] = ' <input data-formengine-input-name="' . htmlspecialchars(‪$name) . '" value="' . $value . '" class="form-control t3js-datetimepicker t3js-clearable" data-date-type="' . htmlspecialchars($type) . '" type="text" id="' . $id . '">';
1757  $html[] = ' <input name="' . htmlspecialchars(‪$name) . '" value="' . htmlspecialchars($timestamp) . '" type="hidden">';
1758  $html[] = ' <span class="input-group-btn">';
1759  $html[] = ' <label class="btn btn-default" for="' . $id . '">';
1760  $html[] = ' <span class="fa fa-calendar"></span>';
1761  $html[] = ' </label>';
1762  $html[] = ' </span>';
1763  $html[] = '</div>';
1764  return implode(LF, $html);
1765  }
1766 
1772  public function ‪setFormName(‪$formName)
1773  {
1774  $this->formName = trim(‪$formName);
1775  }
1776 
1780  protected function ‪getBackendUserAuthentication()
1781  {
1782  return ‪$GLOBALS['BE_USER'];
1783  }
1784 
1788  protected function ‪getModule()
1789  {
1790  return ‪$GLOBALS['SOBE'];
1791  }
1792 
1796  protected function ‪getLanguageService()
1797  {
1798  return ‪$GLOBALS['LANG'];
1799  }
1800 }
‪TYPO3\CMS\Core\Database\QueryGenerator\procesData
‪procesData($qC='')
Definition: QueryGenerator.php:421
‪TYPO3\CMS\Core\Database\Query\QueryHelper\parseOrderBy
‪static array array[] parseOrderBy(string $input)
Definition: QueryHelper.php:42
‪TYPO3\CMS\Core\Database\QueryGenerator\$fieldName
‪string $fieldName
Definition: QueryGenerator.php:230
‪TYPO3\CMS\Core\Database\QueryGenerator\mkTableSelect
‪string mkTableSelect($name, $cur)
Definition: QueryGenerator.php:1174
‪TYPO3\CMS\Core\Utility\MathUtility\canBeInterpretedAsInteger
‪static bool canBeInterpretedAsInteger($var)
Definition: MathUtility.php:73
‪TYPO3\CMS\Core\Core\Environment\getPublicPath
‪static string getPublicPath()
Definition: Environment.php:153
‪TYPO3\CMS\Core\Database\QueryGenerator\cleanInputVal
‪string cleanInputVal($conf, $suffix='')
Definition: QueryGenerator.php:1390
‪TYPO3\CMS\Core\Database\QueryGenerator\getLabelCol
‪string getLabelCol()
Definition: QueryGenerator.php:1443
‪TYPO3\CMS\Core\Database\QueryGenerator\convertIso8601DatetimeStringToUnixTimestamp
‪array convertIso8601DatetimeStringToUnixTimestamp(array $conf)
Definition: QueryGenerator.php:1304
‪TYPO3\CMS\Core\Database\QueryGenerator\userDef
‪string userDef($fieldPrefix, $conf, $fieldName, $fieldType)
Definition: QueryGenerator.php:1249
‪TYPO3\CMS\Core\Database\QueryGenerator\getModule
‪BaseScriptClass getModule()
Definition: QueryGenerator.php:1771
‪TYPO3\CMS\Core\Database\QueryGenerator\verifyComparison
‪int verifyComparison($comparison, $neg)
Definition: QueryGenerator.php:1122
‪TYPO3\CMS\Core\Database\QueryGenerator\getBackendUserAuthentication
‪BackendUserAuthentication getBackendUserAuthentication()
Definition: QueryGenerator.php:1763
‪TYPO3\CMS\Core\Database\Query\QueryHelper\parseGroupBy
‪static array string[] parseGroupBy(string $input)
Definition: QueryHelper.php:100
‪TYPO3\CMS\Core\Database\QueryGenerator\userDefCleanUp
‪array userDefCleanUp($queryConfig)
Definition: QueryGenerator.php:1260
‪TYPO3\CMS\Core\Database\QueryGenerator\$fields
‪array $fields
Definition: QueryGenerator.php:196
‪TYPO3\CMS\Core\Database\QueryGenerator\$name
‪string $name
Definition: QueryGenerator.php:174
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\getTSConfig
‪array getTSConfig($objectString=null, $config=null)
Definition: BackendUserAuthentication.php:1232
‪TYPO3\CMS\Core\Database\QueryGenerator\isDateOfIso8601Format
‪bool isDateOfIso8601Format($date)
Definition: QueryGenerator.php:1322
‪TYPO3\CMS\Core\Database\QueryGenerator\makeOptionList
‪string makeOptionList($fieldName, $conf, $table)
Definition: QueryGenerator.php:771
‪TYPO3\CMS\Core\Database\QueryGenerator\$fieldList
‪string $fieldList
Definition: QueryGenerator.php:190
‪TYPO3\CMS\Core\Database\QueryGenerator\initUserDef
‪initUserDef()
Definition: QueryGenerator.php:1235
‪TYPO3\CMS\Core\Database\QueryGenerator\getSelectQuery
‪string getSelectQuery($qString='')
Definition: QueryGenerator.php:1655
‪TYPO3\CMS\Core\Database\QueryGenerator\setAndCleanUpExternalLists
‪setAndCleanUpExternalLists($name, $list, $force='')
Definition: QueryGenerator.php:404
‪TYPO3\CMS\Core\Localization\LanguageService\sL
‪string sL($input)
Definition: LanguageService.php:158
‪TYPO3\CMS\Core\Database\QueryGenerator\verifyType
‪string verifyType($fieldName)
Definition: QueryGenerator.php:1101
‪TYPO3\CMS\Core\Database\QueryGenerator\$enableQueryParts
‪bool $enableQueryParts
Definition: QueryGenerator.php:214
‪TYPO3\CMS\Core\Database\QueryGenerator\$noWrap
‪string $noWrap
Definition: QueryGenerator.php:168
‪TYPO3\CMS\Core\Database\QueryGenerator\mkOperatorSelect
‪string mkOperatorSelect($name, $op, $draw, $submit)
Definition: QueryGenerator.php:1058
‪TYPO3\CMS\Core\Database\QueryGenerator
Definition: QueryGenerator.php:33
‪TYPO3\CMS\Core\Type\Bitmask\Permission
Definition: Permission.php:23
‪TYPO3\CMS\Core\Database\QueryGenerator\$limitLength
‪int $limitLength
Definition: QueryGenerator.php:226
‪TYPO3\CMS\Core\Database\QueryGenerator\setFormName
‪setFormName($formName)
Definition: QueryGenerator.php:1755
‪TYPO3\CMS\Core\Database\QueryGenerator\makeSelectorTable
‪string makeSelectorTable($modSettings, $enableList='table, fields, query, group, order, limit')
Definition: QueryGenerator.php:1455
‪TYPO3\CMS\Core\Database\QueryGenerator\getSubscript
‪array getSubscript($arr)
Definition: QueryGenerator.php:1216
‪TYPO3\CMS\Core\Database\QueryGenerator\$tableArray
‪array $tableArray
Definition: QueryGenerator.php:184
‪TYPO3\CMS\Core\Database\QueryGenerator\$formName
‪string $formName
Definition: QueryGenerator.php:218
‪TYPO3\CMS\Core\Database\Query\QueryHelper
Definition: QueryHelper.php:30
‪TYPO3\CMS\Backend\Module\BaseScriptClass
Definition: BaseScriptClass.php:72
‪TYPO3\CMS\Core\Database\QueryGenerator\getFormElements
‪array getFormElements($subLevel=0, $queryConfig='', $parent='')
Definition: QueryGenerator.php:587
‪TYPO3\CMS\Core\Database\QueryGenerator\$limitBegin
‪int $limitBegin
Definition: QueryGenerator.php:222
‪TYPO3\CMS\Core\Database\QueryGenerator\$table
‪string $table
Definition: QueryGenerator.php:180
‪TYPO3\CMS\Core\Database\QueryGenerator\getQuerySingle
‪string getQuerySingle($conf, $first)
Definition: QueryGenerator.php:1339
‪TYPO3\CMS\Backend\Utility\BackendUtility\getFuncCheck
‪static string getFuncCheck( $mainParams, $elementName, $currentValue, $script='', $addParams='', $tagParams='')
Definition: BackendUtility.php:3054
‪TYPO3\CMS\Core\Database\QueryGenerator\$compSQL
‪array $compSQL
Definition: QueryGenerator.php:97
‪TYPO3\CMS\Core\Database\QueryGenerator\$lang
‪array $lang
Definition: QueryGenerator.php:36
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication
Definition: BackendUserAuthentication.php:45
‪TYPO3\CMS\Core\Type\Bitmask\Permission\PAGE_SHOW
‪const PAGE_SHOW
Definition: Permission.php:32
‪TYPO3\CMS\Backend\Utility\BackendUtility
Definition: BackendUtility.php:72
‪TYPO3\CMS\Core\Database\QueryGenerator\mkTypeSelect
‪string mkTypeSelect($name, $fieldName, $prepend='FIELD_')
Definition: QueryGenerator.php:1080
‪TYPO3\CMS\Core\Database\QueryGenerator\$comp_offsets
‪array $comp_offsets
Definition: QueryGenerator.php:154
‪TYPO3\CMS\Core\Database\QueryGenerator\$extFieldLists
‪array $extFieldLists
Definition: QueryGenerator.php:200
‪TYPO3\CMS\Core\Database\QueryGenerator\makeComparisonSelector
‪string makeComparisonSelector($subscript, $fieldName, $conf)
Definition: QueryGenerator.php:749
‪TYPO3\CMS\Core\Database\QueryGenerator\getLanguageService
‪LanguageService getLanguageService()
Definition: QueryGenerator.php:1779
‪TYPO3\CMS\Core\Database\QueryGenerator\cleanUpQueryConfig
‪array cleanUpQueryConfig($queryConfig)
Definition: QueryGenerator.php:530
‪TYPO3\CMS\Core\Database\QueryGenerator\makeFieldList
‪string makeFieldList()
Definition: QueryGenerator.php:237
‪TYPO3\CMS\Core\Utility\StringUtility\getUniqueId
‪static string getUniqueId($prefix='')
Definition: StringUtility.php:91
‪TYPO3\CMS\Core\Database\Query\QueryHelper\stripLogicalOperatorPrefix
‪static string stripLogicalOperatorPrefix(string $constraint)
Definition: QueryHelper.php:163
‪TYPO3\CMS\Core\Database\QueryGenerator\getDateTimePickerField
‪string getDateTimePickerField($name, $timestamp, $type)
Definition: QueryGenerator.php:1733
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:5
‪TYPO3\CMS\Core\Database\QueryGenerator\getUserDefQuery
‪getUserDefQuery($qcArr, $first)
Definition: QueryGenerator.php:1424
‪TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction
Definition: DeletedRestriction.php:26
‪TYPO3\CMS\Core\Core\Environment
Definition: Environment.php:39
‪TYPO3\CMS\Core\Database\QueryGenerator\getQuery
‪string getQuery($queryConfig, $pad='')
Definition: QueryGenerator.php:1272
‪TYPO3\CMS\Core\Database\QueryGenerator\mkCompSelect
‪string mkCompSelect($name, $comparison, $neg)
Definition: QueryGenerator.php:1196
‪TYPO3\CMS\Core\Utility\MathUtility
Definition: MathUtility.php:21
‪TYPO3\CMS\Core\Database\QueryGenerator\$enablePrefix
‪bool $enablePrefix
Definition: QueryGenerator.php:210
‪TYPO3\CMS\Core\Localization\LanguageService
Definition: LanguageService.php:29
‪TYPO3\CMS\Core\Database\QueryGenerator\mkFieldToInputSelect
‪string mkFieldToInputSelect($name, $fieldName)
Definition: QueryGenerator.php:1144
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:45
‪TYPO3\CMS\Core\Database\QueryGenerator\updateIcon
‪string updateIcon()
Definition: QueryGenerator.php:1433
‪TYPO3\CMS\Core\Utility\StringUtility
Definition: StringUtility.php:21
‪TYPO3\CMS\Core\Database\QueryGenerator\printCodeArray
‪string printCodeArray($codeArr, $recursionLevel=0)
Definition: QueryGenerator.php:1022
‪TYPO3\CMS\Core\Database\QueryGenerator\init
‪init($name, $table, $fieldList='')
Definition: QueryGenerator.php:268
‪TYPO3\CMS\Core\Database\QueryGenerator\$queryConfig
‪array $queryConfig
Definition: QueryGenerator.php:206
‪TYPO3\CMS\Core\Database
Definition: Connection.php:3
‪TYPO3\CMS\Core\Database\QueryGenerator\getTreeList
‪string getTreeList($id, $depth, $begin=0, $permClause='')
Definition: QueryGenerator.php:1606