[BUGFIX] AddQueryStringMethod overwrites parameters
[Packages/TYPO3.CMS.git] / typo3 / sysext / extbase / Classes / Mvc / Web / Routing / UriBuilder.php
1 <?php
2 namespace TYPO3\CMS\Extbase\Mvc\Web\Routing;
3
4 /* *
5 * This script is part of the TYPO3 project - inspiring people to share! *
6 * *
7 * TYPO3 is free software; you can redistribute it and/or modify it under *
8 * the terms of the GNU General Public License version 2 as published by *
9 * the Free Software Foundation. *
10 * *
11 * This script is distributed in the hope that it will be useful, but *
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- *
13 * TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General *
14 * Public License for more details. *
15 * */
16 use TYPO3\CMS\Backend\Utility\BackendUtility;
17
18 /**
19 * An URI Builder
20 *
21 * @api
22 */
23 class UriBuilder {
24
25 /**
26 * @var \TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface
27 * @inject
28 */
29 protected $configurationManager;
30
31 /**
32 * @var \TYPO3\CMS\Extbase\Service\ExtensionService
33 * @inject
34 */
35 protected $extensionService;
36
37 /**
38 * An instance of \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer
39 *
40 * @var \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer
41 */
42 protected $contentObject;
43
44 /**
45 * @var \TYPO3\CMS\Extbase\Mvc\Web\Request
46 */
47 protected $request;
48
49 /**
50 * @var array
51 */
52 protected $arguments = array();
53
54 /**
55 * Arguments which have been used for building the last URI
56 *
57 * @var array
58 */
59 protected $lastArguments = array();
60
61 /**
62 * @var string
63 */
64 protected $section = '';
65
66 /**
67 * @var boolean
68 */
69 protected $createAbsoluteUri = FALSE;
70
71 /**
72 * @var string
73 */
74 protected $absoluteUriScheme = NULL;
75
76 /**
77 * @var boolean
78 */
79 protected $addQueryString = FALSE;
80
81 /**
82 * @var string
83 */
84 protected $addQueryStringMethod = NULL;
85
86 /**
87 * @var array
88 */
89 protected $argumentsToBeExcludedFromQueryString = array();
90
91 /**
92 * @var boolean
93 */
94 protected $linkAccessRestrictedPages = FALSE;
95
96 /**
97 * @var integer
98 */
99 protected $targetPageUid = NULL;
100
101 /**
102 * @var integer
103 */
104 protected $targetPageType = 0;
105
106 /**
107 * @var boolean
108 */
109 protected $noCache = FALSE;
110
111 /**
112 * @var boolean
113 */
114 protected $useCacheHash = TRUE;
115
116 /**
117 * @var string
118 */
119 protected $format = '';
120
121 /**
122 * @var string
123 */
124 protected $argumentPrefix = NULL;
125
126 /**
127 * @var \TYPO3\CMS\Extbase\Service\EnvironmentService
128 * @inject
129 */
130 protected $environmentService;
131
132 /**
133 * Life-cycle method that is called by the DI container as soon as this object is completely built
134 *
135 * @return void
136 */
137 public function initializeObject() {
138 $this->contentObject = $this->configurationManager->getContentObject();
139 }
140
141 /**
142 * Sets the current request
143 *
144 * @param \TYPO3\CMS\Extbase\Mvc\Request $request
145 * @return \TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder the current UriBuilder to allow method chaining
146 */
147 public function setRequest(\TYPO3\CMS\Extbase\Mvc\Request $request) {
148 $this->request = $request;
149 return $this;
150 }
151
152 /**
153 * @return \TYPO3\CMS\Extbase\Mvc\Web\Request
154 */
155 public function getRequest() {
156 return $this->request;
157 }
158
159 /**
160 * Additional query parameters.
161 * If you want to "prefix" arguments, you can pass in multidimensional arrays:
162 * array('prefix1' => array('foo' => 'bar')) gets "&prefix1[foo]=bar"
163 *
164 * @param array $arguments
165 * @return \TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder the current UriBuilder to allow method chaining
166 * @api
167 */
168 public function setArguments(array $arguments) {
169 $this->arguments = $arguments;
170 return $this;
171 }
172
173 /**
174 * @return array
175 * @api
176 */
177 public function getArguments() {
178 return $this->arguments;
179 }
180
181 /**
182 * If specified, adds a given HTML anchor to the URI (#...)
183 *
184 * @param string $section
185 * @return \TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder the current UriBuilder to allow method chaining
186 * @api
187 */
188 public function setSection($section) {
189 $this->section = $section;
190 return $this;
191 }
192
193 /**
194 * @return string
195 * @api
196 */
197 public function getSection() {
198 return $this->section;
199 }
200
201 /**
202 * Specifies the format of the target (e.g. "html" or "xml")
203 *
204 * @param string $format
205 * @return \TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder the current UriBuilder to allow method chaining
206 * @api
207 */
208 public function setFormat($format) {
209 $this->format = $format;
210 return $this;
211 }
212
213 /**
214 * @return string
215 * @api
216 */
217 public function getFormat() {
218 return $this->format;
219 }
220
221 /**
222 * If set, the URI is prepended with the current base URI. Defaults to FALSE.
223 *
224 * @param boolean $createAbsoluteUri
225 * @return \TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder the current UriBuilder to allow method chaining
226 * @api
227 */
228 public function setCreateAbsoluteUri($createAbsoluteUri) {
229 $this->createAbsoluteUri = $createAbsoluteUri;
230 return $this;
231 }
232
233 /**
234 * @return boolean
235 * @api
236 */
237 public function getCreateAbsoluteUri() {
238 return $this->createAbsoluteUri;
239 }
240
241 /**
242 * @return string
243 */
244 public function getAbsoluteUriScheme() {
245 return $this->absoluteUriScheme;
246 }
247
248 /**
249 * Sets the scheme that should be used for absolute URIs in FE mode
250 *
251 * @param string $absoluteUriScheme the scheme to be used for absolute URIs
252 * @return \TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder the current UriBuilder to allow method chaining
253 */
254 public function setAbsoluteUriScheme($absoluteUriScheme) {
255 $this->absoluteUriScheme = $absoluteUriScheme;
256 return $this;
257 }
258
259 /**
260 * If set, the current query parameters will be merged with $this->arguments. Defaults to FALSE.
261 *
262 * @param boolean $addQueryString
263 * @return \TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder the current UriBuilder to allow method chaining
264 * @api
265 * @see TSref/typolink.addQueryString
266 */
267 public function setAddQueryString($addQueryString) {
268 $this->addQueryString = (boolean) $addQueryString;
269 return $this;
270 }
271
272 /**
273 * @return boolean
274 * @api
275 */
276 public function getAddQueryString() {
277 return $this->addQueryString;
278 }
279
280 /**
281 * Sets the method to get the addQueryString parameters. Defaults undefined
282 * which results in using QUERY_STRING.
283 *
284 * @param string $addQueryStringMethod
285 * @return \TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder the current UriBuilder to allow method chaining
286 * @api
287 * @see TSref/typolink.addQueryString.method
288 */
289 public function setAddQueryStringMethod($addQueryStringMethod) {
290 $this->addQueryStringMethod = $addQueryStringMethod;
291 return $this;
292 }
293
294 /**
295 * @return string
296 * @api
297 */
298 public function getAddQueryStringMethod() {
299 return (string)$this->addQueryStringMethod;
300 }
301
302 /**
303 * A list of arguments to be excluded from the query parameters
304 * Only active if addQueryString is set
305 *
306 * @param array $argumentsToBeExcludedFromQueryString
307 * @return \TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder the current UriBuilder to allow method chaining
308 * @api
309 * @see TSref/typolink.addQueryString.exclude
310 * @see setAddQueryString()
311 */
312 public function setArgumentsToBeExcludedFromQueryString(array $argumentsToBeExcludedFromQueryString) {
313 $this->argumentsToBeExcludedFromQueryString = $argumentsToBeExcludedFromQueryString;
314 return $this;
315 }
316
317 /**
318 * @return array
319 * @api
320 */
321 public function getArgumentsToBeExcludedFromQueryString() {
322 return $this->argumentsToBeExcludedFromQueryString;
323 }
324
325 /**
326 * Specifies the prefix to be used for all arguments.
327 *
328 * @param string $argumentPrefix
329 * @return \TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder the current UriBuilder to allow method chaining
330 */
331 public function setArgumentPrefix($argumentPrefix) {
332 $this->argumentPrefix = (string) $argumentPrefix;
333 return $this;
334 }
335
336 /**
337 * @return string
338 */
339 public function getArgumentPrefix() {
340 return $this->argumentPrefix;
341 }
342
343 /**
344 * If set, URIs for pages without access permissions will be created
345 *
346 * @param boolean $linkAccessRestrictedPages
347 * @return \TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder the current UriBuilder to allow method chaining
348 * @api
349 */
350 public function setLinkAccessRestrictedPages($linkAccessRestrictedPages) {
351 $this->linkAccessRestrictedPages = (boolean) $linkAccessRestrictedPages;
352 return $this;
353 }
354
355 /**
356 * @return boolean
357 * @api
358 */
359 public function getLinkAccessRestrictedPages() {
360 return $this->linkAccessRestrictedPages;
361 }
362
363 /**
364 * Uid of the target page
365 *
366 * @param integer $targetPageUid
367 * @return \TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder the current UriBuilder to allow method chaining
368 * @api
369 */
370 public function setTargetPageUid($targetPageUid) {
371 $this->targetPageUid = $targetPageUid;
372 return $this;
373 }
374
375 /**
376 * returns $this->targetPageUid.
377 *
378 * @return integer
379 * @api
380 */
381 public function getTargetPageUid() {
382 return $this->targetPageUid;
383 }
384
385 /**
386 * Sets the page type of the target URI. Defaults to 0
387 *
388 * @param integer $targetPageType
389 * @return \TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder the current UriBuilder to allow method chaining
390 * @api
391 */
392 public function setTargetPageType($targetPageType) {
393 $this->targetPageType = (int)$targetPageType;
394 return $this;
395 }
396
397 /**
398 * @return integer
399 */
400 public function getTargetPageType() {
401 return $this->targetPageType;
402 }
403
404 /**
405 * by default FALSE; if TRUE, &no_cache=1 will be appended to the URI
406 * This overrules the useCacheHash setting
407 *
408 * @param boolean $noCache
409 * @return \TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder the current UriBuilder to allow method chaining
410 * @api
411 */
412 public function setNoCache($noCache) {
413 $this->noCache = (boolean) $noCache;
414 return $this;
415 }
416
417 /**
418 * @return boolean
419 * @api
420 */
421 public function getNoCache() {
422 return $this->noCache;
423 }
424
425 /**
426 * by default TRUE; if FALSE, no cHash parameter will be appended to the URI
427 * If noCache is set, this setting will be ignored.
428 *
429 * @param boolean $useCacheHash
430 * @return \TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder the current UriBuilder to allow method chaining
431 * @api
432 */
433 public function setUseCacheHash($useCacheHash) {
434 $this->useCacheHash = (boolean) $useCacheHash;
435 return $this;
436 }
437
438 /**
439 * @return boolean
440 * @api
441 */
442 public function getUseCacheHash() {
443 return $this->useCacheHash;
444 }
445
446 /**
447 * Returns the arguments being used for the last URI being built.
448 * This is only set after build() / uriFor() has been called.
449 *
450 * @return array The last arguments
451 */
452 public function getLastArguments() {
453 return $this->lastArguments;
454 }
455
456 /**
457 * Resets all UriBuilder options to their default value
458 *
459 * @return \TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder the current UriBuilder to allow method chaining
460 * @api
461 */
462 public function reset() {
463 $this->arguments = array();
464 $this->section = '';
465 $this->format = '';
466 $this->createAbsoluteUri = FALSE;
467 $this->addQueryString = FALSE;
468 $this->addQueryStringMethod = NULL;
469 $this->argumentsToBeExcludedFromQueryString = array();
470 $this->linkAccessRestrictedPages = FALSE;
471 $this->targetPageUid = NULL;
472 $this->targetPageType = 0;
473 $this->noCache = FALSE;
474 $this->useCacheHash = TRUE;
475 $this->argumentPrefix = NULL;
476 return $this;
477 }
478
479 /**
480 * Creates an URI used for linking to an Extbase action.
481 * Works in Frontend and Backend mode of TYPO3.
482 *
483 * @param string $actionName Name of the action to be called
484 * @param array $controllerArguments Additional query parameters. Will be "namespaced" and merged with $this->arguments.
485 * @param string $controllerName Name of the target controller. If not set, current ControllerName is used.
486 * @param string $extensionName Name of the target extension, without underscores. If not set, current ExtensionName is used.
487 * @param string $pluginName Name of the target plugin. If not set, current PluginName is used.
488 * @return string the rendered URI
489 * @api
490 * @see build()
491 */
492 public function uriFor($actionName = NULL, $controllerArguments = array(), $controllerName = NULL, $extensionName = NULL, $pluginName = NULL) {
493 if ($actionName !== NULL) {
494 $controllerArguments['action'] = $actionName;
495 }
496 if ($controllerName !== NULL) {
497 $controllerArguments['controller'] = $controllerName;
498 } else {
499 $controllerArguments['controller'] = $this->request->getControllerName();
500 }
501 if ($extensionName === NULL) {
502 $extensionName = $this->request->getControllerExtensionName();
503 }
504 if ($pluginName === NULL && $this->environmentService->isEnvironmentInFrontendMode()) {
505 $pluginName = $this->extensionService->getPluginNameByAction($extensionName, $controllerArguments['controller'], $controllerArguments['action']);
506 }
507 if ($pluginName === NULL) {
508 $pluginName = $this->request->getPluginName();
509 }
510 if ($this->environmentService->isEnvironmentInFrontendMode() && $this->configurationManager->isFeatureEnabled('skipDefaultArguments')) {
511 $controllerArguments = $this->removeDefaultControllerAndAction($controllerArguments, $extensionName, $pluginName);
512 }
513 if ($this->targetPageUid === NULL && $this->environmentService->isEnvironmentInFrontendMode()) {
514 $this->targetPageUid = $this->extensionService->getTargetPidByPlugin($extensionName, $pluginName);
515 }
516 if ($this->format !== '') {
517 $controllerArguments['format'] = $this->format;
518 }
519 if ($this->argumentPrefix !== NULL) {
520 $prefixedControllerArguments = array($this->argumentPrefix => $controllerArguments);
521 } else {
522 $pluginNamespace = $this->extensionService->getPluginNamespace($extensionName, $pluginName);
523 $prefixedControllerArguments = array($pluginNamespace => $controllerArguments);
524 }
525 \TYPO3\CMS\Core\Utility\ArrayUtility::mergeRecursiveWithOverrule($this->arguments, $prefixedControllerArguments);
526 return $this->build();
527 }
528
529 /**
530 * This removes controller and/or action arguments from given controllerArguments
531 * if they are equal to the default controller/action of the target plugin.
532 * Note: This is only active in FE mode and if feature "skipDefaultArguments" is enabled
533 *
534 * @see \TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface::isFeatureEnabled()
535 * @param array $controllerArguments the current controller arguments to be modified
536 * @param string $extensionName target extension name
537 * @param string $pluginName target plugin name
538 * @return array
539 */
540 protected function removeDefaultControllerAndAction(array $controllerArguments, $extensionName, $pluginName) {
541 $defaultControllerName = $this->extensionService->getDefaultControllerNameByPlugin($extensionName, $pluginName);
542 if (isset($controllerArguments['action'])) {
543 $defaultActionName = $this->extensionService->getDefaultActionNameByPluginAndController($extensionName, $pluginName, $controllerArguments['controller']);
544 if ($controllerArguments['action'] === $defaultActionName) {
545 unset($controllerArguments['action']);
546 }
547 }
548 if ($controllerArguments['controller'] === $defaultControllerName) {
549 unset($controllerArguments['controller']);
550 }
551 return $controllerArguments;
552 }
553
554 /**
555 * Builds the URI
556 * Depending on the current context this calls buildBackendUri() or buildFrontendUri()
557 *
558 * @return string The URI
559 * @api
560 * @see buildBackendUri()
561 * @see buildFrontendUri()
562 */
563 public function build() {
564 if ($this->environmentService->isEnvironmentInBackendMode()) {
565 return $this->buildBackendUri();
566 } else {
567 return $this->buildFrontendUri();
568 }
569 }
570
571 /**
572 * Builds the URI, backend flavour
573 * The resulting URI is relative and starts with "mod.php".
574 * The settings pageUid, pageType, noCache, useCacheHash & linkAccessRestrictedPages
575 * will be ignored in the backend.
576 *
577 * @return string The URI
578 */
579 public function buildBackendUri() {
580 if ($this->addQueryString === TRUE) {
581 if ($this->addQueryStringMethod) {
582 switch ($this->addQueryStringMethod) {
583 case 'GET':
584 $arguments = \TYPO3\CMS\Core\Utility\GeneralUtility::_GET();
585 break;
586 case 'POST':
587 $arguments = \TYPO3\CMS\Core\Utility\GeneralUtility::_POST();
588 break;
589 case 'GET,POST':
590 $arguments = array_replace_recursive(\TYPO3\CMS\Core\Utility\GeneralUtility::_GET(), \TYPO3\CMS\Core\Utility\GeneralUtility::_POST());
591 break;
592 case 'POST,GET':
593 $arguments = array_replace_recursive(\TYPO3\CMS\Core\Utility\GeneralUtility::_POST(), \TYPO3\CMS\Core\Utility\GeneralUtility::_GET());
594 break;
595 default:
596 $arguments = \TYPO3\CMS\Core\Utility\GeneralUtility::explodeUrl2Array(\TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('QUERY_STRING'), TRUE);
597 }
598 } else {
599 $arguments = \TYPO3\CMS\Core\Utility\GeneralUtility::_GET();
600 }
601 foreach ($this->argumentsToBeExcludedFromQueryString as $argumentToBeExcluded) {
602 $argumentToBeExcluded = \TYPO3\CMS\Core\Utility\GeneralUtility::explodeUrl2Array($argumentToBeExcluded, TRUE);
603 $arguments = \TYPO3\CMS\Core\Utility\GeneralUtility::arrayDiffAssocRecursive($arguments, $argumentToBeExcluded);
604 }
605 } else {
606 $arguments = array(
607 'M' => \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('M'),
608 'id' => \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('id')
609 );
610 }
611 \TYPO3\CMS\Core\Utility\ArrayUtility::mergeRecursiveWithOverrule($arguments, $this->arguments);
612 $arguments = $this->convertDomainObjectsToIdentityArrays($arguments);
613 $this->lastArguments = $arguments;
614 $moduleName = $arguments['M'];
615 unset($arguments['M'], $arguments['moduleToken']);
616 $uri = BackendUtility::getModuleUrl($moduleName, $arguments, '');
617 if ($this->section !== '') {
618 $uri .= '#' . $this->section;
619 }
620 if ($this->createAbsoluteUri === TRUE) {
621 $uri = $this->request->getBaseUri() . $uri;
622 }
623 return $uri;
624 }
625
626 /**
627 * Builds the URI, frontend flavour
628 *
629 * @return string The URI
630 * @see buildTypolinkConfiguration()
631 */
632 public function buildFrontendUri() {
633 $typolinkConfiguration = $this->buildTypolinkConfiguration();
634 if ($this->createAbsoluteUri === TRUE) {
635 $typolinkConfiguration['forceAbsoluteUrl'] = TRUE;
636 if ($this->absoluteUriScheme !== NULL) {
637 $typolinkConfiguration['forceAbsoluteUrl.']['scheme'] = $this->absoluteUriScheme;
638 }
639 }
640 $uri = $this->contentObject->typoLink_URL($typolinkConfiguration);
641 return $uri;
642 }
643
644 /**
645 * Builds a TypoLink configuration array from the current settings
646 *
647 * @return array typolink configuration array
648 * @see TSref/typolink
649 */
650 protected function buildTypolinkConfiguration() {
651 $typolinkConfiguration = array();
652 $typolinkConfiguration['parameter'] = $this->targetPageUid !== NULL ? $this->targetPageUid : $GLOBALS['TSFE']->id;
653 if ($this->targetPageType !== 0) {
654 $typolinkConfiguration['parameter'] .= ',' . $this->targetPageType;
655 } elseif ($this->format !== '') {
656 $targetPageType = $this->extensionService->getTargetPageTypeByFormat($this->request->getControllerExtensionKey(), $this->format);
657 $typolinkConfiguration['parameter'] .= ',' . $targetPageType;
658 }
659 if (count($this->arguments) > 0) {
660 $arguments = $this->convertDomainObjectsToIdentityArrays($this->arguments);
661 $this->lastArguments = $arguments;
662 $typolinkConfiguration['additionalParams'] = \TYPO3\CMS\Core\Utility\GeneralUtility::implodeArrayForUrl(NULL, $arguments);
663 }
664 if ($this->addQueryString === TRUE) {
665 $typolinkConfiguration['addQueryString'] = 1;
666 if (count($this->argumentsToBeExcludedFromQueryString) > 0) {
667 $typolinkConfiguration['addQueryString.'] = array(
668 'exclude' => implode(',', $this->argumentsToBeExcludedFromQueryString)
669 );
670 }
671 if ($this->addQueryStringMethod) {
672 $typolinkConfiguration['addQueryString.']['method'] = $this->addQueryStringMethod;
673 }
674 }
675 if ($this->noCache === TRUE) {
676 $typolinkConfiguration['no_cache'] = 1;
677 } elseif ($this->useCacheHash) {
678 $typolinkConfiguration['useCacheHash'] = 1;
679 }
680 if ($this->section !== '') {
681 $typolinkConfiguration['section'] = $this->section;
682 }
683 if ($this->linkAccessRestrictedPages === TRUE) {
684 $typolinkConfiguration['linkAccessRestrictedPages'] = 1;
685 }
686 return $typolinkConfiguration;
687 }
688
689 /**
690 * Recursively iterates through the specified arguments and turns instances of type \TYPO3\CMS\Extbase\DomainObject\AbstractEntity
691 * into an arrays containing the uid of the domain object.
692 *
693 * @param array $arguments The arguments to be iterated
694 * @throws \TYPO3\CMS\Extbase\Mvc\Exception\InvalidArgumentValueException
695 * @return array The modified arguments array
696 */
697 protected function convertDomainObjectsToIdentityArrays(array $arguments) {
698 foreach ($arguments as $argumentKey => $argumentValue) {
699 // if we have a LazyLoadingProxy here, make sure to get the real instance for further processing
700 if ($argumentValue instanceof \TYPO3\CMS\Extbase\Persistence\Generic\LazyLoadingProxy) {
701 $argumentValue = $argumentValue->_loadRealInstance();
702 // also update the value in the arguments array, because the lazyLoaded object could be
703 // hidden and thus the $argumentValue would be NULL.
704 $arguments[$argumentKey] = $argumentValue;
705 }
706 if ($argumentValue instanceof \TYPO3\CMS\Extbase\DomainObject\AbstractDomainObject) {
707 if ($argumentValue->getUid() !== NULL) {
708 $arguments[$argumentKey] = $argumentValue->getUid();
709 } elseif ($argumentValue instanceof \TYPO3\CMS\Extbase\DomainObject\AbstractValueObject) {
710 $arguments[$argumentKey] = $this->convertTransientObjectToArray($argumentValue);
711 } else {
712 throw new \TYPO3\CMS\Extbase\Mvc\Exception\InvalidArgumentValueException('Could not serialize Domain Object ' . get_class($argumentValue) . '. It is neither an Entity with identity properties set, nor a Value Object.', 1260881688);
713 }
714 } elseif (is_array($argumentValue)) {
715 $arguments[$argumentKey] = $this->convertDomainObjectsToIdentityArrays($argumentValue);
716 }
717 }
718 return $arguments;
719 }
720
721 /**
722 * Converts a given object recursively into an array.
723 *
724 * @param \TYPO3\CMS\Extbase\DomainObject\AbstractDomainObject $object
725 * @return array
726 * @todo Refactore this into convertDomainObjectsToIdentityArrays()
727 */
728 public function convertTransientObjectToArray(\TYPO3\CMS\Extbase\DomainObject\AbstractDomainObject $object) {
729 $result = array();
730 foreach ($object->_getProperties() as $propertyName => $propertyValue) {
731 if ($propertyValue instanceof \TYPO3\CMS\Extbase\DomainObject\AbstractDomainObject) {
732 if ($propertyValue->getUid() !== NULL) {
733 $result[$propertyName] = $propertyValue->getUid();
734 } else {
735 $result[$propertyName] = $this->convertTransientObjectToArray($propertyValue);
736 }
737 } elseif (is_array($propertyValue)) {
738 $result[$propertyName] = $this->convertDomainObjectsToIdentityArrays($propertyValue);
739 } else {
740 $result[$propertyName] = $propertyValue;
741 }
742 }
743 return $result;
744 }
745
746 }