Fixed bug #14050: CleanUp - CGL format of t3lib files - t3lib_tceforms_inline
[Packages/TYPO3.CMS.git] / t3lib / class.t3lib_transferdata.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 1999-2010 Kasper Skårhøj (kasperYYYY@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 * Contains class for getting and transforming data for display in backend forms (TCEforms)
29 *
30 * $Id$
31 * Revised for TYPO3 3.6 September/2003 by Kasper Skårhøj
32 *
33 * @author Kasper Skårhøj <kasperYYYY@typo3.com>
34 */
35 /**
36 * [CLASS/FUNCTION INDEX of SCRIPT]
37 *
38 *
39 *
40 * 99: class t3lib_transferData
41 *
42 * SECTION: Getting record content, ready for display in TCEforms
43 * 138: function fetchRecord($table,$idList,$operation)
44 * 225: function renderRecord($table, $id, $pid, $row)
45 * 269: function renderRecordRaw($table, $id, $pid, $row, $TSconfig='', $tscPID=0)
46 * 327: function renderRecord_SW($data,$fieldConfig,$TSconfig,$table,$row,$field)
47 * 359: function renderRecord_groupProc($data,$fieldConfig,$TSconfig,$table,$row,$field)
48 * 410: function renderRecord_selectProc($data,$fieldConfig,$TSconfig,$table,$row,$field)
49 * 473: function renderRecord_flexProc($data,$fieldConfig,$TSconfig,$table,$row,$field)
50 * 504: function renderRecord_typesProc($totalRecordContent,$types_fieldConfig,$tscPID,$table,$pid)
51 * 545: function renderRecord_inlineProc($data,$fieldConfig,$TSconfig,$table,$row,$field)
52 *
53 * SECTION: FlexForm processing functions
54 * 632: function renderRecord_flexProc_procInData($dataPart,$dataStructArray,$pParams)
55 * 661: function renderRecord_flexProc_procInData_travDS(&$dataValues,$DSelements,$pParams)
56 *
57 * SECTION: Selector box processing functions
58 * 738: function selectAddSpecial($dataAcc, $elements, $specialKey)
59 * 863: function selectAddForeign($dataAcc, $elements, $fieldConfig, $field, $TSconfig, $row, $table)
60 * 917: function getDataIdList($elements, $fieldConfig, $row, $table)
61 * 946: function procesItemArray($selItems,$config,$fieldTSConfig,$table,$row,$field)
62 * 961: function addItems($items,$iArray)
63 * 983: function procItems($items,$itemsProcFuncTSconfig,$config,$table,$row,$field)
64 *
65 * SECTION: Helper functions
66 * 1018: function lockRecord($table, $id, $pid=0)
67 * 1035: function regItem($table, $id, $field, $content)
68 * 1045: function sL($in)
69 *
70 * TOTAL FUNCTIONS: 20
71 * (This index is automatically created/updated by the extension "extdeveval")
72 *
73 */
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88 /**
89 * Class for getting and transforming data for display in backend forms (TCEforms)
90 *
91 * @author Kasper Skårhøj <kasperYYYY@typo3.com>
92 * @package TYPO3
93 * @subpackage t3lib
94 */
95 class t3lib_transferData {
96 // External, static:
97 var $lockRecords=0; // If set, the records requested are locked.
98 var $disableRTE=0; // Is set externally if RTE is disabled.
99 var $prevPageID = ''; // If the pid in the command is 'prev' then $prevPageID is used as pid for the record. This is used to attach new records to other previous records eg. new pages.
100 var $defVals=array(); // Can be set with an array of default values for tables. First key is table name, second level keys are field names. Originally this was a GLOBAL array used internally.
101 var $addRawData = FALSE; // If set, the processed data is overlaid the raw record.
102
103 // Internal, dynamic
104 var $regTableItems = Array(); // Used to register, which items are already loaded!!
105 var $regTableItems_data = Array(); // This stores the record data of the loaded records
106 var $loadModules=''; // Contains loadModules object, if used. (for reuse internally)
107
108
109
110
111
112
113
114
115
116
117 /***********************************************
118 *
119 * Getting record content, ready for display in TCEforms
120 *
121 ***********************************************/
122
123 /**
124 * A function which can be used for load a batch of records from $table into internal memory of this object.
125 * The function is also used to produce proper default data for new records
126 * Ultimately the function will call renderRecord()
127 *
128 * @param string Table name, must be found in $TCA
129 * @param string Comma list of id values. If $idList is "prev" then the value from $this->prevPageID is used. NOTICE: If $operation is "new", then negative ids are meant to point to a "previous" record and positive ids are PID values for new records. Otherwise (for existing records that is) it is straight forward table/id pairs.
130 * @param string If "new", then a record with default data is returned. Further, the $id values are meant to be PID values (or if negative, pointing to a previous record). If NOT new, then the table/ids are just pointing to an existing record!
131 * @return void
132 * @see renderRecord()
133 */
134 function fetchRecord($table,$idList,$operation) {
135 global $TCA;
136
137 if ((string)$idList == 'prev') {$idList = $this->prevPageID;}
138
139 if ($TCA[$table]) {
140 t3lib_div::loadTCA($table);
141
142 // For each ID value (integer) we
143 $ids = t3lib_div::trimExplode(',',$idList,1);
144 foreach($ids as $id) {
145 if (strcmp($id,'')) { // If ID is not blank:
146
147 // For new records to be created, find default values:
148 if ($operation=='new') {
149
150 // Default values:
151 $newRow = Array(); // Used to store default values as found here:
152
153 // Default values as set in userTS:
154 $TCAdefaultOverride = $GLOBALS['BE_USER']->getTSConfigProp('TCAdefaults');
155 if (is_array($TCAdefaultOverride[$table.'.'])) {
156 foreach($TCAdefaultOverride[$table.'.'] as $theF => $theV) {
157 if (isset($TCA[$table]['columns'][$theF])) {
158 $newRow[$theF]=$theV;
159 }
160 }
161 }
162
163 if ($id < 0) {
164 $record = t3lib_beFunc::getRecord ($table, abs($id), 'pid');
165 $pid = $record['pid'];
166 unset($record);
167 } else {
168 $pid = intval($id);
169 }
170
171 $pageTS = t3lib_beFunc::getPagesTSconfig($pid);
172
173 if (isset($pageTS['TCAdefaults.'])) {
174 $TCAPageTSOverride = $pageTS['TCAdefaults.'];
175 if (is_array($TCAPageTSOverride[$table.'.'])) {
176 foreach($TCAPageTSOverride[$table.'.'] as $theF => $theV) {
177 if (isset($TCA[$table]['columns'][$theF])) {
178 $newRow[$theF]=$theV;
179 }
180 }
181 }
182 }
183
184 // Default values as submitted:
185 if (is_array($this->defVals[$table])) {
186 foreach($this->defVals[$table] as $theF => $theV) {
187 if (isset($TCA[$table]['columns'][$theF])) {
188 $newRow[$theF]=$theV;
189 }
190 }
191 }
192
193 // Fetch default values if a previous record exists
194 if ($id<0 && $TCA[$table]['ctrl']['useColumnsForDefaultValues']) {
195 // Fetches the previous record:
196 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', $table, 'uid='.abs($id).t3lib_BEfunc::deleteClause($table));
197 if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
198 // Gets the list of fields to copy from the previous record.
199 $fArr=t3lib_div::trimExplode(',',$TCA[$table]['ctrl']['useColumnsForDefaultValues'],1);
200 foreach ($fArr as $theF) {
201 if (isset($TCA[$table]['columns'][$theF])) {
202 $newRow[$theF]=$row[$theF];
203 }
204 }
205 }
206 $GLOBALS['TYPO3_DB']->sql_free_result($res);
207 }
208
209 // Finally, call renderRecord:
210 $this->renderRecord($table, uniqid('NEW'), $id, $newRow);
211 } else {
212 $id=intval($id);
213
214 // Fetch database values
215 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', $table, 'uid='.intval($id).t3lib_BEfunc::deleteClause($table));
216 if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
217 t3lib_BEfunc::fixVersioningPid($table,$row);
218 $this->renderRecord($table, $id, $row['pid'], $row);
219 $contentTable = $GLOBALS['TYPO3_CONF_VARS']['SYS']['contentTable'];
220 $this->lockRecord($table, $id, $contentTable==$table?$row['pid']:0); // Locking the pid if the table edited is the content table.
221 }
222 $GLOBALS['TYPO3_DB']->sql_free_result($res);
223 }
224 }
225 }
226 }
227 }
228
229 /**
230 * This function performs processing on the input $row array and stores internally a corresponding array which contains processed values, ready to pass on to the TCEforms rendering in the frontend!
231 * The objective with this function is to prepare the content for handling in TCEforms.
232 * Default values from outside/TSconfig is added by fetchRecord(). In this function default values from TCA is used if a field is NOT defined in $row.
233 * The resulting, processed row is stored in $this->regTableItems_data[$uniqueItemRef], where $uniqueItemRef is "[tablename]_[id-value]"
234 *
235 * @param string The table name
236 * @param string The uid value of the record (integer). Can also be a string (NEW-something) if the record is a NEW record.
237 * @param integer The pid integer. For existing records this is of course the row's "pid" field. For new records it can be either a page id (positive) or a pointer to another record from the SAME table (negative) after which the record should be inserted (or on same page)
238 * @param array The row of the current record. If NEW record, then it may be loaded with default values (by eg. fetchRecord()).
239 * @return void
240 * @see fetchRecord()
241 */
242 function renderRecord($table, $id, $pid, $row) {
243 global $TCA;
244
245 // Init:
246 $uniqueItemRef = $table.'_'.$id;
247 t3lib_div::loadTCA($table);
248
249 // Fetches the true PAGE TSconfig pid to use later, if needed. (Until now, only for the RTE, but later..., who knows?)
250 list($tscPID)=t3lib_BEfunc::getTSCpid($table,$id,$pid);
251 $TSconfig = t3lib_BEfunc::getTCEFORM_TSconfig($table,array_merge($row,array('uid'=>$id,'pid'=>$pid)));
252
253 // If the record has not already been loaded (in which case we DON'T do it again)...
254 if (!$this->regTableItems[$uniqueItemRef]) {
255 $this->regTableItems[$uniqueItemRef] = 1; // set "loaded" flag.
256
257 // If the table is pages, set the previous page id internally.
258 if ($table == 'pages') {$this->prevPageID = $id;}
259
260 $this->regTableItems_data[$uniqueItemRef] = $this->renderRecordRaw($table, $id, $pid, $row, $TSconfig, $tscPID);
261
262 // Merges the processed array on-top of the raw one - this is done because some things in TCEforms may need access to other fields than those in the columns configuration!
263 if ($this->addRawData && is_array($row) && is_array($this->regTableItems_data[$uniqueItemRef])) {
264 $this->regTableItems_data[$uniqueItemRef] = array_merge($row, $this->regTableItems_data[$uniqueItemRef]);
265 }
266 }
267 }
268
269
270
271 /**
272 * This function performs processing on the input $row array and stores internally a corresponding array which contains processed values, ready to pass on to the TCEforms rendering in the frontend!
273 * The objective with this function is to prepare the content for handling in TCEforms.
274 * In opposite to renderRecord() this function do not prepare things like fetching TSconfig and others.
275 * The resulting, processed row will be returned.
276 *
277 * @param string The table name
278 * @param string The uid value of the record (integer). Can also be a string (NEW-something) if the record is a NEW record.
279 * @param integer The pid integer. For existing records this is of course the row's "pid" field. For new records it can be either a page id (positive) or a pointer to another record from the SAME table (negative) after which the record should be inserted (or on same page)
280 * @param array The row of the current record. If NEW record, then it may be loaded with default values (by eg. fetchRecord()).
281 * @param array Tsconfig array
282 * @param integer PAGE TSconfig pid
283 * @return array Processed record data
284 * @see renderRecord()
285 */
286 function renderRecordRaw($table, $id, $pid, $row, $TSconfig='', $tscPID=0) {
287 global $TCA;
288
289 if(!is_array($TSconfig)) {
290 $TSconfig = array();
291 }
292
293 // Create blank accumulation array:
294 $totalRecordContent=array();
295
296 // Traverse the configured columns for the table (TCA):
297 // For each column configured, we will perform processing if needed based on the type (eg. for "group" and "select" types this is needed)
298 t3lib_div::loadTCA($table);
299 $copyOfColumns = $TCA[$table]['columns'];
300 foreach($copyOfColumns as $field => $fieldConfig) {
301 // Set $data variable for the field, either inputted value from $row - or if not found, the default value as defined in the "config" array
302 if (isset($row[$field])) {
303 $data = $row[$field];
304 } else {
305 $data = $fieldConfig['config']['default'];
306 }
307
308 $data = $this->renderRecord_SW($data,$fieldConfig,$TSconfig,$table,$row,$field);
309
310 // Set the field in the accumulation array IF the $data variabel is set:
311 $totalRecordContent[$field] = isset($data) ? $data : '';
312 }
313
314 // Further processing may apply for each field in the record depending on the settings in the "types" configuration (the list of fields to currently display for a record in TCEforms).
315 // For instance this could be processing instructions for the Rich Text Editor.
316 $types_fieldConfig = t3lib_BEfunc::getTCAtypes($table,$totalRecordContent);
317 if (is_array($types_fieldConfig)) {
318 $totalRecordContent = $this->renderRecord_typesProc($totalRecordContent,$types_fieldConfig,$tscPID,$table,$pid);
319 }
320
321 // Register items, mostly for external use (overriding the regItem() function)
322 foreach($totalRecordContent as $field => $data) {
323 $this->regItem($table,$id,$field,$data);
324 }
325
326 // Finally, store the result:
327 reset($totalRecordContent);
328
329 return $totalRecordContent;
330
331 }
332
333 /**
334 * Function with the switch() construct which triggers functions for processing of the data value depending on the TCA-config field type.
335 *
336 * @param string Value to process
337 * @param array TCA/columns array for field (independant of TCA for flexforms - coming from XML then)
338 * @param array TSconfig (blank for flexforms for now)
339 * @param string Table name
340 * @param array The row array, always of the real record (also for flexforms)
341 * @param string The field (empty for flexforms!)
342 * @return string Modified $value
343 */
344 function renderRecord_SW($data,$fieldConfig,$TSconfig,$table,$row,$field) {
345 switch((string)$fieldConfig['config']['type']) {
346 case 'group':
347 $data = $this->renderRecord_groupProc($data,$fieldConfig,$TSconfig,$table,$row,$field);
348 break;
349 case 'select':
350 $data = $this->renderRecord_selectProc($data,$fieldConfig,$TSconfig,$table,$row,$field);
351 break;
352 case 'flex':
353 $data = $this->renderRecord_flexProc($data,$fieldConfig,$TSconfig,$table,$row,$field);
354 break;
355 case 'inline':
356 $data = $this->renderRecord_inlineProc($data,$fieldConfig,$TSconfig,$table,$row,$field);
357 break;
358 }
359
360 return $data;
361 }
362
363 /**
364 * Processing of the data value in case the field type is "group"
365 *
366 * @param string The field value
367 * @param array TCA field config
368 * @param array TCEform TSconfig for the record
369 * @param string Table name
370 * @param array The row
371 * @param string Field name
372 * @return string The processed input field value ($data)
373 * @access private
374 * @see renderRecord()
375 */
376 function renderRecord_groupProc($data,$fieldConfig,$TSconfig,$table,$row,$field) {
377 switch ($fieldConfig['config']['internal_type']) {
378 case 'file':
379 // Init array used to accumulate the files:
380 $dataAcc=array();
381
382 // Now, load the files into the $dataAcc array, whether stored by MM or as a list of filenames:
383 if ($fieldConfig['config']['MM']) {
384 $loadDB = t3lib_div::makeInstance('t3lib_loadDBGroup');
385 $loadDB->start('', 'files', $fieldConfig['config']['MM'], $row['uid']); // Setting dummy startup
386
387 foreach($loadDB->itemArray as $value) {
388 if ($value['id']) {
389 $dataAcc[]=rawurlencode($value['id']).'|'.rawurlencode($value['id']);
390 }
391 }
392 } else {
393 $fileList = t3lib_div::trimExplode(',',$data,1);
394 foreach($fileList as $value) {
395 if ($value) {
396 $dataAcc[]=rawurlencode($value).'|'.rawurlencode($value);
397 }
398 }
399 }
400 // Implode the accumulation array to a comma separated string:
401 $data = implode(',',$dataAcc);
402 break;
403 case 'db':
404 $loadDB = t3lib_div::makeInstance('t3lib_loadDBGroup');
405 /* @var $loadDB t3lib_loadDBGroup */
406 $loadDB->start($data, $fieldConfig['config']['allowed'], $fieldConfig['config']['MM'], $row['uid'], $table, $fieldConfig['config']);
407 $loadDB->getFromDB();
408 $data = $loadDB->readyForInterface();
409 break;
410 }
411
412 return $data;
413 }
414
415 /**
416 * Processing of the data value in case the field type is "select"
417 *
418 * @param string The field value
419 * @param array TCA field config
420 * @param array TCEform TSconfig for the record
421 * @param string Table name
422 * @param array The row
423 * @param string Field name
424 * @return string The processed input field value ($data)
425 * @access private
426 * @see renderRecord()
427 */
428 function renderRecord_selectProc($data,$fieldConfig,$TSconfig,$table,$row,$field) {
429 global $TCA;
430
431 // Initialize:
432 $elements = t3lib_div::trimExplode(',',$data,1); // Current data set.
433 $dataAcc=array(); // New data set, ready for interface (list of values, rawurlencoded)
434
435 // For list selectors (multi-value):
436 if (intval($fieldConfig['config']['maxitems'])>1) {
437
438 // Add regular elements:
439 if (!is_array($fieldConfig['config']['items'])) {
440 $fieldConfig['config']['items'] = array();
441 }
442 $fieldConfig['config']['items'] = $this->procesItemArray($fieldConfig['config']['items'], $fieldConfig['config'], $TSconfig[$field], $table, $row, $field);
443 foreach($fieldConfig['config']['items'] as $pvpv) {
444 foreach($elements as $eKey => $value) {
445 if (!strcmp($value,$pvpv[1])) {
446 $dataAcc[$eKey]=rawurlencode($pvpv[1]).'|'.rawurlencode($this->sL($pvpv[0]));
447 }
448 }
449 }
450
451 // Add "special"
452 if ($fieldConfig['config']['special']) {
453 $dataAcc = $this->selectAddSpecial($dataAcc, $elements, $fieldConfig['config']['special']);
454 }
455
456 // Add "foreign table" stuff:
457 if ($TCA[$fieldConfig['config']['foreign_table']]) {
458 $dataAcc = $this->selectAddForeign($dataAcc, $elements, $fieldConfig, $field, $TSconfig, $row, $table);
459 }
460
461 // Always keep the native order for display in interface:
462 ksort($dataAcc);
463 } else { // Normal, <= 1 -> value without title on it
464 if ($TCA[$fieldConfig['config']['foreign_table']]) {
465 // Getting the data
466 $dataIds = $this->getDataIdList($elements, $fieldConfig, $row, $table);
467
468 if (!count($dataIds)) $dataIds = array(0);
469 $dataAcc[]=$dataIds[0];
470 } else {
471 $dataAcc[]=$elements[0];
472 }
473 }
474
475 return implode(',',$dataAcc);
476 }
477
478 /**
479 * Processing of the data value in case the field type is "flex"
480 * MUST NOT be called in case of already INSIDE a flexform!
481 *
482 * @param string The field value
483 * @param array TCA field config
484 * @param array TCEform TSconfig for the record
485 * @param string Table name
486 * @param array The row
487 * @param string Field name
488 * @return string The processed input field value ($data)
489 * @access private
490 * @see renderRecord()
491 */
492 function renderRecord_flexProc($data,$fieldConfig,$TSconfig,$table,$row,$field) {
493 global $TCA;
494
495 // Convert the XML data to PHP array:
496 $currentValueArray = t3lib_div::xml2array($data);
497 if (is_array($currentValueArray)) {
498
499 // Get current value array:
500 $dataStructArray = t3lib_BEfunc::getFlexFormDS($fieldConfig['config'],$row,$table);
501
502 // Manipulate Flexform DS via TSConfig and group access lists
503 if (is_array($dataStructArray)) {
504 $flexFormHelper = t3lib_div::makeInstance('t3lib_TCEforms_Flexforms');
505 $dataStructArray = $flexFormHelper->modifyFlexFormDS($dataStructArray, $table, $field, $row, $fieldConfig);
506 unset($flexFormHelper);
507 }
508
509 if (is_array($dataStructArray)) {
510 $currentValueArray['data'] = $this->renderRecord_flexProc_procInData($currentValueArray['data'],$dataStructArray,array($data,$fieldConfig,$TSconfig,$table,$row,$field));
511
512 $flexObj = t3lib_div::makeInstance('t3lib_flexformtools');
513 $data = $flexObj->flexArray2Xml($currentValueArray, TRUE);
514 }
515 }
516
517 return $data;
518 }
519
520 /**
521 * Processing of the content in $totalRecordcontent based on settings in the types-configuration
522 *
523 * @param array The array of values which has been processed according to their type (eg. "group" or "select")
524 * @param array The "types" configuration for the current display of fields.
525 * @param integer PAGE TSconfig PID
526 * @param string Table name
527 * @param integer PID value
528 * @return array The processed version of $totalRecordContent
529 * @access private
530 */
531 function renderRecord_typesProc($totalRecordContent,$types_fieldConfig,$tscPID,$table,$pid) {
532 foreach($types_fieldConfig as $vconf) {
533
534 // Find file to write to, if configured:
535 $eFile = t3lib_parsehtml_proc::evalWriteFile($vconf['spec']['static_write'],$totalRecordContent);
536
537 // Write file configuration:
538 if (is_array($eFile)) {
539 if ($eFile['loadFromFileField'] && $totalRecordContent[$eFile['loadFromFileField']]) {
540 // Read the external file, and insert the content between the ###TYPO3_STATICFILE_EDIT### markers:
541 $SW_fileContent = t3lib_div::getUrl($eFile['editFile']);
542 $parseHTML = t3lib_div::makeInstance('t3lib_parsehtml_proc');
543 $parseHTML->init('','');
544
545 $totalRecordContent[$vconf['field']] = $parseHTML->getSubpart(
546 $SW_fileContent,
547 $eFile['markerField']&&trim($totalRecordContent[$eFile['markerField']])
548 ? trim($totalRecordContent[$eFile['markerField']])
549 : '###TYPO3_STATICFILE_EDIT###'
550 );
551 }
552 }
553 }
554
555 return $totalRecordContent;
556 }
557
558 /**
559 * Processing of the data value in case the field type is "inline"
560 * In some parts nearly the same as type "select"
561 *
562 * @param string The field value
563 * @param array TCA field config
564 * @param array TCEform TSconfig for the record
565 * @param string Table name
566 * @param array The row
567 * @param string Field name
568 * @return string The processed input field value ($data)
569 * @access private
570 * @see renderRecord()
571 */
572 function renderRecord_inlineProc($data,$fieldConfig,$TSconfig,$table,$row,$field) {
573 global $TCA;
574
575 // Initialize:
576 $elements = t3lib_div::trimExplode(',',$data); // Current data set.
577 $dataAcc=array(); // New data set, ready for interface (list of values, rawurlencoded)
578
579 // At this point all records that CAN be selected is found in $recordList
580 // Now, get the data from loadDBgroup based on the input list of values.
581 $dataIds = $this->getDataIdList($elements, $fieldConfig, $row, $table);
582
583 // After this we can traverse the loadDBgroup values and match values with the list of possible values in $recordList:
584 foreach($dataIds as $theId) {
585 if ($fieldConfig['config']['MM'] || $fieldConfig['config']['foreign_field']) {
586 $dataAcc[]=$theId;
587 } else {
588 foreach($elements as $eKey => $value) {
589 if (!strcmp($theId,$value)) {
590 $dataAcc[$eKey]=$theId;
591 }
592 }
593 }
594 }
595
596 return implode(',',$dataAcc);
597 }
598
599
600
601
602
603
604
605
606
607
608
609
610 /***********************************************
611 *
612 * FlexForm processing functions
613 *
614 ***********************************************/
615
616 /**
617 * Function traversing sheets/languages for flex form data structures
618 *
619 * @param array Data array
620 * @param array Data Structure array
621 * @param array Various parameters to pass-through
622 * @return array Modified $dataPart array.
623 * @access private
624 * @see t3lib_TCEmain::checkValue_flex_procInData(), renderRecord_flexProc_procInData_travDS()
625 */
626 function renderRecord_flexProc_procInData($dataPart,$dataStructArray,$pParams) {
627 if (is_array($dataPart)) {
628 foreach($dataPart as $sKey => $sheetDef) {
629 list ($dataStruct,$actualSheet) = t3lib_div::resolveSheetDefInDS($dataStructArray,$sKey);
630
631 if (is_array($dataStruct) && $actualSheet==$sKey && is_array($sheetDef)) {
632 foreach($sheetDef as $lKey => $lData) {
633 $this->renderRecord_flexProc_procInData_travDS(
634 $dataPart[$sKey][$lKey],
635 $dataStruct['ROOT']['el'],
636 $pParams
637 );
638 }
639 }
640 }
641 }
642
643 return $dataPart;
644 }
645
646 /**
647 * Traverse data array / structure
648 *
649 * @param array Data array passed by reference.
650 * @param array Data structure
651 * @param array Various parameters pass-through.
652 * @return void
653 * @see renderRecord_flexProc_procInData(), t3lib_TCEmain::checkValue_flex_procInData_travDS()
654 */
655 function renderRecord_flexProc_procInData_travDS(&$dataValues,$DSelements,$pParams) {
656 if (is_array($DSelements)) {
657
658 // For each DS element:
659 foreach($DSelements as $key => $dsConf) {
660
661 // Array/Section:
662 if ($DSelements[$key]['type']=='array') {
663 if (is_array($dataValues[$key]['el'])) {
664 if ($DSelements[$key]['section']) {
665 foreach($dataValues[$key]['el'] as $ik => $el) {
666 if (is_array($el)) {
667 $theKey = key($el);
668 if (is_array($dataValues[$key]['el'][$ik][$theKey]['el'])) {
669 $this->renderRecord_flexProc_procInData_travDS(
670 $dataValues[$key]['el'][$ik][$theKey]['el'],
671 $DSelements[$key]['el'][$theKey]['el'],
672 $pParams
673 );
674 }
675 }
676 }
677 } else {
678 if (!isset($dataValues[$key]['el'])) $dataValues[$key]['el']=array();
679 $this->renderRecord_flexProc_procInData_travDS(
680 $dataValues[$key]['el'],
681 $DSelements[$key]['el'],
682 $pParams
683 );
684 }
685 }
686 } else {
687 if (is_array($dsConf['TCEforms']['config']) && is_array($dataValues[$key])) {
688 foreach($dataValues[$key] as $vKey => $data) {
689
690 // $data,$fieldConfig,$TSconfig,$table,$row,$field
691 list(,,$CVTSconfig,$CVtable,$CVrow,$CVfield) = $pParams;
692
693 // Set default value:
694 if (!isset($dataValues[$key][$vKey])) {
695 $dataValues[$key][$vKey] = $dsConf['TCEforms']['config']['default'];
696 }
697
698 // Process value:
699 $dataValues[$key][$vKey] = $this->renderRecord_SW($dataValues[$key][$vKey],$dsConf['TCEforms'],$CVTSconfig,$CVtable,$CVrow,'');
700 }
701 }
702 }
703 }
704 }
705 }
706
707
708
709
710
711
712
713
714
715
716
717
718 /***********************************************
719 *
720 * Selector box processing functions
721 *
722 ***********************************************/
723
724 /**
725 * Adding "special" types to the $dataAcc array of selector items
726 *
727 * @param array Array with numeric keys, containing values for the selector box, prepared for interface. We are going to add elements to this array as needed.
728 * @param array The array of original elements - basically the field value exploded by ","
729 * @param string The "special" key from the TCA config of the field. Determines the type of processing in here.
730 * @return array Modified $dataAcc array
731 * @access private
732 * @see renderRecord_selectProc()
733 */
734 function selectAddSpecial($dataAcc, $elements, $specialKey) {
735 global $TCA;
736
737 // Special select types:
738 switch ((string)$specialKey) {
739 case 'tables': // Listing all tables from $TCA:
740 $tNames = array_keys($TCA);
741 foreach($tNames as $tableName) {
742 foreach($elements as $eKey => $value) {
743 if (!strcmp($tableName,$value)) {
744 $dataAcc[$eKey]=rawurlencode($value).'|'.rawurlencode($this->sL($TCA[$value]['ctrl']['title']));
745 }
746 }
747 }
748 break;
749 case 'pagetypes': // Listing all page types (doktype)
750 $theTypes = $TCA['pages']['columns']['doktype']['config']['items'];
751 if (is_array($theTypes)) {
752 foreach($theTypes as $theTypesArrays) {
753 foreach($elements as $eKey => $value) {
754 if (!strcmp($theTypesArrays[1],$value)) {
755 $dataAcc[$eKey]=rawurlencode($value).'|'.rawurlencode($this->sL($theTypesArrays[0]));
756 }
757 }
758 }
759 }
760 break;
761 case 'exclude': // Listing exclude fields.
762 $theExcludeFields = t3lib_BEfunc::getExcludeFields();
763
764 if (is_array($theExcludeFields)) {
765 foreach($theExcludeFields as $theExcludeFieldsArrays) {
766 foreach($elements as $eKey => $value) {
767 if (!strcmp($theExcludeFieldsArrays[1],$value)) {
768 $dataAcc[$eKey]=rawurlencode($value).'|'.rawurlencode(rtrim($theExcludeFieldsArrays[0], ':'));
769 }
770 }
771 }
772 }
773 break;
774 case 'explicitValues':
775 $theTypes = t3lib_BEfunc::getExplicitAuthFieldValues();
776
777 foreach($theTypes as $tableFieldKey => $theTypeArrays) {
778 if (is_array($theTypeArrays['items'])) {
779 foreach($theTypeArrays['items'] as $itemValue => $itemContent) {
780 foreach($elements as $eKey => $value) {
781 if (!strcmp($tableFieldKey.':'.$itemValue.':'.$itemContent[0], $value)) {
782 $dataAcc[$eKey] = rawurlencode($value).'|'.rawurlencode('['.$itemContent[2].'] '.$itemContent[1]);
783 }
784 }
785 }
786 }
787 }
788 break;
789 case 'languages':
790 $theLangs = t3lib_BEfunc::getSystemLanguages();
791 foreach($theLangs as $lCfg) {
792 foreach($elements as $eKey => $value) {
793 if (!strcmp($lCfg[1], $value)) {
794 $dataAcc[$eKey] = rawurlencode($value).'|'.rawurlencode($lCfg[0]);
795 }
796 }
797 }
798 break;
799 case 'custom':
800 $customOptions = $GLOBALS['TYPO3_CONF_VARS']['BE']['customPermOptions'];
801
802 if (is_array($customOptions)) {
803 foreach($customOptions as $coKey => $coValue) {
804 if (is_array($coValue['items'])) {
805 // Traverse items:
806 foreach($coValue['items'] as $itemKey => $itemCfg) {
807 foreach($elements as $eKey => $value) {
808 if (!strcmp($coKey.':'.$itemKey, $value)) {
809 $dataAcc[$eKey] = rawurlencode($value).'|'.rawurlencode($this->sL($itemCfg[0]));
810 }
811 }
812 }
813 }
814 }
815 }
816 break;
817 case 'modListGroup': // Listing modules for GROUPS
818 case 'modListUser': // Listing modules for USERS:
819 if (!$this->loadModules) {
820 $this->loadModules = t3lib_div::makeInstance('t3lib_loadModules');
821 $this->loadModules->load($GLOBALS['TBE_MODULES']);
822 }
823 $modList = ($specialKey=='modListUser') ? $this->loadModules->modListUser : $this->loadModules->modListGroup;
824
825 foreach($modList as $theModName) {
826 foreach($elements as $eKey => $value) {
827 $label = '';
828 // Add label for main module:
829 $pp = explode('_',$value);
830 if (count($pp)>1) $label.=$GLOBALS['LANG']->moduleLabels['tabs'][$pp[0].'_tab'].'>';
831 // Add modules own label now:
832 $label.= $GLOBALS['LANG']->moduleLabels['tabs'][$value.'_tab'];
833
834 if (!strcmp($theModName,$value)) {
835 $dataAcc[$eKey]=rawurlencode($value).'|'.rawurlencode($label);
836 }
837 }
838 }
839 break;
840 }
841
842 return $dataAcc;
843 }
844
845 /**
846 * Adds the foreign record elements to $dataAcc, if any
847 *
848 * @param array Array with numeric keys, containing values for the selector box, prepared for interface. We are going to add elements to this array as needed.
849 * @param array The array of original elements - basically the field value exploded by ","
850 * @param array Field configuration from TCA
851 * @param string The field name
852 * @param array TSconfig for the record
853 * @param array The record
854 * @param array The current table
855 * @return array Modified $dataAcc array
856 * @access private
857 * @see renderRecord_selectProc()
858 */
859 function selectAddForeign($dataAcc, $elements, $fieldConfig, $field, $TSconfig, $row, $table) {
860 global $TCA;
861
862 // Init:
863 $recordList = Array();
864
865 // foreign_table
866 $subres = t3lib_BEfunc::exec_foreign_table_where_query($fieldConfig,$field,$TSconfig);
867 while ($subrow = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($subres)) {
868 $recordList[$subrow['uid']] = t3lib_BEfunc::getRecordTitle($fieldConfig['config']['foreign_table'],$subrow);
869 }
870
871 // neg_foreign_table
872 if (is_array($TCA[$fieldConfig['config']['neg_foreign_table']])) {
873 $subres = t3lib_BEfunc::exec_foreign_table_where_query($fieldConfig,$field,$TSconfig,'neg_');
874 while ($subrow = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($subres)) {
875 $recordList[-$subrow['uid']] = t3lib_BEfunc::getRecordTitle($fieldConfig['config']['neg_foreign_table'],$subrow);
876 }
877 }
878
879 // At this point all records that CAN be selected is found in $recordList
880 // Now, get the data from loadDBgroup based on the input list of values.
881 $dataIds = $this->getDataIdList($elements, $fieldConfig, $row, $table);
882 if ($fieldConfig['config']['MM']) $dataAcc=array(); // Reset, if MM (which cannot bear anything but real relations!)
883
884 // After this we can traverse the loadDBgroup values and match values with the list of possible values in $recordList:
885 foreach($dataIds as $theId) {
886 if (isset($recordList[$theId])) {
887 $lPrefix = $this->sL($fieldConfig['config'][($theId>0?'':'neg_').'foreign_table_prefix']);
888 if ($fieldConfig['config']['MM'] || $fieldConfig['config']['foreign_field']) {
889 $dataAcc[]=rawurlencode($theId).'|'.rawurlencode(t3lib_div::fixed_lgd_cs($lPrefix.strip_tags($recordList[$theId]),$GLOBALS['BE_USER']->uc['titleLen']));
890 } else {
891 foreach($elements as $eKey => $value) {
892 if (!strcmp($theId,$value)) {
893 $dataAcc[$eKey]=rawurlencode($theId).'|'.rawurlencode(t3lib_div::fixed_lgd_cs($lPrefix.strip_tags($recordList[$theId]),$GLOBALS['BE_USER']->uc['titleLen']));
894 }
895 }
896 }
897 }
898 }
899
900 return $dataAcc;
901 }
902
903 /**
904 * Returning the id-list processed by loadDBgroup for the foreign tables.
905 *
906 * @param array The array of original elements - basically the field value exploded by ","
907 * @param array Field configuration from TCA
908 * @param array The data array, currently. Used to set the "local_uid" for selecting MM relation records.
909 * @param string Current table name. passed on to t3lib_loadDBGroup
910 * @return array An array with ids of the records from the input elements array.
911 * @access private
912 */
913 function getDataIdList($elements, $fieldConfig, $row, $table) {
914 $loadDB = t3lib_div::makeInstance('t3lib_loadDBGroup');
915 $loadDB->registerNonTableValues=$fieldConfig['config']['allowNonIdValues'] ? 1 : 0;
916 $loadDB->start(implode(',',$elements),
917 $fieldConfig['config']['foreign_table'].','.$fieldConfig['config']['neg_foreign_table'],
918 $fieldConfig['config']['MM'],
919 $row['uid'],
920 $table,
921 $fieldConfig['config']
922 );
923
924 $idList = $loadDB->convertPosNeg($loadDB->getValueArray(),$fieldConfig['config']['foreign_table'],$fieldConfig['config']['neg_foreign_table']);
925
926 return $idList;
927 }
928
929 /**
930 * Processing of selector box items. This includes the automated adding of elements plus user-function processing.
931 *
932 * @param array The elements to process
933 * @param array TCA/columns configuration
934 * @param array TSconfig for the field
935 * @param string The table name
936 * @param array The current row
937 * @param string The field name
938 * @return array The modified input $selItems array
939 * @access private
940 * @see renderRecord_selectProc()
941 */
942 function procesItemArray($selItems,$config,$fieldTSConfig,$table,$row,$field) {
943 $selItems = $this->addItems($selItems,$fieldTSConfig['addItems.']);
944 if ($config['itemsProcFunc']) $selItems = $this->procItems($selItems,$fieldTSConfig['itemsProcFunc.'],$config,$table,$row,$field);
945 return $selItems;
946 }
947
948 /**
949 * Adding items from $iArray to $items array
950 *
951 * @param array The array of selector box items to which key(value) / value(label) pairs from $iArray will be added.
952 * @param array The array of elements to add. The keys will become values. The value will become the label.
953 * @return array The modified input $items array
954 * @access private
955 * @see procesItemArray()
956 */
957 function addItems($items,$iArray) {
958 if (is_array($iArray)) {
959 foreach($iArray as $value => $label) {
960 $items[]=array($label,$value);
961 }
962 }
963 return $items;
964 }
965
966 /**
967 * User processing of a selector box array of values.
968 *
969 * @param array The array of selector box items
970 * @param array TSconfig for the fields itemProcFunc
971 * @param array TCA/columns configuration
972 * @param string The table name
973 * @param array The current row
974 * @param string The field name
975 * @return array The modified input $items array
976 * @access private
977 * @see procesItemArray()
978 */
979 function procItems($items,$itemsProcFuncTSconfig,$config,$table,$row,$field) {
980 $params=array();
981 $params['items'] = &$items;
982 $params['config'] = $config;
983 $params['TSconfig'] = $itemsProcFuncTSconfig;
984 $params['table'] = $table;
985 $params['row'] = $row;
986 $params['field'] = $field;
987
988 t3lib_div::callUserFunction($config['itemsProcFunc'],$params,$this);
989 return $items;
990 }
991
992
993
994
995
996
997
998
999
1000 /***********************************************
1001 *
1002 * Helper functions
1003 *
1004 ***********************************************/
1005
1006 /**
1007 * Sets the lock for a record from table/id, IF $this->lockRecords is set!
1008 *
1009 * @param string The table name
1010 * @param integer The id of the record
1011 * @param integer The pid of the record
1012 * @return void
1013 */
1014 function lockRecord($table, $id, $pid=0) {
1015 if ($this->lockRecords) {
1016 t3lib_BEfunc::lockRecords($table,$id,$pid);
1017 }
1018 }
1019
1020 /**
1021 * Dummy function, can be used to "register" records. Used by eg. the "show_item" script.
1022 *
1023 * @param string Table name
1024 * @param integer Record id
1025 * @param string Field name
1026 * @param string Field content.
1027 * @return void
1028 * @access private
1029 * @see renderRecord()
1030 */
1031 function regItem($table, $id, $field, $content) {
1032 }
1033
1034 /**
1035 * Local wrapper function for LANG->sL (returning language labels)
1036 *
1037 * @param string Language label key
1038 * @return string Localized label value.
1039 * @access private
1040 */
1041 function sL($in) {
1042 return $GLOBALS['LANG']->sL($in);
1043 }
1044 }
1045
1046
1047 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_transferdata.php']) {
1048 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_transferdata.php']);
1049 }
1050
1051 ?>