‪TYPO3CMS  ‪main
PageViewHelper.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
20 use Psr\Http\Message\ServerRequestInterface;
23 use ‪TYPO3\CMS\Backend\Routing\UriBuilder as BackendUriBuilder;
29 use ‪TYPO3\CMS\Extbase\Mvc\RequestInterface as ExtbaseRequestInterface;
35 use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
36 use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
37 use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
38 
78 final class ‪PageViewHelper extends AbstractViewHelper
79 {
80  use CompileWithRenderStatic;
81 
82  public function ‪initializeArguments(): void
83  {
84  $this->registerArgument('pageUid', 'int', 'target PID');
85  $this->registerArgument('additionalParams', 'array', 'query parameters to be attached to the resulting URI', false, []);
86  $this->registerArgument('pageType', 'int', 'type of the target page. See typolink.parameter', false, 0);
87  $this->registerArgument('noCache', 'bool', 'set this to disable caching for the target page. You should not need this.', false, false);
88  $this->registerArgument('language', 'string', 'link to a specific language - defaults to the current language, use a language ID or "current" to enforce a specific language', false);
89  $this->registerArgument('section', 'string', 'the anchor to be added to the URI', false, '');
90  $this->registerArgument('linkAccessRestrictedPages', 'bool', 'If set, links pointing to access restricted pages will still link to the page even though the page cannot be accessed.', false, false);
91  $this->registerArgument('absolute', 'bool', 'If set, the URI of the rendered link is absolute', false, false);
92  $this->registerArgument('addQueryString', 'string', 'If set, the current query parameters will be kept in the URL. If set to "untrusted", then ALL query parameters will be added. Be aware, that this might lead to problems when the generated link is cached.', false, false);
93  $this->registerArgument('argumentsToBeExcludedFromQueryString', 'array', 'arguments to be removed from the URI. Only active if $addQueryString = TRUE', false, []);
94  }
95 
96  public static function ‪renderStatic(array $arguments, \Closure $renderChildrenClosure, RenderingContextInterface $renderingContext): string
97  {
99  $request = $renderingContext->getRequest();
100  if ($request instanceof ExtbaseRequestInterface) {
101  return ‪self::renderWithExtbaseContext($request, $arguments);
102  }
103  if ($request instanceof ServerRequestInterface) {
104  if (‪ApplicationType::fromRequest($request)->isFrontend()) {
105  // Use the regular typolink functionality.
106  return ‪self::renderFrontendLinkWithCoreContext($request, $arguments, $renderChildrenClosure);
107  }
108  return ‪self::renderBackendLinkWithCoreContext($request, $arguments);
109  }
110  throw new \RuntimeException(
111  'The rendering context of ViewHelper f:uri.page is missing a valid request object.',
112  1639820200
113  );
114  }
115 
116  protected static function ‪renderBackendLinkWithCoreContext(ServerRequestInterface $request, array $arguments): string
117  {
118  $pageUid = isset($arguments['pageUid']) ? (int)$arguments['pageUid'] : null;
119  $section = isset($arguments['section']) ? (string)$arguments['section'] : '';
120  $additionalParams = isset($arguments['additionalParams']) ? (array)$arguments['additionalParams'] : [];
121  $absolute = isset($arguments['absolute']) && (bool)$arguments['absolute'];
122  $addQueryString = $arguments['addQueryString'] ?? false;
123  $argumentsToBeExcludedFromQueryString = isset($arguments['argumentsToBeExcludedFromQueryString']) ? (array)$arguments['argumentsToBeExcludedFromQueryString'] : [];
124 
125  $arguments = [];
126  if ($addQueryString && $addQueryString !== 'false') {
127  $arguments = $request->getQueryParams();
128  foreach ($argumentsToBeExcludedFromQueryString as $argumentToBeExcluded) {
129  $argumentArrayToBeExcluded = [];
130  parse_str($argumentToBeExcluded, $argumentArrayToBeExcluded);
131  $arguments = ArrayUtility::arrayDiffKeyRecursive($arguments, $argumentArrayToBeExcluded);
132  }
133  }
134 
135  $id = $pageUid ?? $request->getQueryParams()['id'] ?? null;
136  if ($id !== null) {
137  $arguments['id'] = $id;
138  }
139  if (!isset($arguments['route']) && ($route = $request->getAttribute('route')) instanceof ‪Route) {
140  $arguments['route'] = $route->getOption('_identifier');
141  }
142  $arguments = array_replace_recursive($arguments, $additionalParams);
143  $routeName = $arguments['route'] ?? null;
144  unset($arguments['route'], $arguments['token']);
145  $backendUriBuilder = GeneralUtility::makeInstance(BackendUriBuilder::class);
146  try {
147  if ($absolute) {
148  $uri = (string)$backendUriBuilder->buildUriFromRoute($routeName, $arguments, BackendUriBuilder::ABSOLUTE_URL);
149  } else {
150  $uri = (string)$backendUriBuilder->buildUriFromRoute($routeName, $arguments, BackendUriBuilder::ABSOLUTE_PATH);
151  }
152  } catch (‪RouteNotFoundException) {
153  $uri = '';
154  }
155  if ($section !== '') {
156  $uri .= '#' . $section;
157  }
158  return $uri;
159  }
160 
161  protected static function ‪renderFrontendLinkWithCoreContext(ServerRequestInterface $request, array $arguments, \Closure $renderChildrenClosure): string
162  {
163  $pageUid = isset($arguments['pageUid']) ? (int)$arguments['pageUid'] : 'current';
164  $pageType = isset($arguments['pageType']) ? (int)$arguments['pageType'] : 0;
165  $noCache = isset($arguments['noCache']) && (bool)$arguments['noCache'];
166  $section = isset($arguments['section']) ? (string)$arguments['section'] : '';
167  $language = isset($arguments['language']) ? (string)$arguments['language'] : null;
168  $linkAccessRestrictedPages = isset($arguments['linkAccessRestrictedPages']) && (bool)$arguments['linkAccessRestrictedPages'];
169  $additionalParams = isset($arguments['additionalParams']) ? (array)$arguments['additionalParams'] : [];
170  $absolute = isset($arguments['absolute']) && (bool)$arguments['absolute'];
171  $addQueryString = $arguments['addQueryString'] ?? false;
172  $argumentsToBeExcludedFromQueryString = isset($arguments['argumentsToBeExcludedFromQueryString']) ? (array)$arguments['argumentsToBeExcludedFromQueryString'] : [];
173 
174  $typolinkConfiguration = [
175  'parameter' => $pageUid,
176  ];
177  if ($pageType) {
178  $typolinkConfiguration['parameter'] .= ',' . $pageType;
179  }
180  if ($noCache) {
181  $typolinkConfiguration['no_cache'] = 1;
182  }
183  if ($language !== null) {
184  $typolinkConfiguration['language'] = $language;
185  }
186  if ($section) {
187  $typolinkConfiguration['section'] = $section;
188  }
189  if ($linkAccessRestrictedPages) {
190  $typolinkConfiguration['linkAccessRestrictedPages'] = 1;
191  }
192  if ($additionalParams) {
193  $typolinkConfiguration['additionalParams'] = ‪HttpUtility::buildQueryString($additionalParams, '&');
194  }
195  if ($absolute) {
196  $typolinkConfiguration['forceAbsoluteUrl'] = true;
197  }
198  if ($addQueryString && $addQueryString !== 'false') {
199  $typolinkConfiguration['addQueryString'] = $addQueryString;
200  if ($argumentsToBeExcludedFromQueryString !== []) {
201  $typolinkConfiguration['addQueryString.']['exclude'] = implode(',', $argumentsToBeExcludedFromQueryString);
202  }
203  }
204 
205  try {
206  $cObj = GeneralUtility::makeInstance(ContentObjectRenderer::class);
207  $cObj->setRequest($request);
208  $linkFactory = GeneralUtility::makeInstance(LinkFactory::class);
209  $linkResult = $linkFactory->create((string)$renderChildrenClosure(), $typolinkConfiguration, $cObj);
210  return $linkResult->getUrl();
211  } catch (‪UnableToLinkException) {
212  return (string)$renderChildrenClosure();
213  }
214  }
215 
216  protected static function ‪renderWithExtbaseContext(ExtbaseRequestInterface $request, array $arguments): string
217  {
218  $pageUid = $arguments['pageUid'];
219  $additionalParams = $arguments['additionalParams'];
220  $pageType = (int)($arguments['pageType'] ?? 0);
221  $noCache = $arguments['noCache'];
222  $section = $arguments['section'];
223  $language = isset($arguments['language']) ? (string)$arguments['language'] : null;
224  $linkAccessRestrictedPages = $arguments['linkAccessRestrictedPages'];
225  $absolute = $arguments['absolute'];
226  $addQueryString = $arguments['addQueryString'] ?? false;
227  $argumentsToBeExcludedFromQueryString = $arguments['argumentsToBeExcludedFromQueryString'];
228 
229  $uriBuilder = GeneralUtility::makeInstance(ExtbaseUriBuilder::class);
230  $uri = $uriBuilder
231  ->reset()
232  ->setRequest($request)
233  ->setTargetPageType($pageType)
234  ->setNoCache($noCache)
235  ->setSection($section)
236  ->setLanguage($language)
237  ->setLinkAccessRestrictedPages($linkAccessRestrictedPages)
238  ->setArguments($additionalParams)
239  ->setCreateAbsoluteUri($absolute)
240  ->setAddQueryString($addQueryString)
241  ->setArgumentsToBeExcludedFromQueryString($argumentsToBeExcludedFromQueryString);
242 
244  $uriBuilder->setTargetPageUid((int)$pageUid);
245  }
246 
247  return $uri->build();
248  }
249 }
‪TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder
Definition: UriBuilder.php:38
‪TYPO3\CMS\Fluid\ViewHelpers\Uri\PageViewHelper\renderStatic
‪static renderStatic(array $arguments, \Closure $renderChildrenClosure, RenderingContextInterface $renderingContext)
Definition: PageViewHelper.php:95
‪TYPO3\CMS\Backend\Routing\Route
Definition: Route.php:24
‪TYPO3\CMS\Core\Utility\MathUtility\canBeInterpretedAsInteger
‪static bool canBeInterpretedAsInteger(mixed $var)
Definition: MathUtility.php:69
‪TYPO3\CMS\Backend\Routing\Exception\RouteNotFoundException
Definition: RouteNotFoundException.php:21
‪TYPO3\CMS\Fluid\ViewHelpers\Uri\PageViewHelper\renderWithExtbaseContext
‪static renderWithExtbaseContext(ExtbaseRequestInterface $request, array $arguments)
Definition: PageViewHelper.php:215
‪TYPO3\CMS\Fluid\ViewHelpers\Uri\PageViewHelper
Definition: PageViewHelper.php:79
‪TYPO3\CMS\Backend\Routing\UriBuilder
Definition: UriBuilder.php:44
‪TYPO3\CMS\Core\Utility\HttpUtility\buildQueryString
‪static string buildQueryString(array $parameters, string $prependCharacter='', bool $skipEmptyParameters=false)
Definition: HttpUtility.php:124
‪TYPO3\CMS\Extbase\Mvc\RequestInterface
Definition: RequestInterface.php:24
‪TYPO3\CMS\Core\Utility\ArrayUtility
Definition: ArrayUtility.php:26
‪TYPO3\CMS\Fluid\ViewHelpers\Uri
Definition: ActionViewHelper.php:18
‪TYPO3\CMS\Fluid\ViewHelpers\Uri\PageViewHelper\renderFrontendLinkWithCoreContext
‪static renderFrontendLinkWithCoreContext(ServerRequestInterface $request, array $arguments, \Closure $renderChildrenClosure)
Definition: PageViewHelper.php:160
‪TYPO3\CMS\Core\Utility\MathUtility
Definition: MathUtility.php:24
‪TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer
Definition: ContentObjectRenderer.php:102
‪TYPO3\CMS\Fluid\ViewHelpers\Uri\PageViewHelper\renderBackendLinkWithCoreContext
‪static renderBackendLinkWithCoreContext(ServerRequestInterface $request, array $arguments)
Definition: PageViewHelper.php:115
‪TYPO3\CMS\Core\Utility\HttpUtility
Definition: HttpUtility.php:24
‪TYPO3\CMS\Core\Http\fromRequest
‪@ fromRequest
Definition: ApplicationType.php:66
‪TYPO3\CMS\Fluid\ViewHelpers\Uri\PageViewHelper\initializeArguments
‪initializeArguments()
Definition: PageViewHelper.php:81
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:52
‪TYPO3\CMS\Fluid\Core\Rendering\RenderingContext
Definition: RenderingContext.php:35
‪TYPO3\CMS\Core\Http\ApplicationType
‪ApplicationType
Definition: ApplicationType.php:55