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