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