TYPO3  7.6
extbase/Classes/Mvc/Web/Routing/UriBuilder.php
Go to the documentation of this file.
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 
20 use TYPO3\CMS\Extbase\Mvc\Web\Request as WebRequest;
21 
28 {
33 
37  protected $extensionService;
38 
44  protected $contentObject;
45 
49  protected $request;
50 
54  protected $arguments = array();
55 
61  protected $lastArguments = array();
62 
66  protected $section = '';
67 
71  protected $createAbsoluteUri = false;
72 
76  protected $absoluteUriScheme = null;
77 
81  protected $addQueryString = false;
82 
86  protected $addQueryStringMethod = null;
87 
92 
96  protected $linkAccessRestrictedPages = false;
97 
101  protected $targetPageUid = null;
102 
106  protected $targetPageType = 0;
107 
111  protected $noCache = false;
112 
116  protected $useCacheHash = true;
117 
121  protected $format = '';
122 
126  protected $argumentPrefix = null;
127 
132 
136  public function injectConfigurationManager(\TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface $configurationManager)
137  {
138  $this->configurationManager = $configurationManager;
139  }
140 
144  public function injectExtensionService(\TYPO3\CMS\Extbase\Service\ExtensionService $extensionService)
145  {
146  $this->extensionService = $extensionService;
147  }
148 
152  public function injectEnvironmentService(\TYPO3\CMS\Extbase\Service\EnvironmentService $environmentService)
153  {
154  $this->environmentService = $environmentService;
155  }
156 
162  public function initializeObject()
163  {
164  $this->contentObject = $this->configurationManager->getContentObject();
165  }
166 
173  public function setRequest(Request $request)
174  {
175  $this->request = $request;
176  return $this;
177  }
178 
182  public function getRequest()
183  {
184  return $this->request;
185  }
186 
196  public function setArguments(array $arguments)
197  {
198  $this->arguments = $arguments;
199  return $this;
200  }
201 
206  public function getArguments()
207  {
208  return $this->arguments;
209  }
210 
218  public function setSection($section)
219  {
220  $this->section = $section;
221  return $this;
222  }
223 
228  public function getSection()
229  {
230  return $this->section;
231  }
232 
240  public function setFormat($format)
241  {
242  $this->format = $format;
243  return $this;
244  }
245 
250  public function getFormat()
251  {
252  return $this->format;
253  }
254 
263  {
264  $this->createAbsoluteUri = $createAbsoluteUri;
265  return $this;
266  }
267 
272  public function getCreateAbsoluteUri()
273  {
275  }
276 
280  public function getAbsoluteUriScheme()
281  {
283  }
284 
292  {
293  $this->absoluteUriScheme = $absoluteUriScheme;
294  return $this;
295  }
296 
306  {
307  $this->addQueryString = (bool)$addQueryString;
308  return $this;
309  }
310 
315  public function getAddQueryString()
316  {
317  return $this->addQueryString;
318  }
319 
330  {
331  $this->addQueryStringMethod = $addQueryStringMethod;
332  return $this;
333  }
334 
339  public function getAddQueryStringMethod()
340  {
341  return (string)$this->addQueryStringMethod;
342  }
343 
355  {
356  $this->argumentsToBeExcludedFromQueryString = $argumentsToBeExcludedFromQueryString;
357  return $this;
358  }
359 
365  {
367  }
368 
376  {
377  $this->argumentPrefix = (string)$argumentPrefix;
378  return $this;
379  }
380 
384  public function getArgumentPrefix()
385  {
386  return $this->argumentPrefix;
387  }
388 
397  {
398  $this->linkAccessRestrictedPages = (bool)$linkAccessRestrictedPages;
399  return $this;
400  }
401 
407  {
409  }
410 
419  {
420  $this->targetPageUid = $targetPageUid;
421  return $this;
422  }
423 
430  public function getTargetPageUid()
431  {
432  return $this->targetPageUid;
433  }
434 
443  {
444  $this->targetPageType = (int)$targetPageType;
445  return $this;
446  }
447 
451  public function getTargetPageType()
452  {
453  return $this->targetPageType;
454  }
455 
464  public function setNoCache($noCache)
465  {
466  $this->noCache = (bool)$noCache;
467  return $this;
468  }
469 
474  public function getNoCache()
475  {
476  return $this->noCache;
477  }
478 
488  {
489  $this->useCacheHash = (bool)$useCacheHash;
490  return $this;
491  }
492 
497  public function getUseCacheHash()
498  {
499  return $this->useCacheHash;
500  }
501 
508  public function getLastArguments()
509  {
510  return $this->lastArguments;
511  }
512 
519  public function reset()
520  {
521  $this->arguments = array();
522  $this->section = '';
523  $this->format = '';
524  $this->createAbsoluteUri = false;
525  $this->addQueryString = false;
526  $this->addQueryStringMethod = null;
527  $this->argumentsToBeExcludedFromQueryString = array();
528  $this->linkAccessRestrictedPages = false;
529  $this->targetPageUid = null;
530  $this->targetPageType = 0;
531  $this->noCache = false;
532  $this->useCacheHash = true;
533  $this->argumentPrefix = null;
534  return $this;
535  }
536 
550  public function uriFor($actionName = null, $controllerArguments = array(), $controllerName = null, $extensionName = null, $pluginName = null)
551  {
552  if ($actionName !== null) {
553  $controllerArguments['action'] = $actionName;
554  }
555  if ($controllerName !== null) {
556  $controllerArguments['controller'] = $controllerName;
557  } else {
558  $controllerArguments['controller'] = $this->request->getControllerName();
559  }
560  if ($extensionName === null) {
561  $extensionName = $this->request->getControllerExtensionName();
562  }
563  if ($pluginName === null && $this->environmentService->isEnvironmentInFrontendMode()) {
564  $pluginName = $this->extensionService->getPluginNameByAction($extensionName, $controllerArguments['controller'], $controllerArguments['action']);
565  }
566  if ($pluginName === null) {
567  $pluginName = $this->request->getPluginName();
568  }
569  if ($this->environmentService->isEnvironmentInFrontendMode() && $this->configurationManager->isFeatureEnabled('skipDefaultArguments')) {
570  $controllerArguments = $this->removeDefaultControllerAndAction($controllerArguments, $extensionName, $pluginName);
571  }
572  if ($this->targetPageUid === null && $this->environmentService->isEnvironmentInFrontendMode()) {
573  $this->targetPageUid = $this->extensionService->getTargetPidByPlugin($extensionName, $pluginName);
574  }
575  if ($this->format !== '') {
576  $controllerArguments['format'] = $this->format;
577  }
578  if ($this->argumentPrefix !== null) {
579  $prefixedControllerArguments = array($this->argumentPrefix => $controllerArguments);
580  } else {
581  $pluginNamespace = $this->extensionService->getPluginNamespace($extensionName, $pluginName);
582  $prefixedControllerArguments = array($pluginNamespace => $controllerArguments);
583  }
584  ArrayUtility::mergeRecursiveWithOverrule($this->arguments, $prefixedControllerArguments);
585  return $this->build();
586  }
587 
599  protected function removeDefaultControllerAndAction(array $controllerArguments, $extensionName, $pluginName)
600  {
601  $defaultControllerName = $this->extensionService->getDefaultControllerNameByPlugin($extensionName, $pluginName);
602  if (isset($controllerArguments['action'])) {
603  $defaultActionName = $this->extensionService->getDefaultActionNameByPluginAndController($extensionName, $pluginName, $controllerArguments['controller']);
604  if ($controllerArguments['action'] === $defaultActionName) {
605  unset($controllerArguments['action']);
606  }
607  }
608  if ($controllerArguments['controller'] === $defaultControllerName) {
609  unset($controllerArguments['controller']);
610  }
611  return $controllerArguments;
612  }
613 
623  public function build()
624  {
625  if ($this->environmentService->isEnvironmentInBackendMode()) {
626  return $this->buildBackendUri();
627  } else {
628  return $this->buildFrontendUri();
629  }
630  }
631 
640  public function buildBackendUri()
641  {
642  if ($this->addQueryString === true) {
643  if ($this->addQueryStringMethod) {
644  switch ($this->addQueryStringMethod) {
645  case 'GET':
647  break;
648  case 'POST':
650  break;
651  case 'GET,POST':
652  $arguments = array_replace_recursive(GeneralUtility::_GET(), GeneralUtility::_POST());
653  break;
654  case 'POST,GET':
655  $arguments = array_replace_recursive(GeneralUtility::_POST(), GeneralUtility::_GET());
656  break;
657  default:
659  }
660  } else {
662  }
663  foreach ($this->argumentsToBeExcludedFromQueryString as $argumentToBeExcluded) {
664  $argumentToBeExcluded = GeneralUtility::explodeUrl2Array($argumentToBeExcluded, true);
666  }
667  } else {
668  $arguments = array(
669  'M' => GeneralUtility::_GP('M'),
670  'id' => GeneralUtility::_GP('id')
671  );
672  }
675  $this->lastArguments = $arguments;
676  $moduleName = $arguments['M'];
677  unset($arguments['M'], $arguments['moduleToken']);
678  $backendUriBuilder = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Routing\UriBuilder::class);
679  if ($this->request instanceof WebRequest && $this->createAbsoluteUri) {
680  $uri = (string)$backendUriBuilder->buildUriFromModule($moduleName, $arguments, \TYPO3\CMS\Backend\Routing\UriBuilder::ABSOLUTE_URL);
681  } else {
682  $uri = (string)$backendUriBuilder->buildUriFromModule($moduleName, $arguments);
683  }
684  if ($this->section !== '') {
685  $uri .= '#' . $this->section;
686  }
687  return $uri;
688  }
689 
696  public function buildFrontendUri()
697  {
698  $typolinkConfiguration = $this->buildTypolinkConfiguration();
699  if ($this->createAbsoluteUri === true) {
700  $typolinkConfiguration['forceAbsoluteUrl'] = true;
701  if ($this->absoluteUriScheme !== null) {
702  $typolinkConfiguration['forceAbsoluteUrl.']['scheme'] = $this->absoluteUriScheme;
703  }
704  }
705  $uri = $this->contentObject->typoLink_URL($typolinkConfiguration);
706  return $uri;
707  }
708 
715  protected function buildTypolinkConfiguration()
716  {
717  $typolinkConfiguration = array();
718  $typolinkConfiguration['parameter'] = $this->targetPageUid !== null ? $this->targetPageUid : $GLOBALS['TSFE']->id;
719  if ($this->targetPageType !== 0) {
720  $typolinkConfiguration['parameter'] .= ',' . $this->targetPageType;
721  } elseif ($this->format !== '') {
722  $targetPageType = $this->extensionService->getTargetPageTypeByFormat($this->request->getControllerExtensionName(), $this->format);
723  $typolinkConfiguration['parameter'] .= ',' . $targetPageType;
724  }
725  if (!empty($this->arguments)) {
726  $arguments = $this->convertDomainObjectsToIdentityArrays($this->arguments);
727  $this->lastArguments = $arguments;
728  $typolinkConfiguration['additionalParams'] = GeneralUtility::implodeArrayForUrl(null, $arguments);
729  }
730  if ($this->addQueryString === true) {
731  $typolinkConfiguration['addQueryString'] = 1;
732  if (!empty($this->argumentsToBeExcludedFromQueryString)) {
733  $typolinkConfiguration['addQueryString.'] = array(
734  'exclude' => implode(',', $this->argumentsToBeExcludedFromQueryString)
735  );
736  }
737  if ($this->addQueryStringMethod) {
738  $typolinkConfiguration['addQueryString.']['method'] = $this->addQueryStringMethod;
739  }
740  }
741  if ($this->noCache === true) {
742  $typolinkConfiguration['no_cache'] = 1;
743  } elseif ($this->useCacheHash) {
744  $typolinkConfiguration['useCacheHash'] = 1;
745  }
746  if ($this->section !== '') {
747  $typolinkConfiguration['section'] = $this->section;
748  }
749  if ($this->linkAccessRestrictedPages === true) {
750  $typolinkConfiguration['linkAccessRestrictedPages'] = 1;
751  }
752  return $typolinkConfiguration;
753  }
754 
764  {
765  foreach ($arguments as $argumentKey => $argumentValue) {
766  // if we have a LazyLoadingProxy here, make sure to get the real instance for further processing
767  if ($argumentValue instanceof \TYPO3\CMS\Extbase\Persistence\Generic\LazyLoadingProxy) {
768  $argumentValue = $argumentValue->_loadRealInstance();
769  // also update the value in the arguments array, because the lazyLoaded object could be
770  // hidden and thus the $argumentValue would be NULL.
771  $arguments[$argumentKey] = $argumentValue;
772  }
773  if ($argumentValue instanceof \Iterator) {
774  $argumentValue = $this->convertIteratorToArray($argumentValue);
775  }
776  if ($argumentValue instanceof \TYPO3\CMS\Extbase\DomainObject\AbstractDomainObject) {
777  if ($argumentValue->getUid() !== null) {
778  $arguments[$argumentKey] = $argumentValue->getUid();
779  } elseif ($argumentValue instanceof \TYPO3\CMS\Extbase\DomainObject\AbstractValueObject) {
780  $arguments[$argumentKey] = $this->convertTransientObjectToArray($argumentValue);
781  } else {
782  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);
783  }
784  } elseif (is_array($argumentValue)) {
785  $arguments[$argumentKey] = $this->convertDomainObjectsToIdentityArrays($argumentValue);
786  }
787  }
788  return $arguments;
789  }
790 
795  protected function convertIteratorToArray(\Iterator $iterator)
796  {
797  if (method_exists($iterator, 'toArray')) {
798  $array = $iterator->toArray();
799  } else {
800  $array = iterator_to_array($iterator);
801  }
802  return $array;
803  }
804 
812  public function convertTransientObjectToArray(\TYPO3\CMS\Extbase\DomainObject\AbstractDomainObject $object)
813  {
814  $result = array();
815  foreach ($object->_getProperties() as $propertyName => $propertyValue) {
816  if ($propertyValue instanceof \Iterator) {
817  $propertyValue = $this->convertIteratorToArray($propertyValue);
818  }
819  if ($propertyValue instanceof \TYPO3\CMS\Extbase\DomainObject\AbstractDomainObject) {
820  if ($propertyValue->getUid() !== null) {
821  $result[$propertyName] = $propertyValue->getUid();
822  } else {
823  $result[$propertyName] = $this->convertTransientObjectToArray($propertyValue);
824  }
825  } elseif (is_array($propertyValue)) {
826  $result[$propertyName] = $this->convertDomainObjectsToIdentityArrays($propertyValue);
827  } else {
828  $result[$propertyName] = $propertyValue;
829  }
830  }
831  return $result;
832  }
833 }