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