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