Extbase:
authorJochen Rau <j.rau@web.de>
Thu, 16 Apr 2009 15:49:29 +0000 (15:49 +0000)
committerJochen Rau <j.rau@web.de>
Thu, 16 Apr 2009 15:49:29 +0000 (15:49 +0000)
* Revised Request Builder according to the latest syntax of t3lib_extMgm::addExtbasePlugin()
* Added necessary core patch and unit tests

typo3/sysext/extbase/Classes/MVC/Web/RequestBuilder.php
typo3/sysext/extbase/Documentation/t3lib_extMgm_addExtbasePlugin.diff [new file with mode: 0644]
typo3/sysext/extbase/Documentation/t3lib_extMgm_testcase.php [new file with mode: 0644]

index 0c46150..9caca17 100755 (executable)
@@ -69,28 +69,28 @@ class Tx_Extbase_MVC_Web_RequestBuilder {
        protected $allowedControllerActions;
        
        public function initialize($configuration) {
-               $this->pluginKey = $configuration['pluginKey'];
-               if (!empty($configuration['extensionName']) && is_string($configuration['extensionName'])) {
+               if (!empty($configuration['pluginKey'])) {
+                       $this->pluginKey = $configuration['pluginKey'];
+               }
+               if (!empty($configuration['extensionName'])) {
                        $this->extensionName = $configuration['extensionName'];
                }
-               if (!empty($configuration['controllers.']) && is_array($configuration['controllers.'])) {
-                       $defaultControllerConfiguration = current($configuration['controllers.']);
-                       if (!empty($defaultControllerConfiguration['controllerName']) && is_string($defaultControllerConfiguration['controllerName'])) {
-                               $this->defaultControllerName = $defaultControllerConfiguration['controllerName'];
-                               $defaultControllerActions = t3lib_div::trimExplode(',', $defaultControllerConfiguration['actions'], TRUE);
-                               if (!empty($defaultControllerActions[0]) && is_string($defaultControllerActions[0])) {
-                                       $this->defaultActionName = $defaultControllerActions[0];
-                               }
-                       }
-                       $allowedControllerActions = array();
-                       foreach ($configuration['controllers.'] as $controllerConfiguration) {
+               if (!empty($configuration['controller'])) {
+                       $this->defaultControllerName = $configuration['controller'];
+               }
+               if (!empty($configuration['action'])) {
+                       $this->defaultActionName = $configuration['action'];
+               }
+               $allowedControllerActions = array();
+               if (is_array($configuration['switchableControllerActions.'])) {
+                       foreach ($configuration['switchableControllerActions.'] as $controllerConfiguration) {
                                $controllerActions = t3lib_div::trimExplode(',', $controllerConfiguration['actions']);
                                foreach ($controllerActions as $actionName) {
-                                       $allowedControllerActions[$controllerConfiguration['controllerName']][] = $actionName;
+                                       $allowedControllerActions[$controllerConfiguration['controller']][] = $actionName;
                                }
                        }
-                       $this->allowedControllerActions = $allowedControllerActions;
                }
+               $this->allowedControllerActions = $allowedControllerActions;
        }
 
        /**
@@ -105,7 +105,7 @@ class Tx_Extbase_MVC_Web_RequestBuilder {
                        $allowedActions = $this->allowedControllerActions[$controllerName];
                        if (is_string($parameters['action']) && is_array($allowedActions) && in_array($parameters['action'], $allowedActions)) {
                                $actionName = filter_var($parameters['action'], FILTER_SANITIZE_STRING);
-                       } else {;
+                       } else {
                                $actionName = $this->defaultActionName;
                        }
                } else {
@@ -113,7 +113,6 @@ class Tx_Extbase_MVC_Web_RequestBuilder {
                        $actionName = $this->defaultActionName;
                }
 
-
                $request = t3lib_div::makeInstance('Tx_Extbase_MVC_Web_Request');
                $request->setPluginKey($this->pluginKey);
                $request->setExtensionName($this->extensionName);
diff --git a/typo3/sysext/extbase/Documentation/t3lib_extMgm_addExtbasePlugin.diff b/typo3/sysext/extbase/Documentation/t3lib_extMgm_addExtbasePlugin.diff
new file mode 100644 (file)
index 0000000..d409db0
--- /dev/null
@@ -0,0 +1,133 @@
+--- typo3_src-trunk.orig/t3lib/class.t3lib_extmgm.php  2009-04-16 17:41:01.000000000 +0200
++++ typo3_src-trunk/t3lib/class.t3lib_extmgm.php       2009-04-16 17:32:25.000000000 +0200
+@@ -994,7 +994,7 @@
+                       // General plugin:
+               $pluginContent = trim('
+-plugin.'.$cN.$prefix.' = USER' . ($cached ? '' : '_INT') . '
++plugin.'.$cN.$prefix.' = ' . ($cached ? 'USER' : 'USER_INT') . '
+ plugin.'.$cN.$prefix.' {
+   includeLibs = '.$TYPO3_LOADED_EXT[$key]['siteRelPath'].$classFile.'
+   userFunc = '.$cN.$prefix.'->main
+@@ -1042,6 +1042,121 @@
+       }
+       /**
++       * Add an Extbase PlugIn to TypoScript
++       *
++       * When adding a frontend plugin you will have to add both an entry to the TCA definition 
++       * of tt_content table AND to the TypoScript template which must initiate the rendering.
++       * Since the static template with uid 43 is the "content.default" and practically always 
++       * used for rendering the content elements it's very useful to have this function automatically 
++       * adding the necessary TypoScript for calling your plugin. It will also work for the 
++       * extension "css_styled_content"
++       * FOR USE IN ext_locallang.php FILES
++       * Usage: 2
++       *
++       * @param       string          $pluginKey must be a unique id for your plugin in lower_underscore (the string length of the extension key added to the length of the plugin key should be less than 32!)
++       * @param       string          $extensionKEy is the extension key in lower_underscore (available in $_EXTKEY)
++       * @param       string          $controllerActions is an array of allowed combinations of controller and action stored in an array (controller name as key and a comma separated list of action names as value)
++       * @param       string          $nonCachableControllerActions is an optional array of controller name and  action names which should not be cached (array as defined in $controllerActions)
++       * @param       string          $defaultControllerAction is an optional array controller name (as array key) and action name (as array value) that should be called as default
++       * @return      void
++       */
++      // TODO tt_content field 'list_type' should be enabled to hold at least 128 characters
++      public static function addExtbasePlugin($pluginKey, $extensionKey, array $controllerActions = array(), array $nonCachableControllerActions = array(), $defaultControllerAction = NULL) {
++              if (empty($pluginKey)) {
++                      throw new InvalidArgumentException('The plugin key must not be empty', 1239891987);
++              }
++              if (empty($extensionKey) || preg_match('/[^_a-z0-9]/', $extensionKey) === 1) {
++                      throw new InvalidArgumentException('The extension key was invalid (must not be empty and must match [_a-z0-9])', 1239891989);
++              }
++              $extensionName = str_replace(' ', '', ucwords(str_replace('_', ' ', strtolower($extensionKey))));
++
++              $controllerCounter = 1;
++              $hasMultipleActionsCounter = 0;
++              $controllers = '';
++              foreach ($controllerActions as $controller => $actionsList) {
++                      $controllers .= '
++              ' . $controllerCounter . '.controller = ' . $controller . '
++              ' . $controllerCounter . '.actions = ' . $actionsList;
++                      $controllerCounter++;
++                      if (strpos($actionsList, ',') !== FALSE) {
++                              $hasMultipleActionsCounter++;
++                      }
++              }
++              if ($hasMultipleActionsCounter > 0) {
++                              $switchableControllerActions = '
++      switchableControllerActions {' . $controllers . '
++      }';
++              } else {
++                      $switchableControllerActions = '';
++              }
++              
++              reset($controllerActions);
++              if ($defaultControllerAction !== NULL) {
++                      $defaultController = key($defaultControllerAction);
++                      $controller = '
++      controller = ' . $defaultController;
++                      $defaultAction = current($defaultControllerAction);
++                      $action = '
++      action = ' . $defaultAction;
++              } elseif (!empty($controllerActions)) {
++                      $defaultController = key($controllerActions);
++                      $controller = '
++      controller = ' . $defaultController;
++                      $defaultAction = array_shift(t3lib_div::trimExplode(',', current($controllerActions)));
++                      $action = '
++      action = ' . $defaultAction;
++              } else {
++                      $defaultController = NULL;
++                      $controller = '';
++                      $defaultAction = NULL;
++                      $action = '';
++              }
++
++              if (!empty($nonCachableControllerActions[$defaultController])) {
++                      $nonCachableActions = t3lib_div::trimExplode(',', $nonCachableControllerActions[$defaultController]);
++              } else {
++                      $nonCachableActions = array();
++              }
++              $cachableActions = array_diff(t3lib_div::trimExplode(',', $controllerActions[$defaultController]), $nonCachableActions);
++              $contentObjectType = in_array($defaultAction, $nonCachableActions) ? 'USER_INT' : 'USER';
++
++              $conditions = '';
++              foreach ($controllerActions as $controllerName => $actionsList) {
++                      if (!empty($nonCachableControllerActions[$controllerName])) {
++                              $nonCachableActions = t3lib_div::trimExplode(',', $nonCachableControllerActions[$controllerName]);
++                              $cachableActions = array_diff(t3lib_div::trimExplode(',', $controllerActions[$controllerName]), $nonCachableActions);
++                              if ((($contentObjectType === 'USER') && (count($nonCachableActions) !== 0)) || (($contentObjectType === 'USER_INT') && (count($cachableActions) !== 0))) {
++                                      $conditions .= '
++[globalString: GP = tx_' . strtolower($extensionName) . '_' . strtolower($pluginKey) . '|controller = ' . $controllerName . '] && [globalString: GP = tx_' . strtolower($extensionName) . '_' . strtolower($pluginKey) . '|action = /' . implode('|', $contentObjectType === 'USER' ? $nonCachableActions : $cachableActions) . '/]
++tt_content.list.20.' . strtolower($extensionKey) . '_' . strtolower($pluginKey) . ' = ' . ($contentObjectType === 'USER' ? 'USER_INT' : 'USER') . '
++[global]
++';
++                              }
++                      }
++              }
++              
++              $pluginContent = trim('
++includeLibs.tx_extbase_dispatcher = EXT:extbase/class.tx_extbase_dispatcher.php
++
++tt_content.list.20.' . strtolower($extensionKey) . '_' . strtolower($pluginKey) . ' = ' . $contentObjectType . '
++tt_content.list.20.' . strtolower($extensionKey) . '_' . strtolower($pluginKey) . ' {
++      userFunc = tx_extbase_dispatcher->dispatch
++      pluginKey = ' . $pluginKey . '
++      extensionName = ' . $extensionName .
++      $controller .
++      $action . 
++      $switchableControllerActions . '
++}
++' . $conditions);
++
++syslog(LOG_ERR, $pluginContent);
++
++              t3lib_extMgm::addTypoScript($extensionKey, 'setup', '
++# Setting ' . $extensionKey . ' plugin TypoScript
++' . $pluginContent, 43);
++      }
++
++      /**
+        * Call this method to add an entry in the static template list found in sys_templates
+        * "static template files" are the modern equalent (provided from extensions) to the traditional records in "static_templates"
+        * FOR USE IN ext_localconf.php FILES
diff --git a/typo3/sysext/extbase/Documentation/t3lib_extMgm_testcase.php b/typo3/sysext/extbase/Documentation/t3lib_extMgm_testcase.php
new file mode 100644 (file)
index 0000000..ec906ca
--- /dev/null
@@ -0,0 +1,294 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  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!
+***************************************************************/
+
+
+/**
+ * Testcase for class t3lib_extmgm
+ *
+ * @package TYPO3
+ * @subpackage t3lib
+ */
+class t3lib_extMgm_testcase extends tx_phpunit_testcase {
+       
+       public function setUp() {
+               global $TYPO3_CONF_VARS;
+               $this->TYPO3_CONF_VARS_backup = $TYPO3_CONF_VARS;
+               $TYPO3_CONF_VARS['FE']['defaultTypoScript_setup.']['cssstyledcontent/static/current/'] = '';
+       }
+       
+       public function tearDown() {
+               global $TYPO3_CONF_VARS;
+               $TYPO3_CONF_VARS = $this->TYPO3_CONF_VARS_before;
+       }
+       
+       /**
+        * @test
+        */
+       public function addingTsWorksForMinimalisticSetup() {
+               global $TYPO3_CONF_VARS;
+               $TYPO3_CONF_VARS['FE']['defaultTypoScript_setup.']['cssstyledcontent/static/current/'] = '';
+               t3lib_extMgm::addExtbasePlugin(
+                       'pluginkey',
+                       'my_extension'
+               );
+               $staticTypoScript = $TYPO3_CONF_VARS['FE']['defaultTypoScript_setup.']['cssstyledcontent/static/current/'];             
+
+               $this->assertContains('includeLibs.tx_extbase_dispatcher = EXT:extbase/class.tx_extbase_dispatcher.php', $staticTypoScript, 'Did not include "tx_extbase_dispatcher".');
+               $this->assertContains('tt_content.list.20.my_extension_pluginkey = USER', $staticTypoScript);
+               $this->assertContains('
+       pluginKey = pluginkey
+       extensionName = MyExtension', $staticTypoScript);
+       $this->assertNotContains('controller =', $staticTypoScript);
+       $this->assertNotContains('action =', $staticTypoScript);
+               $this->assertNotContains('USER_INT', $staticTypoScript);
+       }
+       
+       /**
+        * @test
+        */
+       public function addingTsWorksForASingleControllerAction() {
+               global $TYPO3_CONF_VARS;
+               $TYPO3_CONF_VARS['FE']['defaultTypoScript_setup.']['cssstyledcontent/static/current/'] = '';
+               t3lib_extMgm::addExtbasePlugin(
+                       'pluginkey',
+                       'my_extension',
+                       array(
+                               'FirstController' => 'index'
+                               )
+               );
+               $staticTypoScript = $TYPO3_CONF_VARS['FE']['defaultTypoScript_setup.']['cssstyledcontent/static/current/'];             
+
+               $this->assertContains('includeLibs.tx_extbase_dispatcher = EXT:extbase/class.tx_extbase_dispatcher.php', $staticTypoScript, 'Did not include "tx_extbase_dispatcher".');
+               $this->assertContains('tt_content.list.20.my_extension_pluginkey = USER', $staticTypoScript);
+               $this->assertContains('
+       pluginKey = pluginkey
+       extensionName = MyExtension
+       controller = FirstController
+       action = index', $staticTypoScript);
+               $this->assertNotContains('USER_INT', $staticTypoScript);
+       }
+       
+       /**
+        * @test
+        */
+       public function addingPluginWithEmptyPluginKeyResultsInAnError() {
+               $this->setExpectedException('InvalidArgumentException');
+               t3lib_extMgm::addExtbasePlugin(
+                       '',
+                       'my_extension',
+                       array(
+                               'FirstController' => 'index'
+                               )
+               );
+       }
+       
+       /**
+        * @test
+        */
+       public function addingPluginWithEmptyExtensionKeyResultsInAnError() {
+               $this->setExpectedException('InvalidArgumentException');
+               t3lib_extMgm::addExtbasePlugin(
+                       'pluginKey',
+                       '',
+                       array(
+                               'FirstController' => 'index'
+                               )
+               );
+       }
+
+       /**
+        * @test
+        */
+       public function addingPluginWithInvalidExtensionKeyResultsInAnError() {
+               $this->setExpectedException('InvalidArgumentException');
+               t3lib_extMgm::addExtbasePlugin(
+                       'pluginKey',
+                       'MyExtension',
+                       array(
+                               'FirstController' => 'index'
+                               )
+               );
+       }
+
+       /**
+        * @test
+        */
+       public function theDefaultControllerActionCanBeSetManually() {
+               global $TYPO3_CONF_VARS;
+               $TYPO3_CONF_VARS['FE']['defaultTypoScript_setup.']['cssstyledcontent/static/current/'] = '';
+               t3lib_extMgm::addExtbasePlugin(
+                       'pluginkey',
+                       'my_extension',
+                       array(
+                               'FirstController' => 'index,show,new,create,delete,edit,update',
+                               'SecondController' => 'index,show,delete',
+                               'ThirdController' => 'create'
+                               ),
+                       array(),
+                       array('SecondController' => 'show')     
+                       );
+               $staticTypoScript = $TYPO3_CONF_VARS['FE']['defaultTypoScript_setup.']['cssstyledcontent/static/current/'];             
+
+               $this->assertContains('
+       pluginKey = pluginkey
+       extensionName = MyExtension
+       controller = SecondController
+       action = show', $staticTypoScript);
+       }
+
+       /**
+        * @test
+        */
+       public function addingPluginRespectsDefaultActionAsANonCachableAction() {
+               global $TYPO3_CONF_VARS;
+               $TYPO3_CONF_VARS['FE']['defaultTypoScript_setup.']['cssstyledcontent/static/current/'] = '';
+               t3lib_extMgm::addExtbasePlugin(
+                       'pluginkey',
+                       'my_extension',
+                       array(
+                               'FirstController' => 'index,show,new,create,delete,edit,update'
+                               ),
+                       array(
+                               'FirstController' => 'index,show'
+                               )
+                       );
+               $staticTypoScript = $TYPO3_CONF_VARS['FE']['defaultTypoScript_setup.']['cssstyledcontent/static/current/'];             
+
+               $this->assertContains('
+tt_content.list.20.my_extension_pluginkey = USER_INT
+tt_content.list.20.my_extension_pluginkey {', $staticTypoScript);
+               $this->assertContains('
+[globalString: GP = tx_myextension_pluginkey|controller = FirstController] && [globalString: GP = tx_myextension_pluginkey|action = /new|create|delete|edit|update/]
+tt_content.list.20.my_extension_pluginkey = USER', $staticTypoScript);
+       }
+
+       /**
+        * @test
+        */
+       public function addingPluginRespectsNonDefaultActionAsANonCachableAction() {
+               global $TYPO3_CONF_VARS;
+               $TYPO3_CONF_VARS['FE']['defaultTypoScript_setup.']['cssstyledcontent/static/current/'] = '';
+               t3lib_extMgm::addExtbasePlugin(
+                       'pluginkey',
+                       'my_extension',
+                       array(
+                               'FirstController' => 'index,show,new,create,delete,edit,update'
+                               ),
+                       array(
+                               'FirstController' => 'show,new'
+                               )
+                       );
+               $staticTypoScript = $TYPO3_CONF_VARS['FE']['defaultTypoScript_setup.']['cssstyledcontent/static/current/'];             
+
+               $this->assertContains('
+tt_content.list.20.my_extension_pluginkey = USER
+tt_content.list.20.my_extension_pluginkey {', $staticTypoScript);
+               $this->assertContains('
+[globalString: GP = tx_myextension_pluginkey|controller = FirstController] && [globalString: GP = tx_myextension_pluginkey|action = /show|new/]
+tt_content.list.20.my_extension_pluginkey = USER_INT', $staticTypoScript);
+       }
+
+       /**
+        * @test
+        */
+       public function addingPluginWorksForMultipleControllerActionsWithCachableActionAsDefault() {
+               global $TYPO3_CONF_VARS;
+               $TYPO3_CONF_VARS['FE']['defaultTypoScript_setup.']['cssstyledcontent/static/current/'] = '';
+               t3lib_extMgm::addExtbasePlugin(
+                       'pluginkey',
+                       'my_extension',
+                       array(
+                               'FirstController' => 'index,show,new,create,delete,edit,update',
+                               'SecondController' => 'index,show,delete',
+                               'ThirdController' => 'create'
+                               ),
+                       array(
+                               'FirstController' => 'new,create,edit,update',
+                               'SecondController' => 'delete',
+                               'ThirdController' => 'create'
+                               ),
+                       array('SecondController' => 'show')     
+                       );
+               $staticTypoScript = $TYPO3_CONF_VARS['FE']['defaultTypoScript_setup.']['cssstyledcontent/static/current/'];             
+       
+               $this->assertContains('
+tt_content.list.20.my_extension_pluginkey = USER
+tt_content.list.20.my_extension_pluginkey {', $staticTypoScript);
+
+               $this->assertContains('
+[globalString: GP = tx_myextension_pluginkey|controller = FirstController] && [globalString: GP = tx_myextension_pluginkey|action = /new|create|edit|update/]
+tt_content.list.20.my_extension_pluginkey = USER_INT', $staticTypoScript);
+
+               $this->assertContains('
+[globalString: GP = tx_myextension_pluginkey|controller = SecondController] && [globalString: GP = tx_myextension_pluginkey|action = /delete/]
+tt_content.list.20.my_extension_pluginkey = USER_INT', $staticTypoScript);
+
+               $this->assertContains('
+[globalString: GP = tx_myextension_pluginkey|controller = ThirdController] && [globalString: GP = tx_myextension_pluginkey|action = /create/]
+tt_content.list.20.my_extension_pluginkey = USER_INT', $staticTypoScript);
+       }
+
+
+       /**
+        * @test
+        */
+       public function addingPluginWorksForMultipleControllerActionsWithNonCachableActionAsDefault() {
+               global $TYPO3_CONF_VARS;
+               $TYPO3_CONF_VARS['FE']['defaultTypoScript_setup.']['cssstyledcontent/static/current/'] = '';
+               t3lib_extMgm::addExtbasePlugin(
+                       'pluginkey',
+                       'my_extension',
+                       array(
+                               'FirstController' => 'index,show,new,create,delete,edit,update',
+                               'SecondController' => 'index,show,delete',
+                               'ThirdController' => 'create'
+                               ),
+                       array(
+                               'FirstController' => 'new,create,edit,update',
+                               'SecondController' => 'delete',
+                               'ThirdController' => 'create'
+                               ),
+                       array('SecondController' => 'delete')   
+                       );
+               $staticTypoScript = $TYPO3_CONF_VARS['FE']['defaultTypoScript_setup.']['cssstyledcontent/static/current/'];             
+
+               $this->assertContains('
+tt_content.list.20.my_extension_pluginkey = USER_INT
+tt_content.list.20.my_extension_pluginkey {', $staticTypoScript);
+
+               $this->assertContains('
+[globalString: GP = tx_myextension_pluginkey|controller = FirstController] && [globalString: GP = tx_myextension_pluginkey|action = /index|show|delete/]
+tt_content.list.20.my_extension_pluginkey = USER', $staticTypoScript);
+
+               $this->assertContains('
+[globalString: GP = tx_myextension_pluginkey|controller = SecondController] && [globalString: GP = tx_myextension_pluginkey|action = /index|show/]
+tt_content.list.20.my_extension_pluginkey = USER', $staticTypoScript);
+
+               $this->assertNotContains('[globalString: GP = tx_myextension_pluginkey|controller = ThirdController]', $staticTypoScript);
+       }
+
+
+}
+
+?>
\ No newline at end of file