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