‪TYPO3CMS  ‪main
ElementEntityProcessor.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
20 use TYPO3\CMS\Backend\Utility\BackendUtility;
24 
31 {
32  protected int ‪$workspace;
34 
38  public function ‪setWorkspace(int ‪$workspace): void
39  {
40  $this->workspace = ‪$workspace;
41  }
42 
46  public function ‪getWorkspace(): int
47  {
48  return ‪$this->workspace;
49  }
50 
51  public function ‪getDataHandler(): ‪DataHandler
52  {
53  if (!isset($this->dataHandler)) {
54  $this->dataHandler = GeneralUtility::makeInstance(DataHandler::class);
55  }
56  return ‪$this->dataHandler;
57  }
58 
64  public function ‪transformDependentElementsToUseLiveId(array $elements): array
65  {
66  $transformedElements = [];
67  foreach ($elements as $element) {
68  $elementName = ‪ElementEntity::getIdentifier($element->getTable(), $element->getDataValue('liveId'));
69  $transformedElements[$elementName] = $element;
70  }
71  return $transformedElements;
72  }
73 
79  public function ‪createNewDependentElementChildReferenceCallback(array $callerArguments, array $targetArgument, ‪ElementEntity $caller, string $eventName): ?string
80  {
81  // skip children in case ancestor is invalid
82  if ($caller->‪isInvalid()) {
84  }
85  $fieldConfiguration = BackendUtility::getTcaFieldConfiguration($caller->‪getTable(), $callerArguments['field']);
86  $inlineFieldType = $this->‪getDataHandler()->getRelationFieldType($fieldConfiguration);
87  if (!$fieldConfiguration || ($fieldConfiguration['type'] !== 'flex' && $inlineFieldType !== 'field' && $inlineFieldType !== 'list')) {
89  }
90  return null;
91  }
92 
98  public function ‪createNewDependentElementParentReferenceCallback(array $callerArguments, array $targetArgument, ‪ElementEntity $caller, string $eventName): ?string
99  {
100  $fieldConfiguration = BackendUtility::getTcaFieldConfiguration($callerArguments['table'], $callerArguments['field']);
101  $inlineFieldType = $this->‪getDataHandler()->getRelationFieldType($fieldConfiguration);
102  if (!$fieldConfiguration || ($fieldConfiguration['type'] !== 'flex' && $inlineFieldType !== 'field' && $inlineFieldType !== 'list')) {
104  }
105  return null;
106  }
107 
114  public function ‪createClearDependentElementChildReferenceCallback(array $callerArguments, array $targetArgument, ‪ElementEntity $caller, string $eventName): ?string
115  {
116  $response = $this->‪createNewDependentElementChildReferenceCallback($callerArguments, $targetArgument, $caller, $eventName);
117  if (empty($response)) {
118  ‪$record = BackendUtility::getRecord($callerArguments['table'], $callerArguments['id']);
119  if (VersionState::tryFrom(‪$record['t3ver_state'] ?? 0) !== VersionState::DELETE_PLACEHOLDER->value) {
121  }
122  }
123  return $response;
124  }
125 
132  public function ‪createClearDependentElementParentReferenceCallback(array $callerArguments, array $targetArgument, ‪ElementEntity $caller, string $eventName): ?string
133  {
134  $response = $this->‪createNewDependentElementParentReferenceCallback($callerArguments, $targetArgument, $caller, $eventName);
135  if (empty($response)) {
136  ‪$record = BackendUtility::getRecord($callerArguments['table'], $callerArguments['id']);
137  if (VersionState::tryFrom(‪$record['t3ver_state'] ?? 0) !== VersionState::DELETE_PLACEHOLDER->value) {
139  }
140  }
141  return $response;
142  }
143 
147  public function ‪createNewDependentElementCallback(array $callerArguments, array $targetArgument, ‪ElementEntity $caller, string $eventName): void
148  {
149  if (!BackendUtility::isTableWorkspaceEnabled($caller->‪getTable())) {
150  $caller->‪setInvalid(true);
151  return;
152  }
153 
154  $versionRecord = $caller->‪getRecord();
155  // If version record does not exist, it probably has been deleted (cleared from workspace), this means,
156  // that the reference index still has an old reference pointer, which is "fine" for deleted parents
157  if (empty($versionRecord)) {
158  throw new \RuntimeException(
159  'Element "' . $caller::getIdentifier($caller->‪getTable(), $caller->‪getId()) . '" does not exist',
160  1393960943
161  );
162  }
163 
164  $deleteFieldName = ‪$GLOBALS['TCA'][$caller->‪getTable()]['ctrl']['delete'] ?? null;
165  // If version is on live workspace, but an "offline" ID is set, mark the record as invalid.
166  // This happens if a change has been discarded (clearWSID) - it will be removed from the command map.
167  if (
168  (int)$versionRecord['t3ver_oid'] > 0 && (
169  (int)$versionRecord['t3ver_wsid'] === 0 // behavior prior to v10.1 (backward compatibility)
170  || !empty($deleteFieldName) && (int)$versionRecord['t3ver_wsid'] === $this->‪getWorkspace()
171  && (int)$versionRecord[$deleteFieldName] > 0 // behavior since v10.1
172  )
173  ) {
174  $caller->‪setDataValue('liveId', $caller->‪getId());
175  $caller->‪setInvalid(true);
176  return;
177  }
178  if ($caller->‪hasDataValue('liveId') === false) {
179  // Set the original uid from the version record
180  if (!empty($versionRecord['t3ver_oid']) && (int)$versionRecord['t3ver_wsid'] === $this->‪getWorkspace()) {
181  $caller->‪setDataValue('liveId', $versionRecord['t3ver_oid']);
182  } elseif ((int)$versionRecord['t3ver_wsid'] === 0 || (int)$versionRecord['t3ver_oid'] === 0) {
183  // The current version record is actually a live record or an accordant placeholder for live
184  $caller->‪setDataValue('liveId', $caller->‪getId());
185  $versionRecord = BackendUtility::getWorkspaceVersionOfRecord(
186  $this->‪getWorkspace(),
187  $caller->‪getTable(),
188  $caller->‪getId(),
189  'uid,t3ver_state'
190  );
191  // Set version uid to caller, most likely it's a delete placeholder
192  // for a child record that is not recognized in the reference index
193  if (!empty($versionRecord['uid'])) {
194  $caller->‪setId($versionRecord['uid']);
195  } else {
196  // If no version could be determined, mark record as invalid
197  // (thus, it will be removed from the command map)
198  $caller->‪setInvalid(true);
199  }
200  } else {
201  // In case of an unexpected record state, mark the record as invalid
202  $caller->‪setInvalid(true);
203  }
204  }
205  }
206 }
‪TYPO3\CMS\Core\DataHandling\DataHandler
Definition: DataHandler.php:94
‪TYPO3\CMS\Workspaces\Dependency\ElementEntity\RESPONSE_Skip
‪const RESPONSE_Skip
Definition: ElementEntity.php:36
‪TYPO3\CMS\Workspaces\Dependency\ElementEntityProcessor\createClearDependentElementChildReferenceCallback
‪string null createClearDependentElementChildReferenceCallback(array $callerArguments, array $targetArgument, ElementEntity $caller, string $eventName)
Definition: ElementEntityProcessor.php:114
‪TYPO3\CMS\Core\Versioning\VersionState
‪VersionState
Definition: VersionState.php:22
‪TYPO3\CMS\Workspaces\Dependency\ElementEntity
Definition: ElementEntity.php:30
‪TYPO3\CMS\Workspaces\Dependency\ElementEntityProcessor\transformDependentElementsToUseLiveId
‪transformDependentElementsToUseLiveId(array $elements)
Definition: ElementEntityProcessor.php:64
‪TYPO3\CMS\Workspaces\Dependency\ElementEntityProcessor\createNewDependentElementChildReferenceCallback
‪string null createNewDependentElementChildReferenceCallback(array $callerArguments, array $targetArgument, ElementEntity $caller, string $eventName)
Definition: ElementEntityProcessor.php:79
‪TYPO3\CMS\Workspaces\Dependency\ElementEntity\setDataValue
‪setDataValue(string $key, mixed $value)
Definition: ElementEntity.php:116
‪TYPO3\CMS\Workspaces\Dependency\ElementEntity\getIdentifier
‪static getIdentifier(string $table, int $id)
Definition: ElementEntity.php:322
‪TYPO3\CMS\Workspaces\Dependency
Definition: DependencyEntityFactory.php:18
‪TYPO3\CMS\Workspaces\Dependency\ElementEntity\setInvalid
‪setInvalid(bool $invalid)
Definition: ElementEntity.php:59
‪TYPO3\CMS\Workspaces\Dependency\ElementEntityProcessor\getDataHandler
‪getDataHandler()
Definition: ElementEntityProcessor.php:51
‪TYPO3\CMS\Webhooks\Message\$record
‪identifier readonly int readonly array $record
Definition: PageModificationMessage.php:36
‪TYPO3\CMS\Workspaces\Dependency\ElementEntityProcessor\createNewDependentElementCallback
‪createNewDependentElementCallback(array $callerArguments, array $targetArgument, ElementEntity $caller, string $eventName)
Definition: ElementEntityProcessor.php:147
‪TYPO3\CMS\Workspaces\Dependency\ElementEntityProcessor\createNewDependentElementParentReferenceCallback
‪string null createNewDependentElementParentReferenceCallback(array $callerArguments, array $targetArgument, ElementEntity $caller, string $eventName)
Definition: ElementEntityProcessor.php:98
‪TYPO3\CMS\Workspaces\Dependency\ElementEntityProcessor
Definition: ElementEntityProcessor.php:31
‪TYPO3\CMS\Workspaces\Dependency\ElementEntityProcessor\$workspace
‪int $workspace
Definition: ElementEntityProcessor.php:32
‪TYPO3\CMS\Workspaces\Dependency\ElementEntity\setId
‪setId(int $id)
Definition: ElementEntity.php:88
‪TYPO3\CMS\Workspaces\Dependency\ElementEntityProcessor\setWorkspace
‪setWorkspace(int $workspace)
Definition: ElementEntityProcessor.php:38
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Workspaces\Dependency\ElementEntityProcessor\$dataHandler
‪DataHandler $dataHandler
Definition: ElementEntityProcessor.php:33
‪TYPO3\CMS\Workspaces\Dependency\ElementEntityProcessor\createClearDependentElementParentReferenceCallback
‪string null createClearDependentElementParentReferenceCallback(array $callerArguments, array $targetArgument, ElementEntity $caller, string $eventName)
Definition: ElementEntityProcessor.php:132
‪TYPO3\CMS\Workspaces\Dependency\ElementEntityProcessor\getWorkspace
‪getWorkspace()
Definition: ElementEntityProcessor.php:46
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:52
‪TYPO3\CMS\Workspaces\Dependency\ElementEntity\getRecord
‪getRecord()
Definition: ElementEntity.php:330
‪TYPO3\CMS\Workspaces\Dependency\ElementEntity\isInvalid
‪isInvalid()
Definition: ElementEntity.php:64
‪TYPO3\CMS\Workspaces\Dependency\ElementEntity\getTable
‪getTable()
Definition: ElementEntity.php:72
‪TYPO3\CMS\Workspaces\Dependency\ElementEntity\getId
‪getId()
Definition: ElementEntity.php:80
‪TYPO3\CMS\Workspaces\Dependency\ElementEntity\hasDataValue
‪hasDataValue(string $key)
Definition: ElementEntity.php:124