* rewrote TBE_EDITOR Javascript functions to use JS "objects"
[Packages/TYPO3.CMS.git] / t3lib / class.t3lib_querygenerator.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 2001-2006 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
237
238
239
240
241
242 /**
243 * @return [type] ...
244 */
245 function makeFieldList() {
246 global $TCA;
247 $fieldListArr = array();
248 if (is_array($TCA[$this->table])) {
249 t3lib_div::loadTCA($this->table);
250 reset($TCA[$this->table]['columns']);
251 while(list($fN)=each($TCA[$this->table]['columns'])) {
252 $fieldListArr[]=$fN;
253 }
254 $fieldListArr[]='uid';
255 $fieldListArr[]='pid';
256 $fieldListArr[]='deleted';
257 if ($TCA[$this->table]['ctrl']['tstamp']) $fieldListArr[]=$TCA[$this->table]['ctrl']['tstamp'];
258 if ($TCA[$this->table]['ctrl']['crdate']) $fieldListArr[]=$TCA[$this->table]['ctrl']['crdate'];
259 if ($TCA[$this->table]['ctrl']['cruser_id']) $fieldListArr[]=$TCA[$this->table]['ctrl']['cruser_id'];
260 if ($TCA[$this->table]['ctrl']['sortby']) $fieldListArr[]=$TCA[$this->table]['ctrl']['sortby'];
261 }
262 return implode(',',$fieldListArr);
263 }
264
265 /**
266 * [Describe function...]
267 *
268 * @param [type] $name: ...
269 * @param [type] $table: ...
270 * @param [type] $fieldList: ...
271 * @return [type] ...
272 */
273 function init($name,$table,$fieldList='') {
274 global $TCA;
275
276 // Analysing the fields in the table.
277 if (is_array($TCA[$table])) {
278 t3lib_div::loadTCA($table);
279 $this->name = $name;
280 $this->table = $table;
281 $this->fieldList = $fieldList ? $fieldList : $this->makeFieldList();
282
283 $fieldArr = t3lib_div::trimExplode(',',$this->fieldList,1);
284 reset($fieldArr);
285 while(list(,$fN)=each($fieldArr)) {
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'] = ereg_replace(':$','',trim($GLOBALS['LANG']->sL($fC['label'])));
291 switch ($this->fields[$fN]['type']) {
292 case 'input':
293 if (eregi('int|year', $this->fields[$fN]['eval'])) {
294 $this->fields[$fN]['type']='number';
295 } elseif (eregi('time', $this->fields[$fN]['eval'])) {
296 $this->fields[$fN]['type'] = 'time';
297 } elseif (eregi('date', $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 reset($fields);
413 $reList=array();
414 while(list(,$fN)=each($fields)) {
415 if ($this->fields[$fN]) $reList[]=$fN;
416 }
417 $this->extFieldLists[$name]=implode(',',$reList);
418 }
419
420 /**
421 * [Describe function...]
422 *
423 * @param [type] $qC: ...
424 * @return [type] ...
425 */
426 function procesData($qC='') {
427 $this->queryConfig = $qC;
428
429 $POST = t3lib_div::_POST();
430
431 // if delete...
432 if($POST['qG_del']) {
433 //initialize array to work on, save special parameters
434 $ssArr = $this->getSubscript($POST['qG_del']);
435 $workArr =& $this->queryConfig;
436 for($i=0;$i<sizeof($ssArr)-1;$i++) {
437 $workArr =& $workArr[$ssArr[$i]];
438 }
439 // delete the entry and move the other entries
440 unset($workArr[$ssArr[$i]]);
441 for($j=$ssArr[$i];$j<sizeof($workArr);$j++) {
442 $workArr[$j] = $workArr[$j+1];
443 unset($workArr[$j+1]);
444 }
445 }
446
447 // if insert...
448 if($POST['qG_ins']) {
449 //initialize array to work on, save special parameters
450 $ssArr = $this->getSubscript($POST['qG_ins']);
451 $workArr =& $this->queryConfig;
452 for($i=0;$i<sizeof($ssArr)-1;$i++) {
453 $workArr =& $workArr[$ssArr[$i]];
454 }
455 // move all entries above position where new entry is to be inserted
456 for($j=sizeof($workArr);$j>$ssArr[$i];$j--) {
457 $workArr[$j] = $workArr[$j-1];
458 }
459 //clear new entry position
460 unset($workArr[$ssArr[$i]+1]);
461 $workArr[$ssArr[$i]+1]['type'] = 'FIELD_';
462 }
463
464 // if move up...
465 if($POST['qG_up']) {
466 //initialize array to work on
467 $ssArr = $this->getSubscript($POST['qG_up']);
468 $workArr =& $this->queryConfig;
469 for($i=0;$i<sizeof($ssArr)-1;$i++) {
470 $workArr =& $workArr[$ssArr[$i]];
471 }
472 //swap entries
473 $qG_tmp = $workArr[$ssArr[$i]];
474 $workArr[$ssArr[$i]] = $workArr[$ssArr[$i]-1];
475 $workArr[$ssArr[$i]-1] = $qG_tmp;
476 }
477
478 // if new level...
479 if($POST['qG_nl']) {
480 //initialize array to work on
481 $ssArr = $this->getSubscript($POST['qG_nl']);
482 $workArr =& $this->queryConfig;
483 for($i=0;$i<sizeof($ssArr)-1;$i++) {
484 $workArr =& $workArr[$ssArr[$i]];
485 }
486 // Do stuff:
487 $tempEl = $workArr[$ssArr[$i]];
488 if (is_array($tempEl)) {
489 if ($tempEl['type']!='newlevel') {
490 $workArr[$ssArr[$i]]=array(
491 'type' => 'newlevel',
492 'operator' => $tempEl['operator'],
493 'nl' => array($tempEl)
494 );
495 }
496 }
497 }
498
499 // if collapse level...
500 if($POST['qG_remnl']) {
501 //initialize array to work on
502 $ssArr = $this->getSubscript($POST['qG_remnl']);
503 $workArr =& $this->queryConfig;
504 for($i=0;$i<sizeof($ssArr)-1;$i++) {
505 $workArr =& $workArr[$ssArr[$i]];
506 }
507
508 // Do stuff:
509 $tempEl = $workArr[$ssArr[$i]];
510 if (is_array($tempEl)) {
511 if ($tempEl['type']=='newlevel') {
512 $a1 = array_slice($workArr,0,$ssArr[$i]);
513 $a2 = array_slice($workArr,$ssArr[$i]);
514 array_shift($a2);
515 $a3 = $tempEl['nl'];
516 $a3[0]['operator'] = $tempEl['operator'];
517 $workArr=array_merge($a1,$a3,$a2);
518 }
519 }
520 }
521 }
522
523 /**
524 * [Describe function...]
525 *
526 * @param [type] $queryConfig: ...
527 * @return [type] ...
528 */
529 function cleanUpQueryConfig($queryConfig) {
530 //since we dont traverse the array using numeric keys in the upcoming whileloop make sure it's fresh and clean before displaying
531 if (is_array($queryConfig)) {
532 ksort($queryConfig);
533 } else {
534 //queryConfig should never be empty!
535 if(!$queryConfig[0] || !$queryConfig[0]['type']) $queryConfig[0] = array('type'=>'FIELD_');
536 }
537 // Traverse:
538 reset($queryConfig);
539 $c=0;
540 $arrCount=0;
541 while(list($key,$conf)=each($queryConfig)) {
542 if(substr($conf['type'],0,6)=='FIELD_') {
543 $fName = substr($conf['type'],6);
544 $fType = $this->fields[$fName]['type'];
545 } elseif($conf['type']=='newlevel') {
546 $fType = $conf['type'];
547 } else {
548 $fType = 'ignore';
549 }
550 // debug($fType);
551 switch($fType) {
552 case 'newlevel':
553 if(!$queryConfig[$key]['nl']) $queryConfig[$key]['nl'][0]['type'] = 'FIELD_';
554 $queryConfig[$key]['nl']=$this->cleanUpQueryConfig($queryConfig[$key]['nl']);
555 break;
556 case 'userdef':
557 $queryConfig[$key]=$this->userDefCleanUp($queryConfig[$key]);
558 break;
559 case 'ignore':
560 default:
561 // debug($queryConfig[$key]);
562 $verifiedName=$this->verifyType($fName);
563 $queryConfig[$key]['type']='FIELD_'.$this->verifyType($verifiedName);
564
565 if($conf['comparison'] >> 5 != $this->comp_offsets[$fType]) $conf['comparison'] = $this->comp_offsets[$fType] << 5;
566 $queryConfig[$key]['comparison']=$this->verifyComparison($conf['comparison'],$conf['negate']?1:0);
567
568 $queryConfig[$key]['inputValue']=$this->cleanInputVal($queryConfig[$key]);
569 $queryConfig[$key]['inputValue1']=$this->cleanInputVal($queryConfig[$key],1);
570
571 // debug($queryConfig[$key]);
572 break;
573 }
574 }
575 return $queryConfig;
576 }
577
578 /**
579 * [Describe function...]
580 *
581 * @param [type] $subLevel: ...
582 * @param [type] $queryConfig: ...
583 * @param [type] $parent: ...
584 * @return [type] ...
585 */
586 function getFormElements($subLevel=0,$queryConfig='',$parent='') {
587 $codeArr=array();
588 if (!is_array($queryConfig)) $queryConfig=$this->queryConfig;
589
590 reset($queryConfig);
591 $c=0;
592 $arrCount=0;
593 while(list($key,$conf)=each($queryConfig)) {
594 $subscript = $parent.'['.$key.']';
595 $lineHTML = '';
596 $lineHTML.=$this->mkOperatorSelect($this->name.$subscript,$conf['operator'],$c,($conf['type']!='FIELD_'));
597 if(substr($conf['type'],0,6)=='FIELD_') {
598 $fName = substr($conf['type'],6);
599 $this->fieldName = $fName;
600 $fType = $this->fields[$fName]['type'];
601 if($conf['comparison'] >> 5 != $this->comp_offsets[$fType]) $conf['comparison'] = $this->comp_offsets[$fType] << 5;
602
603 //nasty nasty...
604 //make sure queryConfig contains _actual_ comparevalue.
605 //mkCompSelect don't care, but getQuery does.
606 $queryConfig[$key]['comparison'] += (isset($conf['negate'])-($conf['comparison']%2));
607
608 } elseif($conf['type']=='newlevel') {
609 $fType = $conf['type'];
610 } else {
611 $fType = 'ignore';
612 }
613 switch($fType) {
614 case 'ignore':
615 break;
616 case 'newlevel':
617 if(!$queryConfig[$key]['nl']) $queryConfig[$key]['nl'][0]['type'] = 'FIELD_';
618 $lineHTML.='<input type="hidden" name="'.$this->name.$subscript.'[type]" value="newlevel">';
619 $codeArr[$arrCount]['sub'] = $this->getFormElements($subLevel+1,$queryConfig[$key]['nl'],$subscript.'[nl]');
620 break;
621 case 'userdef':
622 $lineHTML.=$this->userDef($this->name.$subscript,$conf,$fName,$fType);
623 break;
624 case 'date':
625 $lineHTML.=$this->mkTypeSelect($this->name.$subscript.'[type]',$fName);
626 $lineHTML.=$this->mkCompSelect($this->name.$subscript.'[comparison]',$conf['comparison'],$conf['negate']?1:0);
627 $lineHTML.='<input type="checkbox"'.($conf['negate']?' checked':'').' name="'.$this->name.$subscript.'[negate]'.'" onClick="submit();">';
628
629 if ($conf['comparison']==100 || $conf['comparison']==101) { // between
630 $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]'.'">';
631 $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]'.'">';
632 $this->extJSCODE.='typo3form.fieldSet("'.$this->name.$subscript.'[inputValue]", '.date.', "", 0,0);';
633 $this->extJSCODE.='typo3form.fieldSet("'.$this->name.$subscript.'[inputValue1]", '.date.', "", 0,0);';
634 } else {
635 $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]'.'">';
636 $this->extJSCODE.='typo3form.fieldSet("'.$this->name.$subscript.'[inputValue]", '.date.', "", 0,0);';
637 }
638 break;
639 case 'time':
640 $lineHTML.=$this->mkTypeSelect($this->name.$subscript.'[type]', $fName);
641 $lineHTML.=$this->mkCompSelect($this->name.$subscript.'[comparison]', $conf['comparison'], $conf['negate']?1:0);
642
643 $lineHTML.='<input type="checkbox"'.($conf['negate']?' checked':'').' name="'.$this->name.$subscript.'[negate]'.'" onClick="submit();">';
644 if ($conf['comparison']==100 || $conf['comparison']==101) { // between:
645 $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]'.'">';
646 $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]'.'">';
647 $this->extJSCODE.='typo3form.fieldSet("'.$this->name.$subscript.'[inputValue]", '.datetime.', "", 0,0);';
648 $this->extJSCODE.='typo3form.fieldSet("'.$this->name.$subscript.'[inputValue1]", '.datetime.', "", 0,0);';
649 } else {
650 $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]'.'">';
651 $this->extJSCODE.='typo3form.fieldSet("'.$this->name.$subscript.'[inputValue]", '.datetime.', "", 0,0);';
652 }
653 break;
654 case 'multiple':
655 case 'binary':
656 case 'relation':
657 $lineHTML.=$this->mkTypeSelect($this->name.$subscript.'[type]', $fName);
658 $lineHTML.=$this->mkCompSelect($this->name.$subscript.'[comparison]', $conf['comparison'], $conf['negate']?1:0);
659 $lineHTML.='<input type="checkbox"'.($conf['negate']?' checked':'').' name="'.$this->name.$subscript.'[negate]'.'" onClick="submit();">';
660 if ($conf['comparison']==68 || $conf['comparison']==69 || $conf['comparison']==162 || $conf['comparison']==163) {
661 $lineHTML.='<select name="'.$this->name.$subscript.'[inputValue]'.'[]" style="vertical-align:top;" size="5" multiple>';
662 } elseif ($conf['comparison']==66 || $conf['comparison']==67) {
663 if (is_array($conf['inputValue'])) {
664 $conf['inputValue'] = implode(',', $conf['inputValue']);
665 }
666 $lineHTML.= '<input type="text" value="'.htmlspecialchars($conf['inputValue']).'" name="'.$this->name.$subscript.'[inputValue]'.'"'.$GLOBALS['TBE_TEMPLATE']->formWidth(10).'>';
667 } else {
668 $lineHTML.= '<select name="'.$this->name.$subscript.'[inputValue]'.'" style="vertical-align:top;" onChange="submit();">';
669 }
670 if ($conf['comparison']!=66 && $conf['comparison']!=67) {
671 $lineHTML.= $this->makeOptionList($fName, $conf, $this->table);
672 $lineHTML.= '</select>';
673 }
674 break;
675 case 'files':
676 $lineHTML.= $this->mkTypeSelect($this->name.$subscript.'[type]', $fName);
677 $lineHTML.= $this->mkCompSelect($this->name.$subscript.'[comparison]', $conf['comparison'], $conf['negate']?1:0);
678 $lineHTML.= '<input type="checkbox"'.($conf['negate']?' checked':'').' name="'.$this->name.$subscript.'[negate]'.'" onClick="submit();">';
679 if ($conf['comparison']==68 || $conf['comparison']==69) {
680 $lineHTML .= '<select name="'.$this->name.$subscript.'[inputValue]'.'[]" style="vertical-align:top;" size="5" multiple>';
681 } else {
682 $lineHTML .= '<select name="'.$this->name.$subscript.'[inputValue]'.'" style="vertical-align:top;" onChange="submit();">';
683 }
684 $lineHTML .= '<option value=""></option>'.$this->makeOptionList($fName, $conf, $this->table);
685 $lineHTML .= '</select>';
686 if ($conf['comparison']==66 || $conf['comparison']==67) {
687 $lineHTML .= ' + <input type="text" value="'.htmlspecialchars($conf['inputValue1']).'" name="'.$this->name.$subscript.'[inputValue1]'.'"'.$GLOBALS['TBE_TEMPLATE']->formWidth(10).'>';
688 }
689 break;
690 case 'boolean':
691 $lineHTML .= $this->mkTypeSelect($this->name.$subscript.'[type]', $fName);
692 $lineHTML .= $this->mkCompSelect($this->name.$subscript.'[comparison]', $conf['comparison'], $conf['negate']?1:0);
693 $lineHTML .= '<input type="checkbox"'.($conf['negate']?' checked':'').' name="'.$this->name.$subscript.'[negate]'.'" onClick="submit();">';
694 $lineHTML .= '<input type="hidden" value="1" name="'.$this->name.$subscript.'[inputValue]'.'"'.$GLOBALS['TBE_TEMPLATE']->formWidth(10).'>';
695 break;
696 default:
697 $lineHTML .= $this->mkTypeSelect($this->name.$subscript.'[type]', $fName);
698 $lineHTML .= $this->mkCompSelect($this->name.$subscript.'[comparison]', $conf['comparison'], $conf['negate']?1:0);
699 $lineHTML .= '<input type="checkbox"'.($conf['negate']?' checked':'').' name="'.$this->name.$subscript.'[negate]'.'" onClick="submit();">';
700 if ($conf['comparison']==37 || $conf['comparison']==36) { // between:
701 $lineHTML.='<input type="text" value="'.htmlspecialchars($conf['inputValue']).'" name="'.$this->name.$subscript.'[inputValue]'.'"'.$GLOBALS['TBE_TEMPLATE']->formWidth(5).'>
702 <input type="text" value="'.htmlspecialchars($conf['inputValue1']).'" name="'.$this->name.$subscript.'[inputValue1]'.'"'.$GLOBALS['TBE_TEMPLATE']->formWidth(5).'>'; // onChange='submit();'
703 } else {
704 $lineHTML.='<input type="text" value="'.htmlspecialchars($conf['inputValue']).'" name="'.$this->name.$subscript.'[inputValue]'.'"'.$GLOBALS['TBE_TEMPLATE']->formWidth(10).'>'; // onChange="submit();"
705 }
706 break;
707 }
708 if($fType != 'ignore') {
709 $lineHTML .= $this->updateIcon();
710 if ($loopcount) {
711 $lineHTML .= '<input type="image" border="0" src="'.$GLOBALS['BACK_PATH'].'gfx/garbage.gif" class="absmiddle" width="11" height="12" hspace="3" vspace="3" title="Remove condition" name="qG_del'.$subscript.'">';
712 }
713 $lineHTML .= '<input type="image" border="0" src="'.$GLOBALS['BACK_PATH'].'gfx/add.gif" class="absmiddle" width="12" height="12" hspace="3" vspace="3" title="Add condition" name="qG_ins'.$subscript.'">';
714 if($c!=0) $lineHTML.= '<input type="image" border="0" src="'.$GLOBALS['BACK_PATH'].'gfx/pil2up.gif" class="absmiddle" width="12" height="7" hspace="3" vspace="3" title="Move up" name="qG_up'.$subscript.'">';
715
716 if($c!=0 && $fType!='newlevel') {
717 $lineHTML.= '<input type="image" border="0" src="'.$GLOBALS['BACK_PATH'].'gfx/pil2right.gif" class="absmiddle" height="12" width="7" hspace="3" vspace="3" title="New level" name="qG_nl'.$subscript.'">';
718 }
719 if($fType=='newlevel') {
720 $lineHTML.= '<input type="image" border="0" src="'.$GLOBALS['BACK_PATH'].'gfx/pil2left.gif" class="absmiddle" height="12" width="7" hspace="3" vspace="3" title="Collapse new level" name="qG_remnl'.$subscript.'">';
721 }
722
723 $codeArr[$arrCount]['html'] = $lineHTML;
724 $codeArr[$arrCount]['query'] = $this->getQuerySingle($conf,$c>0?0:1);
725 $arrCount++;
726 $c++;
727 }
728 $loopcount = 1;
729 }
730 // $codeArr[$arrCount] .='<input type="hidden" name="CMD" value="displayQuery">';
731 $this->queryConfig = $queryConfig;
732 //modifyHTMLColor($color,$R,$G,$B)
733 return $codeArr;
734 }
735
736 /**
737 * [Describe function...]
738 *
739 * @param [type] $codeArr: ...
740 * @param [type] $l: ...
741 * @param [type] $table: ...
742 * @return [type] ...
743 */
744 function makeOptionList($fN, $conf, $table) {
745 $fieldSetup = $this->fields[$fN];
746 if ($fieldSetup['type']=='files') {
747 if ($conf['comparison']==66 || $conf['comparison']==67) {
748 $fileExtArray = explode(',', $fieldSetup['allowed']);
749 natcasesort($fileExtArray);
750 foreach ($fileExtArray as $fileExt) {
751 if (t3lib_div::inList($conf['inputValue'], $fileExt)) {
752 $out .= '<option value="'.$fileExt.'" selected>.'.$fileExt.'</option>';
753 } else {
754 $out .= '<option value="'.$fileExt.'">.'.$fileExt.'</option>';
755 }
756 }
757 }
758 $d = dir(t3lib_div::getIndpEnv(TYPO3_DOCUMENT_ROOT).'/'.$fieldSetup['uploadfolder']);
759 while (false !== ($entry=$d->read())) {
760 if ($entry=='.' || $entry=='..') {
761 continue;
762 }
763 $fileArray[] = $entry;
764 }
765 $d->close();
766 natcasesort($fileArray);
767 foreach ($fileArray as $fileName) {
768 if (t3lib_div::inList($conf['inputValue'], $fileName)) {
769 $out .= '<option value="'.$fileName.'" selected>'.$fileName.'</option>';
770 } else {
771 $out .= '<option value="'.$fileName.'">'.$fileName.'</option>';
772 }
773 }
774 }
775 if ($fieldSetup['type']=='multiple') {
776 foreach ($fieldSetup['items'] as $key=>$val) {
777 if (substr($val[0], 0, 4) == 'LLL:') {
778 $value = $GLOBALS['LANG']->sL($val[0]);
779 } else {
780 $value = $val[0];
781 }
782 if (t3lib_div::inList($conf['inputValue'], $val[1])) {
783 $out .= '<option value="'.$val[1].'" selected>'.$value.'</option>';
784 } else {
785 $out .= '<option value="'.$val[1].'">'.$value.'</option>';
786 }
787 }
788 }
789 if ($fieldSetup['type']=='binary') {
790 foreach ($fieldSetup['items'] as $key=>$val) {
791 if (substr($val[0], 0, 4)=='LLL:') {
792 $value = $GLOBALS['LANG']->sL($val[0]);
793 } else {
794 $value = $val[0];
795 }
796 if (t3lib_div::inList($conf['inputValue'], pow(2, $key))) {
797 $out .= '<option value="'.pow(2, $key).'" selected>'.$value.'</option>';
798 } else {
799 $out .= '<option value="'.pow(2, $key).'">'.$value.'</option>';
800 }
801 }
802 }
803 if ($fieldSetup['type']=='relation') {
804 if ($fieldSetup['items']) {
805 foreach ($fieldSetup['items'] as $key=>$val) {
806 if (substr($val[0], 0, 4) == 'LLL:') {
807 $value = $GLOBALS['LANG']->sL($val[0]);
808 } else {
809 $value = $val[0];
810 }
811 if (t3lib_div::inList($conf['inputValue'], $val[1])) {
812 $out .= '<option value="'.$val[1].'" selected>'.$value.'</option>';
813 } else {
814 $out .= '<option value="'.$val[1].'">'.$value.'</option>';
815 }
816 }
817 }
818 global $TCA;
819 if (stristr($fieldSetup['allowed'], ',')) {
820 $from_table_Arr = explode(',', $fieldSetup['allowed']);
821 $useTablePrefix = 1;
822 if (!$fieldSetup['prepend_tname']) {
823 $checkres = $GLOBALS['TYPO3_DB']->exec_SELECTquery($fN, $table, t3lib_BEfunc::deleteClause($table), $groupBy = '', $orderBy = '', $limit = '');
824 if ($checkres) {
825 while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($checkres)) {
826 if (stristr($row[$fN], ',')) {
827 $checkContent = explode(',', $row[$fN]);
828 foreach ($checkContent as $singleValue) {
829 if (!stristr($singleValue, '_')) {
830 $dontPrefixFirstTable = 1;
831 }
832 }
833 } else {
834 $singleValue = $row[$fN];
835 if (strlen($singleValue) && !stristr($singleValue, '_')) {
836 $dontPrefixFirstTable = 1;
837 }
838 }
839 }
840 }
841 }
842 } else {
843 $from_table_Arr[0] = $fieldSetup['allowed'];
844 }
845 if ($fieldSetup['prepend_tname']) {
846 $useTablePrefix = 1;
847 }
848 if ($fieldSetup['foreign_table']) {
849 $from_table_Arr[0] = $fieldSetup['foreign_table'];
850 }
851 $counter = 0;
852 while (list(, $from_table) = each($from_table_Arr)) {
853 if (($useTablePrefix && !$dontPrefixFirstTable && $counter!=1) || $counter==1) {
854 $tablePrefix = $from_table.'_';
855 }
856 $counter = 1;
857 if (is_array($TCA[$from_table])) {
858 t3lib_div::loadTCA($from_table);
859 $labelField = $TCA[$from_table]['ctrl']['label'];
860 $altLabelField = $TCA[$from_table]['ctrl']['label_alt'];
861 if ($TCA[$from_table]['columns'][$labelField]['config']['items']) {
862 foreach ($TCA[$from_table]['columns'][$labelField]['config']['items'] as $labelArray) {
863 if (substr($labelArray[0], 0, 4) == 'LLL:') {
864 $labelFieldSelect[$labelArray[1]] = $GLOBALS['LANG']->sL($labelArray[0]);
865 } else {
866 $labelFieldSelect[$labelArray[1]] = $labelArray[0];
867 }
868 }
869 $useSelectLabels = 1;
870 }
871 if ($TCA[$from_table]['columns'][$altLabelField]['config']['items']) {
872 foreach ($TCA[$from_table]['columns'][$altLabelField]['config']['items'] as $altLabelArray) {
873 if (substr($altLabelArray[0], 0, 4) == 'LLL:') {
874 $altLabelFieldSelect[$altLabelArray[1]] = $GLOBALS['LANG']->sL($altLabelArray[0]);
875 } else {
876 $altLabelFieldSelect[$altLabelArray[1]] = $altLabelArray[0];
877 }
878 }
879 $useAltSelectLabels = 1;
880 }
881 $altLabelFieldSelect = $altLabelField ? ','.$altLabelField : '';
882 $select_fields = 'uid,'.$labelField.$altLabelFieldSelect;
883 if (!$GLOBALS['BE_USER']->isAdmin() && $GLOBALS['TYPO3_CONF_VARS']['BE']['lockBeUserToDBmounts']) {
884 $webMounts = $GLOBALS['BE_USER']->returnWebmounts();
885 $perms_clause = $GLOBALS['BE_USER']->getPagePermsClause(1);
886 foreach ($webMounts as $key => $val) {
887 if ($webMountPageTree) {
888 $webMountPageTreePrefix = ',';
889 }
890 $webMountPageTree .= $webMountPageTreePrefix.$this->getTreeList($val, 999, $begin = 0, $perms_clause);
891 }
892 if ($from_table=='pages') {
893 $where_clause = 'uid IN ('.$webMountPageTree.') ';
894 if (!$GLOBALS['SOBE']->MOD_SETTINGS['show_deleted']) {
895 $where_clause .= t3lib_BEfunc::deleteClause($from_table).' AND'.$perms_clause;
896 }
897 } else {
898 $where_clause = 'pid IN ('.$webMountPageTree.') ';
899 if (!$GLOBALS['SOBE']->MOD_SETTINGS['show_deleted']) {
900 $where_clause .= t3lib_BEfunc::deleteClause($from_table);
901 }
902 }
903 } else {
904 $where_clause = 'uid';
905 if (!$GLOBALS['SOBE']->MOD_SETTINGS['show_deleted']) {
906 $where_clause .= t3lib_BEfunc::deleteClause($from_table);
907 }
908 }
909 $orderBy = 'uid';
910 if (!$this->tableArray[$from_table]) {
911 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery($select_fields, $from_table, $where_clause, $groupBy = '', $orderBy, $limit = '');
912 }
913 if ($res) {
914 while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
915 $this->tableArray[$from_table][] = $row;
916 }
917 }
918 foreach ($this->tableArray[$from_table] as $key=>$val) {
919 if ($useSelectLabels) {
920 $outArray[$tablePrefix.$val['uid']] = htmlspecialchars($labelFieldSelect[$val[$labelField]]);
921 } elseif ($val[$labelField]) {
922 $outArray[$tablePrefix.$val['uid']] = htmlspecialchars($val[$labelField]);
923 } elseif ($useAltSelectLabels) {
924 $outArray[$tablePrefix.$val['uid']] = htmlspecialchars($altLabelFieldSelect[$val[$altLabelField]]);
925 } else {
926 $outArray[$tablePrefix.$val['uid']] = htmlspecialchars($val[$altLabelField]);
927 }
928 }
929 if ($GLOBALS['SOBE']->MOD_SETTINGS['options_sortlabel'] && is_array($outArray)) {
930 natcasesort($outArray);
931 }
932 }
933 }
934 foreach ($outArray as $key2 => $val2) {
935 if (t3lib_div::inList($conf['inputValue'], $key2)) {
936 $out .= '<option value="'.$key2.'" selected>['.$key2.'] '.$val2.'</option>';
937 } else {
938 $out .= '<option value="'.$key2.'">['.$key2.'] '.$val2.'</option>';
939 }
940 }
941 }
942 return $out;
943 }
944
945
946 /**
947 * [Describe function...]
948 *
949 * @param [type] $codeArr: ...
950 * @param [type] $l: ...
951 * @return [type] ...
952 */
953 function printCodeArray($codeArr,$l=0) {
954 reset($codeArr);
955 $line='';
956 if ($l) $indent='<td style="vertical-align:top;"><img height="1" width="50"></td>';
957 $lf=$l*30;
958 $bgColor = t3lib_div::modifyHTMLColor($GLOBALS['TBE_TEMPLATE']->bgColor2,$lf,$lf,$lf);
959 while(list($k,$v)=each($codeArr)) {
960 $line.= '<tr>'.$indent.'<td bgcolor="'.$bgColor.'"'.$this->noWrap.'>'.$v['html'].'</td></tr>';
961 if ($this->enableQueryParts) {$line.= '<tr>'.$indent.'<td>'.$this->formatQ($v['query']).'</td></tr>';}
962 if (is_array($v['sub'])) {
963 $line.= '<tr>'.$indent.'<td'.$this->noWrap.'>'.$this->printCodeArray($v['sub'],$l+1).'</td></tr>';
964 }
965 }
966 $out='<table border="0" cellpadding="0" cellspacing="1">'.$line.'</table>';
967 return $out;
968 }
969
970 /**
971 * [Describe function...]
972 *
973 * @param [type] $str: ...
974 * @return [type] ...
975 */
976 function formatQ($str) {
977 return '<font size="1" face="verdana" color="maroon"><i>'.$str.'</i></font>';
978 }
979
980 /**
981 * [Describe function...]
982 *
983 * @param [type] $name: ...
984 * @param [type] $op: ...
985 * @param [type] $draw: ...
986 * @param [type] $submit: ...
987 * @return [type] ...
988 */
989 function mkOperatorSelect($name,$op,$draw,$submit) {
990 if ($draw) {
991 $out='<select name="'.$name.'[operator]"'.($submit?' onChange="submit();"':'').'>'; //
992 $out.='<option value="AND"'.(!$op||$op=="AND" ? ' selected':'').'>'.$this->lang["AND"].'</option>';
993 $out.='<option value="OR"'.($op=='OR' ? ' selected':'').'>'.$this->lang['OR'].'</option>';
994 $out.='</select>';
995 } else {
996 $out.='<input type="hidden" value="'.$op.'" name="'.$name.'[operator]">';
997 $out.='<img src="clear.gif" height="1" width="47">';
998
999 }
1000 return $out;
1001 }
1002
1003 /**
1004 * [Describe function...]
1005 *
1006 * @param [type] $name: ...
1007 * @param [type] $fieldName: ...
1008 * @param [type] $prepend: ...
1009 * @return [type] ...
1010 */
1011 function mkTypeSelect($name,$fieldName,$prepend='FIELD_') {
1012 $out='<select name="'.$name.'" onChange="submit();">';
1013 $out.='<option value=""></option>';
1014 reset($this->fields);
1015 while(list($key,)=each($this->fields)) {
1016 if (!$fieldValue['exclude'] || $GLOBALS['BE_USER']->check('non_exclude_fields', $this->table.':'.$key)) {
1017 $label = $this->fields[$key]['label'];
1018 $label_alt = $this->fields[$key]['label_alt'];
1019 $out .= '<option value="'.$prepend.$key.'"'.($key==$fieldName ? ' selected' : '').'>'.$label.'</option>';
1020 }
1021 }
1022 $out.='</select>';
1023 return $out;
1024 }
1025
1026 /**
1027 * [Describe function...]
1028 *
1029 * @param [type] $fieldName: ...
1030 * @return [type] ...
1031 */
1032 function verifyType($fieldName) {
1033 reset($this->fields);
1034 $first = '';
1035 while(list($key,)=each($this->fields)) {
1036 if (!$first) $first = $key;
1037 if ($key==$fieldName) return $key;
1038 }
1039 return $first;
1040 }
1041
1042 /**
1043 * [Describe function...]
1044 *
1045 * @param [type] $comparison: ...
1046 * @param [type] $neg: ...
1047 * @return [type] ...
1048 */
1049 function verifyComparison($comparison,$neg) {
1050 $compOffSet = $comparison >> 5;
1051 $first=-1;
1052 for($i=32*$compOffSet+$neg;$i<32*($compOffSet+1);$i+=2) {
1053 if ($first==-1) $first = $i;
1054 if (($i >> 1)==($comparison >> 1)) {
1055 return $i;
1056 }
1057 }
1058 return $first;
1059 }
1060
1061 /**
1062 * [Describe function...]
1063 *
1064 * @param [type] $name: ...
1065 * @param [type] $fieldName: ...
1066 * @return [type] ...
1067 */
1068 function mkFieldToInputSelect($name,$fieldName) {
1069 $out='<input type="Text" value="'.htmlspecialchars($fieldName).'" name="'.$name.'"'.$GLOBALS['TBE_TEMPLATE']->formWidth().'>'.$this->updateIcon();
1070 $out.='<a href="#" onClick="document.forms[0][\''.$name.'\'].value=\'\';return false;"><img src="'.$GLOBALS['BACK_PATH'].'gfx/garbage.gif" class="absmiddle" width="11" height="12" hspace="3" vspace="3" title="Clear list" border="0"></a>';
1071 $out.='<BR><select name="_fieldListDummy" size="5" onChange="document.forms[0][\''.$name.'\'].value+=\',\'+this.value">';
1072 reset($this->fields);
1073 while(list($key,)=each($this->fields)) {
1074 if (!$fieldValue['exclude'] || $GLOBALS['BE_USER']->check('non_exclude_fields', $this->table.':'.$key)) {
1075 $label = $this->fields[$key]['label'];
1076 $label_alt = $this->fields[$key]['label_alt'];
1077 $out .= '<option value="'.$key.'"'.($key==$fieldName ? ' selected':'').'>'.$label.'</option>';
1078 }
1079 }
1080 $out.='</select>';
1081 return $out;
1082 }
1083
1084 /**
1085 * [Describe function...]
1086 *
1087 * @param [type] $name: ...
1088 * @param [type] $cur: ...
1089 * @return [type] ...
1090 */
1091 function mkTableSelect($name,$cur) {
1092 global $TCA;
1093 $out='<select name="'.$name.'" onChange="submit();">';
1094 $out.='<option value=""></option>';
1095 reset($TCA);
1096 while(list($tN)=each($TCA)) {
1097 if ($GLOBALS['BE_USER']->check('tables_select',$tN)) {
1098 $out.='<option value="'.$tN.'"'.($tN==$cur ? ' selected':'').'>'.$GLOBALS['LANG']->sl($TCA[$tN]['ctrl']['title']).'</option>';
1099 }
1100 }
1101 $out.='</select>';
1102 return $out;
1103 }
1104
1105 /**
1106 * [Describe function...]
1107 *
1108 * @param [type] $name: ...
1109 * @param [type] $comparison: ...
1110 * @param [type] $neg: ...
1111 * @return [type] ...
1112 */
1113 function mkCompSelect($name,$comparison,$neg) {
1114 $compOffSet = $comparison >> 5;
1115 $out='<select name="'.$name.'" onChange="submit();">';
1116 for($i=32*$compOffSet+$neg;$i<32*($compOffSet+1);$i+=2) {
1117 if($this->lang['comparison'][$i.'_']) {
1118 $out.='<option value="'.$i.'"'.(($i >> 1)==($comparison >> 1) ? ' selected':'').'>'.$this->lang['comparison'][$i.'_'].'</option>';
1119 }
1120 }
1121 $out.='</select>';
1122 return $out;
1123 }
1124
1125 /**
1126 * [Describe function...]
1127 *
1128 * @param [type] $arr: ...
1129 * @return [type] ...
1130 */
1131 function getSubscript($arr) {
1132 while(is_array($arr)) {
1133 reset($arr);
1134 list($key,)=each($arr);
1135 $retArr[] = $key;
1136 $arr = $arr[$key];
1137 }
1138 return $retArr;
1139 }
1140
1141 /**
1142 * [Describe function...]
1143 *
1144 * @return [type] ...
1145 */
1146 function initUserDef() {
1147
1148 }
1149
1150 /**
1151 * [Describe function...]
1152 *
1153 * @return [type] ...
1154 */
1155 function userDef() {
1156 }
1157
1158 /**
1159 * [Describe function...]
1160 *
1161 * @param [type] $queryConfig: ...
1162 * @return [type] ...
1163 */
1164 function userDefCleanUp($queryConfig) {
1165 return $queryConfig;
1166 }
1167
1168 /**
1169 * [Describe function...]
1170 *
1171 * @param [type] $queryConfig: ...
1172 * @param [type] $pad: ...
1173 * @return [type] ...
1174 */
1175 function getQuery ($queryConfig,$pad='') {
1176 $qs = '';
1177 // Since we don't traverse the array using numeric keys in the upcoming whileloop make sure it's fresh and clean
1178 ksort($queryConfig);
1179 reset($queryConfig);
1180 $first=1;
1181 while(list($key,$conf) = each($queryConfig)) {
1182 switch($conf['type']) {
1183 case 'newlevel':
1184 $qs.=chr(10).$pad.trim($conf['operator']).' ('.$this->getQuery($queryConfig[$key]['nl'],$pad.' ').chr(10).$pad.')';
1185 break;
1186 case 'userdef':
1187 $qs.=chr(10).$pad.getUserDefQuery($conf,$first);
1188 break;
1189 default:
1190 $qs.=chr(10).$pad.$this->getQuerySingle($conf,$first);
1191 break;
1192 }
1193 $first=0;
1194 }
1195 return $qs;
1196 }
1197
1198 /**
1199 * [Describe function...]
1200 *
1201 * @param [type] $conf: ...
1202 * @param [type] $first: ...
1203 * @return [type] ...
1204 */
1205 function getQuerySingle($conf,$first) {
1206 $prefix = $this->enablePrefix ? $this->table.'.' : '';
1207 if (!$first) {
1208 // Is it OK to insert the AND operator if none is set?
1209 $qs .= trim(($conf['operator'] ? $conf['operator'] : 'AND')).' ';
1210 }
1211 $qsTmp = str_replace('#FIELD#', $prefix.trim(substr($conf['type'],6)), $this->compSQL[$conf['comparison']]);
1212 $inputVal = $this->cleanInputVal($conf);
1213 if ($conf['comparison']==68 || $conf['comparison']==69) {
1214 $inputVal = explode(',', $inputVal);
1215 foreach ($inputVal as $key => $fileName) {
1216 $inputVal[$key] = "'".$fileName."'";
1217 }
1218 $inputVal = implode(',', $inputVal);
1219 $qsTmp = str_replace('#VALUE#', $inputVal, $qsTmp);
1220 } elseif ($conf['comparison']==162 || $conf['comparison']==163) {
1221 $inputValArray = explode(',', $inputVal);
1222 $inputVal = 0;
1223 foreach ($inputValArray as $key=>$fileName) {
1224 $inputVal += intval($fileName);
1225 }
1226 $qsTmp = str_replace('#VALUE#', $inputVal, $qsTmp);
1227 } else {
1228 $qsTmp = str_replace('#VALUE#', $GLOBALS['TYPO3_DB']->quoteStr($inputVal,$this->table), $qsTmp);
1229 }
1230 if ($conf['comparison']==37 || $conf['comparison']==36 || $conf['comparison']==66 || $conf['comparison']==67 || $conf['comparison']==100 || $conf['comparison']==101) { // between:
1231 $inputVal = $this->cleanInputVal($conf,'1');
1232 $qsTmp = str_replace('#VALUE1#', $GLOBALS['TYPO3_DB']->quoteStr($inputVal,$this->table), $qsTmp);
1233 }
1234 $qs .= trim($qsTmp);
1235 return $qs;
1236 }
1237
1238 /**
1239 * [Describe function...]
1240 *
1241 * @param [type] $conf: ...
1242 * @param [type] $suffix: ...
1243 * @return [type] ...
1244 */
1245 function cleanInputVal($conf,$suffix='') {
1246 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)) {
1247 $inputVal = $conf['inputValue'.$suffix];
1248 } elseif ($conf['comparison']==39 || $conf['comparison']==38) { // in list:
1249 $inputVal = implode(',',t3lib_div::intExplode(',',$conf['inputValue'.$suffix]));
1250 } elseif ($conf['comparison']==68 || $conf['comparison']==69 || $conf['comparison']==162 || $conf['comparison']==163) { // in list:
1251 if (is_array($conf['inputValue'.$suffix])) {
1252 $inputVal = implode(',', $conf['inputValue'.$suffix]);
1253 } elseif ($conf['inputValue'.$suffix]) {
1254 $inputVal = $conf['inputValue'.$suffix];
1255 } else {
1256 $inputVal = 0;
1257 }
1258 } else {
1259 $inputVal = doubleval($conf['inputValue'.$suffix]);
1260 }
1261 return $inputVal;
1262 }
1263
1264 /**
1265 * [Describe function...]
1266 *
1267 * @param [type] $qcArr: ...
1268 * @return [type] ...
1269 */
1270 function getUserDefQuery ($qcArr) {
1271 }
1272
1273 /**
1274 * [Describe function...]
1275 *
1276 * @return [type] ...
1277 */
1278 function updateIcon() {
1279 return '<input type="image" border="0" src="'.$GLOBALS['BACK_PATH'].'gfx/refresh_n.gif" class="absmiddle" width="14" height="14" hspace="3" vspace="3" title="Update" name="just_update">';
1280 }
1281
1282 /**
1283 * [Describe function...]
1284 *
1285 * @return [type] ...
1286 */
1287 function getLabelCol() {
1288 global $TCA;
1289 return $TCA[$this->table]['ctrl']['label'];
1290 }
1291
1292 /**
1293 * [Describe function...]
1294 *
1295 * @param [type] $modSettings: ...
1296 * @param [type] $enableList: ...
1297 * @return [type] ...
1298 */
1299 function makeSelectorTable($modSettings,$enableList='table,fields,query,group,order,limit') {
1300 $enableArr=explode(',',$enableList);
1301 // Make output
1302 $TDparams = ' class="bgColor5" nowrap';
1303
1304 if (in_array('table',$enableArr) && !$GLOBALS['BE_USER']->userTS['mod.']['dbint.']['disableSelectATable']) {
1305 $out='
1306 <tr>
1307 <td'.$TDparams.'><strong>Select a table:</strong></td>
1308 <td'.$TDparams.'>'.$this->mkTableSelect('SET[queryTable]',$this->table).'</td>
1309 </tr>';
1310 }
1311 if ($this->table) {
1312
1313 // Init fields:
1314 $this->setAndCleanUpExternalLists('queryFields',$modSettings['queryFields'],'uid,'.$this->getLabelCol());
1315 $this->setAndCleanUpExternalLists('queryGroup',$modSettings['queryGroup']);
1316 $this->setAndCleanUpExternalLists('queryOrder',$modSettings['queryOrder'].','.$modSettings['queryOrder2']);
1317
1318 // Limit:
1319 $this->extFieldLists['queryLimit']=$modSettings['queryLimit'];
1320 if (!$this->extFieldLists['queryLimit']) $this->extFieldLists['queryLimit']=100;
1321 $parts = t3lib_div::intExplode(',',$this->extFieldLists['queryLimit']);
1322 if ($parts[1]) {
1323 $this->limitBegin = $parts[0];
1324 $this->limitLength = $parts[1];
1325 } else {
1326 $this->limitLength = $this->extFieldLists['queryLimit'];
1327 }
1328 $this->extFieldLists['queryLimit'] = implode(',',array_slice($parts,0,2));
1329
1330 // Insert Descending parts
1331 if ($this->extFieldLists['queryOrder']) {
1332 $descParts = explode(',',$modSettings['queryOrderDesc'].','.$modSettings['queryOrder2Desc']);
1333 $orderParts = explode(',',$this->extFieldLists['queryOrder']);
1334 reset($orderParts);
1335 $reList=array();
1336 while(list($kk,$vv)=each($orderParts)) {
1337 $reList[]=$vv.($descParts[$kk]?' DESC':'');
1338 }
1339 $this->extFieldLists['queryOrder_SQL'] = implode(',',$reList);
1340 }
1341
1342 // Query Generator:
1343 $this->procesData($modSettings['queryConfig'] ? unserialize($modSettings['queryConfig']) : '');
1344 // debug($this->queryConfig);
1345 $this->queryConfig = $this->cleanUpQueryConfig($this->queryConfig);
1346 // debug($this->queryConfig);
1347 $this->enableQueryParts = $modSettings['search_query_smallparts'];
1348
1349 $codeArr=$this->getFormElements();
1350 $queryCode=$this->printCodeArray($codeArr);
1351
1352 if (in_array('fields',$enableArr) && !$GLOBALS['BE_USER']->userTS['mod.']['dbint.']['disableSelectFields']) {
1353 $out.='
1354 <tr>
1355 <td'.$TDparams.'><strong>Select fields:</strong></td>
1356 <td'.$TDparams.'>'.$this->mkFieldToInputSelect('SET[queryFields]',$this->extFieldLists['queryFields']).'</td>
1357 </tr>';
1358 }
1359 if (in_array('query',$enableArr) && !$GLOBALS['BE_USER']->userTS['mod.']['dbint.']['disableMakeQuery']) {
1360 $out.='<tr>
1361 <td colspan="2"'.$TDparams.'><strong>Make Query:</strong></td>
1362 </tr>
1363 <tr>
1364 <td colspan="2">'.$queryCode.'</td>
1365 </tr>
1366 ';
1367 }
1368 if (in_array('group',$enableArr) && !$GLOBALS['BE_USER']->userTS['mod.']['dbint.']['disableGroupBy']) {
1369 $out.='<tr>
1370 <td'.$TDparams.'><strong>Group By:</strong></td>
1371 <td'.$TDparams.'>'.$this->mkTypeSelect('SET[queryGroup]',$this->extFieldLists['queryGroup'],'').'</td>
1372 </tr>';
1373 }
1374 if (in_array('order',$enableArr) && !$GLOBALS['BE_USER']->userTS['mod.']['dbint.']['disableOrderBy']) {
1375 $orderByArr = explode(',',$this->extFieldLists['queryOrder']);
1376 // debug($orderByArr);
1377 $orderBy='';
1378 $orderBy.=$this->mkTypeSelect('SET[queryOrder]',$orderByArr[0],'').
1379 '&nbsp;'.t3lib_BEfunc::getFuncCheck($GLOBALS['SOBE']->id,'SET[queryOrderDesc]',$modSettings['queryOrderDesc']).'&nbsp;Descending';
1380 if ($orderByArr[0]) {
1381 $orderBy.= '<BR>'.$this->mkTypeSelect('SET[queryOrder2]',$orderByArr[1],'').
1382 '&nbsp;'.t3lib_BEfunc::getFuncCheck($GLOBALS['SOBE']->id,'SET[queryOrder2Desc]',$modSettings['queryOrder2Desc']).'&nbsp;Descending';
1383 }
1384 $out.='<tr>
1385 <td'.$TDparams.'><strong>Order By:</strong></td>
1386 <td'.$TDparams.'>'.$orderBy.'</td>
1387 </tr>';
1388 }
1389 if (in_array('limit',$enableArr) && !$GLOBALS['BE_USER']->userTS['mod.']['dbint.']['disableLimit']) {
1390 $limit = '<input type="Text" value="'.htmlspecialchars($this->extFieldLists['queryLimit']).'" name="SET[queryLimit]" id="queryLimit"'.$GLOBALS['TBE_TEMPLATE']->formWidth(10).'>'.$this->updateIcon();
1391
1392 $prevLimit = ($this->limitBegin-$this->limitLength) < 0 ? 0 :
1393 $this->limitBegin-$this->limitLength;
1394 if ($this->limitBegin) {
1395 $prevButton = '<input type="button" value="previous '.$this->limitLength.'" onclick=\'document.getElementById("queryLimit").value="'.$prevLimit.','.$this->limitLength.'";document.forms[0].submit();\'>';
1396 }
1397 if (!$this->limitLength) {
1398 $this->limitLength = 100;
1399 }
1400 $nextLimit = $this->limitBegin + $this->limitLength;
1401 if ($nextLimit < 0) $nextLimit = 0;
1402 if ($nextLimit) {
1403 $nextButton = '<input type="button" value="next '.$this->limitLength.'" onclick=\'document.getElementById("queryLimit").value="'.$nextLimit.','.$this->limitLength.'";document.forms[0].submit();\'>';
1404 }
1405
1406 $numberButtons = '<input type="button" value="10" onclick=\'document.getElementById("queryLimit").value="10";document.forms[0].submit();\'>';
1407 $numberButtons .= '<input type="button" value="20" onclick=\'document.getElementById("queryLimit").value="20";document.forms[0].submit();\'>';
1408 $numberButtons .= '<input type="button" value="50" onclick=\'document.getElementById("queryLimit").value="50";document.forms[0].submit();\'>';
1409 $numberButtons .= '<input type="button" value="100" onclick=\'document.getElementById("queryLimit").value="100";document.forms[0].submit();\'>';
1410 $out.='<tr>
1411 <td'.$TDparams.'><strong>Limit:</strong></td>
1412 <td'.$TDparams.'>'.$limit.$prevButton.$nextButton.'&nbsp;'.$numberButtons.'</td>
1413 </tr>
1414 ';
1415 }
1416 }
1417 $out='<table border="0" cellpadding="3" cellspacing="1">'.$out.'</table>';
1418 $out.=$this->JSbottom();
1419 return $out;
1420 }
1421
1422 /**
1423 * [Describe function...]
1424 *
1425 * @param [type] $qString: ...
1426 * @param [type] $depth: ...
1427 * @param [type] $begin: ...
1428 * @param [type] $perms_clause: ...
1429 * @return [type] ...
1430 */
1431 function getTreeList($id, $depth, $begin=0, $perms_clause) {
1432 $depth = intval($depth);
1433 $begin = intval($begin);
1434 $id = intval($id);
1435 if ($begin==0) {
1436 $theList = $id;
1437 } else {
1438 $theList = '';
1439 }
1440 if ($id && $depth > 0) {
1441 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
1442 'uid',
1443 'pages',
1444 'pid='.$id.' '.t3lib_BEfunc::deleteClause('pages').' AND '.$perms_clause
1445 );
1446 while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
1447 if ($begin <= 0) {
1448 $theList .= ','.$row['uid'];
1449 }
1450 if ($depth > 1) {
1451 $theList .= $this->getTreeList($row['uid'], $depth-1, $begin-1, $perms_clause);
1452 }
1453 }
1454 }
1455 return $theList;
1456 }
1457
1458 /**
1459 * [Describe function...]
1460 *
1461 * @param [type] $qString: ...
1462 * @param [type] $fN: ...
1463 * @return [type] ...
1464 */
1465 function getSelectQuery($qString = '', $fN = '') {
1466 if (!$qString) $qString = $this->getQuery($this->queryConfig);
1467 $qString = '('.$qString.')';
1468 if (!$GLOBALS['BE_USER']->isAdmin() && $GLOBALS['TYPO3_CONF_VARS']['BE']['lockBeUserToDBmounts']) {
1469 $webMounts = $GLOBALS['BE_USER']->returnWebmounts();
1470 $perms_clause = $GLOBALS['BE_USER']->getPagePermsClause(1);
1471 foreach($webMounts as $key => $val) {
1472 if ($webMountPageTree) {
1473 $webMountPageTreePrefix = ',';
1474 }
1475 $webMountPageTree .= $webMountPageTreePrefix.$this->getTreeList($val, 999, $begin = 0, $perms_clause);
1476 }
1477 if ($this->table == 'pages') {
1478 $qString .= ' AND uid IN ('.$webMountPageTree.')';
1479 } else {
1480 $qString .= ' AND pid IN ('.$webMountPageTree.')';
1481 }
1482 }
1483 $fieldlist = $this->extFieldLists['queryFields'].',pid,deleted';
1484 if (!$GLOBALS['SOBE']->MOD_SETTINGS['show_deleted']) {
1485 $qString .= t3lib_BEfunc::deleteClause($this->table);
1486 }
1487 $query = $GLOBALS['TYPO3_DB']->SELECTquery(
1488 $fieldlist,
1489 $this->table,
1490 $qString,
1491 trim($this->extFieldLists['queryGroup']),
1492 $this->extFieldLists['queryOrder'] ? trim($this->extFieldLists['queryOrder_SQL']) : '',
1493 $this->extFieldLists['queryLimit']
1494 );
1495 return $query;
1496 }
1497
1498 /**
1499 * [Describe function...]
1500 *
1501 * @param [type] $formname: ...
1502 * @return [type] ...
1503 */
1504 function JSbottom($formname='forms[0]') {
1505 if ($this->extJSCODE) {
1506 $out.='
1507 <script language="javascript" type="text/javascript" src="'.$GLOBALS['BACK_PATH'].'../t3lib/jsfunc.evalfield.js"></script>
1508 <script language="javascript" type="text/javascript" src="'.$GLOBALS['BACK_PATH'].'jsfunc.tbe_editor.js"></script>
1509 <script language="javascript" type="text/javascript">'.$this->extJSCODE.'</script>';
1510 return $out;
1511 }
1512 }
1513 }
1514
1515
1516 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_querygenerator.php']) {
1517 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_querygenerator.php']);
1518 }
1519 ?>