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