TYPO3CMS  8
 All Classes Namespaces Files Functions Variables Pages
ElementEntityProcessor.php
Go to the documentation of this file.
1 <?php
2 namespace TYPO3\CMS\Version\Dependency;
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 
176  public function createNewDependentElementCallback(array $callerArguments, array $targetArgument, ElementEntity $caller, $eventName)
177  {
179  $caller->setInvalid(true);
180  return;
181  }
182 
183  $versionRecord = $caller->getRecord();
184  // If version record does not exist, it probably has been deleted (cleared from workspace), this means,
185  // that the reference index still has an old reference pointer, which is "fine" for deleted parents
186  if (empty($versionRecord)) {
187  throw new \RuntimeException(
188  'Element "' . $caller::getIdentifier($caller->getTable(), $caller->getId()) . '" does not exist',
189  1393960943
190  );
191  }
192  // If version is on live workspace, but the pid is negative, mark the record as invalid.
193  // This happens if a change has been discarded (clearWSID) - it will be removed from the command map.
194  if ((int)$versionRecord['t3ver_wsid'] === 0 && (int)$versionRecord['pid'] === -1) {
195  $caller->setDataValue('liveId', $caller->getId());
196  $caller->setInvalid(true);
197  return;
198  }
199  if ($caller->hasDataValue('liveId') === false) {
200  // Set the original uid from the version record
201  if (!empty($versionRecord['t3ver_oid']) && (int)$versionRecord['pid'] === -1 && (int)$versionRecord['t3ver_wsid'] === $this->getWorkspace()) {
202  $caller->setDataValue('liveId', $versionRecord['t3ver_oid']);
203  // The current version record is actually a live record or an accordant placeholder for live
204  } elseif ((int)$versionRecord['t3ver_wsid'] === 0 || (int)$versionRecord['pid'] !== -1) {
205  $caller->setDataValue('liveId', $caller->getId());
207  $this->getWorkspace(),
208  $caller->getTable(),
209  $caller->getId(),
210  'uid,t3ver_state'
211  );
212  // Set version uid to caller, most likely it's a delete placeholder
213  // for a child record that is not recognized in the reference index
214  if (!empty($versionRecord['uid'])) {
215  $caller->setId($versionRecord['uid']);
216  // If no version could be determined, mark record as invalid
217  // (thus, it will be removed from the command map)
218  } else {
219  $caller->setInvalid(true);
220  }
221  // In case of an unexpected record state, mark the record as invalid
222  } else {
223  $caller->setInvalid(true);
224  }
225  }
226  }
227 }
createNewDependentElementCallback(array $callerArguments, array $targetArgument, ElementEntity $caller, $eventName)
createNewDependentElementParentReferenceCallback(array $callerArguments, array $targetArgument, ElementEntity $caller, $eventName)
static getRecord($table, $uid, $fields= '*', $where= '', $useDeleteClause=true)
createClearDependentElementParentReferenceCallback(array $callerArguments, array $targetArgument, ElementEntity $caller, $eventName)
createNewDependentElementChildReferenceCallback(array $callerArguments, array $targetArgument, ElementEntity $caller, $eventName)
static makeInstance($className,...$constructorArguments)
createClearDependentElementChildReferenceCallback(array $callerArguments, array $targetArgument, ElementEntity $caller, $eventName)
static getWorkspaceVersionOfRecord($workspace, $table, $uid, $fields= '*')