Extbase:
authorBastian Waidelich <bastian@typo3.org>
Fri, 12 Jun 2009 16:36:59 +0000 (16:36 +0000)
committerBastian Waidelich <bastian@typo3.org>
Fri, 12 Jun 2009 16:36:59 +0000 (16:36 +0000)
* Tx_Extbase_MVC_Web_Routing_URIBuilder:
  * $additionalArguments is an array now. URIFor() merges additionalArguments with arguments. Fixes #3575
  * DomainObjects in arguments are now replaced recursively. DomainObjects are replaced in additionalArguments too.
  * cache hash is disabled if noCache is set
  * added test cases
  * some smaller tweaks and typo-fixes
* Fixed Tx_Extbase_MVC_Controller_AbstractController_testcase - was still refering to "Tx_Extbase_MVC_View_Helper_URIHelper"

typo3/sysext/extbase/Classes/MVC/Web/Routing/URIBuilder.php
typo3/sysext/extbase/Tests/MVC/Controller/AbstractController_testcase.php
typo3/sysext/extbase/Tests/MVC/Web/Routing/URIBuilder_testcase.php [new file with mode: 0644]

index cb11a7f..127fa93 100644 (file)
@@ -28,7 +28,7 @@ class Tx_Extbase_MVC_Web_Routing_URIBuilder {
        /**
         * An instance of tslib_cObj
         *
-        * @var tslib_cObj
+        * @var tslib_cObj
         */
        protected $contentObject;
 
@@ -40,8 +40,8 @@ class Tx_Extbase_MVC_Web_Routing_URIBuilder {
        /**
         * Constructs this URI Helper
         */
-       public function __construct() {
-               $this->contentObject = t3lib_div::makeInstance('tslib_cObj');
+       public function __construct(tslib_cObj $contentObject = NULL) {
+               $this->contentObject = $contentObject !== NULL ? $contentObject : t3lib_div::makeInstance('tslib_cObj');
        }
 
        /**
@@ -68,18 +68,11 @@ class Tx_Extbase_MVC_Web_Routing_URIBuilder {
         * @param boolean $useCacheHash by default TRUE; if FALSE, disable the cHash
         * @param string $section If specified, adds a given HTML anchor to the URI (#...)
         * @param boolean $linkAccessRestrictedPages If TRUE, generates links for pages where the user does not have permission to see it
-        * @param string $additionalParams An additional params query string which will be appended to the URI
+        * @param array $additionalParams An additional params query array which will be appended to the URI (overrules $arguments)
         * @return string the typolink URI
         * @internal
         */
-       public function URIFor($pageUid = NULL, $actionName = NULL, $arguments = array(), $controllerName = NULL, $extensionName = NULL, $pluginName = NULL, $pageType = 0, $noCache = FALSE, $useCacheHash = TRUE, $section = '', $linkAccessRestrictedPages = FALSE, $additionalParams = '') {
-               if (is_array($arguments)) {
-                       foreach ($arguments as $argumentKey => $argumentValue) {
-                               if ($argumentValue instanceof Tx_Extbase_DomainObject_AbstractEntity) {
-                                       $arguments[$argumentKey] = array('uid' => $argumentValue->getUid());
-                               }
-                       }
-               }
+       public function URIFor($pageUid = NULL, $actionName = NULL, $arguments = array(), $controllerName = NULL, $extensionName = NULL, $pluginName = NULL, $pageType = 0, $noCache = FALSE, $useCacheHash = TRUE, $section = '', $linkAccessRestrictedPages = FALSE, array $additionalParams = array()) {
                if ($actionName !== NULL) {
                        $arguments['action'] = $actionName;
                }
@@ -96,8 +89,31 @@ class Tx_Extbase_MVC_Web_Routing_URIBuilder {
                }
                $argumentPrefix = strtolower('tx_' . $extensionName . '_' . $pluginName);
                $prefixedArguments = (count($arguments) > 0) ? array($argumentPrefix => $arguments) : array();
+               if (count($additionalParams) > 0) {
+                       $prefixedArguments = t3lib_div::array_merge_recursive_overrule($prefixedArguments, $additionalParams);
+               }
+               $prefixedArguments = $this->convertDomainObjectsToIdentityArrays($prefixedArguments);
+
+               return $this->typolinkURI($pageUid, $prefixedArguments, $pageType, $noCache, $useCacheHash, $section, $linkAccessRestrictedPages);
+       }
 
-               return $this->typolinkURI($pageUid, $prefixedArguments, $pageType, $noCache, $useCacheHash, $section, $linkAccessRestrictedPages, $additionalParams);
+       /**
+        * Recursively iterates through the specified arguments and turns instances of type Tx_Extbase_DomainObject_AbstractEntity
+        * into an arrays containing the uid of the domain object.
+        *
+        * @param array $arguments The arguments to be iterated
+        * @return array The modified arguments array
+        * @internal
+        */
+       protected function convertDomainObjectsToIdentityArrays(array $arguments) {
+               foreach ($arguments as $argumentKey => $argumentValue) {
+                       if ($argumentValue instanceof Tx_Extbase_DomainObject_AbstractEntity) {
+                               $arguments[$argumentKey] = array('uid' => $argumentValue->getUid());
+                       } elseif (is_array($argumentValue)) {
+                               $arguments[$argumentKey] = $this->convertDomainObjectsToIdentityArrays($argumentValue);
+                       }
+               }
+               return $arguments;
        }
 
        /**
@@ -110,11 +126,10 @@ class Tx_Extbase_MVC_Web_Routing_URIBuilder {
         * @param boolean $useCacheHash by default TRUE; if FALSE, disable the cHash
         * @param string $section If specified, adds a given HTML anchor to the URI (#...)
         * @param boolean $linkAccessRestrictedPages If TRUE, generates links for pages where the user does not have permission to see it
-        * @param string $additionalParams An additional params query string which will be appended to the URI
         * @return The URI
         * @internal
         */
-       public function typolinkURI($pageUid = NULL, array $arguments = array(), $pageType = 0, $noCache = FALSE, $useCacheHash = TRUE, $section = '', $linkAccessRestrictedPages = FALSE, $additionalParams = '') {
+       public function typolinkURI($pageUid = NULL, array $arguments = array(), $pageType = 0, $noCache = FALSE, $useCacheHash = TRUE, $section = '', $linkAccessRestrictedPages = FALSE) {
                if ($pageUid === NULL) {
                        $pageUid = $GLOBALS['TSFE']->id;
                }
@@ -124,17 +139,15 @@ class Tx_Extbase_MVC_Web_Routing_URIBuilder {
                if ($pageType !== 0) {
                        $typolinkConfiguration['parameter'] .= ',' . $pageType;
                }
-               $typolinkConfiguration['additionalParams'] = '';
+
                if (count($arguments) > 0) {
-                       $typolinkConfiguration['additionalParams'] .= '&' . http_build_query($arguments, NULL, '&');
+                       $typolinkConfiguration['additionalParams'] = '&' . http_build_query($arguments, NULL, '&');
                }
 
                if ($noCache) {
                        $typolinkConfiguration['no_cache'] = 1;
                        // TODO: stdwrap
-               }
-
-               if ($useCacheHash) {
+               } elseif ($useCacheHash) {
                        $typolinkConfiguration['useCacheHash'] = 1;
                }
 
@@ -143,14 +156,8 @@ class Tx_Extbase_MVC_Web_Routing_URIBuilder {
                        // TODO: stdwrap
                }
 
-               if ($linkAccessRestrictedPages === TRUE) {
-                       $typolinkConfiguration['linkAccessRestrictedPages'] = $linkAccessRestrictedPages;
-               }
-
-               if (isset($options['additionalParams'])) {
-                       // TODO: Stdwrap
-                       // TODO FIX THIS: $typolinkConfiguration['additionalParams'] .= $this->contentObject->stdWrap($options['additionalParams'], isset($options['additionalParams.']) ? $options['additionalParams.'] : array());
-                       $typolinkConfiguration['additionalParams'] .= $additionalParams;
+               if ($linkAccessRestrictedPages) {
+                       $typolinkConfiguration['linkAccessRestrictedPages'] = 1;
                }
 
                return $this->contentObject->typoLink_URL($typolinkConfiguration);
index 27df15b..301f6bc 100644 (file)
@@ -103,14 +103,14 @@ class Tx_Extbase_MVC_Controller_AbstractController_testcase extends Tx_Extbase_B
                $mockRequest = $this->getMock('Tx_Extbase_MVC_Web_Request');
                $mockResponse = $this->getMock('Tx_Extbase_MVC_Web_Response');
                
-               $mockURIHelper = $this->getMock('Tx_Extbase_MVC_View_Helper_URIHelper');
-               $mockURIHelper->expects($this->once())->method('URIFor')->with(123, 'theActionName', $arguments, 'TheControllerName', 'TheExtensionName')->will($this->returnValue('the uri'));
+               $mockURIBuilder = $this->getMock('Tx_Extbase_MVC_Web_Routing_URIBuilder');
+               $mockURIBuilder->expects($this->once())->method('URIFor')->with(123, 'theActionName', $arguments, 'TheControllerName', 'TheExtensionName')->will($this->returnValue('the uri'));
        
                $controller = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_MVC_Controller_AbstractController'), array('redirectToURI'), array(), '', FALSE);
                $controller->expects($this->once())->method('redirectToURI')->with('the uri');
                $controller->_set('request', $mockRequest);
                $controller->_set('response', $mockResponse);
-               $controller->_set('URIHelper', $mockURIHelper);
+               $controller->_set('URIBuilder', $mockURIBuilder);
                $controller->_call('redirect', 'theActionName', 'TheControllerName', 'TheExtensionName', $arguments, 123);
        }
        
diff --git a/typo3/sysext/extbase/Tests/MVC/Web/Routing/URIBuilder_testcase.php b/typo3/sysext/extbase/Tests/MVC/Web/Routing/URIBuilder_testcase.php
new file mode 100644 (file)
index 0000000..13e61e9
--- /dev/null
@@ -0,0 +1,268 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3. 
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+class Tx_Extbase_MVC_Web_Routing_URIBuilder_testcase extends Tx_Extbase_Base_testcase {
+
+       protected $tsfeBackup;
+
+       public function setUp() {
+               $this->tsfeBackup = $GLOBALS['TSFE'];
+               $GLOBALS['TSFE'] = $this->getMock('tslib_fe', array(), array(), '', FALSE);
+       }
+
+       public function tearDown() {
+               $GLOBALS['TSFE'] = $this->tsfeBackup;
+       }
+
+       /**
+        * @test
+        */
+       public function uriForPrefixesArgumentsWithExtensionAndPluginNameAndSetsControllerArgument() {
+               $URIBuilder = $this->getMock('Tx_Extbase_MVC_Web_Routing_URIBuilder', array('typolinkURI'));
+
+               $expectedArguments = array('tx_someextension_someplugin' => array('foo' => 'bar', 'baz' => array('extbase' => 'fluid'), 'controller' => 'SomeController'));
+               $URIBuilder->expects($this->once())->method('typolinkURI')->with(NULL, $expectedArguments, 0, FALSE, TRUE, '', FALSE);
+               $URIBuilder->URIFor(NULL, NULL, array('foo' => 'bar', 'baz' => array('extbase' => 'fluid')), 'SomeController', 'SomeExtension', 'SomePlugin');
+       }
+
+       /**
+        * @test
+        */
+       public function additionalArgumentsOverruleArguments() {
+               $URIBuilder = $this->getMock('Tx_Extbase_MVC_Web_Routing_URIBuilder', array('typolinkURI'));
+
+               $arguments = array('foo' => 'bar', 'baz' => array('extbase' => 'fluid'));
+               $additionalArguments = array('tx_someextension_someplugin' => array('foo' => 'overruled'), 'additionalParam' => 'additionalValue');
+               $expectedArguments = array('tx_someextension_someplugin' => array('foo' => 'overruled', 'baz' => array('extbase' => 'fluid'), 'controller' => 'SomeController'), 'additionalParam' => 'additionalValue');
+               $URIBuilder->expects($this->once())->method('typolinkURI')->with(NULL, $expectedArguments, 0, FALSE, TRUE, '', FALSE);
+               $URIBuilder->URIFor(NULL, NULL, $arguments, 'SomeController', 'SomeExtension', 'SomePlugin', 0, FALSE, TRUE, '', FALSE, $additionalArguments);
+       }
+
+       /**
+        * @test
+        */
+       public function uriForForwardsAllParametersToTypolinkURI() {
+               $URIBuilder = $this->getMock('Tx_Extbase_MVC_Web_Routing_URIBuilder', array('typolinkURI'));
+
+               $expectedArguments = array('tx_someextension_someplugin' => array('action' => 'SomeAction', 'controller' => 'SomeController'));
+               $URIBuilder->expects($this->once())->method('typolinkURI')->with(123, $expectedArguments, 2, TRUE, FALSE, 'SomeSection', TRUE);
+               $URIBuilder->URIFor(123, 'SomeAction', array(), 'SomeController', 'SomeExtension', 'SomePlugin', 2, TRUE, FALSE, 'SomeSection', TRUE);
+       }
+
+       /**
+        * @test
+        */
+       public function uriForSetsActionArgument() {
+               $URIBuilder = $this->getMock('Tx_Extbase_MVC_Web_Routing_URIBuilder', array('typolinkURI'));
+
+               $expectedArguments = array('tx_someextension_someplugin' => array('action' => 'SomeAction', 'controller' => 'SomeController'));
+               $URIBuilder->expects($this->once())->method('typolinkURI')->with(NULL, $expectedArguments, 0, FALSE, TRUE, '', FALSE);
+               $URIBuilder->URIFor(NULL, 'SomeAction', array(), 'SomeController', 'SomeExtension', 'SomePlugin');
+       }
+
+       /**
+        * @test
+        */
+       public function uriForSetsControllerFromRequestIfControllerIsNotSet() {
+               $mockRequest = $this->getMock('Tx_Extbase_MVC_Request');
+               $mockRequest->expects($this->once())->method('getControllerName')->will($this->returnValue('SomeControllerFromRequest'));
+
+               $URIBuilder = $this->getMock('Tx_Extbase_MVC_Web_Routing_URIBuilder', array('typolinkURI'));
+               $URIBuilder->setRequest($mockRequest);
+
+               $expectedArguments = array('tx_someextension_someplugin' => array('controller' => 'SomeControllerFromRequest'));
+               $URIBuilder->expects($this->once())->method('typolinkURI')->with(NULL, $expectedArguments, 0, FALSE, TRUE, '', FALSE);
+               $URIBuilder->URIFor(NULL, NULL, array(), NULL, 'SomeExtension', 'SomePlugin');
+       }
+
+       /**
+        * @test
+        */
+       public function uriForSetsExtensionNameFromRequestIfExtensionNameIsNotSet() {
+               $mockRequest = $this->getMock('Tx_Extbase_MVC_Request');
+               $mockRequest->expects($this->once())->method('getControllerExtensionName')->will($this->returnValue('SomeExtensionNameFromRequest'));
+
+               $URIBuilder = $this->getMock('Tx_Extbase_MVC_Web_Routing_URIBuilder', array('typolinkURI'));
+               $URIBuilder->setRequest($mockRequest);
+
+               $expectedArguments = array('tx_someextensionnamefromrequest_someplugin' => array('controller' => 'SomeController'));
+               $URIBuilder->expects($this->once())->method('typolinkURI')->with(NULL, $expectedArguments, 0, FALSE, TRUE, '', FALSE);
+               $URIBuilder->URIFor(NULL, NULL, array(), 'SomeController', NULL, 'SomePlugin');
+       }
+
+       /**
+        * @test
+        */
+       public function uriForSetsPluginNameFromRequestIfPluginNameIsNotSet() {
+               $mockRequest = $this->getMock('Tx_Extbase_MVC_Request');
+               $mockRequest->expects($this->once())->method('getPluginName')->will($this->returnValue('SomePluginNameFromRequest'));
+
+               $URIBuilder = $this->getMock('Tx_Extbase_MVC_Web_Routing_URIBuilder', array('typolinkURI'));
+               $URIBuilder->setRequest($mockRequest);
+
+               $expectedArguments = array('tx_someextension_somepluginnamefromrequest' => array('controller' => 'SomeController'));
+               $URIBuilder->expects($this->once())->method('typolinkURI')->with(NULL, $expectedArguments, 0, FALSE, TRUE, '', FALSE);
+               $URIBuilder->URIFor(NULL, NULL, array(), 'SomeController', 'SomeExtension');
+       }
+
+       /**
+        * @test
+        */
+       public function uriForCallsConvertDomainObjectsToIdentityArraysAfterArgumentsHaveBeenMerged() {
+               $URIBuilder = $this->getMock('Tx_Extbase_MVC_Web_Routing_URIBuilder', array('typolinkURI', 'convertDomainObjectsToIdentityArrays'));
+
+               $arguments = array('foo' => 'bar', 'baz' => array('extbase' => 'fluid'));
+               $additionalArguments = array('tx_someextension_someplugin' => array('foo' => 'overruled'), 'additionalParam' => 'additionalValue');
+               $expectedArguments = array('tx_someextension_someplugin' => array('foo' => 'overruled', 'baz' => array('extbase' => 'fluid'), 'controller' => 'SomeController'), 'additionalParam' => 'additionalValue');
+               $URIBuilder->expects($this->once())->method('convertDomainObjectsToIdentityArrays')->with($expectedArguments)->will($this->returnValue(array()));;
+               $URIBuilder->URIFor(NULL, NULL, $arguments, 'SomeController', 'SomeExtension', 'SomePlugin', 0, FALSE, TRUE, '', FALSE, $additionalArguments);
+       }
+
+       /**
+        * @test
+        */
+       public function convertDomainObjectsToIdentityArraysConvertsDomainObjects() {
+               $mockDomainObject1 = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_DomainObject_AbstractEntity'), array('dummy'));
+               $mockDomainObject1->_set('uid', '123');
+
+               $mockDomainObject2 = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_DomainObject_AbstractEntity'), array('dummy'));
+               $mockDomainObject2->_set('uid', '321');
+
+               $URIBuilder = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_MVC_Web_Routing_URIBuilder'), array('dummy'));
+
+               $expectedResult = array('foo' => array('bar' => 'baz'), 'domainObject1' => array('uid' => '123'), 'second' => array('domainObject2' => array('uid' => '321')));
+               $actualResult = $URIBuilder->_call('convertDomainObjectsToIdentityArrays', array('foo' => array('bar' => 'baz'), 'domainObject1' => $mockDomainObject1, 'second' => array('domainObject2' => $mockDomainObject2)));
+
+               $this->assertEquals($expectedResult, $actualResult);
+       }
+
+       /**
+        * @test
+        */
+       public function typolinkURILinksToCurrentPageIfPageUidIsNotSet() {
+               $mockContentObject = $this->getMock('tslib_cObj');
+               $URIBuilder = new Tx_Extbase_MVC_Web_Routing_URIBuilder($mockContentObject);
+
+               $GLOBALS['TSFE']->id = 123;
+               $expectedConfiguration = array('parameter' => 123, 'useCacheHash' => 1);
+               $mockContentObject->expects($this->once())->method('typoLink_URL')->with($expectedConfiguration);
+
+               $URIBuilder->typolinkURI();
+       }
+
+       /**
+        * @test
+        */
+       public function typolinkURILinksToPageUidIfSet() {
+               $mockContentObject = $this->getMock('tslib_cObj');
+               $URIBuilder = new Tx_Extbase_MVC_Web_Routing_URIBuilder($mockContentObject);
+
+               $expectedConfiguration = array('parameter' => 321, 'useCacheHash' => 1);
+               $mockContentObject->expects($this->once())->method('typoLink_URL')->with($expectedConfiguration);
+
+               $URIBuilder->typolinkURI(321);
+       }
+
+       /**
+        * @test
+        */
+       public function typolinkURILinksProperlySetsAdditionalArguments() {
+               $mockContentObject = $this->getMock('tslib_cObj');
+               $URIBuilder = new Tx_Extbase_MVC_Web_Routing_URIBuilder($mockContentObject);
+
+               $expectedConfiguration = array('parameter' => 123, 'useCacheHash' => 1, 'additionalParams' => '&foo=bar&baz%5Bextbase%5D=fluid');
+               $mockContentObject->expects($this->once())->method('typoLink_URL')->with($expectedConfiguration);
+
+               $URIBuilder->typolinkURI(123, array('foo' => 'bar', 'baz' => array('extbase' => 'fluid')));
+       }
+
+       /**
+        * @test
+        */
+       public function typolinkURIConsidersPageType() {
+               $mockContentObject = $this->getMock('tslib_cObj');
+               $URIBuilder = new Tx_Extbase_MVC_Web_Routing_URIBuilder($mockContentObject);
+
+               $expectedConfiguration = array('parameter' => '123,2', 'useCacheHash' => 1);
+               $mockContentObject->expects($this->once())->method('typoLink_URL')->with($expectedConfiguration);
+
+               $URIBuilder->typolinkURI(123, array(), 2);
+       }
+
+       /**
+        * @test
+        */
+       public function typolinkURIDisablesCacheHashIfNoCacheIsSet() {
+               $mockContentObject = $this->getMock('tslib_cObj');
+               $URIBuilder = new Tx_Extbase_MVC_Web_Routing_URIBuilder($mockContentObject);
+
+               $expectedConfiguration = array('parameter' => 123, 'no_cache' => 1);
+               $mockContentObject->expects($this->once())->method('typoLink_URL')->with($expectedConfiguration);
+
+               $URIBuilder->typolinkURI(123, array(), 0, TRUE, TRUE);
+       }
+
+       /**
+        * @test
+        */
+       public function cacheHashCanBeDisabled() {
+               $mockContentObject = $this->getMock('tslib_cObj');
+               $URIBuilder = new Tx_Extbase_MVC_Web_Routing_URIBuilder($mockContentObject);
+
+               $expectedConfiguration = array('parameter' => 123);
+               $mockContentObject->expects($this->once())->method('typoLink_URL')->with($expectedConfiguration);
+
+               $URIBuilder->typolinkURI(123, array(), 0, FALSE, FALSE);
+       }
+
+       /**
+        * @test
+        */
+       public function typolinkURIConsidersSection() {
+               $mockContentObject = $this->getMock('tslib_cObj');
+               $URIBuilder = new Tx_Extbase_MVC_Web_Routing_URIBuilder($mockContentObject);
+
+               $expectedConfiguration = array('parameter' => 123, 'section' => 'SomeSection');
+               $mockContentObject->expects($this->once())->method('typoLink_URL')->with($expectedConfiguration);
+
+               $URIBuilder->typolinkURI(123, array(), 0, FALSE, FALSE, 'SomeSection');
+       }
+
+       /**
+        * @test
+        */
+       public function typolinkURIConsidersLinkAccessRestrictedPages() {
+               $mockContentObject = $this->getMock('tslib_cObj');
+               $URIBuilder = new Tx_Extbase_MVC_Web_Routing_URIBuilder($mockContentObject);
+
+               $expectedConfiguration = array('parameter' => 123, 'linkAccessRestrictedPages' => 1);
+               $mockContentObject->expects($this->once())->method('typoLink_URL')->with($expectedConfiguration);
+
+               $URIBuilder->typolinkURI(123, array(), 0, FALSE, FALSE, '', TRUE);
+       }
+}
+?>