[TASK] Re-work/simplify copyright header in PHP files - Part 2
[Packages/TYPO3.CMS.git] / typo3 / sysext / version / Classes / Dependency / ElementEntityProcessor.php
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
17 use TYPO3\CMS\Core\Utility\GeneralUtility;
18 use TYPO3\CMS\Backend\Utility\BackendUtility;
19 use TYPO3\CMS\Core\Versioning\VersionState;
20
21 /**
22 * Processor having generic callback methods for element entities
23 */
24 class ElementEntityProcessor {
25
26 /**
27 * @var int
28 */
29 protected $workspace;
30
31 /**
32 * @var \TYPO3\CMS\Core\DataHandling\DataHandler
33 */
34 protected $dataHandler;
35
36 /**
37 * Sets the current workspace.
38 *
39 * @param int $workspace
40 */
41 public function setWorkspace($workspace) {
42 $this->workspace = (int)$workspace;
43 }
44
45 /**
46 * Gets the current workspace.
47 *
48 * @return int
49 */
50 public function getWorkspace() {
51 return $this->workspace;
52 }
53
54 /**
55 * @return \TYPO3\CMS\Core\DataHandling\DataHandler
56 */
57 public function getDataHandler() {
58 if (!isset($this->dataHandler)) {
59 $this->dataHandler = GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\DataHandling\\DataHandler');
60 }
61 return $this->dataHandler;
62 }
63
64 /**
65 * Transforms dependent elements to use the liveId as array key.
66 *
67 * @param array|ElementEntity[] $elements
68 * @return array
69 */
70 public function transformDependentElementsToUseLiveId(array $elements) {
71 $transformedElements = array();
72 /** @var $element ElementEntity */
73 foreach ($elements as $element) {
74 $elementName = ElementEntity::getIdentifier($element->getTable(), $element->getDataValue('liveId'));
75 $transformedElements[$elementName] = $element;
76 }
77 return $transformedElements;
78 }
79
80 /**
81 * Callback to determine whether a new child reference shall be considered in the dependency resolver utility.
82 *
83 * @param array $callerArguments
84 * @param array $targetArgument
85 * @param ElementEntity $caller
86 * @param string $eventName
87 * @return NULL|string Skip response (if required)
88 */
89 public function createNewDependentElementChildReferenceCallback(array $callerArguments, array $targetArgument, ElementEntity $caller, $eventName) {
90 $fieldConfiguration = BackendUtility::getTcaFieldConfiguration($caller->getTable(), $callerArguments['field']);
91 if (!$fieldConfiguration || !GeneralUtility::inList('field,list', $this->getDataHandler()->getInlineFieldType($fieldConfiguration))) {
92 return ElementEntity::RESPONSE_Skip;
93 }
94 return NULL;
95 }
96
97 /**
98 * Callback to determine whether a new parent reference shall be considered in the dependency resolver utility.
99 *
100 * @param array $callerArguments
101 * @param array $targetArgument
102 * @param \TYPO3\CMS\Version\Dependency\ElementEntity $caller
103 * @param string $eventName
104 * @return NULL|string Skip response (if required)
105 */
106 public function createNewDependentElementParentReferenceCallback(array $callerArguments, array $targetArgument, ElementEntity $caller, $eventName) {
107 $fieldConfiguration = BackendUtility::getTcaFieldConfiguration($callerArguments['table'], $callerArguments['field']);
108 if (!$fieldConfiguration || !GeneralUtility::inList('field,list', $this->getDataHandler()->getInlineFieldType($fieldConfiguration))) {
109 return ElementEntity::RESPONSE_Skip;
110 }
111 return NULL;
112 }
113
114 /**
115 * Callback to determine whether a new child reference shall be considered in the dependency resolver utility.
116 * Only elements that are a delete placeholder are considered.
117 *
118 * @param array $callerArguments
119 * @param array $targetArgument
120 * @param ElementEntity $caller
121 * @param string $eventName
122 * @return NULL|string Skip response (if required)
123 */
124 public function createClearDependentElementChildReferenceCallback(array $callerArguments, array $targetArgument, ElementEntity $caller, $eventName) {
125 $response = $this->createNewDependentElementChildReferenceCallback($callerArguments, $targetArgument, $caller, $eventName);
126 if (empty($response)) {
127 $record = BackendUtility::getRecord($callerArguments['table'], $callerArguments['id']);
128 if (!VersionState::cast($record['t3ver_state'])->equals(VersionState::DELETE_PLACEHOLDER)) {
129 $response = ElementEntity::RESPONSE_Skip;
130 }
131 }
132 return $response;
133 }
134
135 /**
136 * Callback to determine whether a new parent reference shall be considered in the dependency resolver utility.
137 * Only elements that are a delete placeholder are considered.
138 *
139 * @param array $callerArguments
140 * @param array $targetArgument
141 * @param ElementEntity $caller
142 * @param string $eventName
143 * @return NULL|string Skip response (if required)
144 */
145 public function createClearDependentElementParentReferenceCallback(array $callerArguments, array $targetArgument, ElementEntity $caller, $eventName) {
146 $response = $this->createNewDependentElementParentReferenceCallback($callerArguments, $targetArgument, $caller, $eventName);
147 if (empty($response)) {
148 $record = BackendUtility::getRecord($callerArguments['table'], $callerArguments['id']);
149 if (!VersionState::cast($record['t3ver_state'])->equals(VersionState::DELETE_PLACEHOLDER)) {
150 $response = ElementEntity::RESPONSE_Skip;
151 }
152 }
153 return $response;
154 }
155
156 /**
157 * Callback to add additional data to new elements created in the dependency resolver utility.
158 *
159 * @throws \RuntimeException
160 * @param ElementEntity $caller
161 * @param array $callerArguments
162 * @param array $targetArgument
163 * @param string $eventName
164 * @return void
165 */
166 public function createNewDependentElementCallback(array $callerArguments, array $targetArgument, ElementEntity $caller, $eventName) {
167 $versionRecord = $caller->getRecord();
168 // If version record does not exist, it probably has been deleted (cleared from workspace), this means,
169 // that the reference index still has an old reference pointer, which is "fine" for deleted parents
170 if (empty($versionRecord)) {
171 throw new \RuntimeException(
172 'Element "' . $caller::getIdentifier($caller->getTable(), $caller->getId()) . '" does not exist',
173 1393960943
174 );
175 }
176 // If version is on live workspace, but the pid is negative, mark the record as invalid.
177 // This happens if a change has been discarded (clearWSID) - it will be removed from the command map.
178 if ((int)$versionRecord['t3ver_wsid'] === 0 && (int)$versionRecord['pid'] === -1) {
179 $caller->setDataValue('liveId', $caller->getId());
180 $caller->setInvalid(TRUE);
181 return;
182 }
183 if ($caller->hasDataValue('liveId') === FALSE) {
184 // Set the original uid from the version record
185 if (!empty($versionRecord['t3ver_oid']) && (int)$versionRecord['pid'] === -1 && (int)$versionRecord['t3ver_wsid'] === $this->getWorkspace()) {
186 $caller->setDataValue('liveId', $versionRecord['t3ver_oid']);
187 // The current version record is actually a live record or an accordant placeholder for live
188 } elseif ((int)$versionRecord['t3ver_wsid'] === 0 || (int)$versionRecord['pid'] !== -1) {
189 $caller->setDataValue('liveId', $caller->getId());
190 $versionRecord = BackendUtility::getWorkspaceVersionOfRecord(
191 $this->getWorkspace(),
192 $caller->getTable(),
193 $caller->getId(),
194 'uid,t3ver_state'
195 );
196 // Set version uid to caller, most likely it's a delete placeholder
197 // for a child record that is not recognized in the reference index
198 if (!empty($versionRecord['uid'])) {
199 $caller->setId($versionRecord['uid']);
200 // If no version could be determined, mark record as invalid
201 // (thus, it will be removed from the command map)
202 } else {
203 $caller->setInvalid(TRUE);
204 }
205 // In case of an unexpected record state, mark the record as invalid
206 } else {
207 $caller->setInvalid(TRUE);
208 }
209 }
210 }
211
212 }