2e016eb962e4d68d8238c8e3763f4aad550d4b74
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Tests / Functional / DataHandling / Framework / ActionService.php
1 <?php
2 namespace TYPO3\CMS\Core\Tests\Functional\DataHandling\Framework;
3
4 /***************************************************************
5 * Copyright notice
6 *
7 * (c) 2014 Oliver Hader <oliver.hader@typo3.org>
8 * All rights reserved
9 *
10 * This script is part of the TYPO3 project. The TYPO3 project is
11 * free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * The GNU General Public License can be found at
17 * http://www.gnu.org/copyleft/gpl.html.
18 *
19 * This script is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * This copyright notice MUST APPEAR in all copies of the script!
25 ***************************************************************/
26
27 use TYPO3\CMS\Core\DataHandling\DataHandler;
28
29 /**
30 * DataHandler Actions
31 */
32 class ActionService {
33
34 /**
35 * @var DataHandler
36 */
37 protected $dataHandler;
38
39 /**
40 * @return DataHandler
41 */
42 public function getDataHander() {
43 return $this->dataHandler;
44 }
45
46 /**
47 * @param string $tableName
48 * @param integer $pageId
49 * @param array $recordData
50 * @return array
51 */
52 public function createNewRecord($tableName, $pageId, array $recordData) {
53 return $this->createNewRecords($pageId, array($tableName => $recordData));
54 }
55
56 /**
57 * @param integer $pageId
58 * @param array $tableRecordData
59 * @return array
60 */
61 public function createNewRecords($pageId, array $tableRecordData) {
62 $dataMap = array();
63 $newTableIds = array();
64 $currentUid = NULL;
65 $previousTableName = NULL;
66 $previousUid = NULL;
67 foreach ($tableRecordData as $tableName => $recordData) {
68 $recordData = $this->resolvePreviousUid($recordData, $currentUid);
69 if (!isset($recordData['pid'])) {
70 $recordData['pid'] = $pageId;
71 }
72 $currentUid = uniqid('NEW');
73 $newTableIds[$tableName][] = $currentUid;
74 $dataMap[$tableName][$currentUid] = $recordData;
75 if ($previousTableName !== NULL && $previousUid !== NULL) {
76 $dataMap[$previousTableName][$previousUid] = $this->resolveNextUid(
77 $dataMap[$previousTableName][$previousUid],
78 $currentUid
79 );
80 }
81 $previousTableName = $tableName;
82 $previousUid = $currentUid;
83 }
84 $this->createDataHandler();
85 $this->dataHandler->start($dataMap, array());
86 $this->dataHandler->process_datamap();
87
88 foreach ($newTableIds as $tableName => &$ids) {
89 foreach ($ids as &$id) {
90 if (!empty($this->dataHandler->substNEWwithIDs[$id])) {
91 $id = $this->dataHandler->substNEWwithIDs[$id];
92 }
93 }
94 }
95
96 return $newTableIds;
97 }
98
99 /**
100 * @param string $tableName
101 * @param integer $uid
102 * @param array $recordData
103 * @param NULL|array $deleteTableRecordIds
104 */
105 public function modifyRecord($tableName, $uid, array $recordData, array $deleteTableRecordIds = NULL) {
106 $dataMap = array(
107 $tableName => array(
108 $uid => $recordData,
109 ),
110 );
111 $commandMap = array();
112 if (!empty($deleteTableRecordIds)) {
113 foreach ($deleteTableRecordIds as $tableName => $recordIds) {
114 foreach ($recordIds as $recordId) {
115 $commandMap[$tableName][$recordId]['delete'] = TRUE;
116 }
117 }
118 }
119 $this->createDataHandler();
120 $this->dataHandler->start($dataMap, $commandMap);
121 $this->dataHandler->process_datamap();
122 if (!empty($commandMap)) {
123 $this->dataHandler->process_cmdmap();
124 }
125 }
126
127 /**
128 * @param integer $pageId
129 * @param array $tableRecordData
130 */
131 public function modifyRecords($pageId, array $tableRecordData) {
132 $dataMap = array();
133 $currentUid = NULL;
134 $previousTableName = NULL;
135 $previousUid = NULL;
136 foreach ($tableRecordData as $tableName => $recordData) {
137 if (empty($recordData['uid'])) {
138 continue;
139 }
140 $recordData = $this->resolvePreviousUid($recordData, $currentUid);
141 $currentUid = $recordData['uid'];
142 if ($recordData['uid'] === '__NEW') {
143 $recordData['pid'] = $pageId;
144 $currentUid = uniqid('NEW');
145 }
146 unset($recordData['uid']);
147 $dataMap[$tableName][$currentUid] = $recordData;
148 if ($previousTableName !== NULL && $previousUid !== NULL) {
149 $dataMap[$previousTableName][$previousUid] = $this->resolveNextUid(
150 $dataMap[$previousTableName][$previousUid],
151 $currentUid
152 );
153 }
154 $previousTableName = $tableName;
155 $previousUid = $currentUid;
156 }
157 $this->createDataHandler();
158 $this->dataHandler->start($dataMap, array());
159 $this->dataHandler->process_datamap();
160 }
161
162 /**
163 * @param string $tableName
164 * @param integer $uid
165 * @return array
166 */
167 public function deleteRecord($tableName, $uid) {
168 return $this->deleteRecords(
169 array(
170 $tableName => array($uid),
171 )
172 );
173 }
174
175 /**
176 * @param array $tableRecordIds
177 * @return array
178 */
179 public function deleteRecords(array $tableRecordIds) {
180 $commandMap = array();
181 foreach ($tableRecordIds as $tableName => $ids) {
182 foreach ($ids as $uid) {
183 $commandMap[$tableName][$uid] = array(
184 'delete' => TRUE,
185 );
186 }
187 }
188 $this->createDataHandler();
189 $this->dataHandler->start(array(), $commandMap);
190 $this->dataHandler->process_cmdmap();
191 // Deleting workspace records is actually a copy(!)
192 return $this->dataHandler->copyMappingArray;
193 }
194
195 /**
196 * @param string $tableName
197 * @param integer $uid
198 */
199 public function clearWorkspaceRecord($tableName, $uid) {
200 $this->clearWorkspaceRecords(
201 array(
202 $tableName => array($uid),
203 )
204 );
205 }
206
207 /**
208 * @param array $tableRecordIds
209 */
210 public function clearWorkspaceRecords(array $tableRecordIds) {
211 $commandMap = array();
212 foreach ($tableRecordIds as $tableName => $ids) {
213 foreach ($ids as $uid) {
214 $commandMap[$tableName][$uid] = array(
215 'version' => array(
216 'action' => 'clearWSID',
217 )
218 );
219 }
220 }
221 $this->createDataHandler();
222 $this->dataHandler->start(array(), $commandMap);
223 $this->dataHandler->process_cmdmap();
224 }
225
226 /**
227 * @param string $tableName
228 * @param integer $uid
229 * @param integer $pageId
230 * @param NULL|array $recordData
231 * @return array
232 */
233 public function copyRecord($tableName, $uid, $pageId, array $recordData = NULL) {
234 $commandMap = array(
235 $tableName => array(
236 $uid => array(
237 'copy' => $pageId,
238 ),
239 ),
240 );
241 if ($recordData !== NULL) {
242 $commandMap[$tableName][$uid]['copy'] = array(
243 'action' => 'paste',
244 'target' => $pageId,
245 'update' => $recordData,
246 );
247 }
248 $this->createDataHandler();
249 $this->dataHandler->start(array(), $commandMap);
250 $this->dataHandler->process_cmdmap();
251 return $this->dataHandler->copyMappingArray;
252 }
253
254 /**
255 * @param string $tableName
256 * @param integer $uid
257 * @param integer $pageId
258 * @param NULL|array $recordData
259 */
260 public function moveRecord($tableName, $uid, $pageId, array $recordData = NULL) {
261 $commandMap = array(
262 $tableName => array(
263 $uid => array(
264 'move' => $pageId,
265 ),
266 ),
267 );
268 if ($recordData !== NULL) {
269 $commandMap[$tableName][$uid]['move'] = array(
270 'action' => 'paste',
271 'target' => $pageId,
272 'update' => $recordData,
273 );
274 }
275 $this->createDataHandler();
276 $this->dataHandler->start(array(), $commandMap);
277 $this->dataHandler->process_cmdmap();
278 }
279
280 /**
281 * @param string $tableName
282 * @param integer $uid
283 * @param integer $languageId
284 * @return array
285 */
286 public function localizeRecord($tableName, $uid, $languageId) {
287 $commandMap = array(
288 $tableName => array(
289 $uid => array(
290 'localize' => $languageId,
291 ),
292 ),
293 );
294 $this->createDataHandler();
295 $this->dataHandler->start(array(), $commandMap);
296 $this->dataHandler->process_cmdmap();
297 return $this->dataHandler->copyMappingArray;
298 }
299
300 /**
301 * @param string $tableName
302 * @param integer $uid
303 * @param string $fieldName
304 * @param array $referenceIds
305 */
306 public function modifyReferences($tableName, $uid, $fieldName, array $referenceIds) {
307 $dataMap = array(
308 $tableName => array(
309 $uid => array(
310 $fieldName => implode(',', $referenceIds),
311 ),
312 )
313 );
314 $this->createDataHandler();
315 $this->dataHandler->start($dataMap, array());
316 $this->dataHandler->process_datamap();
317 }
318
319 /**
320 * @param string $tableName
321 * @param int $liveUid
322 * @param bool $throwException
323 */
324 public function publishRecord($tableName, $liveUid, $throwException = TRUE) {
325 $this->publishRecords(array($tableName => array($liveUid)), $throwException);
326 }
327
328 /**
329 * @param array $tableLiveUids
330 * @param bool $throwException
331 * @throws \TYPO3\CMS\Core\Tests\Exception
332 */
333 public function publishRecords(array $tableLiveUids, $throwException = TRUE) {
334 $commandMap = array();
335 foreach ($tableLiveUids as $tableName => $liveUids) {
336 foreach ($liveUids as $liveUid) {
337 $versionedUid = $this->getVersionedId($tableName, $liveUid);
338 if (empty($versionedUid)) {
339 if ($throwException) {
340 throw new \TYPO3\CMS\Core\Tests\Exception('Versioned UID could not be determined');
341 } else {
342 continue;
343 }
344 }
345
346 $commandMap[$tableName][$liveUid] = array(
347 'version' => array(
348 'action' => 'swap',
349 'swapWith' => $versionedUid,
350 'notificationAlternativeRecipients' => array(),
351 ),
352 );
353 }
354 }
355 $this->createDataHandler();
356 $this->dataHandler->start(array(), $commandMap);
357 $this->dataHandler->process_cmdmap();
358 }
359
360 /**
361 * @param int $workspaceId
362 */
363 public function publishWorkspace($workspaceId) {
364 $commandMap = $this->getWorkspaceService()->getCmdArrayForPublishWS($workspaceId, FALSE);
365 $this->createDataHandler();
366 $this->dataHandler->start(array(), $commandMap);
367 $this->dataHandler->process_cmdmap();
368 }
369
370 /**
371 * @param int $workspaceId
372 */
373 public function swapWorkspace($workspaceId) {
374 $commandMap = $this->getWorkspaceService()->getCmdArrayForPublishWS($workspaceId, TRUE);
375 $this->createDataHandler();
376 $this->dataHandler->start(array(), $commandMap);
377 $this->dataHandler->process_cmdmap();
378 }
379
380 /**
381 * @param array $recordData
382 * @param NULL|string|int $previousUid
383 * @return array
384 */
385 protected function resolvePreviousUid(array $recordData, $previousUid) {
386 if ($previousUid === NULL) {
387 return $recordData;
388 }
389 foreach ($recordData as $fieldName => $fieldValue) {
390 if (strpos($fieldValue, '__previousUid') === FALSE) {
391 continue;
392 }
393 $recordData[$fieldName] = str_replace('__previousUid', $previousUid, $fieldValue);
394 }
395 return $recordData;
396 }
397
398 /**
399 * @param array $recordData
400 * @param NULL|string|int $nextUid
401 * @return array
402 */
403 protected function resolveNextUid(array $recordData, $nextUid) {
404 if ($nextUid === NULL) {
405 return $recordData;
406 }
407 foreach ($recordData as $fieldName => $fieldValue) {
408 if (strpos($fieldValue, '__nextUid') === FALSE) {
409 continue;
410 }
411 $recordData[$fieldName] = str_replace('__nextUid', $nextUid, $fieldValue);
412 }
413 return $recordData;
414 }
415
416 /**
417 * @param string $tableName
418 * @param int $liveUid
419 * @param bool $useDeleteClause
420 * @return NULL|int
421 */
422 protected function getVersionedId($tableName, $liveUid, $useDeleteClause = FALSE) {
423 $versionedId = NULL;
424 $liveUid = (int)$liveUid;
425 $workspaceId = (int)$this->getBackendUser()->workspace;
426 $row = $this->getDatabaseConnection()->exec_SELECTgetSingleRow(
427 'uid',
428 $tableName,
429 'pid=-1 AND t3ver_oid=' . $liveUid . ' AND t3ver_wsid=' . $workspaceId .
430 ($useDeleteClause ? \TYPO3\CMS\Backend\Utility\BackendUtility::deleteClause($tableName) : '')
431 );
432 if (!empty($row['uid'])) {
433 $versionedId = (int)$row['uid'];
434 }
435 return $versionedId;
436 }
437
438 /**
439 * @return \TYPO3\CMS\Core\DataHandling\DataHandler
440 */
441 protected function createDataHandler() {
442 $dataHandler = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(
443 'TYPO3\\CMS\\Core\\DataHandling\\DataHandler'
444 );
445 $this->dataHandler = $dataHandler;
446 return $dataHandler;
447 }
448
449 /**
450 * @return \TYPO3\CMS\Workspaces\Service\WorkspaceService
451 */
452 protected function getWorkspaceService() {
453 return \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(
454 'TYPO3\\CMS\\Workspaces\\Service\\WorkspaceService'
455 );
456 }
457
458 /**
459 * @return \TYPO3\CMS\Core\Authentication\BackendUserAuthentication
460 */
461 protected function getBackendUser() {
462 return $GLOBALS['BE_USER'];
463 }
464
465 /**
466 * @return \TYPO3\CMS\Core\Database\DatabaseConnection
467 */
468 protected function getDatabaseConnection() {
469 return $GLOBALS['TYPO3_DB'];
470 }
471
472 }