[TASK] Change HTML code to match Bootstrap layout
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Classes / Database / QueryGenerator.php
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
17 use TYPO3\CMS\Backend\Utility\BackendUtility;
18
19 /**
20 * Class for generating front end for building queries
21 *
22 * @author Christian Jul Jensen <christian@typo3.com>
23 * @author Kasper Skårhøj <kasperYYYY@typo3.com>
24 * @coauthor Jo Hasenau <info@cybercraft.de>
25 */
26 class QueryGenerator {
27
28 /**
29 * @todo Define visibility
30 */
31 public $lang = array(
32 'OR' => 'or',
33 'AND' => 'and',
34 'comparison' => array(
35 // Type = text offset = 0
36 '0_' => 'contains',
37 '1_' => 'does not contain',
38 '2_' => 'starts with',
39 '3_' => 'does not start with',
40 '4_' => 'ends with',
41 '5_' => 'does not end with',
42 '6_' => 'equals',
43 '7_' => 'does not equal',
44 // Type = number , offset = 32
45 '32_' => 'equals',
46 '33_' => 'does not equal',
47 '34_' => 'is greater than',
48 '35_' => 'is less than',
49 '36_' => 'is between',
50 '37_' => 'is not between',
51 '38_' => 'is in list',
52 '39_' => 'is not in list',
53 '40_' => 'binary AND equals',
54 '41_' => 'binary AND does not equal',
55 '42_' => 'binary OR equals',
56 '43_' => 'binary OR does not equal',
57 // Type = multiple, relation, files , offset = 64
58 '64_' => 'equals',
59 '65_' => 'does not equal',
60 '66_' => 'contains',
61 '67_' => 'does not contain',
62 '68_' => 'is in list',
63 '69_' => 'is not in list',
64 '70_' => 'binary AND equals',
65 '71_' => 'binary AND does not equal',
66 '72_' => 'binary OR equals',
67 '73_' => 'binary OR does not equal',
68 // Type = date,time offset = 96
69 '96_' => 'equals',
70 '97_' => 'does not equal',
71 '98_' => 'is greater than',
72 '99_' => 'is less than',
73 '100_' => 'is between',
74 '101_' => 'is not between',
75 '102_' => 'binary AND equals',
76 '103_' => 'binary AND does not equal',
77 '104_' => 'binary OR equals',
78 '105_' => 'binary OR does not equal',
79 // Type = boolean, offset = 128
80 '128_' => 'is True',
81 '129_' => 'is False',
82 // Type = binary , offset = 160
83 '160_' => 'equals',
84 '161_' => 'does not equal',
85 '162_' => 'contains',
86 '163_' => 'does not contain'
87 )
88 );
89
90 /**
91 * @todo Define visibility
92 */
93 public $compSQL = array(
94 // Type = text offset = 0
95 '0' => '#FIELD# LIKE \'%#VALUE#%\'',
96 '1' => '#FIELD# NOT LIKE \'%#VALUE#%\'',
97 '2' => '#FIELD# LIKE \'#VALUE#%\'',
98 '3' => '#FIELD# NOT LIKE \'#VALUE#%\'',
99 '4' => '#FIELD# LIKE \'%#VALUE#\'',
100 '5' => '#FIELD# NOT LIKE \'%#VALUE#\'',
101 '6' => '#FIELD# = \'#VALUE#\'',
102 '7' => '#FIELD# != \'#VALUE#\'',
103 // Type = number, offset = 32
104 '32' => '#FIELD# = \'#VALUE#\'',
105 '33' => '#FIELD# != \'#VALUE#\'',
106 '34' => '#FIELD# > #VALUE#',
107 '35' => '#FIELD# < #VALUE#',
108 '36' => '#FIELD# >= #VALUE# AND #FIELD# <= #VALUE1#',
109 '37' => 'NOT (#FIELD# >= #VALUE# AND #FIELD# <= #VALUE1#)',
110 '38' => '#FIELD# IN (#VALUE#)',
111 '39' => '#FIELD# NOT IN (#VALUE#)',
112 '40' => '(#FIELD# & #VALUE#)=#VALUE#',
113 '41' => '(#FIELD# & #VALUE#)!=#VALUE#',
114 '42' => '(#FIELD# | #VALUE#)=#VALUE#',
115 '43' => '(#FIELD# | #VALUE#)!=#VALUE#',
116 // Type = multiple, relation, files , offset = 64
117 '64' => '#FIELD# = \'#VALUE#\'',
118 '65' => '#FIELD# != \'#VALUE#\'',
119 '66' => '#FIELD# LIKE \'%#VALUE#%\' AND #FIELD# LIKE \'%#VALUE1#%\'',
120 '67' => '(#FIELD# NOT LIKE \'%#VALUE#%\' OR #FIELD# NOT LIKE \'%#VALUE1#%\')',
121 '68' => '#FIELD# IN (#VALUE#)',
122 '69' => '#FIELD# NOT IN (#VALUE#)',
123 '70' => '(#FIELD# & #VALUE#)=#VALUE#',
124 '71' => '(#FIELD# & #VALUE#)!=#VALUE#',
125 '72' => '(#FIELD# | #VALUE#)=#VALUE#',
126 '73' => '(#FIELD# | #VALUE#)!=#VALUE#',
127 // Type = date, offset = 32
128 '96' => '#FIELD# = \'#VALUE#\'',
129 '97' => '#FIELD# != \'#VALUE#\'',
130 '98' => '#FIELD# > #VALUE#',
131 '99' => '#FIELD# < #VALUE#',
132 '100' => '#FIELD# >= #VALUE# AND #FIELD# <= #VALUE1#',
133 '101' => 'NOT (#FIELD# >= #VALUE# AND #FIELD# <= #VALUE1#)',
134 '102' => '(#FIELD# & #VALUE#)=#VALUE#',
135 '103' => '(#FIELD# & #VALUE#)!=#VALUE#',
136 '104' => '(#FIELD# | #VALUE#)=#VALUE#',
137 '105' => '(#FIELD# | #VALUE#)!=#VALUE#',
138 // Type = boolean, offset = 128
139 '128' => '#FIELD# = \'1\'',
140 '129' => '#FIELD# != \'1\'',
141 // Type = binary = 160
142 '160' => '#FIELD# = \'#VALUE#\'',
143 '161' => '#FIELD# != \'#VALUE#\'',
144 '162' => '(#FIELD# & #VALUE#)=#VALUE#',
145 '163' => '(#FIELD# & #VALUE#)=0'
146 );
147
148 /**
149 * @todo Define visibility
150 */
151 public $comp_offsets = array(
152 'text' => 0,
153 'number' => 1,
154 'multiple' => 2,
155 'relation' => 2,
156 'files' => 2,
157 'date' => 3,
158 'time' => 3,
159 'boolean' => 4,
160 'binary' => 5
161 );
162
163 /**
164 * @todo Define visibility
165 */
166 public $noWrap = ' nowrap';
167
168 // Form data name prefix
169 /**
170 * @todo Define visibility
171 */
172 public $name;
173
174 // Table for the query
175 /**
176 * @todo Define visibility
177 */
178 public $table;
179
180 // Field list
181 /**
182 * @todo Define visibility
183 */
184 public $fieldList;
185
186 // Array of the fields possible
187 /**
188 * @todo Define visibility
189 */
190 public $fields = array();
191
192 /**
193 * @todo Define visibility
194 */
195 public $extFieldLists = array();
196
197 // The query config
198 /**
199 * @todo Define visibility
200 */
201 public $queryConfig = array();
202
203 /**
204 * @todo Define visibility
205 */
206 public $enablePrefix = 0;
207
208 /**
209 * @todo Define visibility
210 */
211 public $enableQueryParts = 0;
212
213 /**
214 * @todo Define visibility
215 */
216 public $extJSCODE = '';
217
218 protected $formName = '';
219
220 /**
221 * Make a list of fields for current table
222 *
223 * @return string Separated list of fields
224 * @todo Define visibility
225 */
226 public function makeFieldList() {
227 $fieldListArr = array();
228 if (is_array($GLOBALS['TCA'][$this->table])) {
229 foreach ($GLOBALS['TCA'][$this->table]['columns'] as $fN => $value) {
230 $fieldListArr[] = $fN;
231 }
232 $fieldListArr[] = 'uid';
233 $fieldListArr[] = 'pid';
234 $fieldListArr[] = 'deleted';
235 if ($GLOBALS['TCA'][$this->table]['ctrl']['tstamp']) {
236 $fieldListArr[] = $GLOBALS['TCA'][$this->table]['ctrl']['tstamp'];
237 }
238 if ($GLOBALS['TCA'][$this->table]['ctrl']['crdate']) {
239 $fieldListArr[] = $GLOBALS['TCA'][$this->table]['ctrl']['crdate'];
240 }
241 if ($GLOBALS['TCA'][$this->table]['ctrl']['cruser_id']) {
242 $fieldListArr[] = $GLOBALS['TCA'][$this->table]['ctrl']['cruser_id'];
243 }
244 if ($GLOBALS['TCA'][$this->table]['ctrl']['sortby']) {
245 $fieldListArr[] = $GLOBALS['TCA'][$this->table]['ctrl']['sortby'];
246 }
247 }
248 return implode(',', $fieldListArr);
249 }
250
251 /**
252 * [Describe function...]
253 *
254 * @param [type] $name: ...
255 * @param [type] $table: ...
256 * @param [type] $fieldList: ...
257 * @return [type] ...
258 * @todo Define visibility
259 */
260 public function init($name, $table, $fieldList = '') {
261 // Analysing the fields in the table.
262 if (is_array($GLOBALS['TCA'][$table])) {
263 $this->name = $name;
264 $this->table = $table;
265 $this->fieldList = $fieldList ? $fieldList : $this->makeFieldList();
266 $fieldArr = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $this->fieldList, TRUE);
267 foreach ($fieldArr as $fN) {
268 $fC = $GLOBALS['TCA'][$this->table]['columns'][$fN];
269 $this->fields[$fN] = $fC['config'];
270 $this->fields[$fN]['exclude'] = $fC['exclude'];
271 if (is_array($fC) && $fC['label']) {
272 $this->fields[$fN]['label'] = rtrim(trim($GLOBALS['LANG']->sL($fC['label'])), ':');
273 switch ($this->fields[$fN]['type']) {
274 case 'input':
275 if (preg_match('/int|year/i', $this->fields[$fN]['eval'])) {
276 $this->fields[$fN]['type'] = 'number';
277 } elseif (preg_match('/time/i', $this->fields[$fN]['eval'])) {
278 $this->fields[$fN]['type'] = 'time';
279 } elseif (preg_match('/date/i', $this->fields[$fN]['eval'])) {
280 $this->fields[$fN]['type'] = 'date';
281 } else {
282 $this->fields[$fN]['type'] = 'text';
283 }
284 break;
285 case 'check':
286 if (!$this->fields[$fN]['items']) {
287 $this->fields[$fN]['type'] = 'boolean';
288 } else {
289 $this->fields[$fN]['type'] = 'binary';
290 }
291 break;
292 case 'radio':
293 $this->fields[$fN]['type'] = 'multiple';
294 break;
295 case 'select':
296 $this->fields[$fN]['type'] = 'multiple';
297 if ($this->fields[$fN]['foreign_table']) {
298 $this->fields[$fN]['type'] = 'relation';
299 }
300 if ($this->fields[$fN]['special']) {
301 $this->fields[$fN]['type'] = 'text';
302 }
303 break;
304 case 'group':
305 $this->fields[$fN]['type'] = 'files';
306 if ($this->fields[$fN]['internal_type'] == 'db') {
307 $this->fields[$fN]['type'] = 'relation';
308 }
309 break;
310 case 'user':
311
312 case 'flex':
313
314 case 'passthrough':
315
316 case 'none':
317
318 case 'text':
319
320 default:
321 $this->fields[$fN]['type'] = 'text';
322 }
323 } else {
324 $this->fields[$fN]['label'] = '[FIELD: ' . $fN . ']';
325 switch ($fN) {
326 case 'pid':
327 $this->fields[$fN]['type'] = 'relation';
328 $this->fields[$fN]['allowed'] = 'pages';
329 break;
330 case 'cruser_id':
331 $this->fields[$fN]['type'] = 'relation';
332 $this->fields[$fN]['allowed'] = 'be_users';
333 break;
334 case 'tstamp':
335
336 case 'crdate':
337 $this->fields[$fN]['type'] = 'time';
338 break;
339 case 'deleted':
340 $this->fields[$fN]['type'] = 'boolean';
341 break;
342 default:
343 $this->fields[$fN]['type'] = 'number';
344 }
345 }
346 }
347 }
348 /* // EXAMPLE:
349 $this->queryConfig = array(
350 array(
351 'operator' => 'AND',
352 'type' => 'FIELD_spaceBefore',
353 ),
354 array(
355 'operator' => 'AND',
356 'type' => 'FIELD_records',
357 'negate' => 1,
358 'inputValue' => 'foo foo'
359 ),
360 array(
361 'type' => 'newlevel',
362 'nl' => array(
363 array(
364 'operator' => 'AND',
365 'type' => 'FIELD_spaceBefore',
366 'negate' => 1,
367 'inputValue' => 'foo foo'
368 ),
369 array(
370 'operator' => 'AND',
371 'type' => 'FIELD_records',
372 'negate' => 1,
373 'inputValue' => 'foo foo'
374 )
375 )
376 ),
377 array(
378 'operator' => 'OR',
379 'type' => 'FIELD_maillist',
380 )
381 );
382 */
383 $this->initUserDef();
384 }
385
386 /**
387 * [Describe function...]
388 *
389 * @param [type] $name: ...
390 * @param [type] $list: ...
391 * @param [type] $force: ...
392 * @return [type] ...
393 * @todo Define visibility
394 */
395 public function setAndCleanUpExternalLists($name, $list, $force = '') {
396 $fields = array_unique(\TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $list . ',' . $force, TRUE));
397 $reList = array();
398 foreach ($fields as $fN) {
399 if ($this->fields[$fN]) {
400 $reList[] = $fN;
401 }
402 }
403 $this->extFieldLists[$name] = implode(',', $reList);
404 }
405
406 /**
407 * [Describe function...]
408 *
409 * @param [type] $qC: ...
410 * @return [type] ...
411 * @todo Define visibility
412 */
413 public function procesData($qC = '') {
414 $this->queryConfig = $qC;
415 $POST = \TYPO3\CMS\Core\Utility\GeneralUtility::_POST();
416 // If delete...
417 if ($POST['qG_del']) {
418 // Initialize array to work on, save special parameters
419 $ssArr = $this->getSubscript($POST['qG_del']);
420 $workArr = &$this->queryConfig;
421 $ssArrSize = sizeof($ssArr) - 1;
422 for ($i = 0; $i < $ssArrSize; $i++) {
423 $workArr = &$workArr[$ssArr[$i]];
424 }
425 // Delete the entry and move the other entries
426 unset($workArr[$ssArr[$i]]);
427 $workArrSize = sizeof($workArr);
428 for ($j = $ssArr[$i]; $j < $workArrSize; $j++) {
429 $workArr[$j] = $workArr[$j + 1];
430 unset($workArr[$j + 1]);
431 }
432 }
433 // If insert...
434 if ($POST['qG_ins']) {
435 // Initialize array to work on, save special parameters
436 $ssArr = $this->getSubscript($POST['qG_ins']);
437 $workArr = &$this->queryConfig;
438 $ssArrSize = sizeof($ssArr) - 1;
439 for ($i = 0; $i < $ssArrSize; $i++) {
440 $workArr = &$workArr[$ssArr[$i]];
441 }
442 // Move all entries above position where new entry is to be inserted
443 $workArrSize = sizeof($workArr);
444 for ($j = $workArrSize; $j > $ssArr[$i]; $j--) {
445 $workArr[$j] = $workArr[$j - 1];
446 }
447 // Clear new entry position
448 unset($workArr[$ssArr[$i] + 1]);
449 $workArr[$ssArr[$i] + 1]['type'] = 'FIELD_';
450 }
451 // If move up...
452 if ($POST['qG_up']) {
453 // Initialize array to work on
454 $ssArr = $this->getSubscript($POST['qG_up']);
455 $workArr = &$this->queryConfig;
456 $ssArrSize = sizeof($ssArr) - 1;
457 for ($i = 0; $i < $ssArrSize; $i++) {
458 $workArr = &$workArr[$ssArr[$i]];
459 }
460 // Swap entries
461 $qG_tmp = $workArr[$ssArr[$i]];
462 $workArr[$ssArr[$i]] = $workArr[$ssArr[$i] - 1];
463 $workArr[$ssArr[$i] - 1] = $qG_tmp;
464 }
465 // If new level...
466 if ($POST['qG_nl']) {
467 // Initialize array to work on
468 $ssArr = $this->getSubscript($POST['qG_nl']);
469 $workArr = &$this->queryConfig;
470 $ssArraySize = sizeof($ssArr) - 1;
471 for ($i = 0; $i < $ssArraySize; $i++) {
472 $workArr = &$workArr[$ssArr[$i]];
473 }
474 // Do stuff:
475 $tempEl = $workArr[$ssArr[$i]];
476 if (is_array($tempEl)) {
477 if ($tempEl['type'] != 'newlevel') {
478 $workArr[$ssArr[$i]] = array(
479 'type' => 'newlevel',
480 'operator' => $tempEl['operator'],
481 'nl' => array($tempEl)
482 );
483 }
484 }
485 }
486 // If collapse level...
487 if ($POST['qG_remnl']) {
488 // Initialize array to work on
489 $ssArr = $this->getSubscript($POST['qG_remnl']);
490 $workArr = &$this->queryConfig;
491 $ssArrSize = sizeof($ssArr) - 1;
492 for ($i = 0; $i < $ssArrSize; $i++) {
493 $workArr = &$workArr[$ssArr[$i]];
494 }
495 // Do stuff:
496 $tempEl = $workArr[$ssArr[$i]];
497 if (is_array($tempEl)) {
498 if ($tempEl['type'] == 'newlevel') {
499 $a1 = array_slice($workArr, 0, $ssArr[$i]);
500 $a2 = array_slice($workArr, $ssArr[$i]);
501 array_shift($a2);
502 $a3 = $tempEl['nl'];
503 $a3[0]['operator'] = $tempEl['operator'];
504 $workArr = array_merge($a1, $a3, $a2);
505 }
506 }
507 }
508 }
509
510 /**
511 * [Describe function...]
512 *
513 * @param [type] $queryConfig: ...
514 * @return [type] ...
515 * @todo Define visibility
516 */
517 public function cleanUpQueryConfig($queryConfig) {
518 // Since we dont traverse the array using numeric keys in the upcoming whileloop make sure it's fresh and clean before displaying
519 if (is_array($queryConfig)) {
520 ksort($queryConfig);
521 } else {
522 // queryConfig should never be empty!
523 if (!$queryConfig[0] || !$queryConfig[0]['type']) {
524 $queryConfig[0] = array('type' => 'FIELD_');
525 }
526 }
527 // Traverse:
528 $c = 0;
529 $arrCount = 0;
530 foreach ($queryConfig as $key => $conf) {
531 if (substr($conf['type'], 0, 6) == 'FIELD_') {
532 $fName = substr($conf['type'], 6);
533 $fType = $this->fields[$fName]['type'];
534 } elseif ($conf['type'] == 'newlevel') {
535 $fType = $conf['type'];
536 } else {
537 $fType = 'ignore';
538 }
539 switch ($fType) {
540 case 'newlevel':
541 if (!$queryConfig[$key]['nl']) {
542 $queryConfig[$key]['nl'][0]['type'] = 'FIELD_';
543 }
544 $queryConfig[$key]['nl'] = $this->cleanUpQueryConfig($queryConfig[$key]['nl']);
545 break;
546 case 'userdef':
547 $queryConfig[$key] = $this->userDefCleanUp($queryConfig[$key]);
548 break;
549 case 'ignore':
550
551 default:
552 $verifiedName = $this->verifyType($fName);
553 $queryConfig[$key]['type'] = 'FIELD_' . $this->verifyType($verifiedName);
554 if ($conf['comparison'] >> 5 != $this->comp_offsets[$fType]) {
555 $conf['comparison'] = $this->comp_offsets[$fType] << 5;
556 }
557 $queryConfig[$key]['comparison'] = $this->verifyComparison($conf['comparison'], $conf['negate'] ? 1 : 0);
558 $queryConfig[$key]['inputValue'] = $this->cleanInputVal($queryConfig[$key]);
559 $queryConfig[$key]['inputValue1'] = $this->cleanInputVal($queryConfig[$key], 1);
560 }
561 }
562 return $queryConfig;
563 }
564
565 /**
566 * [Describe function...]
567 *
568 * @param [type] $subLevel: ...
569 * @param [type] $queryConfig: ...
570 * @param [type] $parent: ...
571 * @return [type] ...
572 * @todo Define visibility
573 */
574 public function getFormElements($subLevel = 0, $queryConfig = '', $parent = '') {
575 $codeArr = array();
576 if (!is_array($queryConfig)) {
577 $queryConfig = $this->queryConfig;
578 }
579 $c = 0;
580 $arrCount = 0;
581 $loopcount = 0;
582 foreach ($queryConfig as $key => $conf) {
583 $subscript = $parent . '[' . $key . ']';
584 $lineHTML = '';
585 $lineHTML .= $this->mkOperatorSelect($this->name . $subscript, $conf['operator'], $c, $conf['type'] != 'FIELD_');
586 if (substr($conf['type'], 0, 6) == 'FIELD_') {
587 $fName = substr($conf['type'], 6);
588 $this->fieldName = $fName;
589 $fType = $this->fields[$fName]['type'];
590 if ($conf['comparison'] >> 5 != $this->comp_offsets[$fType]) {
591 $conf['comparison'] = $this->comp_offsets[$fType] << 5;
592 }
593 //nasty nasty...
594 //make sure queryConfig contains _actual_ comparevalue.
595 //mkCompSelect don't care, but getQuery does.
596 $queryConfig[$key]['comparison'] += isset($conf['negate']) - $conf['comparison'] % 2;
597 } elseif ($conf['type'] == 'newlevel') {
598 $fType = $conf['type'];
599 } else {
600 $fType = 'ignore';
601 }
602 switch ($fType) {
603 case 'ignore':
604 break;
605 case 'newlevel':
606 if (!$queryConfig[$key]['nl']) {
607 $queryConfig[$key]['nl'][0]['type'] = 'FIELD_';
608 }
609 $lineHTML .= '<input type="hidden" name="' . $this->name . $subscript . '[type]" value="newlevel">';
610 $codeArr[$arrCount]['sub'] = $this->getFormElements($subLevel + 1, $queryConfig[$key]['nl'], $subscript . '[nl]');
611 break;
612 case 'userdef':
613 $lineHTML .= $this->userDef($this->name . $subscript, $conf, $fName, $fType);
614 break;
615 case 'date':
616 $lineHTML .= $this->mkTypeSelect($this->name . $subscript . '[type]', $fName);
617 $lineHTML .= $this->mkCompSelect($this->name . $subscript . '[comparison]', $conf['comparison'], $conf['negate'] ? 1 : 0);
618 $lineHTML .= '<input type="checkbox" class="checkbox"' . ($conf['negate'] ? ' checked' : '') . ' name="' . $this->name . $subscript . '[negate]' . '" onClick="submit();">';
619 if ($conf['comparison'] == 100 || $conf['comparison'] == 101) {
620 // between
621 $lineHTML .= '<input type="text" name="' . $this->name . $subscript . '[inputValue]_hr' . '" value="' . strftime('%e-%m-%Y', $conf['inputValue']) . '" ' . $GLOBALS['TBE_TEMPLATE']->formWidth(10) . ' onChange="typo3form.fieldGet(\'' . $this->name . $subscript . '[inputValue]\', \'date\', \'\', 0,0);"><input type="hidden" value="' . htmlspecialchars($conf['inputValue']) . '" name="' . $this->name . $subscript . '[inputValue]' . '">';
622 $lineHTML .= '<input type="text" name="' . $this->name . $subscript . '[inputValue1]_hr' . '" value="' . strftime('%e-%m-%Y', $conf['inputValue1']) . '" ' . $GLOBALS['TBE_TEMPLATE']->formWidth(10) . ' onChange="typo3form.fieldGet(\'' . $this->name . $subscript . '[inputValue1]\', \'date\', \'\', 0,0);"><input type="hidden" value="' . htmlspecialchars($conf['inputValue1']) . '" name="' . $this->name . $subscript . '[inputValue1]' . '">';
623 $this->extJSCODE .= 'typo3form.fieldSet("' . $this->name . $subscript . '[inputValue]", "date", "", 0,0);';
624 $this->extJSCODE .= 'typo3form.fieldSet("' . $this->name . $subscript . '[inputValue1]", "date", "", 0,0);';
625 } else {
626 $lineHTML .= '<input type="text" name="' . $this->name . $subscript . '[inputValue]_hr' . '" value="' . strftime('%e-%m-%Y', $conf['inputValue']) . '" ' . $GLOBALS['TBE_TEMPLATE']->formWidth(10) . ' onChange="typo3form.fieldGet(\'' . $this->name . $subscript . '[inputValue]\', \'date\', \'\', 0,0);"><input type="hidden" value="' . htmlspecialchars($conf['inputValue']) . '" name="' . $this->name . $subscript . '[inputValue]' . '">';
627 $this->extJSCODE .= 'typo3form.fieldSet("' . $this->name . $subscript . '[inputValue]", "date", "", 0,0);';
628 }
629 break;
630 case 'time':
631 $lineHTML .= $this->mkTypeSelect($this->name . $subscript . '[type]', $fName);
632 $lineHTML .= $this->mkCompSelect($this->name . $subscript . '[comparison]', $conf['comparison'], $conf['negate'] ? 1 : 0);
633 $lineHTML .= '<input type="checkbox" class="checkbox"' . ($conf['negate'] ? ' checked' : '') . ' name="' . $this->name . $subscript . '[negate]' . '" onClick="submit();">';
634 if ($conf['comparison'] == 100 || $conf['comparison'] == 101) {
635 // between:
636 $lineHTML .= '<input type="text" name="' . $this->name . $subscript . '[inputValue]_hr' . '" value="' . strftime('%H:%M %e-%m-%Y', $conf['inputValue']) . '" ' . $GLOBALS['TBE_TEMPLATE']->formWidth(10) . ' onChange="typo3form.fieldGet(\'' . $this->name . $subscript . '[inputValue]\', \'datetime\', \'\', 0,0);"><input type="hidden" value="' . htmlspecialchars($conf['inputValue']) . '" name="' . $this->name . $subscript . '[inputValue]' . '">';
637 $lineHTML .= '<input type="text" name="' . $this->name . $subscript . '[inputValue1]_hr' . '" value="' . strftime('%H:%M %e-%m-%Y', $conf['inputValue1']) . '" ' . $GLOBALS['TBE_TEMPLATE']->formWidth(10) . ' onChange="typo3form.fieldGet(\'' . $this->name . $subscript . '[inputValue1]\', \'datetime\', \'\', 0,0);"><input type="hidden" value="' . htmlspecialchars($conf['inputValue1']) . '" name="' . $this->name . $subscript . '[inputValue1]' . '">';
638 $this->extJSCODE .= 'typo3form.fieldSet("' . $this->name . $subscript . '[inputValue]", "datetime", "", 0,0);';
639 $this->extJSCODE .= 'typo3form.fieldSet("' . $this->name . $subscript . '[inputValue1]", "datetime", "", 0,0);';
640 } else {
641 $lineHTML .= '<input type="text" name="' . $this->name . $subscript . '[inputValue]_hr' . '" value="' . strftime('%H:%M %e-%m-%Y', (int)$conf['inputValue']) . '" ' . $GLOBALS['TBE_TEMPLATE']->formWidth(10) . ' onChange="typo3form.fieldGet(\'' . $this->name . $subscript . '[inputValue]\', \'datetime\', \'\', 0,0);"><input type="hidden" value="' . htmlspecialchars($conf['inputValue']) . '" name="' . $this->name . $subscript . '[inputValue]' . '">';
642 $this->extJSCODE .= 'typo3form.fieldSet("' . $this->name . $subscript . '[inputValue]", "datetime", "", 0,0);';
643 }
644 break;
645 case 'multiple':
646
647 case 'binary':
648
649 case 'relation':
650 $lineHTML .= $this->mkTypeSelect($this->name . $subscript . '[type]', $fName);
651 $lineHTML .= $this->mkCompSelect($this->name . $subscript . '[comparison]', $conf['comparison'], $conf['negate'] ? 1 : 0);
652 $lineHTML .= '<input type="checkbox" class="checkbox"' . ($conf['negate'] ? ' checked' : '') . ' name="' . $this->name . $subscript . '[negate]' . '" onClick="submit();">';
653 if ($conf['comparison'] == 68 || $conf['comparison'] == 69 || $conf['comparison'] == 162 || $conf['comparison'] == 163) {
654 $lineHTML .= '<select name="' . $this->name . $subscript . '[inputValue]' . '[]" style="vertical-align:top;" size="5" multiple>';
655 } elseif ($conf['comparison'] == 66 || $conf['comparison'] == 67) {
656 if (is_array($conf['inputValue'])) {
657 $conf['inputValue'] = implode(',', $conf['inputValue']);
658 }
659 $lineHTML .= '<input type="text" value="' . htmlspecialchars($conf['inputValue']) . '" name="' . $this->name . $subscript . '[inputValue]' . '"' . $GLOBALS['TBE_TEMPLATE']->formWidth(10) . '>';
660 } else {
661 $lineHTML .= '<select name="' . $this->name . $subscript . '[inputValue]' . '" style="vertical-align:top;" onChange="submit();">';
662 }
663 if ($conf['comparison'] != 66 && $conf['comparison'] != 67) {
664 $lineHTML .= $this->makeOptionList($fName, $conf, $this->table);
665 $lineHTML .= '</select>';
666 }
667 break;
668 case 'files':
669 $lineHTML .= $this->mkTypeSelect($this->name . $subscript . '[type]', $fName);
670 $lineHTML .= $this->mkCompSelect($this->name . $subscript . '[comparison]', $conf['comparison'], $conf['negate'] ? 1 : 0);
671 $lineHTML .= '<input type="checkbox" class="checkbox"' . ($conf['negate'] ? ' checked' : '') . ' name="' . $this->name . $subscript . '[negate]' . '" onClick="submit();">';
672 if ($conf['comparison'] == 68 || $conf['comparison'] == 69) {
673 $lineHTML .= '<select name="' . $this->name . $subscript . '[inputValue]' . '[]" style="vertical-align:top;" size="5" multiple>';
674 } else {
675 $lineHTML .= '<select name="' . $this->name . $subscript . '[inputValue]' . '" style="vertical-align:top;" onChange="submit();">';
676 }
677 $lineHTML .= '<option value=""></option>' . $this->makeOptionList($fName, $conf, $this->table);
678 $lineHTML .= '</select>';
679 if ($conf['comparison'] == 66 || $conf['comparison'] == 67) {
680 $lineHTML .= ' + <input type="text" value="' . htmlspecialchars($conf['inputValue1']) . '" name="' . $this->name . $subscript . '[inputValue1]' . '"' . $GLOBALS['TBE_TEMPLATE']->formWidth(10) . '>';
681 }
682 break;
683 case 'boolean':
684 $lineHTML .= $this->mkTypeSelect($this->name . $subscript . '[type]', $fName);
685 $lineHTML .= $this->mkCompSelect($this->name . $subscript . '[comparison]', $conf['comparison'], $conf['negate'] ? 1 : 0);
686 $lineHTML .= '<input type="checkbox" class="checkbox"' . ($conf['negate'] ? ' checked' : '') . ' name="' . $this->name . $subscript . '[negate]' . '" onClick="submit();">';
687 $lineHTML .= '<input type="hidden" value="1" name="' . $this->name . $subscript . '[inputValue]' . '"' . $GLOBALS['TBE_TEMPLATE']->formWidth(10) . '>';
688 break;
689 default:
690 $lineHTML .= $this->mkTypeSelect($this->name . $subscript . '[type]', $fName);
691 $lineHTML .= $this->mkCompSelect($this->name . $subscript . '[comparison]', $conf['comparison'], $conf['negate'] ? 1 : 0);
692 $lineHTML .= '<input type="checkbox" class="checkbox"' . ($conf['negate'] ? ' checked' : '') . ' name="' . $this->name . $subscript . '[negate]' . '" onClick="submit();">';
693 if ($conf['comparison'] == 37 || $conf['comparison'] == 36) {
694 // between:
695 $lineHTML .= '<input type="text" value="' . htmlspecialchars($conf['inputValue']) . '" name="' . $this->name . $subscript . '[inputValue]' . '"' . $GLOBALS['TBE_TEMPLATE']->formWidth(5) . '>
696 <input type="text" value="' . htmlspecialchars($conf['inputValue1']) . '" name="' . $this->name . $subscript . '[inputValue1]' . '"' . $GLOBALS['TBE_TEMPLATE']->formWidth(5) . '>';
697 } else {
698 $lineHTML .= '<input type="text" value="' . htmlspecialchars($conf['inputValue']) . '" name="' . $this->name . $subscript . '[inputValue]' . '"' . $GLOBALS['TBE_TEMPLATE']->formWidth(10) . '>';
699 }
700 }
701 if ($fType != 'ignore') {
702 $lineHTML .= $this->updateIcon();
703 if ($loopcount) {
704 $lineHTML .= '<input type="image" border="0" ' . \TYPO3\CMS\Backend\Utility\IconUtility::skinImg($GLOBALS['BACK_PATH'], 'gfx/garbage.gif', 'width="11" height="12"') . 'title="Remove condition" name="qG_del' . $subscript . '">';
705 }
706 $lineHTML .= '<input type="image" border="0" ' . \TYPO3\CMS\Backend\Utility\IconUtility::skinImg($GLOBALS['BACK_PATH'], 'gfx/add.gif', 'width="12" height="12"') . ' title="Add condition" name="qG_ins' . $subscript . '">';
707 if ($c != 0) {
708 $lineHTML .= '<input type="image" border="0" ' . \TYPO3\CMS\Backend\Utility\IconUtility::skinImg($GLOBALS['BACK_PATH'], 'gfx/pil2up.gif', 'width="12" height="7"') . ' title="Move up" name="qG_up' . $subscript . '">';
709 }
710 if ($c != 0 && $fType != 'newlevel') {
711 $lineHTML .= '<input type="image" border="0" ' . \TYPO3\CMS\Backend\Utility\IconUtility::skinImg($GLOBALS['BACK_PATH'], 'gfx/pil2right.gif', 'height="12" width="7"') . ' title="New level" name="qG_nl' . $subscript . '">';
712 }
713 if ($fType == 'newlevel') {
714 $lineHTML .= '<input type="image" border="0" ' . \TYPO3\CMS\Backend\Utility\IconUtility::skinImg($GLOBALS['BACK_PATH'], 'gfx/pil2left.gif', 'height="12" width="7"') . ' title="Collapse new level" name="qG_remnl' . $subscript . '">';
715 }
716 $codeArr[$arrCount]['html'] = $lineHTML;
717 $codeArr[$arrCount]['query'] = $this->getQuerySingle($conf, $c > 0 ? 0 : 1);
718 $arrCount++;
719 $c++;
720 }
721 $loopcount = 1;
722 }
723 $this->queryConfig = $queryConfig;
724 return $codeArr;
725 }
726
727 /**
728 * [Describe function...]
729 *
730 * @param [type] $codeArr: ...
731 * @param [type] $l: ...
732 * @param [type] $table: ...
733 * @return [type] ...
734 * @todo Define visibility
735 */
736 public function makeOptionList($fN, $conf, $table) {
737 $out = '';
738 $fieldSetup = $this->fields[$fN];
739 if ($fieldSetup['type'] == 'files') {
740 if ($conf['comparison'] == 66 || $conf['comparison'] == 67) {
741 $fileExtArray = explode(',', $fieldSetup['allowed']);
742 natcasesort($fileExtArray);
743 foreach ($fileExtArray as $fileExt) {
744 if (\TYPO3\CMS\Core\Utility\GeneralUtility::inList($conf['inputValue'], $fileExt)) {
745 $out .= '<option value="' . $fileExt . '" selected>.' . $fileExt . '</option>';
746 } else {
747 $out .= '<option value="' . $fileExt . '">.' . $fileExt . '</option>';
748 }
749 }
750 }
751 $d = dir(PATH_site . $fieldSetup['uploadfolder']);
752 while (FALSE !== ($entry = $d->read())) {
753 if ($entry == '.' || $entry == '..') {
754 continue;
755 }
756 $fileArray[] = $entry;
757 }
758 $d->close();
759 natcasesort($fileArray);
760 foreach ($fileArray as $fileName) {
761 if (\TYPO3\CMS\Core\Utility\GeneralUtility::inList($conf['inputValue'], $fileName)) {
762 $out .= '<option value="' . $fileName . '" selected>' . $fileName . '</option>';
763 } else {
764 $out .= '<option value="' . $fileName . '">' . $fileName . '</option>';
765 }
766 }
767 }
768 if ($fieldSetup['type'] == 'multiple') {
769 foreach ($fieldSetup['items'] as $key => $val) {
770 if (substr($val[0], 0, 4) == 'LLL:') {
771 $value = $GLOBALS['LANG']->sL($val[0]);
772 } else {
773 $value = $val[0];
774 }
775 if (\TYPO3\CMS\Core\Utility\GeneralUtility::inList($conf['inputValue'], $val[1])) {
776 $out .= '<option value="' . $val[1] . '" selected>' . $value . '</option>';
777 } else {
778 $out .= '<option value="' . $val[1] . '">' . $value . '</option>';
779 }
780 }
781 }
782 if ($fieldSetup['type'] == 'binary') {
783 foreach ($fieldSetup['items'] as $key => $val) {
784 if (substr($val[0], 0, 4) == 'LLL:') {
785 $value = $GLOBALS['LANG']->sL($val[0]);
786 } else {
787 $value = $val[0];
788 }
789 if (\TYPO3\CMS\Core\Utility\GeneralUtility::inList($conf['inputValue'], pow(2, $key))) {
790 $out .= '<option value="' . pow(2, $key) . '" selected>' . $value . '</option>';
791 } else {
792 $out .= '<option value="' . pow(2, $key) . '">' . $value . '</option>';
793 }
794 }
795 }
796 if ($fieldSetup['type'] == 'relation') {
797 if ($fieldSetup['items']) {
798 foreach ($fieldSetup['items'] as $key => $val) {
799 if (substr($val[0], 0, 4) == 'LLL:') {
800 $value = $GLOBALS['LANG']->sL($val[0]);
801 } else {
802 $value = $val[0];
803 }
804 if (\TYPO3\CMS\Core\Utility\GeneralUtility::inList($conf['inputValue'], $val[1])) {
805 $out .= '<option value="' . $val[1] . '" selected>' . $value . '</option>';
806 } else {
807 $out .= '<option value="' . $val[1] . '">' . $value . '</option>';
808 }
809 }
810 }
811 if (stristr($fieldSetup['allowed'], ',')) {
812 $from_table_Arr = explode(',', $fieldSetup['allowed']);
813 $useTablePrefix = 1;
814 if (!$fieldSetup['prepend_tname']) {
815 $checkres = $GLOBALS['TYPO3_DB']->exec_SELECTquery($fN, $table, BackendUtility::deleteClause($table), ($groupBy = ''), ($orderBy = ''), ($limit = ''));
816 if ($checkres) {
817 while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($checkres)) {
818 if (stristr($row[$fN], ',')) {
819 $checkContent = explode(',', $row[$fN]);
820 foreach ($checkContent as $singleValue) {
821 if (!stristr($singleValue, '_')) {
822 $dontPrefixFirstTable = 1;
823 }
824 }
825 } else {
826 $singleValue = $row[$fN];
827 if (strlen($singleValue) && !stristr($singleValue, '_')) {
828 $dontPrefixFirstTable = 1;
829 }
830 }
831 }
832 $GLOBALS['TYPO3_DB']->sql_free_result($checkres);
833 }
834 }
835 } else {
836 $from_table_Arr[0] = $fieldSetup['allowed'];
837 }
838 if ($fieldSetup['prepend_tname']) {
839 $useTablePrefix = 1;
840 }
841 if ($fieldSetup['foreign_table']) {
842 $from_table_Arr[0] = $fieldSetup['foreign_table'];
843 }
844 $counter = 0;
845 $webMountPageTree = '';
846 while (list(, $from_table) = each($from_table_Arr)) {
847 if ($useTablePrefix && !$dontPrefixFirstTable && $counter != 1 || $counter == 1) {
848 $tablePrefix = $from_table . '_';
849 }
850 $counter = 1;
851 if (is_array($GLOBALS['TCA'][$from_table])) {
852 $labelField = $GLOBALS['TCA'][$from_table]['ctrl']['label'];
853 $altLabelField = $GLOBALS['TCA'][$from_table]['ctrl']['label_alt'];
854 if ($GLOBALS['TCA'][$from_table]['columns'][$labelField]['config']['items']) {
855 foreach ($GLOBALS['TCA'][$from_table]['columns'][$labelField]['config']['items'] as $labelArray) {
856 if (substr($labelArray[0], 0, 4) == 'LLL:') {
857 $labelFieldSelect[$labelArray[1]] = $GLOBALS['LANG']->sL($labelArray[0]);
858 } else {
859 $labelFieldSelect[$labelArray[1]] = $labelArray[0];
860 }
861 }
862 $useSelectLabels = 1;
863 }
864 if ($GLOBALS['TCA'][$from_table]['columns'][$altLabelField]['config']['items']) {
865 foreach ($GLOBALS['TCA'][$from_table]['columns'][$altLabelField]['config']['items'] as $altLabelArray) {
866 if (substr($altLabelArray[0], 0, 4) == 'LLL:') {
867 $altLabelFieldSelect[$altLabelArray[1]] = $GLOBALS['LANG']->sL($altLabelArray[0]);
868 } else {
869 $altLabelFieldSelect[$altLabelArray[1]] = $altLabelArray[0];
870 }
871 }
872 $useAltSelectLabels = 1;
873 }
874 $altLabelFieldSelect = $altLabelField ? ',' . $altLabelField : '';
875 $select_fields = 'uid,' . $labelField . $altLabelFieldSelect;
876 if (!$GLOBALS['BE_USER']->isAdmin() && $GLOBALS['TYPO3_CONF_VARS']['BE']['lockBeUserToDBmounts']) {
877 $webMounts = $GLOBALS['BE_USER']->returnWebmounts();
878 $perms_clause = $GLOBALS['BE_USER']->getPagePermsClause(1);
879 foreach ($webMounts as $key => $val) {
880 if ($webMountPageTree) {
881 $webMountPageTreePrefix = ',';
882 }
883 $webMountPageTree .= $webMountPageTreePrefix . $this->getTreeList($val, 999, ($begin = 0), $perms_clause);
884 }
885 if ($from_table == 'pages') {
886 $where_clause = 'uid IN (' . $webMountPageTree . ') ';
887 if (!$GLOBALS['SOBE']->MOD_SETTINGS['show_deleted']) {
888 $where_clause .= BackendUtility::deleteClause($from_table) . ' AND' . $perms_clause;
889 }
890 } else {
891 $where_clause = 'pid IN (' . $webMountPageTree . ') ';
892 if (!$GLOBALS['SOBE']->MOD_SETTINGS['show_deleted']) {
893 $where_clause .= BackendUtility::deleteClause($from_table);
894 }
895 }
896 } else {
897 $where_clause = 'uid';
898 if (!$GLOBALS['SOBE']->MOD_SETTINGS['show_deleted']) {
899 $where_clause .= BackendUtility::deleteClause($from_table);
900 }
901 }
902 $orderBy = 'uid';
903 if (!$this->tableArray[$from_table]) {
904 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery($select_fields, $from_table, $where_clause, ($groupBy = ''), $orderBy, ($limit = ''));
905 }
906 if ($res) {
907 while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
908 $this->tableArray[$from_table][] = $row;
909 }
910 $GLOBALS['TYPO3_DB']->sql_free_result($res);
911 }
912 foreach ($this->tableArray[$from_table] as $key => $val) {
913 if ($useSelectLabels) {
914 $outArray[$tablePrefix . $val['uid']] = htmlspecialchars($labelFieldSelect[$val[$labelField]]);
915 } elseif ($val[$labelField]) {
916 $outArray[$tablePrefix . $val['uid']] = htmlspecialchars($val[$labelField]);
917 } elseif ($useAltSelectLabels) {
918 $outArray[$tablePrefix . $val['uid']] = htmlspecialchars($altLabelFieldSelect[$val[$altLabelField]]);
919 } else {
920 $outArray[$tablePrefix . $val['uid']] = htmlspecialchars($val[$altLabelField]);
921 }
922 }
923 if ($GLOBALS['SOBE']->MOD_SETTINGS['options_sortlabel'] && is_array($outArray)) {
924 natcasesort($outArray);
925 }
926 }
927 }
928 foreach ($outArray as $key2 => $val2) {
929 if (\TYPO3\CMS\Core\Utility\GeneralUtility::inList($conf['inputValue'], $key2)) {
930 $out .= '<option value="' . $key2 . '" selected>[' . $key2 . '] ' . $val2 . '</option>';
931 } else {
932 $out .= '<option value="' . $key2 . '">[' . $key2 . '] ' . $val2 . '</option>';
933 }
934 }
935 }
936 return $out;
937 }
938
939 /**
940 * [Describe function...]
941 *
942 * @param [type] $codeArr: ...
943 * @param [type] $l: ...
944 * @return [type] ...
945 * @todo Define visibility
946 */
947 public function printCodeArray($codeArr, $l = 0) {
948 $line = '';
949 if ($l) {
950 $indent = '<td style="vertical-align:top;"><img height="1" width="50"></td>';
951 }
952 $lf = $l * 30;
953 $bgColor = \TYPO3\CMS\Core\Utility\GeneralUtility::modifyHTMLColor($GLOBALS['TBE_TEMPLATE']->bgColor2, $lf, $lf, $lf);
954 foreach ($codeArr as $k => $v) {
955 $line .= '<tr>' . $indent . '<td bgcolor="' . $bgColor . '"' . $this->noWrap . '>' . $v['html'] . '</td></tr>';
956 if ($this->enableQueryParts) {
957 $line .= '<tr>' . $indent . '<td>' . $this->formatQ($v['query']) . '</td></tr>';
958 }
959 if (is_array($v['sub'])) {
960 $line .= '<tr>' . $indent . '<td' . $this->noWrap . '>' . $this->printCodeArray($v['sub'], ($l + 1)) . '</td></tr>';
961 }
962 }
963 $out = '<table border="0" cellpadding="0" cellspacing="1">' . $line . '</table>';
964 return $out;
965 }
966
967 /**
968 * [Describe function...]
969 *
970 * @param [type] $str: ...
971 * @return [type] ...
972 * @todo Define visibility
973 */
974 public function formatQ($str) {
975 return '<font size="1" face="verdana" color="maroon"><i>' . htmlspecialchars($str) . '</i></font>';
976 }
977
978 /**
979 * [Describe function...]
980 *
981 * @param [type] $name: ...
982 * @param [type] $op: ...
983 * @param [type] $draw: ...
984 * @param [type] $submit: ...
985 * @return [type] ...
986 * @todo Define visibility
987 */
988 public function mkOperatorSelect($name, $op, $draw, $submit) {
989 if ($draw) {
990 $out = '<select name="' . $name . '[operator]"' . ($submit ? ' onChange="submit();"' : '') . '>';
991 //
992 $out .= '<option value="AND"' . (!$op || $op == 'AND' ? ' selected' : '') . '>' . $this->lang['AND'] . '</option>';
993 $out .= '<option value="OR"' . ($op == 'OR' ? ' selected' : '') . '>' . $this->lang['OR'] . '</option>';
994 $out .= '</select>';
995 } else {
996 $out = '<input type="hidden" value="' . $op . '" name="' . $name . '[operator]">';
997 $out .= '<img src="clear.gif" height="1" width="47">';
998 }
999 return $out;
1000 }
1001
1002 /**
1003 * [Describe function...]
1004 *
1005 * @param [type] $name: ...
1006 * @param [type] $fieldName: ...
1007 * @param [type] $prepend: ...
1008 * @return [type] ...
1009 * @todo Define visibility
1010 */
1011 public function mkTypeSelect($name, $fieldName, $prepend = 'FIELD_') {
1012 $out = '<select name="' . $name . '" onChange="submit();">';
1013 $out .= '<option value=""></option>';
1014 foreach ($this->fields as $key => $value) {
1015 if (!$value['exclude'] || $GLOBALS['BE_USER']->check('non_exclude_fields', $this->table . ':' . $key)) {
1016 $label = $this->fields[$key]['label'];
1017 $label_alt = $this->fields[$key]['label_alt'];
1018 $out .= '<option value="' . $prepend . $key . '"' . ($key == $fieldName ? ' selected' : '') . '>' . $label . '</option>';
1019 }
1020 }
1021 $out .= '</select>';
1022 return $out;
1023 }
1024
1025 /**
1026 * [Describe function...]
1027 *
1028 * @param [type] $fieldName: ...
1029 * @return [type] ...
1030 * @todo Define visibility
1031 */
1032 public function verifyType($fieldName) {
1033 $first = '';
1034 foreach ($this->fields as $key => $value) {
1035 if (!$first) {
1036 $first = $key;
1037 }
1038 if ($key == $fieldName) {
1039 return $key;
1040 }
1041 }
1042 return $first;
1043 }
1044
1045 /**
1046 * [Describe function...]
1047 *
1048 * @param [type] $comparison: ...
1049 * @param [type] $neg: ...
1050 * @return [type] ...
1051 * @todo Define visibility
1052 */
1053 public function verifyComparison($comparison, $neg) {
1054 $compOffSet = $comparison >> 5;
1055 $first = -1;
1056 for ($i = 32 * $compOffSet + $neg; $i < 32 * ($compOffSet + 1); $i += 2) {
1057 if ($first == -1) {
1058 $first = $i;
1059 }
1060 if ($i >> 1 == $comparison >> 1) {
1061 return $i;
1062 }
1063 }
1064 return $first;
1065 }
1066
1067 /**
1068 * [Describe function...]
1069 *
1070 * @param [type] $name: ...
1071 * @param [type] $fieldName: ...
1072 * @return [type] ...
1073 * @todo Define visibility
1074 */
1075 public function mkFieldToInputSelect($name, $fieldName) {
1076 $out = '<input type="Text" value="' . htmlspecialchars($fieldName) . '" name="' . $name . '"' . $GLOBALS['TBE_TEMPLATE']->formWidth() . '>' . $this->updateIcon();
1077 $out .= '<a href="#" onClick="document.forms[0][\'' . $name . '\'].value=\'\';return false;">' . \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIcon('actions-edit-delete', array('title' => 'Clear list')) . '</a>';
1078 $out .= '<BR><select name="_fieldListDummy" size="5" onChange="document.forms[0][\'' . $name . '\'].value+=\',\'+this.value">';
1079 foreach ($this->fields as $key => $value) {
1080 if (!$value['exclude'] || $GLOBALS['BE_USER']->check('non_exclude_fields', $this->table . ':' . $key)) {
1081 $label = $this->fields[$key]['label'];
1082 $label_alt = $this->fields[$key]['label_alt'];
1083 $out .= '<option value="' . $key . '"' . ($key == $fieldName ? ' selected' : '') . '>' . $label . '</option>';
1084 }
1085 }
1086 $out .= '</select>';
1087 return $out;
1088 }
1089
1090 /**
1091 * [Describe function...]
1092 *
1093 * @param [type] $name: ...
1094 * @param [type] $cur: ...
1095 * @return [type] ...
1096 * @todo Define visibility
1097 */
1098 public function mkTableSelect($name, $cur) {
1099 $out = '<select name="' . $name . '" onChange="submit();">';
1100 $out .= '<option value=""></option>';
1101 foreach ($GLOBALS['TCA'] as $tN => $value) {
1102 if ($GLOBALS['BE_USER']->check('tables_select', $tN)) {
1103 $out .= '<option value="' . $tN . '"' . ($tN == $cur ? ' selected' : '') . '>' . $GLOBALS['LANG']->sl($GLOBALS['TCA'][$tN]['ctrl']['title']) . '</option>';
1104 }
1105 }
1106 $out .= '</select>';
1107 return $out;
1108 }
1109
1110 /**
1111 * [Describe function...]
1112 *
1113 * @param [type] $name: ...
1114 * @param [type] $comparison: ...
1115 * @param [type] $neg: ...
1116 * @return [type] ...
1117 * @todo Define visibility
1118 */
1119 public function mkCompSelect($name, $comparison, $neg) {
1120 $compOffSet = $comparison >> 5;
1121 $out = '<select name="' . $name . '" onChange="submit();">';
1122 for ($i = 32 * $compOffSet + $neg; $i < 32 * ($compOffSet + 1); $i += 2) {
1123 if ($this->lang['comparison'][$i . '_']) {
1124 $out .= '<option value="' . $i . '"' . ($i >> 1 == $comparison >> 1 ? ' selected' : '') . '>' . $this->lang['comparison'][($i . '_')] . '</option>';
1125 }
1126 }
1127 $out .= '</select>';
1128 return $out;
1129 }
1130
1131 /**
1132 * [Describe function...]
1133 *
1134 * @param [type] $arr: ...
1135 * @return [type] ...
1136 * @todo Define visibility
1137 */
1138 public function getSubscript($arr) {
1139 while (is_array($arr)) {
1140 reset($arr);
1141 list($key, ) = each($arr);
1142 $retArr[] = $key;
1143 $arr = $arr[$key];
1144 }
1145 return $retArr;
1146 }
1147
1148 /**
1149 * [Describe function...]
1150 *
1151 * @return [type] ...
1152 * @todo Define visibility
1153 */
1154 public function initUserDef() {
1155
1156 }
1157
1158 /**
1159 * [Describe function...]
1160 *
1161 * @return [type] ...
1162 * @todo Define visibility
1163 */
1164 public function userDef() {
1165
1166 }
1167
1168 /**
1169 * [Describe function...]
1170 *
1171 * @param [type] $queryConfig: ...
1172 * @return [type] ...
1173 * @todo Define visibility
1174 */
1175 public function userDefCleanUp($queryConfig) {
1176 return $queryConfig;
1177 }
1178
1179 /**
1180 * [Describe function...]
1181 *
1182 * @param [type] $queryConfig: ...
1183 * @param [type] $pad: ...
1184 * @return [type] ...
1185 * @todo Define visibility
1186 */
1187 public function getQuery($queryConfig, $pad = '') {
1188 $qs = '';
1189 // Since we don't traverse the array using numeric keys in the upcoming whileloop make sure it's fresh and clean
1190 ksort($queryConfig);
1191 $first = 1;
1192 foreach ($queryConfig as $key => $conf) {
1193 switch ($conf['type']) {
1194 case 'newlevel':
1195 $qs .= LF . $pad . trim($conf['operator']) . ' (' . $this->getQuery($queryConfig[$key]['nl'], ($pad . ' ')) . LF . $pad . ')';
1196 break;
1197 case 'userdef':
1198 $qs .= LF . $pad . getUserDefQuery($conf, $first);
1199 break;
1200 default:
1201 $qs .= LF . $pad . $this->getQuerySingle($conf, $first);
1202 }
1203 $first = 0;
1204 }
1205 return $qs;
1206 }
1207
1208 /**
1209 * [Describe function...]
1210 *
1211 * @param [type] $conf: ...
1212 * @param [type] $first: ...
1213 * @return [type] ...
1214 * @todo Define visibility
1215 */
1216 public function getQuerySingle($conf, $first) {
1217 $qs = '';
1218 $prefix = $this->enablePrefix ? $this->table . '.' : '';
1219 if (!$first) {
1220 // Is it OK to insert the AND operator if none is set?
1221 $qs .= trim(($conf['operator'] ?: 'AND')) . ' ';
1222 }
1223 $qsTmp = str_replace('#FIELD#', $prefix . trim(substr($conf['type'], 6)), $this->compSQL[$conf['comparison']]);
1224 $inputVal = $this->cleanInputVal($conf);
1225 if ($conf['comparison'] == 68 || $conf['comparison'] == 69) {
1226 $inputVal = explode(',', $inputVal);
1227 foreach ($inputVal as $key => $fileName) {
1228 $inputVal[$key] = '\'' . $fileName . '\'';
1229 }
1230 $inputVal = implode(',', $inputVal);
1231 $qsTmp = str_replace('#VALUE#', $inputVal, $qsTmp);
1232 } elseif ($conf['comparison'] == 162 || $conf['comparison'] == 163) {
1233 $inputValArray = explode(',', $inputVal);
1234 $inputVal = 0;
1235 foreach ($inputValArray as $fileName) {
1236 $inputVal += (int)$fileName;
1237 }
1238 $qsTmp = str_replace('#VALUE#', $inputVal, $qsTmp);
1239 } else {
1240 $qsTmp = str_replace('#VALUE#', $GLOBALS['TYPO3_DB']->quoteStr($inputVal, $this->table), $qsTmp);
1241 }
1242 if ($conf['comparison'] == 37 || $conf['comparison'] == 36 || $conf['comparison'] == 66 || $conf['comparison'] == 67 || $conf['comparison'] == 100 || $conf['comparison'] == 101) {
1243 // between:
1244 $inputVal = $this->cleanInputVal($conf, '1');
1245 $qsTmp = str_replace('#VALUE1#', $GLOBALS['TYPO3_DB']->quoteStr($inputVal, $this->table), $qsTmp);
1246 }
1247 $qs .= trim($qsTmp);
1248 return $qs;
1249 }
1250
1251 /**
1252 * [Describe function...]
1253 *
1254 * @param [type] $conf: ...
1255 * @param [type] $suffix: ...
1256 * @return [type] ...
1257 * @todo Define visibility
1258 */
1259 public function cleanInputVal($conf, $suffix = '') {
1260 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)) {
1261 $inputVal = $conf['inputValue' . $suffix];
1262 } elseif ($conf['comparison'] == 39 || $conf['comparison'] == 38) {
1263 // in list:
1264 $inputVal = implode(',', \TYPO3\CMS\Core\Utility\GeneralUtility::intExplode(',', $conf['inputValue' . $suffix]));
1265 } elseif ($conf['comparison'] == 68 || $conf['comparison'] == 69 || $conf['comparison'] == 162 || $conf['comparison'] == 163) {
1266 // in list:
1267 if (is_array($conf['inputValue' . $suffix])) {
1268 $inputVal = implode(',', $conf['inputValue' . $suffix]);
1269 } elseif ($conf['inputValue' . $suffix]) {
1270 $inputVal = $conf['inputValue' . $suffix];
1271 } else {
1272 $inputVal = 0;
1273 }
1274 } else {
1275 $inputVal = doubleval($conf['inputValue' . $suffix]);
1276 }
1277 return $inputVal;
1278 }
1279
1280 /**
1281 * [Describe function...]
1282 *
1283 * @param [type] $qcArr: ...
1284 * @return [type] ...
1285 * @todo Define visibility
1286 */
1287 public function getUserDefQuery($qcArr) {
1288
1289 }
1290
1291 /**
1292 * [Describe function...]
1293 *
1294 * @return [type] ...
1295 * @todo Define visibility
1296 */
1297 public function updateIcon() {
1298 return '<input type="image" border="0" ' . \TYPO3\CMS\Backend\Utility\IconUtility::skinImg($GLOBALS['BACK_PATH'], 'gfx/refresh_n.gif', 'width="14" height="14"') . ' title="Update" name="just_update">';
1299 }
1300
1301 /**
1302 * [Describe function...]
1303 *
1304 * @return [type] ...
1305 * @todo Define visibility
1306 */
1307 public function getLabelCol() {
1308 return $GLOBALS['TCA'][$this->table]['ctrl']['label'];
1309 }
1310
1311 /**
1312 * [Describe function...]
1313 *
1314 * @param [type] $modSettings: ...
1315 * @param [type] $enableList: ...
1316 * @return [type] ...
1317 * @todo Define visibility
1318 */
1319 public function makeSelectorTable($modSettings, $enableList = 'table,fields,query,group,order,limit') {
1320 $enableArr = explode(',', $enableList);
1321 // Make output
1322 $TDparams = ' class="bgColor5" nowrap';
1323 if (in_array('table', $enableArr) && !$GLOBALS['BE_USER']->userTS['mod.']['dbint.']['disableSelectATable']) {
1324 $out = '
1325 <tr>
1326 <td' . $TDparams . '><strong>Select a table:</strong></td>
1327 <td' . $TDparams . '>' . $this->mkTableSelect('SET[queryTable]', $this->table) . '</td>
1328 </tr>';
1329 }
1330 if ($this->table) {
1331 // Init fields:
1332 $this->setAndCleanUpExternalLists('queryFields', $modSettings['queryFields'], 'uid,' . $this->getLabelCol());
1333 $this->setAndCleanUpExternalLists('queryGroup', $modSettings['queryGroup']);
1334 $this->setAndCleanUpExternalLists('queryOrder', $modSettings['queryOrder'] . ',' . $modSettings['queryOrder2']);
1335 // Limit:
1336 $this->extFieldLists['queryLimit'] = $modSettings['queryLimit'];
1337 if (!$this->extFieldLists['queryLimit']) {
1338 $this->extFieldLists['queryLimit'] = 100;
1339 }
1340 $parts = \TYPO3\CMS\Core\Utility\GeneralUtility::intExplode(',', $this->extFieldLists['queryLimit']);
1341 if ($parts[1]) {
1342 $this->limitBegin = $parts[0];
1343 $this->limitLength = $parts[1];
1344 } else {
1345 $this->limitLength = $this->extFieldLists['queryLimit'];
1346 }
1347 $this->extFieldLists['queryLimit'] = implode(',', array_slice($parts, 0, 2));
1348 // Insert Descending parts
1349 if ($this->extFieldLists['queryOrder']) {
1350 $descParts = explode(',', $modSettings['queryOrderDesc'] . ',' . $modSettings['queryOrder2Desc']);
1351 $orderParts = explode(',', $this->extFieldLists['queryOrder']);
1352 $reList = array();
1353 foreach ($orderParts as $kk => $vv) {
1354 $reList[] = $vv . ($descParts[$kk] ? ' DESC' : '');
1355 }
1356 $this->extFieldLists['queryOrder_SQL'] = implode(',', $reList);
1357 }
1358 // Query Generator:
1359 $this->procesData($modSettings['queryConfig'] ? unserialize($modSettings['queryConfig']) : '');
1360 $this->queryConfig = $this->cleanUpQueryConfig($this->queryConfig);
1361 $this->enableQueryParts = $modSettings['search_query_smallparts'];
1362 $codeArr = $this->getFormElements();
1363 $queryCode = $this->printCodeArray($codeArr);
1364 if (in_array('fields', $enableArr) && !$GLOBALS['BE_USER']->userTS['mod.']['dbint.']['disableSelectFields']) {
1365 $out .= '
1366 <tr>
1367 <td' . $TDparams . '><strong>Select fields:</strong></td>
1368 <td' . $TDparams . '>' . $this->mkFieldToInputSelect('SET[queryFields]', $this->extFieldLists['queryFields']) . '</td>
1369 </tr>';
1370 }
1371 if (in_array('query', $enableArr) && !$GLOBALS['BE_USER']->userTS['mod.']['dbint.']['disableMakeQuery']) {
1372 $out .= '<tr>
1373 <td colspan="2"' . $TDparams . '><strong>Make Query:</strong></td>
1374 </tr>
1375 <tr>
1376 <td colspan="2">' . $queryCode . '</td>
1377 </tr>
1378 ';
1379 }
1380 if (in_array('group', $enableArr) && !$GLOBALS['BE_USER']->userTS['mod.']['dbint.']['disableGroupBy']) {
1381 $out .= '<tr>
1382 <td' . $TDparams . '><strong>Group By:</strong></td>
1383 <td' . $TDparams . '>' . $this->mkTypeSelect('SET[queryGroup]', $this->extFieldLists['queryGroup'], '') . '</td>
1384 </tr>';
1385 }
1386 if (in_array('order', $enableArr) && !$GLOBALS['BE_USER']->userTS['mod.']['dbint.']['disableOrderBy']) {
1387 $orderByArr = explode(',', $this->extFieldLists['queryOrder']);
1388 $orderBy = '';
1389 $orderBy .= $this->mkTypeSelect('SET[queryOrder]', $orderByArr[0], '') . '&nbsp;'
1390 . '<div class="checkbox"><label for="checkQueryOrderDesc">' . BackendUtility::getFuncCheck($GLOBALS['SOBE']->id, 'SET[queryOrderDesc]', $modSettings['queryOrderDesc'], '', '', 'id="checkQueryOrderDesc"') . 'Descending</label></div>';
1391 if ($orderByArr[0]) {
1392 $orderBy .= '<BR>' . $this->mkTypeSelect('SET[queryOrder2]', $orderByArr[1], '') . '&nbsp;'
1393 . '<div class="checkbox"><label for="checkQueryOrder2Desc">' . BackendUtility::getFuncCheck($GLOBALS['SOBE']->id, 'SET[queryOrder2Desc]', $modSettings['queryOrder2Desc'], '', '', 'id="checkQueryOrder2Desc"') . 'Descending</label></div>';
1394 }
1395 $out .= '<tr>
1396 <td' . $TDparams . '><strong>Order By:</strong></td>
1397 <td' . $TDparams . '>' . $orderBy . '</td>
1398 </tr>';
1399 }
1400 if (in_array('limit', $enableArr) && !$GLOBALS['BE_USER']->userTS['mod.']['dbint.']['disableLimit']) {
1401 $limit = '<input type="Text" value="' . htmlspecialchars($this->extFieldLists['queryLimit']) . '" name="SET[queryLimit]" id="queryLimit"' . $GLOBALS['TBE_TEMPLATE']->formWidth(10) . '>' . $this->updateIcon();
1402 $prevLimit = $this->limitBegin - $this->limitLength < 0 ? 0 : $this->limitBegin - $this->limitLength;
1403 if ($this->limitBegin) {
1404 $prevButton = '<input type="button" value="previous ' . $this->limitLength . '" onclick=\'document.getElementById("queryLimit").value="' . $prevLimit . ',' . $this->limitLength . '";document.forms[0].submit();\'>';
1405 }
1406 if (!$this->limitLength) {
1407 $this->limitLength = 100;
1408 }
1409 $nextLimit = $this->limitBegin + $this->limitLength;
1410 if ($nextLimit < 0) {
1411 $nextLimit = 0;
1412 }
1413 if ($nextLimit) {
1414 $nextButton = '<input type="button" value="next ' . $this->limitLength . '" onclick=\'document.getElementById("queryLimit").value="' . $nextLimit . ',' . $this->limitLength . '";document.forms[0].submit();\'>';
1415 }
1416 $numberButtons = '<input type="button" value="10" onclick=\'document.getElementById("queryLimit").value="10";document.forms[0].submit();\'>';
1417 $numberButtons .= '<input type="button" value="20" onclick=\'document.getElementById("queryLimit").value="20";document.forms[0].submit();\'>';
1418 $numberButtons .= '<input type="button" value="50" onclick=\'document.getElementById("queryLimit").value="50";document.forms[0].submit();\'>';
1419 $numberButtons .= '<input type="button" value="100" onclick=\'document.getElementById("queryLimit").value="100";document.forms[0].submit();\'>';
1420 $out .= '<tr>
1421 <td' . $TDparams . '><strong>Limit:</strong></td>
1422 <td' . $TDparams . '>' . $limit . $prevButton . $nextButton . '&nbsp;' . $numberButtons . '</td>
1423 </tr>
1424 ';
1425 }
1426 }
1427 $out = '<table border="0" cellpadding="3" cellspacing="1" class="qg-make-query">' . $out . '</table>';
1428 $out .= $this->JSbottom($this->formName);
1429 return $out;
1430 }
1431
1432 /**
1433 * [Describe function...]
1434 *
1435 * @param [type] $qString: ...
1436 * @param [type] $depth: ...
1437 * @param [type] $begin: ...
1438 * @param [type] $perms_clause: ...
1439 * @return [type] ...
1440 * @todo Define visibility
1441 */
1442 public function getTreeList($id, $depth, $begin = 0, $perms_clause) {
1443 $depth = (int)$depth;
1444 $begin = (int)$begin;
1445 $id = (int)$id;
1446 if ($id < 0) {
1447 $id = abs($id);
1448 }
1449 if ($begin == 0) {
1450 $theList = $id;
1451 } else {
1452 $theList = '';
1453 }
1454 if ($id && $depth > 0) {
1455 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid', 'pages', 'pid=' . $id . ' ' . BackendUtility::deleteClause('pages') . ' AND ' . $perms_clause);
1456 while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
1457 if ($begin <= 0) {
1458 $theList .= ',' . $row['uid'];
1459 }
1460 if ($depth > 1) {
1461 $theList .= $this->getTreeList($row['uid'], $depth - 1, $begin - 1, $perms_clause);
1462 }
1463 }
1464 $GLOBALS['TYPO3_DB']->sql_free_result($res);
1465 }
1466 return $theList;
1467 }
1468
1469 /**
1470 * [Describe function...]
1471 *
1472 * @param [type] $qString: ...
1473 * @param [type] $fN: ...
1474 * @return [type] ...
1475 * @todo Define visibility
1476 */
1477 public function getSelectQuery($qString = '', $fN = '') {
1478 if (!$qString) {
1479 $qString = $this->getQuery($this->queryConfig);
1480 }
1481 $qString = '(' . $qString . ')';
1482 if (!$GLOBALS['BE_USER']->isAdmin() && $GLOBALS['TYPO3_CONF_VARS']['BE']['lockBeUserToDBmounts']) {
1483 $webMounts = $GLOBALS['BE_USER']->returnWebmounts();
1484 $perms_clause = $GLOBALS['BE_USER']->getPagePermsClause(1);
1485 $webMountPageTree = '';
1486 foreach ($webMounts as $key => $val) {
1487 if ($webMountPageTree) {
1488 $webMountPageTreePrefix = ',';
1489 }
1490 $webMountPageTree .= $webMountPageTreePrefix . $this->getTreeList($val, 999, ($begin = 0), $perms_clause);
1491 }
1492 if ($this->table == 'pages') {
1493 $qString .= ' AND uid IN (' . $webMountPageTree . ')';
1494 } else {
1495 $qString .= ' AND pid IN (' . $webMountPageTree . ')';
1496 }
1497 }
1498 $fieldlist = $this->extFieldLists['queryFields'] . ',pid' . ($GLOBALS['TCA'][$this->table]['ctrl']['delete'] ? ',' . $GLOBALS['TCA'][$this->table]['ctrl']['delete'] : '');
1499 if (!$GLOBALS['SOBE']->MOD_SETTINGS['show_deleted']) {
1500 $qString .= BackendUtility::deleteClause($this->table);
1501 }
1502 $query = $GLOBALS['TYPO3_DB']->SELECTquery($fieldlist, $this->table, $qString, trim($this->extFieldLists['queryGroup']), $this->extFieldLists['queryOrder'] ? trim($this->extFieldLists['queryOrder_SQL']) : '', $this->extFieldLists['queryLimit']);
1503 return $query;
1504 }
1505
1506 /**
1507 * [Describe function...]
1508 *
1509 * @param string $formname
1510 * @return string
1511 * @todo Define visibility
1512 */
1513 public function JSbottom($formname) {
1514 $out = '';
1515 if ($this->extJSCODE) {
1516 $out .= '
1517 <script language="javascript" type="text/javascript" src="' . $GLOBALS['BACK_PATH'] . 'sysext/backend/Resources/Public/JavaScript/jsfunc.evalfield.js"></script>
1518 <script language="javascript" type="text/javascript" src="' . $GLOBALS['BACK_PATH'] . 'sysext/backend/Resources/Public/JavaScript/jsfunc.tbe_editor.js"></script>
1519 <script language="javascript" type="text/javascript">
1520 TBE_EDITOR.formname = "' . $formname . '";
1521 TBE_EDITOR.formnameUENC = "' . rawurlencode($formname) . '";
1522 TBE_EDITOR.backend_interface = "' . $GLOBALS['BE_USER']->uc['interfaceSetup'] . '";
1523 ' . $this->extJSCODE . '
1524 </script>';
1525 }
1526 return $out;
1527 }
1528
1529 /**
1530 * Sets the current name of the input form.
1531 *
1532 * @param string $formName The name of the form.
1533 * @return void
1534 */
1535 public function setFormName($formName) {
1536 $this->formName = trim($formName);
1537 }
1538
1539 }