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