TYPO3 CMS  TYPO3_8-7
ElementEntityProcessor.php
Go to the documentation of this file.
1 <?php
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 
25 {
29  protected $workspace;
30 
34  protected $dataHandler;
35 
41  public function setWorkspace($workspace)
42  {
43  $this->workspace = (int)$workspace;
44  }
45 
51  public function getWorkspace()
52  {
53  return $this->workspace;
54  }
55 
59  public function getDataHandler()
60  {
61  if (!isset($this->dataHandler)) {
62  $this->dataHandler = GeneralUtility::makeInstance(\TYPO3\CMS\Core\DataHandling\DataHandler::class);
63  }
64  return $this->dataHandler;
65  }
66 
73  public function transformDependentElementsToUseLiveId(array $elements)
74  {
75  $transformedElements = [];
77  foreach ($elements as $element) {
78  $elementName = ElementEntity::getIdentifier($element->getTable(), $element->getDataValue('liveId'));
79  $transformedElements[$elementName] = $element;
80  }
81  return $transformedElements;
82  }
83 
93  public function createNewDependentElementChildReferenceCallback(array $callerArguments, array $targetArgument, ElementEntity $caller, $eventName)
94  {
95  $fieldConfiguration = BackendUtility::getTcaFieldConfiguration($caller->getTable(), $callerArguments['field']);
96  $inlineFieldType = $this->getDataHandler()->getInlineFieldType($fieldConfiguration);
97  if (!$fieldConfiguration || ($fieldConfiguration['type'] !== 'flex' && $inlineFieldType !== 'field' && $inlineFieldType !== 'list')) {
99  }
100  return null;
101  }
102 
112  public function createNewDependentElementParentReferenceCallback(array $callerArguments, array $targetArgument, ElementEntity $caller, $eventName)
113  {
114  $fieldConfiguration = BackendUtility::getTcaFieldConfiguration($callerArguments['table'], $callerArguments['field']);
115  $inlineFieldType = $this->getDataHandler()->getInlineFieldType($fieldConfiguration);
116  if (!$fieldConfiguration || ($fieldConfiguration['type'] !== 'flex' && $inlineFieldType !== 'field' && $inlineFieldType !== 'list')) {
118  }
119  return null;
120  }
121 
132  public function createClearDependentElementChildReferenceCallback(array $callerArguments, array $targetArgument, ElementEntity $caller, $eventName)
133  {
134  $response = $this->createNewDependentElementChildReferenceCallback($callerArguments, $targetArgument, $caller, $eventName);
135  if (empty($response)) {
136  $record = BackendUtility::getRecord($callerArguments['table'], $callerArguments['id']);
137  if (!VersionState::cast($record['t3ver_state'])->equals(VersionState::DELETE_PLACEHOLDER)) {
138  $response = ElementEntity::RESPONSE_Skip;
139  }
140  }
141  return $response;
142  }
143 
154  public function createClearDependentElementParentReferenceCallback(array $callerArguments, array $targetArgument, ElementEntity $caller, $eventName)
155  {
156  $response = $this->createNewDependentElementParentReferenceCallback($callerArguments, $targetArgument, $caller, $eventName);
157  if (empty($response)) {
158  $record = BackendUtility::getRecord($callerArguments['table'], $callerArguments['id']);
159  if (!VersionState::cast($record['t3ver_state'])->equals(VersionState::DELETE_PLACEHOLDER)) {
160  $response = ElementEntity::RESPONSE_Skip;
161  }
162  }
163  return $response;
164  }
165 
175  public function createNewDependentElementCallback(array $callerArguments, array $targetArgument, ElementEntity $caller, $eventName)
176  {
178  $caller->setInvalid(true);
179  return;
180  }
181 
182  $versionRecord = $caller->getRecord();
183  // If version record does not exist, it probably has been deleted (cleared from workspace), this means,
184  // that the reference index still has an old reference pointer, which is "fine" for deleted parents
185  if (empty($versionRecord)) {
186  throw new \RuntimeException(
187  'Element "' . $caller::getIdentifier($caller->getTable(), $caller->getId()) . '" does not exist',
188  1393960943
189  );
190  }
191  // If version is on live workspace, but the pid is negative, mark the record as invalid.
192  // This happens if a change has been discarded (clearWSID) - it will be removed from the command map.
193  if ((int)$versionRecord['t3ver_wsid'] === 0 && (int)$versionRecord['pid'] === -1) {
194  $caller->setDataValue('liveId', $caller->getId());
195  $caller->setInvalid(true);
196  return;
197  }
198  if ($caller->hasDataValue('liveId') === false) {
199  // Set the original uid from the version record
200  if (!empty($versionRecord['t3ver_oid']) && (int)$versionRecord['pid'] === -1 && (int)$versionRecord['t3ver_wsid'] === $this->getWorkspace()) {
201  $caller->setDataValue('liveId', $versionRecord['t3ver_oid']);
202  } elseif ((int)$versionRecord['t3ver_wsid'] === 0 || (int)$versionRecord['pid'] !== -1) {
203  // The current version record is actually a live record or an accordant placeholder for live
204  $caller->setDataValue('liveId', $caller->getId());
206  $this->getWorkspace(),
207  $caller->getTable(),
208  $caller->getId(),
209  'uid,t3ver_state'
210  );
211  // Set version uid to caller, most likely it's a delete placeholder
212  // for a child record that is not recognized in the reference index
213  if (!empty($versionRecord['uid'])) {
214  $caller->setId($versionRecord['uid']);
215  } else {
216  // If no version could be determined, mark record as invalid
217  // (thus, it will be removed from the command map)
218  $caller->setInvalid(true);
219  }
220  } else {
221  // In case of an unexpected record state, mark the record as invalid
222  $caller->setInvalid(true);
223  }
224  }
225  }
226 }
createClearDependentElementChildReferenceCallback(array $callerArguments, array $targetArgument, ElementEntity $caller, $eventName)
static getWorkspaceVersionOfRecord($workspace, $table, $uid, $fields=' *')
createNewDependentElementChildReferenceCallback(array $callerArguments, array $targetArgument, ElementEntity $caller, $eventName)
createNewDependentElementParentReferenceCallback(array $callerArguments, array $targetArgument, ElementEntity $caller, $eventName)
static makeInstance($className,... $constructorArguments)
createClearDependentElementParentReferenceCallback(array $callerArguments, array $targetArgument, ElementEntity $caller, $eventName)
static getTcaFieldConfiguration($table, $field)
static getRecord($table, $uid, $fields=' *', $where='', $useDeleteClause=true)
createNewDependentElementCallback(array $callerArguments, array $targetArgument, ElementEntity $caller, $eventName)