TYPO3CMS  8
 All Classes Namespaces Files Functions Variables Pages
InlineStackProcessor.php
Go to the documentation of this file.
1 <?php
2 namespace TYPO3\CMS\Backend\Form;
3 
4 /*
5  * This file is part of the TYPO3 CMS project.
6  *
7  * It is free software; you can redistribute it and/or modify it under
8  * the terms of the GNU General Public License, either version 2
9  * of the License, or any later version.
10  *
11  * For the full copyright and license information, please read the
12  * LICENSE.txt file that was distributed with this source code.
13  *
14  * The TYPO3 project - inspiring people to share!
15  */
16 
20 
30 {
36  protected $inlineStructure = [];
37 
43  public function initializeByGivenStructure(array $structure = [])
44  {
45  $this->inlineStructure = $structure;
46  }
47 
59  public function initializeByParsingDomObjectIdString($domObjectId)
60  {
61  $unstable = [];
62  $vector = ['table', 'uid', 'field'];
63 
64  // Substitute FlexForm addition and make parsing a bit easier
65  $domObjectId = str_replace('---', ':', $domObjectId);
66  // The starting pattern of an object identifier (e.g. "data-<firstPidValue>-<anything>)
67  $pattern = '/^data' . '-' . '(.+?)' . '-' . '(.+)$/';
68 
69  if (preg_match($pattern, $domObjectId, $match)) {
70  $inlineFirstPid = $match[1];
71  $parts = explode('-', $match[2]);
72  $partsCnt = count($parts);
73  for ($i = 0; $i < $partsCnt; $i++) {
74  if ($i > 0 && $i % 3 == 0) {
75  // Load the TCA configuration of the table field and store it in the stack
76  // @todo: This TCA loading here must fall - config sub-array shouldn't exist at all!
77  $unstable['config'] = $GLOBALS['TCA'][$unstable['table']]['columns'][$unstable['field']]['config'];
78  // Fetch TSconfig:
79  // @todo: aaargs ;)
80  $TSconfig = FormEngineUtility::getTSconfigForTableRow($unstable['table'], ['uid' => $unstable['uid'], 'pid' => $inlineFirstPid], $unstable['field']);
81  // Override TCA field config by TSconfig:
82  if (!$TSconfig['disabled']) {
83  $unstable['config'] = FormEngineUtility::overrideFieldConf($unstable['config'], $TSconfig);
84  }
85  $unstable['localizationMode'] = BackendUtility::getInlineLocalizationMode($unstable['table'], $unstable['config']);
86 
87  // Extract FlexForm from field part (if any)
88  if (strpos($unstable['field'], ':') !== false) {
89  $fieldParts = GeneralUtility::trimExplode(':', $unstable['field']);
90  $unstable['field'] = array_shift($fieldParts);
91  // FlexForm parts start with data:
92  if (!empty($fieldParts) && $fieldParts[0] === 'data') {
93  $unstable['flexform'] = $fieldParts;
94  }
95  }
96 
97  $this->inlineStructure['stable'][] = $unstable;
98  $unstable = [];
99  }
100  $unstable[$vector[$i % 3]] = $parts[$i];
101  }
102  if (!empty($unstable)) {
103  $this->inlineStructure['unstable'] = $unstable;
104  }
105  }
106  }
107 
117  public function injectAjaxConfiguration($contextString = '')
118  {
119  $level = $this->calculateStructureLevel(-1);
120  if (empty($contextString) || $level === false) {
121  return;
122  }
123  $current = &$this->inlineStructure['stable'][$level];
124  $context = json_decode($contextString, true);
125  if (GeneralUtility::hmac(serialize($context['config'])) !== $context['hmac']) {
126  return;
127  }
128  // Remove the data structure pointers, only relevant for the FormInlineAjaxController
129  unset($context['flexDataStructurePointers']);
130  $current['config'] = $context['config'];
131  $current['localizationMode'] = BackendUtility::getInlineLocalizationMode(
132  $current['table'],
133  $current['config']
134  );
135  }
136 
142  public function getStructure()
143  {
144  return $this->inlineStructure;
145  }
146 
153  public function pushStableStructureItem(array $structureItem = [])
154  {
155  $this->inlineStructure['stable'][] = $structureItem;
156  }
157 
164  {
165  $current = $this->getStructureLevel(-1);
166  $inlineFormName = '';
167  // If there are still more inline levels available
168  if ($current !== false) {
169  $inlineFormName = 'data' . $this->getStructureItemName($current, 'Disposal_AttributeName');
170  }
171  return $inlineFormName;
172  }
173 
180  public function getCurrentStructureDomObjectIdPrefix($inlineFirstPid)
181  {
182  $current = $this->getStructureLevel(-1);
183  $inlineDomObjectId = '';
184  // If there are still more inline levels available
185  if ($current !== false) {
186  $inlineDomObjectId = 'data' . '-' . $inlineFirstPid . '-' . $this->getStructurePath();
187  }
188  return $inlineDomObjectId;
189  }
190 
200  public function getStructureLevel($level)
201  {
202  $level = $this->calculateStructureLevel($level);
203 
204  if ($level !== false) {
205  return $this->inlineStructure['stable'][$level];
206  } else {
207  return false;
208  }
209  }
210 
218  public function getUnstableStructure()
219  {
220  if (!isset($this->inlineStructure['unstable'])) {
221  throw new \RuntimeException('No unstable inline structure found', 1428582655);
222  }
223  return $this->inlineStructure['unstable'];
224  }
225 
232  protected function calculateStructureLevel($level)
233  {
234  $result = false;
235  $inlineStructureCount = count($this->inlineStructure['stable']);
236  if ($level < 0) {
237  $level = $inlineStructureCount + $level;
238  }
239  if ($level >= 0 && $level < $inlineStructureCount) {
240  $result = $level;
241  }
242  return $result;
243  }
244 
252  protected function getStructurePath($structureDepth = -1)
253  {
254  $structureLevels = [];
255  $structureCount = $this->getStructureDepth();
256  if ($structureDepth < 0 || $structureDepth > $structureCount) {
257  $structureDepth = $structureCount;
258  }
259  for ($i = 1; $i <= $structureDepth; $i++) {
260  array_unshift($structureLevels, $this->getStructureItemName($this->getStructureLevel(-$i), 'Disposal_AttributeId'));
261  }
262  return implode('-', $structureLevels);
263  }
264 
271  public function getStructureDepth()
272  {
273  return count($this->inlineStructure['stable']);
274  }
275 
283  protected function getStructureItemName($levelData, $disposal = 'Disposal_AttributeId')
284  {
285  $name = null;
286 
287  if (is_array($levelData)) {
288  $parts = [$levelData['table'], $levelData['uid']];
289 
290  if (!empty($levelData['field'])) {
291  $parts[] = $levelData['field'];
292  }
293 
294  // Use in name attributes:
295  if ($disposal === 'Disposal_AttributeName') {
296  if (!empty($levelData['field']) && !empty($levelData['flexform']) && $this->getStructureLevel(-1) === $levelData) {
297  $parts[] = implode('][', $levelData['flexform']);
298  }
299  $name = '[' . implode('][', $parts) . ']';
300  // Use in object id attributes:
301  } else {
302  $name = implode('-', $parts);
303 
304  if (!empty($levelData['field']) && !empty($levelData['flexform'])) {
305  array_unshift($levelData['flexform'], $name);
306  $name = implode('---', $levelData['flexform']);
307  }
308  }
309  }
310 
311  return $name;
312  }
313 }
static trimExplode($delim, $string, $removeEmptyValues=false, $limit=0)
static getTSconfigForTableRow($table, $row, $field= '')
static static overrideFieldConf($fieldConfig, $TSconfig)
if(TYPO3_MODE=== 'BE') $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['frontendEditingController']['default']
static hmac($input, $additionalSecret= '')
getStructureItemName($levelData, $disposal= 'Disposal_AttributeId')