[FEATURE] Add uri/link to backend route ViewHelper 06/47306/16
authorRuud Silvrants <ruudsilvrants@gmail.com>
Fri, 2 Sep 2016 19:35:45 +0000 (21:35 +0200)
committerSusanne Moog <susanne.moog@typo3.org>
Sat, 9 Dec 2017 21:48:54 +0000 (22:48 +0100)
Since unified URL routing is in place for TYPO3 v9 now,
a new pair of linking to routes is added.

Change-Id: Ied1a67aee173a9a1dc00eaadc9676ded1276076f
Resolves: #75161
Releases: master
Reviewed-on: https://review.typo3.org/47306
Reviewed-by: Benni Mack <benni@typo3.org>
Tested-by: Benni Mack <benni@typo3.org>
Tested-by: TYPO3com <no-reply@typo3.com>
Reviewed-by: Susanne Moog <susanne.moog@typo3.org>
Tested-by: Susanne Moog <susanne.moog@typo3.org>
typo3/sysext/core/Documentation/Changelog/master/Feature-75161-CreateUrilinkToBackendModulesViewhelper.rst [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Be/LinkViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Be/UriViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/ViewHelpers/Be/LinkViewHelperTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/ViewHelpers/Be/UriViewHelperTest.php [new file with mode: 0644]

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 (file)
index 0000000..80a8c0b
--- /dev/null
@@ -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 (file)
index 0000000..90d9598
--- /dev/null
@@ -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 (file)
index 0000000..f5d9a47
--- /dev/null
@@ -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 (file)
index 0000000..48ff9d2
--- /dev/null
@@ -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 (file)
index 0000000..1b97e7d
--- /dev/null
@@ -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());
+    }
+}