TYPO3 CMS  TYPO3_6-2
FlexFormTools.php
Go to the documentation of this file.
1 <?php
3 
18 
25 
26  // If set, the charset of data XML is converted to system charset.
30  public $convertCharset = FALSE;
31 
32  // If set, section indexes are re-numbered before processing
37 
38  // Contains data structure when traversing flexform
42  public $traverseFlexFormXMLData_DS = array();
43 
44  // Contains data array when traversing flexform
49 
50  // Options for array2xml() for flexform.
51  // This will map the weird keys from the internal array to tags that could potentially be checked with a DTD/schema
55  public $flexArray2Xml_options = array(
56  'parentTagMap' => array(
57  'data' => 'sheet',
58  'sheet' => 'language',
59  'language' => 'field',
60  'el' => 'field',
61  'field' => 'value',
62  'field:el' => 'el',
63  'el:_IS_NUM' => 'section',
64  'section' => 'itemType'
65  ),
66  'disableTypeAttrib' => 2
67  );
68 
74  public $callBackObj = NULL;
75 
76  // Used for accumulation of clean XML
80  public $cleanFlexFormXML = array();
81 
93  public function traverseFlexFormXMLData($table, $field, $row, $callBackObj, $callBackMethod_value) {
94  if (!is_array($GLOBALS['TCA'][$table]) || !is_array($GLOBALS['TCA'][$table]['columns'][$field])) {
95  return 'TCA table/field was not defined.';
96  }
97  $this->callBackObj = $callBackObj;
98  // Get Data Structure:
99  $dataStructArray = BackendUtility::getFlexFormDS($GLOBALS['TCA'][$table]['columns'][$field]['config'], $row, $table, $field);
100  // If data structure was ok, proceed:
101  if (is_array($dataStructArray)) {
102  // Get flexform XML data:
103  $xmlData = $row[$field];
104  // Convert charset:
105  if ($this->convertCharset) {
106  $xmlHeaderAttributes = \TYPO3\CMS\Core\Utility\GeneralUtility::xmlGetHeaderAttribs($xmlData);
107  $storeInCharset = strtolower($xmlHeaderAttributes['encoding']);
108  if ($storeInCharset) {
109  $currentCharset = $GLOBALS['LANG']->charSet;
110  $xmlData = $GLOBALS['LANG']->csConvObj->conv($xmlData, $storeInCharset, $currentCharset, 1);
111  }
112  }
114  if (!is_array($editData)) {
115  return 'Parsing error: ' . $editData;
116  }
117  // Language settings:
118  $langChildren = $dataStructArray['meta']['langChildren'] ? 1 : 0;
119  $langDisabled = $dataStructArray['meta']['langDisable'] ? 1 : 0;
120  // Empty or invalid <meta>
121  if (!is_array($editData['meta'])) {
122  $editData['meta'] = array();
123  }
124  $editData['meta']['currentLangId'] = array();
125  $languages = $this->getAvailableLanguages();
126  foreach ($languages as $lInfo) {
127  $editData['meta']['currentLangId'][] = $lInfo['ISOcode'];
128  }
129  if (!count($editData['meta']['currentLangId'])) {
130  $editData['meta']['currentLangId'] = array('DEF');
131  }
132  $editData['meta']['currentLangId'] = array_unique($editData['meta']['currentLangId']);
133  if ($langChildren || $langDisabled) {
134  $lKeys = array('DEF');
135  } else {
136  $lKeys = $editData['meta']['currentLangId'];
137  }
138  // Tabs sheets
139  if (is_array($dataStructArray['sheets'])) {
140  $sKeys = array_keys($dataStructArray['sheets']);
141  } else {
142  $sKeys = array('sDEF');
143  }
144  // Traverse languages:
145  foreach ($lKeys as $lKey) {
146  foreach ($sKeys as $sheet) {
147  $sheetCfg = $dataStructArray['sheets'][$sheet];
148  list($dataStruct, $sheet) = \TYPO3\CMS\Core\Utility\GeneralUtility::resolveSheetDefInDS($dataStructArray, $sheet);
149  // Render sheet:
150  if (is_array($dataStruct['ROOT']) && is_array($dataStruct['ROOT']['el'])) {
151  // Separate language key
152  $lang = 'l' . $lKey;
153  $PA['vKeys'] = $langChildren && !$langDisabled ? $editData['meta']['currentLangId'] : array('DEF');
154  $PA['lKey'] = $lang;
155  $PA['callBackMethod_value'] = $callBackMethod_value;
156  $PA['table'] = $table;
157  $PA['field'] = $field;
158  $PA['uid'] = $row['uid'];
159  $this->traverseFlexFormXMLData_DS = &$dataStruct;
160  $this->traverseFlexFormXMLData_Data = &$editData;
161  // Render flexform:
162  $this->traverseFlexFormXMLData_recurse($dataStruct['ROOT']['el'], $editData['data'][$sheet][$lang], $PA, 'data/' . $sheet . '/' . $lang);
163  } else {
164  return 'Data Structure ERROR: No ROOT element found for sheet "' . $sheet . '".';
165  }
166  }
167  }
168  } else {
169  return 'Data Structure ERROR: ' . $dataStructArray;
170  }
171  }
172 
183  public function traverseFlexFormXMLData_recurse($dataStruct, $editData, &$PA, $path = '') {
184  if (is_array($dataStruct)) {
185  foreach ($dataStruct as $key => $value) {
186  // The value of each entry must be an array.
187  if (is_array($value)) {
188  if ($value['type'] == 'array') {
189  // Array (Section) traversal
190  if ($value['section']) {
191  $cc = 0;
192  if (is_array($editData[$key]['el'])) {
193  if ($this->reNumberIndexesOfSectionData) {
194  $temp = array();
195  $c3 = 0;
196  foreach ($editData[$key]['el'] as $v3) {
197  $temp[++$c3] = $v3;
198  }
199  $editData[$key]['el'] = $temp;
200  }
201  foreach ($editData[$key]['el'] as $k3 => $v3) {
202  if (is_array($v3)) {
203  $cc = $k3;
204  $theType = key($v3);
205  $theDat = $v3[$theType];
206  $newSectionEl = $value['el'][$theType];
207  if (is_array($newSectionEl)) {
208  $this->traverseFlexFormXMLData_recurse(array($theType => $newSectionEl), array($theType => $theDat), $PA, $path . '/' . $key . '/el/' . $cc);
209  }
210  }
211  }
212  }
213  } else {
214  // Array traversal
215  if (is_array($editData) && is_array($editData[$key])) {
216  $this->traverseFlexFormXMLData_recurse($value['el'], $editData[$key]['el'], $PA, $path . '/' . $key . '/el');
217  }
218  }
219  } elseif (is_array($value['TCEforms']['config'])) {
220  // Processing a field value:
221  foreach ($PA['vKeys'] as $vKey) {
222  $vKey = 'v' . $vKey;
223  // Call back
224  if ($PA['callBackMethod_value'] && is_array($editData) && is_array($editData[$key])) {
225  $this->executeCallBackMethod($PA['callBackMethod_value'], array($value, $editData[$key][$vKey], $PA, $path . '/' . $key . '/' . $vKey, $this));
226  }
227  }
228  }
229  }
230  }
231  }
232  }
233 
241  protected function executeCallBackMethod($methodName, array $parameterArray) {
242  return call_user_func_array(array($this->callBackObj, $methodName), $parameterArray);
243  }
244 
251  public function getAvailableLanguages() {
253  // Find all language records in the system
254  $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('static_lang_isocode,title,uid', 'sys_language', 'pid=0' . BackendUtility::deleteClause('sys_language'), '', 'title');
255  // Traverse them
256  $output = array();
257  $output[0] = array(
258  'uid' => 0,
259  'title' => 'Default language',
260  'ISOcode' => 'DEF'
261  );
262  while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
263  $output[$row['uid']] = $row;
264  if ($isL && $row['static_lang_isocode']) {
265  $rr = BackendUtility::getRecord('static_languages', $row['static_lang_isocode'], 'lg_iso_2');
266  if ($rr['lg_iso_2']) {
267  $output[$row['uid']]['ISOcode'] = $rr['lg_iso_2'];
268  }
269  }
270  if (!$output[$row['uid']]['ISOcode']) {
271  unset($output[$row['uid']]);
272  }
273  }
274  $GLOBALS['TYPO3_DB']->sql_free_result($res);
275  return $output;
276  }
277 
278  /***********************************
279  *
280  * Processing functions
281  *
282  ***********************************/
293  public function cleanFlexFormXML($table, $field, $row) {
294  // New structure:
295  $this->cleanFlexFormXML = array();
296  // Create and call iterator object:
297  $flexObj = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Configuration\\FlexForm\\FlexFormTools');
298  $flexObj->reNumberIndexesOfSectionData = TRUE;
299  $flexObj->traverseFlexFormXMLData($table, $field, $row, $this, 'cleanFlexFormXML_callBackFunction');
300  return $this->flexArray2Xml($this->cleanFlexFormXML, TRUE);
301  }
302 
315  public function cleanFlexFormXML_callBackFunction($dsArr, $data, $PA, $path, $pObj) {
316  // Just setting value in our own result array, basically replicating the structure:
317  $pObj->setArrayValueByPath($path, $this->cleanFlexFormXML, $data);
318  // Looking if an "extension" called ".vDEFbase" is found and if so, accept that too:
319  if ($GLOBALS['TYPO3_CONF_VARS']['BE']['flexFormXMLincludeDiffBase']) {
320  $vDEFbase = $pObj->getArrayValueByPath($path . '.vDEFbase', $pObj->traverseFlexFormXMLData_Data);
321  if (isset($vDEFbase)) {
322  $pObj->setArrayValueByPath($path . '.vDEFbase', $this->cleanFlexFormXML, $vDEFbase);
323  }
324  }
325  }
326 
327  /***********************************
328  *
329  * Multi purpose functions
330  *
331  ***********************************/
340  public function &getArrayValueByPath($pathArray, &$array) {
341  if (!is_array($pathArray)) {
342  $pathArray = explode('/', $pathArray);
343  }
344  if (is_array($array)) {
345  if (count($pathArray)) {
346  $key = array_shift($pathArray);
347  if (isset($array[$key])) {
348  if (!count($pathArray)) {
349  return $array[$key];
350  } else {
351  return $this->getArrayValueByPath($pathArray, $array[$key]);
352  }
353  } else {
354  return NULL;
355  }
356  }
357  }
358  }
359 
369  public function setArrayValueByPath($pathArray, &$array, $value) {
370  if (isset($value)) {
371  if (!is_array($pathArray)) {
372  $pathArray = explode('/', $pathArray);
373  }
374  if (is_array($array)) {
375  if (count($pathArray)) {
376  $key = array_shift($pathArray);
377  if (!count($pathArray)) {
378  $array[$key] = $value;
379  return TRUE;
380  } else {
381  if (!isset($array[$key])) {
382  $array[$key] = array();
383  }
384  return $this->setArrayValueByPath($pathArray, $array[$key], $value);
385  }
386  }
387  }
388  }
389  }
390 
399  public function flexArray2Xml($array, $addPrologue = FALSE) {
400  if ($GLOBALS['TYPO3_CONF_VARS']['BE']['flexformForceCDATA']) {
401  $this->flexArray2Xml_options['useCDATA'] = 1;
402  }
403  $options = $GLOBALS['TYPO3_CONF_VARS']['BE']['niceFlexFormXMLtags'] ? $this->flexArray2Xml_options : array();
404  $spaceInd = $GLOBALS['TYPO3_CONF_VARS']['BE']['compactFlexFormXML'] ? -1 : 4;
405  $output = \TYPO3\CMS\Core\Utility\GeneralUtility::array2xml($array, '', 0, 'T3FlexForms', $spaceInd, $options);
406  if ($addPrologue) {
407  $output = '<?xml version="1.0" encoding="utf-8" standalone="yes" ?>' . LF . $output;
408  }
409  return $output;
410  }
411 
412 }
executeCallBackMethod($methodName, array $parameterArray)
static getFlexFormDS($conf, $row, $table, $fieldName='', $WSOL=TRUE, $newRecordPidValue=0)
static array2xml(array $array, $NSprefix='', $level=0, $docTag='phparray', $spaceInd=0, array $options=array(), array $stackData=array())
traverseFlexFormXMLData_recurse($dataStruct, $editData, &$PA, $path='')
static resolveSheetDefInDS($dataStructArray, $sheet='sDEF')
cleanFlexFormXML_callBackFunction($dsArr, $data, $PA, $path, $pObj)
traverseFlexFormXMLData($table, $field, $row, $callBackObj, $callBackMethod_value)
if(!defined('TYPO3_MODE')) $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_userauth.php']['logoff_pre_processing'][]
static xml2array($string, $NSprefix='', $reportDocTag=FALSE)
static deleteClause($table, $tableAlias='')