TYPO3  7.6
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 = array();
37 
43  public function initializeByGivenStructure(array $structure = array())
44  {
45  $this->inlineStructure = $structure;
46  }
47 
59  public function initializeByParsingDomObjectIdString($domObjectId)
60  {
61  $unstable = array();
62  $vector = array('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'], array('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 = array();
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  $current['config'] = $context['config'];
129  $current['localizationMode'] = BackendUtility::getInlineLocalizationMode(
130  $current['table'],
131  $current['config']
132  );
133  }
134 
140  public function getStructure()
141  {
142  return $this->inlineStructure;
143  }
144 
151  public function pushStableStructureItem(array $structureItem = array())
152  {
153  $this->inlineStructure['stable'][] = $structureItem;
154  }
155 
162  {
163  $current = $this->getStructureLevel(-1);
164  $inlineFormName = '';
165  // If there are still more inline levels available
166  if ($current !== false) {
167  $inlineFormName = 'data' . $this->getStructureItemName($current, 'Disposal_AttributeName');
168  }
169  return $inlineFormName;
170  }
171 
178  public function getCurrentStructureDomObjectIdPrefix($inlineFirstPid)
179  {
180  $current = $this->getStructureLevel(-1);
181  $inlineDomObjectId = '';
182  // If there are still more inline levels available
183  if ($current !== false) {
184  $inlineDomObjectId = 'data' . '-' . $inlineFirstPid . '-' . $this->getStructurePath();
185  }
186  return $inlineDomObjectId;
187  }
188 
198  public function getStructureLevel($level)
199  {
200  $level = $this->calculateStructureLevel($level);
201 
202  if ($level !== false) {
203  return $this->inlineStructure['stable'][$level];
204  } else {
205  return false;
206  }
207  }
208 
216  public function getUnstableStructure()
217  {
218  if (!isset($this->inlineStructure['unstable'])) {
219  throw new \RuntimeException('No unstable inline structure found', 1428582655);
220  }
221  return $this->inlineStructure['unstable'];
222  }
223 
230  protected function calculateStructureLevel($level)
231  {
232  $result = false;
233  $inlineStructureCount = count($this->inlineStructure['stable']);
234  if ($level < 0) {
235  $level = $inlineStructureCount + $level;
236  }
237  if ($level >= 0 && $level < $inlineStructureCount) {
238  $result = $level;
239  }
240  return $result;
241  }
242 
250  protected function getStructurePath($structureDepth = -1)
251  {
252  $structureLevels = array();
253  $structureCount = $this->getStructureDepth();
254  if ($structureDepth < 0 || $structureDepth > $structureCount) {
255  $structureDepth = $structureCount;
256  }
257  for ($i = 1; $i <= $structureDepth; $i++) {
258  array_unshift($structureLevels, $this->getStructureItemName($this->getStructureLevel(-$i), 'Disposal_AttributeId'));
259  }
260  return implode('-', $structureLevels);
261  }
262 
269  public function getStructureDepth()
270  {
271  return count($this->inlineStructure['stable']);
272  }
273 
281  protected function getStructureItemName($levelData, $disposal = 'Disposal_AttributeId')
282  {
283  $name = null;
284 
285  if (is_array($levelData)) {
286  $parts = array($levelData['table'], $levelData['uid']);
287 
288  if (!empty($levelData['field'])) {
289  $parts[] = $levelData['field'];
290  }
291 
292  // Use in name attributes:
293  if ($disposal === 'Disposal_AttributeName') {
294  if (!empty($levelData['field']) && !empty($levelData['flexform']) && $this->getStructureLevel(-1) === $levelData) {
295  $parts[] = implode('][', $levelData['flexform']);
296  }
297  $name = '[' . implode('][', $parts) . ']';
298  // Use in object id attributes:
299  } else {
300  $name = implode('-', $parts);
301 
302  if (!empty($levelData['field']) && !empty($levelData['flexform'])) {
303  array_unshift($levelData['flexform'], $name);
304  $name = implode('---', $levelData['flexform']);
305  }
306  }
307  }
308 
309  return $name;
310  }
311 }