diff --git a/typo3/sysext/core/Documentation/Changelog/master/Feature-75161-CreateUrilinkToBackendModulesViewhelper.rst b/typo3/sysext/core/Documentation/Changelog/master/Feature-75161-CreateUrilinkToBackendModulesViewhelper.rst new file mode 100644 index 0000000000000000000000000000000000000000..80a8c0be39d4491724dcb7ecfa47cc185c574bd1 --- /dev/null +++ b/typo3/sysext/core/Documentation/Changelog/master/Feature-75161-CreateUrilinkToBackendModulesViewhelper.rst @@ -0,0 +1,33 @@ +.. include:: ../../Includes.txt + +=============================================================== +Feature: #75161 - Create uri/link to backend modules viewhelper +=============================================================== + +See :issue:`75161` + +Description +=========== + +Adds viewhelpers to build an uri or a link to a certain backend module. + +Can be used to generate only an URI: + +.. code-block:: html + + <f:be.uri route="web_ts" parameters="{id: 92}"/> + +Or a full link tag: + +.. code-block:: html + + <f:be.link route="web_ts" parameters="{id: 92}">Go to template module on page 92</f:be.link> + +Both viewhelpers can also be used inline: + +.. code-block:: none + + {f:be.uri(route: 'web_ts', parameters: '{id: 92}')} + {f:be.link(route: 'web_ts', parameters: '{id: 92}')} + +.. index:: Backend, Fluid \ No newline at end of file diff --git a/typo3/sysext/fluid/Classes/ViewHelpers/Be/LinkViewHelper.php b/typo3/sysext/fluid/Classes/ViewHelpers/Be/LinkViewHelper.php new file mode 100644 index 0000000000000000000000000000000000000000..90d9598fe4a2df50cb83a65a3e00053c8e464ee5 --- /dev/null +++ b/typo3/sysext/fluid/Classes/ViewHelpers/Be/LinkViewHelper.php @@ -0,0 +1,83 @@ +<?php +namespace TYPO3\CMS\Fluid\ViewHelpers\Be; + +/* + * This file is part of the TYPO3 CMS project. + * + * It is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, either version 2 + * of the License, or any later version. + * + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. + * + * The TYPO3 project - inspiring people to share! + */ + +use TYPO3\CMS\Backend\Routing\UriBuilder; +use TYPO3\CMS\Core\Utility\GeneralUtility; +use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractTagBasedViewHelper; + +/** + * A view helper for creating URIs to modules. + * = Examples = + * <code title="URI to the web_ts module on page 92"> + * <f:be.link route="web_ts" parameters="{id: 92}">Go to web_ts</f:be.link> + * </code> + * <output> + * <a href="/typo3/index.php?route=%2module%2web_ts%2&moduleToken=b6e9c9f?id=92">Go to web_ts</a> + * </output> + */ +class LinkViewHelper extends AbstractTagBasedViewHelper +{ + + /** + * @var string + */ + protected $tagName = 'a'; + + /** + * Arguments initialization + * + * @throws \TYPO3Fluid\Fluid\Core\ViewHelper\Exception + */ + public function initializeArguments() + { + parent::initializeArguments(); + $this->registerArgument('route', 'string', 'The name of the route'); + $this->registerArgument('parameters', 'array', 'An array of parameters'); + $this->registerArgument('referenceType', 'string', 'The type of reference to be generated (one of the constants)', false, UriBuilder::ABSOLUTE_PATH); + $this->registerTagAttribute('name', 'string', 'Specifies the name of an anchor'); + $this->registerTagAttribute( + 'rel', + 'string', + 'Specifies the relationship between the current document and the linked document' + ); + $this->registerTagAttribute( + 'rev', + 'string', + 'Specifies the relationship between the linked document and the current document' + ); + $this->registerTagAttribute('target', 'string', 'Specifies where to open the linked document'); + $this->registerUniversalTagAttributes(); + } + + /** + * @return string Rendered link + */ + public function render() + { + $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class); + $route = $this->arguments['route']; + $parameters = $this->arguments['parameters']; + $referenceType = $this->arguments['referenceType']; + + $uri = $uriBuilder->buildUriFromRoute($route, $parameters, $referenceType); + + $this->tag->addAttribute('href', $uri); + $this->tag->setContent($this->renderChildren()); + $this->tag->forceClosingTag(true); + + return $this->tag->render(); + } +} diff --git a/typo3/sysext/fluid/Classes/ViewHelpers/Be/UriViewHelper.php b/typo3/sysext/fluid/Classes/ViewHelpers/Be/UriViewHelper.php new file mode 100644 index 0000000000000000000000000000000000000000..f5d9a4772c271a176e91a203b93edd2b937907c2 --- /dev/null +++ b/typo3/sysext/fluid/Classes/ViewHelpers/Be/UriViewHelper.php @@ -0,0 +1,73 @@ +<?php +namespace TYPO3\CMS\Fluid\ViewHelpers\Be; + +/* + * This file is part of the TYPO3 CMS project. + * + * It is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, either version 2 + * of the License, or any later version. + * + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. + * + * The TYPO3 project - inspiring people to share! + */ + +use TYPO3\CMS\Backend\Routing\UriBuilder; +use TYPO3\CMS\Core\Utility\GeneralUtility; + +/** + * A view helper for creating URIs to modules. + * = Examples = + * <code title="URI to the web_ts module on page 92"> + * <f:be.uri route="web_ts" parameters="{id: 92}"/> + * </code> + * <output> + * /typo3/index.php?M=web_ts&moduleToken=b6e9c9f?id=92 + * </output> + * + * <code title="Inline notation"> + * {f:be.uri(route: 'web_ts', parameters: '{id: 92}')} + * </code> + * <output> + * /typo3/index.php?route=%2module%2web_ts%2&moduleToken=b6e9c9f?id=92 + * </output> + */ +class UriViewHelper extends AbstractBackendViewHelper +{ + + /** + * Arguments initialization + * + * @throws \TYPO3Fluid\Fluid\Core\ViewHelper\Exception + */ + public function initializeArguments() + { + parent::initializeArguments(); + $this->registerArgument('route', 'string', 'The name of the route'); + $this->registerArgument('parameters', 'array', 'An array of parameters'); + $this->registerArgument( + 'referenceType', + 'string', + 'The type of reference to be generated (one of the constants)', + false, + UriBuilder::ABSOLUTE_PATH + ); + } + + /** + * @return string Rendered link + */ + public function render() + { + /** @var UriBuilder $uriBuilder */ + $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class); + $route = $this->arguments['route']; + $parameters = $this->arguments['parameters']; + $referenceType = $this->arguments['referenceType']; + $uri = $uriBuilder->buildUriFromRoute($route, $parameters, $referenceType); + + return (string)$uri; + } +} diff --git a/typo3/sysext/fluid/Tests/Unit/ViewHelpers/Be/LinkViewHelperTest.php b/typo3/sysext/fluid/Tests/Unit/ViewHelpers/Be/LinkViewHelperTest.php new file mode 100644 index 0000000000000000000000000000000000000000..48ff9d208eb9a86577e09777eb933e0dc3465eb2 --- /dev/null +++ b/typo3/sysext/fluid/Tests/Unit/ViewHelpers/Be/LinkViewHelperTest.php @@ -0,0 +1,106 @@ +<?php + +namespace TYPO3\CMS\Fluid\Tests\Unit\ViewHelpers\Be; + +/* + * This file is part of the TYPO3 CMS project. + * + * It is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, either version 2 + * of the License, or any later version. + * + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. + * + * The TYPO3 project - inspiring people to share! + */ + +use TYPO3\CMS\Backend\Routing\UriBuilder; +use TYPO3\CMS\Core\Utility\GeneralUtility; +use TYPO3\CMS\Fluid\Core\ViewHelper\TagBuilder; +use TYPO3\CMS\Fluid\ViewHelpers\Be\LinkViewHelper; +use TYPO3\TestingFramework\Fluid\Unit\ViewHelpers\ViewHelperBaseTestcase; + +/** + * Test-case for Be\LinkViewHelper + */ +class LinkViewHelperTest extends ViewHelperBaseTestcase +{ + + /** + * @var LinkViewHelper|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\TestingFramework\Core\AccessibleObjectInterface + */ + protected $viewHelper; + + /** + * @var UriBuilder|\PHPUnit_Framework_MockObject_MockBuilder + */ + protected $uriBuilderMock; + + /** + * setUp function + */ + protected function setUp() + { + parent::setUp(); + $this->viewHelper = $this->getAccessibleMock(LinkViewHelper::class, ['renderChildren']); + $this->injectDependenciesIntoViewHelper($this->viewHelper); + + $this->uriBuilderMock = $this->getMockBuilder(UriBuilder::class)->getMock(); + + $this->tagBuilder = $this->getMockBuilder(TagBuilder::class)->setMethods([ + 'addAttribute', + 'setContent', + 'forceClosingTag', + 'render' + ])->getMock(); + + $this->inject($this->viewHelper, 'tag', $this->tagBuilder); + } + + /** + * @test + */ + public function initializeArgumentsRegistersExpectedArguments() + { + $viewHelper = $this->getMockBuilder(LinkViewHelper::class) + ->setMethods(['registerTagAttribute', 'registerUniversalTagAttributes', 'registerArgument']) + ->getMock(); + + $viewHelper->expects($this->at(2))->method('registerArgument')->with('route', 'string', $this->anything()); + $viewHelper->expects($this->at(3))->method('registerArgument')->with('parameters', 'array', $this->anything()); + $viewHelper->expects($this->at(4))->method('registerArgument') + ->with('referenceType', 'string', $this->anything()); + + $viewHelper->expects($this->at(5))->method('registerTagAttribute')->with('name', 'string', $this->anything()); + $viewHelper->expects($this->at(6))->method('registerTagAttribute')->with('rel', 'string', $this->anything()); + $viewHelper->expects($this->at(7))->method('registerTagAttribute')->with('rev', 'string', $this->anything()); + $viewHelper->expects($this->at(8))->method('registerTagAttribute')->with('target', 'string', $this->anything()); + $viewHelper->expects($this->once())->method('registerUniversalTagAttributes'); + $viewHelper->initializeArguments(); + } + + /** + * @test + */ + public function renderRendersTagWithHrefFromRoute() + { + $this->viewHelper->setArguments([ + 'route' => 'theRouteArgument', + 'parameters' => ['parameter' => 'to pass'], + 'referenceType' => 'theReferenceTypeArgument' + ]); + + GeneralUtility::addInstance(UriBuilder::class, $this->uriBuilderMock); + + $this->uriBuilderMock->expects($this->once())->method('buildUriFromRoute') + ->with('theRouteArgument', ['parameter' => 'to pass'], 'theReferenceTypeArgument')->willReturn('theUri'); + + $this->tagBuilder->expects($this->once())->method('addAttribute')->with('href', 'theUri'); + $this->tagBuilder->expects($this->once())->method('setContent'); + $this->tagBuilder->expects($this->once())->method('forceClosingTag')->with(true); + $this->tagBuilder->expects($this->once())->method('render'); + + $this->viewHelper->render(); + } +} diff --git a/typo3/sysext/fluid/Tests/Unit/ViewHelpers/Be/UriViewHelperTest.php b/typo3/sysext/fluid/Tests/Unit/ViewHelpers/Be/UriViewHelperTest.php new file mode 100644 index 0000000000000000000000000000000000000000..1b97e7ddf21d3173173727d8add8733c8ffbec35 --- /dev/null +++ b/typo3/sysext/fluid/Tests/Unit/ViewHelpers/Be/UriViewHelperTest.php @@ -0,0 +1,85 @@ +<?php + +namespace TYPO3\CMS\Fluid\Tests\Unit\ViewHelpers\Be; + +/* + * This file is part of the TYPO3 CMS project. + * + * It is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, either version 2 + * of the License, or any later version. + * + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. + * + * The TYPO3 project - inspiring people to share! + */ + +use TYPO3\CMS\Backend\Routing\UriBuilder; +use TYPO3\CMS\Core\Utility\GeneralUtility; +use TYPO3\CMS\Fluid\ViewHelpers\Be\UriViewHelper; +use TYPO3\TestingFramework\Fluid\Unit\ViewHelpers\ViewHelperBaseTestcase; + +/** + * Test-case for Be\UriViewHelper + */ +class UriViewHelperTest extends ViewHelperBaseTestcase +{ + + /** + * @var UriViewHelper|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\TestingFramework\Core\AccessibleObjectInterface + */ + protected $viewHelper; + + /** + * @var UriBuilder|\PHPUnit_Framework_MockObject_MockBuilder + */ + protected $uriBuilderMock; + + /** + * setUp function + */ + protected function setUp() + { + parent::setUp(); + $this->viewHelper = new UriViewHelper(); + $this->injectDependenciesIntoViewHelper($this->viewHelper); + + $this->uriBuilderMock = $this->getMockBuilder(UriBuilder::class)->getMock(); + } + + /** + * @test + */ + public function initializeArgumentsRegistersExpectedArguments() + { + $viewHelper = $this->getMockBuilder(UriViewHelper::class) + ->setMethods(['registerArgument']) + ->getMock(); + + $viewHelper->expects($this->at(0))->method('registerArgument')->with('route', 'string', $this->anything()); + $viewHelper->expects($this->at(1))->method('registerArgument')->with('parameters', 'array', $this->anything()); + $viewHelper->expects($this->at(2))->method('registerArgument') + ->with('referenceType', 'string', $this->anything(), false, UriBuilder::ABSOLUTE_PATH); + $viewHelper->initializeArguments(); + } + + /** + * @test + */ + public function renderRendersTagWithHrefFromRoute() + { + $this->viewHelper->setArguments([ + 'route' => 'theRouteArgument', + 'parameters' => ['parameter' => 'to pass'], + 'referenceType' => 'theReferenceTypeArgument' + ]); + + GeneralUtility::addInstance(UriBuilder::class, $this->uriBuilderMock); + + $this->uriBuilderMock->expects($this->once())->method('buildUriFromRoute') + ->with('theRouteArgument', ['parameter' => 'to pass'], 'theReferenceTypeArgument')->willReturn('theUri'); + + $this->assertEquals('theUri', $this->viewHelper->render()); + } +}