/**
  * Processing of the data value in case the field type is "flex"
  * MUST NOT be called in case of already INSIDE a flexform!
  *
  * @param	string		The field value
  * @param	array		TCA field config
  * @param	array		TCEform TSconfig for the record
  * @param	string		Table name
  * @param	array		The row
  * @param	string		Field name
  * @return	string		The processed input field value ($data)
  * @access private
  * @see renderRecord()
  */
 function renderRecord_flexProc($data, $fieldConfig, $TSconfig, $table, $row, $field)
 {
     global $TCA;
     // Convert the XML data to PHP array:
     $currentValueArray = t3lib_div::xml2array($data);
     if (is_array($currentValueArray)) {
         // Get current value array:
         $dataStructArray = t3lib_BEfunc::getFlexFormDS($fieldConfig['config'], $row, $table);
         // Manipulate Flexform DS via TSConfig and group access lists
         if (is_array($dataStructArray)) {
             $flexFormHelper = t3lib_div::makeInstance('t3lib_TCEforms_Flexforms');
             $dataStructArray = $flexFormHelper->modifyFlexFormDS($dataStructArray, $table, $field, $row, $fieldConfig);
             unset($flexFormHelper);
         }
         if (is_array($dataStructArray)) {
             $currentValueArray['data'] = $this->renderRecord_flexProc_procInData($currentValueArray['data'], $dataStructArray, array($data, $fieldConfig, $TSconfig, $table, $row, $field));
             $flexObj = t3lib_div::makeInstance('t3lib_flexformtools');
             $data = $flexObj->flexArray2Xml($currentValueArray, TRUE);
         }
     }
     return $data;
 }
 function ajaxExpandCollapse($params, &$ajaxObj)
 {
     $this->table = trim(t3lib_div::_GP('tceFormsTable'));
     $this->field = trim(t3lib_div::_GP('tceFormsField'));
     $this->field = t3lib_div::trimExplode(',', $this->field, 1);
     $this->recID = trim(t3lib_div::_GP('recID'));
     if (intval($this->recID) == $this->recID) {
         $this->row = t3lib_BEfunc::getRecord($this->table, $this->recID);
     }
     if (!is_array($this->row)) {
         $this->row = array('uid' => $this->recID, 'CType' => $this->field[4], 'list_type' => $this->field[5]);
     }
     t3lib_div::loadTCA($this->table);
     if ($this->table == 'tt_content') {
         $flexFormArray = t3lib_BEfunc::getFlexFormDS($GLOBALS['TCA']['tt_content']['columns']['pi_flexform']['config'], $this->row, $this->table);
         $this->fieldConfig = $flexFormArray['sheets'][$this->field[1]]['ROOT']['el'][$this->field[0]]['TCEforms']['config'];
         $this->PA['itemFormElName'] = 'data[' . $this->table . '][' . $this->recID . '][pi_flexform][data][' . $this->field[1] . '][' . $this->field[2] . '][' . $this->field[0] . '][' . $this->field[3] . ']';
         $this->fieldConfig['piFlexFormSheet'] = $this->field[1];
         $this->fieldConfig['piFlexFormLang'] = $this->field[2];
         $this->fieldConfig['piFlexFormValue'] = $this->field[3];
     } else {
         $this->fieldConfig = $GLOBALS['TCA'][$this->table]['columns'][$this->field[0]]['config'];
         $this->PA['itemFormElName'] = 'data[' . $this->table . '][' . $this->recID . '][' . $this->field[0] . ']';
     }
     $this->itemFormElName = $this->PA['itemFormElName'];
     $this->field = $this->field[0];
     if (isset($this->fieldConfig['MM'])) {
         $result = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid_foreign', $this->fieldConfig['MM'], 'uid_local=' . $this->row['uid']);
         while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($result)) {
             $this->selectedItems[] = $row['uid_foreign'];
         }
     } else {
         $this->setSelectedItems();
     }
     $tree = $this->renderTree();
     $ajaxObj->addContent('tree', $tree);
 }
 /**
  * Returns the content tree (based on the data structure) for a certain page or a flexible content element. In case of a page it will contain all the references
  * to content elements (and some more information) and in case of a FCE, references to its sub-elements.
  *
  * @param	string		$table: Table which contains the (XML) data structure. Only records from table 'pages' or flexible content elements from 'tt_content' are handled
  * @param	array		$row: Record of the root element where the tree starts (Possibly overlaid with workspace content)
  * @param	array		$tt_content_elementRegister: Register of used tt_content elements, don't mess with it! (passed by reference since data is built up)
  * @param	string		$prevRecList: comma separated list of uids, used internally for recursive calls. Don't mess with it!
  * @return	array		The content tree
  * @access	protected
  */
 function getContentTree_element($table, $row, &$tt_content_elementRegister, $prevRecList = '')
 {
     global $TCA, $LANG;
     $tree = array();
     $tree['el'] = array('table' => $table, 'uid' => $row['uid'], 'pid' => $row['pid'], '_ORIG_uid' => $row['_ORIG_uid'], 'title' => t3lib_div::fixed_lgd_cs(t3lib_BEfunc::getRecordTitle($table, $row), 50), 'icon' => t3lib_iconWorks::getIcon($table, $row), 'sys_language_uid' => $row['sys_language_uid'], 'l18n_parent' => $row['l18n_parent'], 'CType' => $row['CType']);
     if ($this->includePreviewData) {
         $tree['previewData'] = array('fullRow' => $row);
     }
     // If element is a Flexible Content Element (or a page) then look at the content inside:
     if ($table == 'pages' || $table == $this->rootTable || $table == 'tt_content' && $row['CType'] == 'templavoila_pi1') {
         t3lib_div::loadTCA($table);
         $rawDataStructureArr = t3lib_BEfunc::getFlexFormDS($TCA[$table]['columns']['tx_templavoila_flex']['config'], $row, $table);
         $expandedDataStructureArr = $this->ds_getExpandedDataStructure($table, $row);
         switch ($table) {
             case 'pages':
                 $currentTemplateObject = $this->getContentTree_fetchPageTemplateObject($row);
                 break;
             case 'tt_content':
                 $currentTemplateObject = t3lib_beFunc::getRecordWSOL('tx_templavoila_tmplobj', $row['tx_templavoila_to']);
                 break;
             default:
                 $currentTemplateObject = FALSE;
         }
         if (is_array($currentTemplateObject)) {
             $templateMappingArr = unserialize($currentTemplateObject['templatemapping']);
         }
         $tree['ds_is_found'] = is_array($rawDataStructureArr);
         $tree['ds_meta'] = $rawDataStructureArr['meta'];
         $flexformContentArr = t3lib_div::xml2array($row['tx_templavoila_flex']);
         if (!is_array($flexformContentArr)) {
             $flexformContentArr = array();
         }
         // Respect the currently selected language, for both concepts - with langChildren enabled and disabled:
         $langChildren = intval($tree['ds_meta']['langChildren']);
         $langDisable = intval($tree['ds_meta']['langDisable']);
         $lKeys = $langDisable ? array('lDEF') : ($langChildren ? array('lDEF') : $this->allSystemWebsiteLanguages['all_lKeys']);
         $vKeys = $langDisable ? array('vDEF') : ($langChildren ? $this->allSystemWebsiteLanguages['all_vKeys'] : array('vDEF'));
         // Traverse each sheet in the FlexForm Structure:
         foreach ($expandedDataStructureArr as $sheetKey => $sheetData) {
             // Add some sheet meta information:
             $tree['sub'][$sheetKey] = array();
             $tree['contentFields'][$sheetKey] = array();
             $tree['meta'][$sheetKey] = array('title' => is_array($sheetData) && $sheetData['ROOT']['TCEforms']['sheetTitle'] ? $LANG->sL($sheetData['ROOT']['TCEforms']['sheetTitle']) : '', 'description' => is_array($sheetData) && $sheetData['ROOT']['TCEforms']['sheetDescription'] ? $LANG->sL($sheetData['ROOT']['TCEforms']['sheetDescription']) : '', 'short' => is_array($sheetData) && $sheetData['ROOT']['TCEforms']['sheetShortDescr'] ? $LANG->sL($sheetData['ROOT']['TCEforms']['sheetShortDescr']) : '');
             // Traverse the sheet's elements:
             if (is_array($sheetData) && is_array($sheetData['ROOT']['el'])) {
                 foreach ($sheetData['ROOT']['el'] as $fieldKey => $fieldData) {
                     // Compile preview data:
                     if ($this->includePreviewData) {
                         $tree['previewData']['sheets'][$sheetKey][$fieldKey] = array('TCEforms' => $fieldData['TCEforms'], 'type' => $fieldData['type'], 'section' => $fieldData['section'], 'data' => array(), 'subElements' => array(), 'isMapped' => is_array($templateMappingArr['MappingInfo']['ROOT']['el'][$fieldKey]));
                         foreach ($lKeys as $lKey) {
                             foreach ($vKeys as $vKey) {
                                 if (is_array($flexformContentArr['data'])) {
                                     $tree['previewData']['sheets'][$sheetKey][$fieldKey]['data'][$lKey][$vKey] = $flexformContentArr['data'][$sheetKey][$lKey][$fieldKey][$vKey];
                                 }
                             }
                             if ($fieldData['type'] == 'array') {
                                 $tree['previewData']['sheets'][$sheetKey][$fieldKey]['subElements'][$lKey] = $flexformContentArr['data'][$sheetKey][$lKey][$fieldKey]['el'];
                             }
                         }
                     }
                     // If the current field points to other content elements, process them:
                     if ($fieldData['TCEforms']['config']['type'] == 'group' && $fieldData['TCEforms']['config']['internal_type'] == 'db' && $fieldData['TCEforms']['config']['allowed'] == 'tt_content') {
                         foreach ($lKeys as $lKey) {
                             foreach ($vKeys as $vKey) {
                                 $listOfSubElementUids = $flexformContentArr['data'][$sheetKey][$lKey][$fieldKey][$vKey];
                                 $tree['sub'][$sheetKey][$lKey][$fieldKey][$vKey] = $this->getContentTree_processSubContent($listOfSubElementUids, $tt_content_elementRegister, $prevRecList);
                                 $tree['sub'][$sheetKey][$lKey][$fieldKey][$vKey]['meta']['title'] = $fieldData['TCEforms']['label'];
                             }
                         }
                     } elseif ($fieldData['type'] != 'array' && $fieldData['TCEforms']['config']) {
                         // If generally there are non-container fields, register them:
                         $tree['contentFields'][$sheetKey][] = $fieldKey;
                     }
                 }
             }
         }
     }
     // Add localization info for this element:
     $tree['localizationInfo'] = $this->getContentTree_getLocalizationInfoForElement($tree, $tt_content_elementRegister);
     return $tree;
 }
    /**
     * Renders the header fields menu item.
     * It iss possible to define a list of fields (currently only from the pages table) which should appear
     * as a header above the content zones while editing the content of a page. This function renders those fields.
     * The fields to be displayed are defined in the page's datastructure.
     *
     * @param	$pObj:		Reference to the parent object ($this)
     * @return	string		HTML output
     * @access	private
     */
    function renderItem_headerFields(&$pObj)
    {
        global $LANG, $TCA;
        $output = '';
        if ($pObj->rootElementTable != 'pages') {
            return '';
        }
        t3lib_div::loadTCA('pages');
        $conf = $TCA['pages']['columns']['tx_templavoila_flex']['config'];
        $dataStructureArr = t3lib_BEfunc::getFlexFormDS($conf, $pObj->rootElementRecord, 'pages');
        if (is_array($dataStructureArr) && is_array($dataStructureArr['ROOT']['tx_templavoila']['pageModule'])) {
            $headerTablesAndFieldNames = t3lib_div::trimExplode(chr(10), str_replace(chr(13), '', $dataStructureArr['ROOT']['tx_templavoila']['pageModule']['displayHeaderFields']), 1);
            if (is_array($headerTablesAndFieldNames)) {
                $fieldNames = array();
                $headerFieldRows = array();
                $headerFields = array();
                foreach ($headerTablesAndFieldNames as $tableAndFieldName) {
                    list($table, $field) = explode('.', $tableAndFieldName);
                    $fieldNames[$table][] = $field;
                    $headerFields[] = array('table' => $table, 'field' => $field, 'label' => $LANG->sL(t3lib_BEfunc::getItemLabel('pages', $field)), 'value' => t3lib_BEfunc::getProcessedValue('pages', $field, $pObj->rootElementRecord[$field], 200));
                }
                if (count($headerFields)) {
                    foreach ($headerFields as $headerFieldArr) {
                        if ($headerFieldArr['table'] == 'pages') {
                            $onClick = t3lib_BEfunc::editOnClick('&edit[pages][' . $pObj->id . ']=edit&columnsOnly=' . implode(',', $fieldNames['pages']), $this->doc->backPath);
                            $linkedValue = '<a style="text-decoration: none;" href="#" onclick="' . htmlspecialchars($onClick) . '">' . htmlspecialchars($headerFieldArr['value']) . '</a>';
                            $linkedLabel = '<a style="text-decoration: none;" href="#" onclick="' . htmlspecialchars($onClick) . '">' . htmlspecialchars($headerFieldArr['label']) . '</a>';
                            $headerFieldRows[] = '
								<tr>
									<td class="bgColor4-20" style="width: 10%; vertical-align:top">' . $linkedLabel . '</td><td class="bgColor4" style="vertical-align:top"><em>' . $linkedValue . '</em></td>
								</tr>
							';
                        }
                    }
                    $output = '
						<table border="0" cellpadding="0" cellspacing="1" width="100%" class="lrPadding">
							<tr>
								<td colspan="2" class="bgColor4-20">' . $LANG->getLL('pagerelatedinformation') . ':</td>
							</tr>
							' . implode('', $headerFieldRows) . '
						</table>
					';
                }
            }
        }
        return $output;
    }
 /**
  * Processing of soft references
  *
  * @return	void
  */
 function processSoftReferences()
 {
     global $TCA;
     // Initialize:
     $inData = array();
     // Traverse records:
     if (is_array($this->dat['header']['records'])) {
         foreach ($this->dat['header']['records'] as $table => $recs) {
             foreach ($recs as $uid => $thisRec) {
                 // If there are soft references defined, traverse those:
                 if (isset($TCA[$table]) && is_array($thisRec['softrefs'])) {
                     t3lib_div::loadTCA($table);
                     // First traversal is to collect softref configuration and split them up based on fields. This could probably also have been done with the "records" key instead of the header.
                     $fieldsIndex = array();
                     foreach ($thisRec['softrefs'] as $softrefDef) {
                         // If a substitution token is set:
                         if ($softrefDef['field'] && is_array($softrefDef['subst']) && $softrefDef['subst']['tokenID']) {
                             $fieldsIndex[$softrefDef['field']][$softrefDef['subst']['tokenID']] = $softrefDef;
                         }
                     }
                     // The new id:
                     $thisNewUid = t3lib_BEfunc::wsMapId($table, $this->import_mapId[$table][$uid]);
                     // Now, if there are any fields that require substitution to be done, lets go for that:
                     foreach ($fieldsIndex as $field => $softRefCfgs) {
                         if (is_array($TCA[$table]['columns'][$field])) {
                             $conf = $TCA[$table]['columns'][$field]['config'];
                             if ($conf['type'] === 'flex') {
                                 $origRecordRow = t3lib_BEfunc::getRecord($table, $thisNewUid, '*');
                                 // This will fetch the new row for the element (which should be updated with any references to data structures etc.)
                                 if (is_array($origRecordRow)) {
                                     // Get current data structure and value array:
                                     $dataStructArray = t3lib_BEfunc::getFlexFormDS($conf, $origRecordRow, $table);
                                     $currentValueArray = t3lib_div::xml2array($origRecordRow[$field]);
                                     // Do recursive processing of the XML data:
                                     $iteratorObj = t3lib_div::makeInstance('t3lib_TCEmain');
                                     $iteratorObj->callBackObj = $this;
                                     $currentValueArray['data'] = $iteratorObj->checkValue_flex_procInData($currentValueArray['data'], array(), array(), $dataStructArray, array($table, $uid, $field, $softRefCfgs), 'processSoftReferences_flexFormCallBack');
                                     // The return value is set as an array which means it will be processed by tcemain for file and DB references!
                                     if (is_array($currentValueArray['data'])) {
                                         $inData[$table][$thisNewUid][$field] = $currentValueArray;
                                     }
                                 }
                             } else {
                                 // Get tokenizedContent string and proceed only if that is not blank:
                                 $tokenizedContent = $this->dat['records'][$table . ':' . $uid]['rels'][$field]['softrefs']['tokenizedContent'];
                                 if (strlen($tokenizedContent) && is_array($softRefCfgs)) {
                                     $inData[$table][$thisNewUid][$field] = $this->processSoftReferences_substTokens($tokenizedContent, $softRefCfgs, $table, $uid);
                                 }
                             }
                         }
                     }
                 }
             }
         }
     }
     // Now write to database:
     $tce = $this->getNewTCE();
     $this->callHook('before_processSoftReferences', array('tce' => &$tce, 'data' => &$inData));
     $tce->enableLogging = TRUE;
     $tce->start($inData, array());
     $tce->process_datamap();
     $this->callHook('after_processSoftReferences', array('tce' => &$tce));
 }
 /**
  * Processes the fields with references as registered during the copy process. This includes all FlexForm fields which had references.
  *
  * @return	void
  */
 function remapListedDBRecords()
 {
     global $TCA;
     if (count($this->registerDBList)) {
         foreach ($this->registerDBList as $table => $records) {
             t3lib_div::loadTCA($table);
             foreach ($records as $uid => $fields) {
                 $newData = array();
                 $theUidToUpdate = $this->copyMappingArray_merged[$table][$uid];
                 $theUidToUpdate_saveTo = t3lib_BEfunc::wsMapId($table, $theUidToUpdate);
                 foreach ($fields as $fieldName => $value) {
                     $conf = $TCA[$table]['columns'][$fieldName]['config'];
                     switch ($conf['type']) {
                         case 'group':
                         case 'select':
                             $vArray = $this->remapListedDBRecords_procDBRefs($conf, $value, $theUidToUpdate, $table);
                             if (is_array($vArray)) {
                                 $newData[$fieldName] = implode(',', $vArray);
                             }
                             break;
                         case 'flex':
                             if ($value == 'FlexForm_reference') {
                                 $origRecordRow = $this->recordInfo($table, $theUidToUpdate, '*');
                                 // This will fetch the new row for the element
                                 if (is_array($origRecordRow)) {
                                     t3lib_BEfunc::workspaceOL($table, $origRecordRow);
                                     // Get current data structure and value array:
                                     $dataStructArray = t3lib_BEfunc::getFlexFormDS($conf, $origRecordRow, $table);
                                     $currentValueArray = t3lib_div::xml2array($origRecordRow[$fieldName]);
                                     // Do recursive processing of the XML data:
                                     $currentValueArray['data'] = $this->checkValue_flex_procInData($currentValueArray['data'], array(), array(), $dataStructArray, array($table, $theUidToUpdate, $fieldName), 'remapListedDBRecords_flexFormCallBack');
                                     // The return value should be compiled back into XML, ready to insert directly in the field (as we call updateDB() directly later):
                                     if (is_array($currentValueArray['data'])) {
                                         $newData[$fieldName] = $this->checkValue_flexArray2Xml($currentValueArray, TRUE);
                                     }
                                 }
                             }
                             break;
                         case 'inline':
                             $this->remapListedDBRecords_procInline($conf, $value, $uid, $table);
                             break;
                         default:
                             debug('Field type should not appear here: ' . $conf['type']);
                             break;
                     }
                 }
                 if (count($newData)) {
                     // If any fields were changed, those fields are updated!
                     $this->updateDB($table, $theUidToUpdate_saveTo, $newData);
                 }
             }
         }
     }
 }
 /**
  * This method returns the contents of the flex-field given.
  *
  * @param	array		The page row
  * @param	string		The field name
  * @return	string		The contents of the field
  */
 function getPageFlexValue($page, $field)
 {
     $xml = t3lib_div::xml2array($page['tx_templavoila_flex']);
     $GLOBALS['TSFE']->includeTCA();
     t3lib_div::loadTCA('pages');
     $ds = t3lib_BEfunc::getFlexFormDS($GLOBALS['TCA']['pages']['columns']['tx_templavoila_flex']['config'], $page, 'pages', 'tx_templavoila_flex');
     if (is_array($ds) && is_array($ds['meta'])) {
         $langChildren = intval($ds['meta']['langChildren']);
         $langDisable = intval($ds['meta']['langDisable']);
     } else {
         $langChildren = 0;
         $langDisable = 0;
     }
     $translatedLanguagesArr = $this->getAvailableLanguages($pageUid);
     $tryLang = $GLOBALS['TSFE']->sys_language_content;
     $tryLangArr = $this->languageFallback;
     do {
         if ($langArr = $translatedLanguagesArr[$tryLang]) {
             $lKey = $langDisable ? 'lDEF' : ($langChildren ? 'lDEF' : 'l' . $langArr['ISOcode']);
             $vKey = $langDisable ? 'vDEF' : ($langChildren ? 'v' . $langArr['ISOcode'] : 'vDEF');
         } else {
             $lKey = 'lDEF';
             $vKey = 'vDEF';
         }
         $value = '';
         if (is_array($xml) && is_array($xml['data']) && is_array($xml['data']['sDEF']) && is_array($xml['data']['sDEF'][$lKey])) {
             $value = $this->getSubKey($xml['data']['sDEF'][$lKey], t3lib_div::trimExplode(',', $field, 1), $vKey);
         }
     } while (!strlen($value) && strlen($tryLang = array_shift($tryLangArr)));
     return $value;
 }
 /**
  * References all unreferenced elements with the specified
  * parent id (page uid)
  *
  * @param	integer		$pageUid: Parent id of the elements to reference
  * @return	void
  * @access	protected
  */
 function createReferencesForPage($pageUid)
 {
     $unreferencedElementRecordsArr = $this->getUnreferencedElementsRecords($pageUid);
     $langField = $GLOBALS['TCA']['tt_content']['ctrl']['languageField'];
     foreach ($unreferencedElementRecordsArr as $elementUid => $elementRecord) {
         $lDef = array();
         $vDef = array();
         if ($langField && $elementRecord[$langField]) {
             $pageRec = t3lib_BEfunc::getRecordWSOL('pages', $pageUid);
             $xml = t3lib_BEfunc::getFlexFormDS($GLOBALS['TCA']['pages']['columns']['tx_templavoila_flex']['config'], $pageRec, 'pages', 'tx_templavoila_ds');
             $langChildren = intval($xml['meta']['langChildren']);
             $langDisable = intval($xml['meta']['langDisable']);
             if ($elementRecord[$langField] == -1) {
                 $translatedLanguagesArr = $this->getAvailableLanguages($pageUid);
                 foreach ($translatedLanguagesArr as $lUid => $lArr) {
                     if ($lUid >= 0) {
                         $lDef[] = $langDisable ? 'lDEF' : ($langChildren ? 'lDEF' : 'l' . $lArr['ISOcode']);
                         $vDef[] = $langDisable ? 'vDEF' : ($langChildren ? 'v' . $lArr['ISOcode'] : 'vDEF');
                     }
                 }
             } elseif ($rLang = $this->allAvailableLanguages[$elementRecord[$langField]]) {
                 $lDef[] = $langDisable ? 'lDEF' : ($langChildren ? 'lDEF' : 'l' . $rLang['ISOcode']);
                 $vDef[] = $langDisable ? 'vDEF' : ($langChildren ? 'v' . $rLang['ISOcode'] : 'vDEF');
             } else {
                 $lDef[] = 'lDEF';
                 $vDef[] = 'vDEF';
             }
         } else {
             $lDef[] = 'lDEF';
             $vDef[] = 'vDEF';
         }
         $contentAreaFieldName = $this->templavoilaAPIObj->ds_getFieldNameByColumnPosition($pageUid, $elementRecord['colPos']);
         if ($contentAreaFieldName !== FALSE) {
             foreach ($lDef as $iKey => $lKey) {
                 $vKey = $vDef[$iKey];
                 $destinationPointer = array('table' => 'pages', 'uid' => $pageUid, 'sheet' => 'sDEF', 'sLang' => $lKey, 'field' => $contentAreaFieldName, 'vLang' => $vKey, 'position' => -1);
                 $this->templavoilaAPIObj->referenceElementByUid($elementUid, $destinationPointer);
             }
         }
     }
 }
 /**
  * Handler for Flex Forms
  *
  * @param	string		The table name of the record
  * @param	string		The field name of the flexform field to work on
  * @param	array		The record data array
  * @param	object		Object (passed by reference) in which the call back function is located
  * @param	string		Method name of call back function in object for values
  * @return	boolean		If true, error happened (error string returned)
  */
 function traverseFlexFormXMLData($table, $field, $row, $callBackObj, $callBackMethod_value)
 {
     if (!is_array($GLOBALS['TCA'][$table]) || !is_array($GLOBALS['TCA'][$table]['columns'][$field])) {
         return 'TCA table/field was not defined.';
     }
     $this->callBackObj = $callBackObj;
     // Get Data Structure:
     $dataStructArray = t3lib_BEfunc::getFlexFormDS($GLOBALS['TCA'][$table]['columns'][$field]['config'], $row, $table);
     // If data structure was ok, proceed:
     if (is_array($dataStructArray)) {
         // Get flexform XML data:
         $xmlData = $row[$field];
         // Convert charset:
         if ($this->convertCharset) {
             $xmlHeaderAttributes = t3lib_div::xmlGetHeaderAttribs($xmlData);
             $storeInCharset = strtolower($xmlHeaderAttributes['encoding']);
             if ($storeInCharset) {
                 $currentCharset = $GLOBALS['LANG']->charSet;
                 $xmlData = $GLOBALS['LANG']->csConvObj->conv($xmlData, $storeInCharset, $currentCharset, 1);
             }
         }
         $editData = t3lib_div::xml2array($xmlData);
         if (!is_array($editData)) {
             return 'Parsing error: ' . $editData;
         }
         // Language settings:
         $langChildren = $dataStructArray['meta']['langChildren'] ? 1 : 0;
         $langDisabled = $dataStructArray['meta']['langDisable'] ? 1 : 0;
         // empty or invalid <meta>
         if (!is_array($editData['meta'])) {
             $editData['meta'] = array();
         }
         $editData['meta']['currentLangId'] = array();
         $languages = $this->getAvailableLanguages();
         foreach ($languages as $lInfo) {
             $editData['meta']['currentLangId'][] = $lInfo['ISOcode'];
         }
         if (!count($editData['meta']['currentLangId'])) {
             $editData['meta']['currentLangId'] = array('DEF');
         }
         $editData['meta']['currentLangId'] = array_unique($editData['meta']['currentLangId']);
         if ($langChildren || $langDisabled) {
             $lKeys = array('DEF');
         } else {
             $lKeys = $editData['meta']['currentLangId'];
         }
         // Tabs sheets
         if (is_array($dataStructArray['sheets'])) {
             $sKeys = array_keys($dataStructArray['sheets']);
         } else {
             $sKeys = array('sDEF');
         }
         // Traverse languages:
         foreach ($lKeys as $lKey) {
             foreach ($sKeys as $sheet) {
                 $sheetCfg = $dataStructArray['sheets'][$sheet];
                 list($dataStruct, $sheet) = t3lib_div::resolveSheetDefInDS($dataStructArray, $sheet);
                 // Render sheet:
                 if (is_array($dataStruct['ROOT']) && is_array($dataStruct['ROOT']['el'])) {
                     $lang = 'l' . $lKey;
                     // Separate language key
                     $PA['vKeys'] = $langChildren && !$langDisabled ? $editData['meta']['currentLangId'] : array('DEF');
                     $PA['lKey'] = $lang;
                     $PA['callBackMethod_value'] = $callBackMethod_value;
                     $PA['table'] = $table;
                     $PA['field'] = $field;
                     $PA['uid'] = $row['uid'];
                     $this->traverseFlexFormXMLData_DS =& $dataStruct;
                     $this->traverseFlexFormXMLData_Data =& $editData;
                     // Render flexform:
                     $this->traverseFlexFormXMLData_recurse($dataStruct['ROOT']['el'], $editData['data'][$sheet][$lang], $PA, 'data/' . $sheet . '/' . $lang);
                 } else {
                     return 'Data Structure ERROR: No ROOT element found for sheet "' . $sheet . '".';
                 }
             }
         }
     } else {
         return 'Data Structure ERROR: ' . $dataStructArray;
     }
 }
 /**
  * Look for flexform field and add to internal translation details
  *
  * @param string $table Table name
  * @param array  $row   Table row
  * @return void
  */
 function _lookForFlexFormFieldAndAddToInternalTranslationDetails($table, $row)
 {
     global $TCA;
     foreach ($TCA[$table]['columns'] as $field => $cfg) {
         $conf = $cfg['config'];
         // For "flex" fieldtypes we need to traverse the structure looking for file and db references of course!
         if ($conf['type'] == 'flex') {
             // We might like to add the filter that detects if record is tt_content/CType is "tx_flex...:" since otherwise we would translate flexform content that might be hidden if say the record had a DS set but was later changed back to "Text w/Image" or so... But probably this is a rare case.
             // Get current data structure to see if translation is needed:
             $dataStructArray = t3lib_BEfunc::getFlexFormDS($conf, $row, $table);
             $this->detailsOutput['log'][] = 'FlexForm field "' . $field . '": DataStructure status: ' . (is_array($dataStructArray) ? 'OK' : 'Error: ' . $dataStructArray);
             if (is_array($dataStructArray) && !$dataStructArray['meta']['langDisable']) {
                 $this->detailsOutput['log'][] = 'FlexForm Localization enabled, type: ' . ($dataStructArray['meta']['langChildren'] ? 'Inheritance: Continue' : 'Separate: Stop');
                 if ($dataStructArray['meta']['langChildren']) {
                     $currentValueArray = t3lib_div::xml2array($row[$field]);
                     // Traversing the XML structure, processing files:
                     if (is_array($currentValueArray)) {
                         // Create and call iterator object:
                         /** @var $flexObj t3lib_flexformtools */
                         $flexObj = t3lib_div::makeInstance('t3lib_flexformtools');
                         $flexObj->traverseFlexFormXMLData($table, $field, $row, $this, 'translationDetails_flexFormCallBack');
                     }
                 }
             } else {
                 $this->detailsOutput['log'][] = 'FlexForm Localization disabled. Nothing to do.';
             }
         }
     }
 }
 /**
  * Handler for Flex Forms
  *
  * @param	string		The table name of the record
  * @param	string		The field name which this element is supposed to edit
  * @param	array		The record data array where the value(s) for the field can be found
  * @param	array		An array with additional configuration options.
  * @return	string		The HTML code for the TCEform field
  */
 function getSingleField_typeFlex($table, $field, $row, &$PA)
 {
     // Data Structure:
     $dataStructArray = t3lib_BEfunc::getFlexFormDS($PA['fieldConf']['config'], $row, $table);
     // Manipulate Flexform DS via TSConfig and group access lists
     if (is_array($dataStructArray)) {
         $flexFormHelper = t3lib_div::makeInstance('t3lib_TCEforms_Flexforms');
         $dataStructArray = $flexFormHelper->modifyFlexFormDS($dataStructArray, $table, $field, $row, $PA['fieldConf']['config']);
         unset($flexFormHelper);
     }
     // Get data structure:
     if (is_array($dataStructArray)) {
         // Get data:
         $xmlData = $PA['itemFormElValue'];
         $xmlHeaderAttributes = t3lib_div::xmlGetHeaderAttribs($xmlData);
         $storeInCharset = strtolower($xmlHeaderAttributes['encoding']);
         if ($storeInCharset) {
             $currentCharset = $GLOBALS['LANG']->charSet;
             $xmlData = $GLOBALS['LANG']->csConvObj->conv($xmlData, $storeInCharset, $currentCharset, 1);
         }
         $editData = t3lib_div::xml2array($xmlData);
         if (!is_array($editData)) {
             // Must be XML parsing error...
             $editData = array();
         } elseif (!isset($editData['meta']) || !is_array($editData['meta'])) {
             $editData['meta'] = array();
         }
         // Find the data structure if sheets are found:
         $sheet = $editData['meta']['currentSheetId'] ? $editData['meta']['currentSheetId'] : 'sDEF';
         // Sheet to display
         // Create sheet menu:
         //TODO; Why is this commented out?
         //			if (is_array($dataStructArray['sheets']))	{
         //				#$item.=$this->getSingleField_typeFlex_sheetMenu($dataStructArray['sheets'], $PA['itemFormElName'].'[meta][currentSheetId]', $sheet).'<br />';
         //			}
         // Create language menu:
         $langChildren = $dataStructArray['meta']['langChildren'] ? 1 : 0;
         $langDisabled = $dataStructArray['meta']['langDisable'] ? 1 : 0;
         $editData['meta']['currentLangId'] = array();
         // Look up page overlays:
         $checkPageLanguageOverlay = $GLOBALS['BE_USER']->getTSConfigVal('options.checkPageLanguageOverlay') ? TRUE : FALSE;
         if ($checkPageLanguageOverlay) {
             $pageOverlays = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('*', 'pages_language_overlay', 'pid=' . intval($row['pid']) . t3lib_BEfunc::deleteClause('pages_language_overlay') . t3lib_BEfunc::versioningPlaceholderClause('pages_language_overlay'), '', '', '', 'sys_language_uid');
         }
         $languages = $this->getAvailableLanguages();
         foreach ($languages as $lInfo) {
             if ($GLOBALS['BE_USER']->checkLanguageAccess($lInfo['uid']) && (!$checkPageLanguageOverlay || $lInfo['uid'] <= 0 || is_array($pageOverlays[$lInfo['uid']]))) {
                 $editData['meta']['currentLangId'][] = $lInfo['ISOcode'];
             }
         }
         if (!is_array($editData['meta']['currentLangId']) || !count($editData['meta']['currentLangId'])) {
             $editData['meta']['currentLangId'] = array('DEF');
         }
         $editData['meta']['currentLangId'] = array_unique($editData['meta']['currentLangId']);
         //TODO: Why is this commented out?
         //			if (!$langDisabled && count($languages) > 1)	{
         //				$item.=$this->getSingleField_typeFlex_langMenu($languages, $PA['itemFormElName'].'[meta][currentLangId]', $editData['meta']['currentLangId']).'<br />';
         //			}
         $PA['_noEditDEF'] = FALSE;
         if ($langChildren || $langDisabled) {
             $rotateLang = array('DEF');
         } else {
             if (!in_array('DEF', $editData['meta']['currentLangId'])) {
                 array_unshift($editData['meta']['currentLangId'], 'DEF');
                 $PA['_noEditDEF'] = TRUE;
             }
             $rotateLang = $editData['meta']['currentLangId'];
         }
         // Tabs sheets
         if (is_array($dataStructArray['sheets'])) {
             $tabsToTraverse = array_keys($dataStructArray['sheets']);
         } else {
             $tabsToTraverse = array($sheet);
         }
         foreach ($rotateLang as $lKey) {
             if (!$langChildren && !$langDisabled) {
                 $item .= '<strong>' . $this->getLanguageIcon($table, $row, 'v' . $lKey) . $lKey . ':</strong>';
             }
             $tabParts = array();
             foreach ($tabsToTraverse as $sheet) {
                 list($dataStruct, $sheet) = t3lib_div::resolveSheetDefInDS($dataStructArray, $sheet);
                 // Render sheet:
                 if (is_array($dataStruct['ROOT']) && is_array($dataStruct['ROOT']['el'])) {
                     $lang = 'l' . $lKey;
                     // Default language, other options are "lUK" or whatever country code (independant of system!!!)
                     $PA['_valLang'] = $langChildren && !$langDisabled ? $editData['meta']['currentLangId'] : 'DEF';
                     // Default language, other options are "lUK" or whatever country code (independant of system!!!)
                     $PA['_lang'] = $lang;
                     // Assemble key for loading the correct CSH file
                     $dsPointerFields = t3lib_div::trimExplode(',', $GLOBALS['TCA'][$table]['columns'][$field]['config']['ds_pointerField'], TRUE);
                     $PA['_cshKey'] = $table . '.' . $field;
                     foreach ($dsPointerFields as $key) {
                         $PA['_cshKey'] .= '.' . $row[$key];
                     }
                     // Push the sheet level tab to DynNestedStack
                     if (is_array($dataStructArray['sheets'])) {
                         $tabIdentString = $GLOBALS['TBE_TEMPLATE']->getDynTabMenuId('TCEFORMS:flexform:' . $PA['itemFormElName'] . $PA['_lang']);
                         $this->pushToDynNestedStack('tab', $tabIdentString . '-' . (count($tabParts) + 1));
                     }
                     // Render flexform:
                     $tRows = $this->getSingleField_typeFlex_draw($dataStruct['ROOT']['el'], $editData['data'][$sheet][$lang], $table, $field, $row, $PA, '[data][' . $sheet . '][' . $lang . ']');
                     $sheetContent = '<div class="typo3-TCEforms-flexForm">' . $tRows . '</div>';
                     // Pop the sheet level tab from DynNestedStack
                     if (is_array($dataStructArray['sheets'])) {
                         $this->popFromDynNestedStack('tab', $tabIdentString . '-' . (count($tabParts) + 1));
                     }
                 } else {
                     $sheetContent = 'Data Structure ERROR: No ROOT element found for sheet "' . $sheet . '".';
                 }
                 // Add to tab:
                 $tabParts[] = array('label' => $dataStruct['ROOT']['TCEforms']['sheetTitle'] ? $this->sL($dataStruct['ROOT']['TCEforms']['sheetTitle']) : $sheet, 'description' => $dataStruct['ROOT']['TCEforms']['sheetDescription'] ? $this->sL($dataStruct['ROOT']['TCEforms']['sheetDescription']) : '', 'linkTitle' => $dataStruct['ROOT']['TCEforms']['sheetShortDescr'] ? $this->sL($dataStruct['ROOT']['TCEforms']['sheetShortDescr']) : '', 'content' => $sheetContent);
             }
             if (is_array($dataStructArray['sheets'])) {
                 $dividersToTabsBehaviour = isset($GLOBALS['TCA'][$table]['ctrl']['dividers2tabs']) ? $GLOBALS['TCA'][$table]['ctrl']['dividers2tabs'] : 1;
                 $item .= $this->getDynTabMenu($tabParts, 'TCEFORMS:flexform:' . $PA['itemFormElName'] . $PA['_lang'], $dividersToTabsBehaviour);
             } else {
                 $item .= $sheetContent;
             }
         }
     } else {
         $item = 'Data Structure ERROR: ' . $dataStructArray;
     }
     return $item;
 }
	/**
	 * Using the checkRecordUpdateAccess hook to grant access to flexfields if the user
	 * make the attempt to update a reference list within a flex field
	 *
	 * @see http://bugs.typo3.org/view.php?id=485
	 *
	 * @param string $table
	 * @param integer $id
	 * @param array $data
	 * @param boolean $res
	 * @param object $pObj
	 * @return mixed - "1" if we grant access and "false" if we can't decide whether to give access or not
	 */
	function checkRecordUpdateAccess($table, $id, $data, $res, &$pObj)	{

		global $TCA;
			// Only perform additional checks if not admin and just for pages table.
		if (($table=='pages') && is_array($data) && !$pObj->admin)	{
			$res = 1;
			foreach ($data as $field => $value)	{
				if (in_array($table.'-'.$field, $pObj->exclude_array) || $pObj->data_disableFields[$table][$id][$field])	{
					continue;
				}
					// we're not inserting useful data - can't make a decission
				if(!is_array($data[$field]['data'])) {
					$res = false;
					break;
				}
					// we're not inserting operating on an flex field - can't make a decission
				if (!is_array($TCA[$table]['columns'][$field]['config']) ||
					$TCA[$table]['columns'][$field]['config']['type'] != 'flex') {
					$res = false;
					break;
				}
					// get the field-information and check if only "ce" fields are updated
				$conf = $TCA[$table]['columns'][$field]['config'];
				$currentRecord = t3lib_BEfunc::getRecord($table, $id);
				$dataStructArray = t3lib_BEfunc::getFlexFormDS($conf, $currentRecord, $table, $field, true);
				foreach ($data[$field]['data'] as $sheet => $sheetData)	{
					if (!is_array($sheetData) || !is_array($dataStructArray['ROOT']['el']))	{
						$res = false;
						break;
					}
					foreach ($sheetData as $lDef => $lData)	{
						if (!is_array($lData))	{
							$res = false;
							break;
						}
						foreach ($lData as $fieldName => $fieldData)	{

							if (!isset($dataStructArray['ROOT']['el'][$fieldName])) {
								$res = false;
								break;
							}

							$fieldConf = $dataStructArray['ROOT']['el'][$fieldName];
							if ($fieldConf['tx_templavoila']['eType'] != 'ce')	{
								$res = false;
								break;
							}
						}
					}
				}
			}
			if (($res==1) && !$pObj->doesRecordExist($table, $id, 'editcontent'))	{
				$res = false;
			}
		}

		return $res;
	}
 /**
  * Handler for Flex Forms
  *
  * @param	string		The table name of the record
  * @param	string		The field name which this element is supposed to edit
  * @param	array		The record data array where the value(s) for the field can be found
  * @param	array		An array with additional configuration options.
  * @return	string		The HTML code for the TCEform field
  */
 function getSingleField_typeFlex($table, $field, $row, &$PA)
 {
     // Data Structure:
     $dataStructArray = t3lib_BEfunc::getFlexFormDS($PA['fieldConf']['config'], $row, $table);
     // Get data structure:
     if (is_array($dataStructArray)) {
         // Get data:
         $xmlData = $PA['itemFormElValue'];
         $xmlHeaderAttributes = t3lib_div::xmlGetHeaderAttribs($xmlData);
         $storeInCharset = strtolower($xmlHeaderAttributes['encoding']);
         if ($storeInCharset) {
             $currentCharset = $GLOBALS['LANG']->charSet;
             $xmlData = $GLOBALS['LANG']->csConvObj->conv($xmlData, $storeInCharset, $currentCharset, 1);
         }
         $editData = t3lib_div::xml2array($xmlData);
         if (!is_array($editData)) {
             // Must be XML parsing error...
             $editData = array();
         } elseif (!isset($editData['meta']) || !is_array($editData['meta'])) {
             $editData['meta'] = array();
         }
         // Find the data structure if sheets are found:
         $sheet = $editData['meta']['currentSheetId'] ? $editData['meta']['currentSheetId'] : 'sDEF';
         // Sheet to display
         // Create sheet menu:
         //			if (is_array($dataStructArray['sheets']))	{
         //				#$item.=$this->getSingleField_typeFlex_sheetMenu($dataStructArray['sheets'], $PA['itemFormElName'].'[meta][currentSheetId]', $sheet).'<br />';
         //			}
         // Create language menu:
         $langChildren = $dataStructArray['meta']['langChildren'] ? 1 : 0;
         $langDisabled = $dataStructArray['meta']['langDisable'] ? 1 : 0;
         $editData['meta']['currentLangId'] = array();
         // Look up page overlays:
         $checkPageLanguageOverlay = $GLOBALS['BE_USER']->getTSConfigVal('options.checkPageLanguageOverlay') ? TRUE : FALSE;
         if ($checkPageLanguageOverlay) {
             $pageOverlays = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('*', 'pages_language_overlay', 'pid=' . intval($row['pid']) . t3lib_BEfunc::deleteClause('pages_language_overlay') . t3lib_BEfunc::versioningPlaceholderClause('pages_language_overlay'), '', '', '', 'sys_language_uid');
         }
         $languages = $this->getAvailableLanguages();
         foreach ($languages as $lInfo) {
             if ($GLOBALS['BE_USER']->checkLanguageAccess($lInfo['uid']) && (!$checkPageLanguageOverlay || $lInfo['uid'] <= 0 || is_array($pageOverlays[$lInfo['uid']]))) {
                 $editData['meta']['currentLangId'][] = $lInfo['ISOcode'];
             }
         }
         if (!is_array($editData['meta']['currentLangId']) || !count($editData['meta']['currentLangId'])) {
             $editData['meta']['currentLangId'] = array('DEF');
         }
         $editData['meta']['currentLangId'] = array_unique($editData['meta']['currentLangId']);
         //			if (!$langDisabled && count($languages) > 1)	{
         //				$item.=$this->getSingleField_typeFlex_langMenu($languages, $PA['itemFormElName'].'[meta][currentLangId]', $editData['meta']['currentLangId']).'<br />';
         //			}
         $PA['_noEditDEF'] = FALSE;
         if ($langChildren || $langDisabled) {
             $rotateLang = array('DEF');
         } else {
             if (!in_array('DEF', $editData['meta']['currentLangId'])) {
                 array_unshift($editData['meta']['currentLangId'], 'DEF');
                 $PA['_noEditDEF'] = TRUE;
             }
             $rotateLang = $editData['meta']['currentLangId'];
         }
         // Tabs sheets
         if (is_array($dataStructArray['sheets'])) {
             $tabsToTraverse = array_keys($dataStructArray['sheets']);
         } else {
             $tabsToTraverse = array($sheet);
         }
         foreach ($rotateLang as $lKey) {
             if (!$langChildren && !$langDisabled) {
                 $item .= '<strong>' . $this->getLanguageIcon($table, $row, 'v' . $lKey) . $lKey . ':</strong>';
             }
             $tabParts = array();
             foreach ($tabsToTraverse as $sheet) {
                 list($dataStruct, $sheet) = t3lib_div::resolveSheetDefInDS($dataStructArray, $sheet);
                 // Render sheet:
                 if (is_array($dataStruct['ROOT']) && is_array($dataStruct['ROOT']['el'])) {
                     $lang = 'l' . $lKey;
                     // Default language, other options are "lUK" or whatever country code (independant of system!!!)
                     $PA['_valLang'] = $langChildren && !$langDisabled ? $editData['meta']['currentLangId'] : 'DEF';
                     // Default language, other options are "lUK" or whatever country code (independant of system!!!)
                     $PA['_lang'] = $lang;
                     $PA['_cshFile'] = isset($dataStruct['ROOT']['TCEforms']) && isset($dataStruct['ROOT']['TCEforms']['cshFile']) ? $dataStruct['ROOT']['TCEforms']['cshFile'] : '';
                     // Render flexform:
                     $tRows = $this->getSingleField_typeFlex_draw($dataStruct['ROOT']['el'], $editData['data'][$sheet][$lang], $table, $field, $row, $PA, '[data][' . $sheet . '][' . $lang . ']');
                     #$sheetContent= '<table border="0" cellpadding="1" cellspacing="1" class="typo3-TCEforms-flexForm">'.implode('',$tRows).'</table>';
                     $sheetContent = '<div class="typo3-TCEforms-flexForm">' . $tRows . '</div>';
                     #			$item = '<div style=" position:absolute;">'.$item.'</div>';
                     //visibility:hidden;
                 } else {
                     $sheetContent = 'Data Structure ERROR: No ROOT element found for sheet "' . $sheet . '".';
                 }
                 // Add to tab:
                 $tabParts[] = array('label' => $dataStruct['ROOT']['TCEforms']['sheetTitle'] ? $this->sL($dataStruct['ROOT']['TCEforms']['sheetTitle']) : $sheet, 'description' => $dataStruct['ROOT']['TCEforms']['sheetDescription'] ? $this->sL($dataStruct['ROOT']['TCEforms']['sheetDescription']) : '', 'linkTitle' => $dataStruct['ROOT']['TCEforms']['sheetShortDescr'] ? $this->sL($dataStruct['ROOT']['TCEforms']['sheetShortDescr']) : '', 'content' => $sheetContent);
             }
             if (is_array($dataStructArray['sheets'])) {
                 $dividersToTabsBehaviour = isset($GLOBALS['TCA'][$table]['ctrl']['dividers2tabs']) ? $GLOBALS['TCA'][$table]['ctrl']['dividers2tabs'] : 1;
                 $item .= $this->getDynTabMenu($tabParts, 'TCEFORMS:flexform:' . $PA['itemFormElName'] . $PA['_lang'], $dividersToTabsBehaviour);
             } else {
                 $item .= $sheetContent;
             }
         }
     } else {
         $item = 'Data Structure ERROR: ' . $dataStructArray;
     }
     return $item;
 }
 /**
  * Processing of the data value in case the field type is "flex"
  * MUST NOT be called in case of already INSIDE a flexform!
  *
  * @param	string		The field value
  * @param	array		TCA field config
  * @param	array		TCEform TSconfig for the record
  * @param	string		Table name
  * @param	array		The row
  * @param	string		Field name
  * @return	string		The processed input field value ($data)
  * @access private
  * @see renderRecord()
  */
 function renderRecord_flexProc($data, $fieldConfig, $TSconfig, $table, $row, $field)
 {
     global $TCA;
     // Convert the XML data to PHP array:
     $currentValueArray = t3lib_div::xml2array($data);
     if (is_array($currentValueArray)) {
         // Get current value array:
         $dataStructArray = t3lib_BEfunc::getFlexFormDS($fieldConfig['config'], $row, $table);
         if (is_array($dataStructArray)) {
             $currentValueArray['data'] = $this->renderRecord_flexProc_procInData($currentValueArray['data'], $dataStructArray, array($data, $fieldConfig, $TSconfig, $table, $row, $field));
             $flexObj = t3lib_div::makeInstance('t3lib_flexformtools');
             $data = $flexObj->flexArray2Xml($currentValueArray, TRUE);
         }
     }
     return $data;
 }
 /**
  * Returns relation information for a $table/$row-array
  * Traverses all fields in input row which are configured in TCA/columns
  * It looks for hard relations to files and records in the TCA types "select" and "group"
  *
  * @param	string		Table name
  * @param	array		Row from table
  * @param	string		Specific field to fetch for.
  * @return	array		Array with information about relations
  * @see export_addRecord()
  */
 function getRelations($table, $row, $onlyField = '')
 {
     global $TCA;
     // Load full table description
     t3lib_div::loadTCA($table);
     // Initialize:
     $uid = $row['uid'];
     $nonFields = explode(',', 'uid,perms_userid,perms_groupid,perms_user,perms_group,perms_everybody,pid');
     $outRow = array();
     foreach ($row as $field => $value) {
         if (!in_array($field, $nonFields) && is_array($TCA[$table]['columns'][$field]) && (!$onlyField || $onlyField === $field)) {
             $conf = $TCA[$table]['columns'][$field]['config'];
             // Add files
             if ($result = $this->getRelations_procFiles($value, $conf, $uid)) {
                 // Creates an entry for the field with all the files:
                 $outRow[$field] = array('type' => 'file', 'newValueFiles' => $result);
             }
             // Add DB:
             if ($result = $this->getRelations_procDB($value, $conf, $uid, $table)) {
                 // Create an entry for the field with all DB relations:
                 $outRow[$field] = array('type' => 'db', 'itemArray' => $result);
             }
             // For "flex" fieldtypes we need to traverse the structure looking for file and db references of course!
             if ($conf['type'] == 'flex') {
                 // Get current value array:
                 // NOTICE: failure to resolve Data Structures can lead to integrity problems with the reference index. Please look up the note in the JavaDoc documentation for the function t3lib_BEfunc::getFlexFormDS()
                 $dataStructArray = t3lib_BEfunc::getFlexFormDS($conf, $row, $table, '', $this->WSOL);
                 $currentValueArray = t3lib_div::xml2array($value);
                 // Traversing the XML structure, processing files:
                 if (is_array($currentValueArray)) {
                     $this->temp_flexRelations = array('db' => array(), 'file' => array(), 'softrefs' => array());
                     // Create and call iterator object:
                     $flexObj = t3lib_div::makeInstance('t3lib_flexformtools');
                     $flexObj->traverseFlexFormXMLData($table, $field, $row, $this, 'getRelations_flexFormCallBack');
                     // Create an entry for the field:
                     $outRow[$field] = array('type' => 'flex', 'flexFormRels' => $this->temp_flexRelations);
                 }
             }
             // Soft References:
             if (strlen($value) && ($softRefs = t3lib_BEfunc::explodeSoftRefParserList($conf['softref']))) {
                 $softRefValue = $value;
                 foreach ($softRefs as $spKey => $spParams) {
                     $softRefObj = t3lib_BEfunc::softRefParserObj($spKey);
                     if (is_object($softRefObj)) {
                         $resultArray = $softRefObj->findRef($table, $field, $uid, $softRefValue, $spKey, $spParams);
                         if (is_array($resultArray)) {
                             $outRow[$field]['softrefs']['keys'][$spKey] = $resultArray['elements'];
                             if (strlen($resultArray['content'])) {
                                 $softRefValue = $resultArray['content'];
                             }
                         }
                     }
                 }
                 if (is_array($outRow[$field]['softrefs']) && count($outRow[$field]['softrefs']) && strcmp($value, $softRefValue) && strstr($softRefValue, '{softref:')) {
                     $outRow[$field]['softrefs']['tokenizedContent'] = $softRefValue;
                 }
             }
         }
     }
     return $outRow;
 }