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