1<?php
2
3/*
4 * This file is part of the TYPO3 CMS project.
5 *
6 * It is free software; you can redistribute it and/or modify it under
7 * the terms of the GNU General Public License, either version 2
8 * of the License, or any later version.
9 *
10 * For the full copyright and license information, please read the
11 * LICENSE.txt file that was distributed with this source code.
12 *
13 * The TYPO3 project - inspiring people to share!
14 */
15
16namespace TYPO3\CMS\Fluid\ViewHelpers\Uri;
17
18use TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder;
19use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
20use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
21use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
22
23/**
24 * A ViewHelper for creating URIs to extbase actions.
25 *
26 * Examples
27 * ========
28 *
29 * URI to the show-action of the current controller::
30 *
31 *    <f:uri.action action="show" />
32 *
33 * ``/page/path/name.html?tx_myextension_plugin[action]=show&tx_myextension_plugin[controller]=Standard&cHash=xyz``
34 *
35 * Depending on current page, routing and page path configuration.
36 */
37class ActionViewHelper extends AbstractViewHelper
38{
39    use CompileWithRenderStatic;
40
41    /**
42     * Initialize arguments
43     */
44    public function initializeArguments()
45    {
46        $this->registerArgument('action', 'string', 'Target action');
47        $this->registerArgument('arguments', 'array', 'Arguments', false, []);
48        $this->registerArgument('controller', 'string', 'Target controller. If NULL current controllerName is used');
49        $this->registerArgument('extensionName', 'string', 'Target Extension Name (without "tx_" prefix and no underscores). If NULL the current extension name is used');
50        $this->registerArgument('pluginName', 'string', 'Target plugin. If empty, the current plugin name is used');
51        $this->registerArgument('pageUid', 'int', 'Target page. See TypoLink destination');
52        $this->registerArgument('pageType', 'int', 'Type of the target page. See typolink.parameter', false, 0);
53        $this->registerArgument('noCache', 'bool', 'Set this to disable caching for the target page. You should not need this.', false, null);
54        // @deprecated
55        $this->registerArgument('noCacheHash', 'bool', 'Deprecated: Set this to suppress the cHash query parameter created by TypoLink. You should not need this.', false, null);
56        $this->registerArgument('section', 'string', 'The anchor to be added to the URI', false, '');
57        $this->registerArgument('format', 'string', 'The requested format, e.g. ".html', false, '');
58        $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);
59        $this->registerArgument('additionalParams', 'array', 'additional query parameters that won\'t be prefixed like $arguments (overrule $arguments)', false, []);
60        $this->registerArgument('absolute', 'bool', 'If set, an absolute URI is rendered', false, false);
61        $this->registerArgument('addQueryString', 'bool', 'If set, the current query parameters will be kept in the URI', false, false);
62        $this->registerArgument('argumentsToBeExcludedFromQueryString', 'array', 'arguments to be removed from the URI. Only active if $addQueryString = TRUE', false, []);
63        $this->registerArgument('addQueryStringMethod', 'string', 'Set which parameters will be kept. Only active if $addQueryString = TRUE');
64    }
65
66    /**
67     * @param array $arguments
68     * @param \Closure $renderChildrenClosure
69     * @param RenderingContextInterface $renderingContext
70     * @return string
71     */
72    public static function renderStatic(array $arguments, \Closure $renderChildrenClosure, RenderingContextInterface $renderingContext)
73    {
74        /** @var int $pageUid */
75        $pageUid = $arguments['pageUid'] ?? 0;
76        /** @var int $pageType */
77        $pageType = $arguments['pageType'] ?? 0;
78        /** @var bool $noCache */
79        $noCache = $arguments['noCache'] ?? false;
80        if (isset($arguments['noCacheHash'])) {
81            trigger_error('Using the argument "noCacheHash" in <f:uri.action> ViewHelper has no effect anymore. Remove the argument in your fluid template, as it will result in a fatal error.', E_USER_DEPRECATED);
82        }
83        /** @var string|null $section */
84        $section = $arguments['section'] ?? null;
85        /** @var string|null $format */
86        $format = $arguments['format'] ?? null;
87        /** @var bool $linkAccessRestrictedPages */
88        $linkAccessRestrictedPages = $arguments['linkAccessRestrictedPages'] ?? false;
89        /** @var array|null $additionalParams */
90        $additionalParams = $arguments['additionalParams'] ?? null;
91        /** @var bool $absolute */
92        $absolute = $arguments['absolute'] ?? false;
93        /** @var bool $addQueryString */
94        $addQueryString = $arguments['addQueryString'] ?? false;
95        /** @var array|null $argumentsToBeExcludedFromQueryString */
96        $argumentsToBeExcludedFromQueryString = $arguments['argumentsToBeExcludedFromQueryString'] ?? null;
97        /** @var string $addQueryStringMethod */
98        $addQueryStringMethod = $arguments['addQueryStringMethod'] ?? '';
99        /** @var string|null $action */
100        $action = $arguments['action'] ?? null;
101        /** @var string|null $controller */
102        $controller = $arguments['controller'] ?? null;
103        /** @var string|null $extensionName */
104        $extensionName = $arguments['extensionName'] ?? null;
105        /** @var string|null $pluginName */
106        $pluginName = $arguments['pluginName'] ?? null;
107        /** @var array|null $arguments */
108        $arguments = $arguments['arguments'] ?? [];
109
110        /** @var UriBuilder $uriBuilder */
111        $uriBuilder = $renderingContext->getControllerContext()->getUriBuilder();
112        $uriBuilder->reset();
113
114        if ($pageUid > 0) {
115            $uriBuilder->setTargetPageUid($pageUid);
116        }
117
118        if ($pageType > 0) {
119            $uriBuilder->setTargetPageType($pageType);
120        }
121
122        if ($noCache === true) {
123            $uriBuilder->setNoCache($noCache);
124        }
125
126        if (is_string($section)) {
127            $uriBuilder->setSection($section);
128        }
129
130        if (is_string($format)) {
131            $uriBuilder->setFormat($format);
132        }
133
134        if (is_array($additionalParams)) {
135            $uriBuilder->setArguments($additionalParams);
136        }
137
138        if ($absolute === true) {
139            $uriBuilder->setCreateAbsoluteUri($absolute);
140        }
141
142        if ($addQueryString === true) {
143            $uriBuilder->setAddQueryString($addQueryString);
144        }
145
146        if (is_array($argumentsToBeExcludedFromQueryString)) {
147            $uriBuilder->setArgumentsToBeExcludedFromQueryString($argumentsToBeExcludedFromQueryString);
148        }
149
150        if ($addQueryStringMethod !== '') {
151            $uriBuilder->setAddQueryStringMethod($addQueryStringMethod);
152        }
153
154        if ($linkAccessRestrictedPages === true) {
155            $uriBuilder->setLinkAccessRestrictedPages($linkAccessRestrictedPages);
156        }
157
158        return $uriBuilder->uriFor($action, $arguments, $controller, $extensionName, $pluginName);
159    }
160}
161