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