‪TYPO3CMS  11.5
TypolinkViewHelper.php
Go to the documentation of this file.
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 
17 
19 use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
20 use TYPO3\CMS\Frontend\Service\TypoLinkCodecService;
21 use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
22 use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
23 use TYPO3Fluid\Fluid\Core\ViewHelper\Exception;
24 use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
25 
90 class ‪TypolinkViewHelper extends AbstractViewHelper
91 {
92  use CompileWithRenderStatic;
93 
97  protected ‪$escapeOutput = false;
98 
104  public function ‪initializeArguments()
105  {
106  $this->registerArgument('parameter', 'string', 'stdWrap.typolink style parameter string', true);
107  $this->registerArgument('target', 'string', 'Define where to display the linked URL', false, '');
108  $this->registerArgument('class', 'string', 'Define classes for the link element', false, '');
109  $this->registerArgument('title', 'string', 'Define the title for the link element', false, '');
110  $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, null);
111  $this->registerArgument('additionalParams', 'string', 'Additional query parameters to be attached to the resulting URL', false, '');
112  $this->registerArgument('additionalAttributes', 'array', 'Additional tag attributes to be added directly to the resulting HTML tag', false, []);
113  $this->registerArgument('addQueryString', 'bool', 'If set, the current query parameters will be kept in the URL', false, false);
114  $this->registerArgument('addQueryStringMethod', 'string', 'This argument is not evaluated anymore and will be removed in TYPO3 v12.');
115  $this->registerArgument('addQueryStringExclude', 'string', 'Define parameters to be excluded from the query string (only active if addQueryString is set)', false, '');
116  $this->registerArgument('absolute', 'bool', 'Ensure the resulting URL is an absolute URL', false, false);
117  $this->registerArgument('parts-as', 'string', 'Variable name containing typoLink parts (if any)', false, 'typoLinkParts');
118  $this->registerArgument('textWrap', 'string', 'Wrap the link using the typoscript "wrap" data type', false, '');
119  }
120 
131  public static function ‪renderStatic(array $arguments, \Closure $renderChildrenClosure, RenderingContextInterface $renderingContext)
132  {
133  $parameter = $arguments['parameter'] ?? '';
134  $partsAs = $arguments['parts-as'] ?? 'typoLinkParts';
135 
136  $typoLinkCodec = GeneralUtility::makeInstance(TypoLinkCodecService::class);
137  $typoLinkConfiguration = $typoLinkCodec->decode($parameter);
138  // Merge the $parameter with other arguments
139  $mergedTypoLinkConfiguration = static::mergeTypoLinkConfiguration($typoLinkConfiguration, $arguments);
140  $typoLinkParameter = $typoLinkCodec->encode($mergedTypoLinkConfiguration);
141 
142  // expose internal typoLink configuration to Fluid child context
143  $variableProvider = $renderingContext->getVariableProvider();
144  $variableProvider->add($partsAs, $typoLinkConfiguration);
145  // If no link has to be rendered, the inner content will be returned as such
146  $content = (string)$renderChildrenClosure();
147  // clean up exposed variables
148  $variableProvider->remove($partsAs);
149 
150  if ($parameter) {
151  $content = static::invokeContentObjectRenderer($arguments, $typoLinkParameter, $content);
152  }
153  return $content;
154  }
155 
156  protected static function ‪invokeContentObjectRenderer(array $arguments, string $typoLinkParameter, string $content): string
157  {
158  if (isset($arguments['addQueryStringMethod'])) {
159  trigger_error('Using the argument "addQueryStringMethod" in <f:link.typolink> ViewHelper has no effect anymore and will be removed in TYPO3 v12. Remove the argument in your fluid template, as it will result in a fatal error.', E_USER_DEPRECATED);
160  }
161  $addQueryString = $arguments['addQueryString'] ?? false;
162  $addQueryStringExclude = $arguments['addQueryStringExclude'] ?? '';
163  $absolute = $arguments['absolute'] ?? false;
164  $aTagParams = static::serializeTagParameters($arguments);
165 
166  $instructions = [
167  'parameter' => $typoLinkParameter,
168  'ATagParams' => $aTagParams,
169  'forceAbsoluteUrl' => $absolute,
170  ];
171  if (isset($arguments['language']) && $arguments['language'] !== null) {
172  $instructions['language'] = $arguments['language'];
173  }
174  if ($addQueryString) {
175  $instructions['addQueryString'] = $addQueryString;
176  $instructions['addQueryString.'] = [
177  'exclude' => $addQueryStringExclude,
178  ];
179  }
180  if ((string)($arguments['textWrap'] ?? '') !== '') {
181  $instructions['ATagBeforeWrap'] = true;
182  $instructions['wrap'] = $arguments['textWrap'];
183  }
184 
185  $contentObject = GeneralUtility::makeInstance(ContentObjectRenderer::class);
186  return $contentObject->stdWrap($content, ['typolink.' => $instructions]);
187  }
188 
189  protected static function ‪serializeTagParameters(array $arguments): string
190  {
191  // array(param1 -> value1, param2 -> value2) --> param1="value1" param2="value2" for typolink.ATagParams
192  $extraAttributes = [];
193  $additionalAttributes = $arguments['additionalAttributes'] ?? [];
194  foreach ($additionalAttributes as $attributeName => $attributeValue) {
195  $extraAttributes[] = $attributeName . '="' . htmlspecialchars((string)$attributeValue) . '"';
196  }
197  return implode(' ', $extraAttributes);
198  }
199 
207  protected static function ‪mergeTypoLinkConfiguration(array $typoLinkConfiguration, array $arguments): array
208  {
209  if ($typoLinkConfiguration === []) {
210  return $typoLinkConfiguration;
211  }
212 
213  $target = $arguments['target'] ?? '';
214  $class = $arguments['class'] ?? '';
215  $title = $arguments['title'] ?? '';
216  $additionalParams = $arguments['additionalParams'] ?? '';
217 
218  // Override target if given in target argument
219  if ($target) {
220  $typoLinkConfiguration['target'] = $target;
221  }
222  // Combine classes if given in both "parameter" string and "class" argument
223  if ($class) {
224  $classes = explode(' ', trim($typoLinkConfiguration['class']) . ' ' . trim($class));
225  $typoLinkConfiguration['class'] = implode(' ', array_unique(array_filter($classes)));
226  }
227  // Override title if given in title argument
228  if ($title) {
229  $typoLinkConfiguration['title'] = $title;
230  }
231  // Combine additionalParams
232  if ($additionalParams) {
233  $typoLinkConfiguration['additionalParams'] .= $additionalParams;
234  }
235 
236  return $typoLinkConfiguration;
237  }
238 }
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:50