Extbase:
authorJochen Rau <j.rau@web.de>
Mon, 18 May 2009 19:16:25 +0000 (19:16 +0000)
committerJochen Rau <j.rau@web.de>
Mon, 18 May 2009 19:16:25 +0000 (19:16 +0000)
* Added a new registerPlugin() method to Extbase
UtilityTx_Extbase_Utility_Plugin::registerPlugin('BlogExample', 'Pi1', 'A Blog Example', array('Blog' => 'index,show,edit'));
* Added Unit Tests

typo3/sysext/extbase/Classes/Utility/Plugin.php [new file with mode: 0644]
typo3/sysext/extbase/Tests/Utility/Plugin_testcase.php [new file with mode: 0644]
typo3/sysext/extbase/ext_emconf.php

diff --git a/typo3/sysext/extbase/Classes/Utility/Plugin.php b/typo3/sysext/extbase/Classes/Utility/Plugin.php
new file mode 100644 (file)
index 0000000..fb22351
--- /dev/null
@@ -0,0 +1,137 @@
+<?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!
+***************************************************************/
+
+/**
+ * Utilities to manage the plugins of an extension
+ *
+ * @package Extbase
+ * @subpackage extbase
+ * @version $ID:$
+ */
+class Tx_Extbase_Utility_Plugin {
+
+       /**
+        * 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_tables.php FILES
+        * Usage: 2
+        *
+        * @param       string          $extensionName is the extension name in UpperCamelCase
+        * @param       string          $pluginName must be a unique id for your plugin in UpperCamelCase (the string length of the extension key added to the length of the plugin name should be less than 32!)
+        * @param       string          $pluginTitle is a speaking title of the plugin that will be displayed in the drop down menu in the backend
+        * @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, the first controller and its first action is chosen as default)
+        * @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
+        */
+       public static function registerPlugin($extensionName, $pluginName, $pluginTitle, array $controllerActions, array $nonCachableControllerActions = array()) {
+               if (empty($pluginName)) {
+                       throw new InvalidArgumentException('The plugin name must not be empty', 1239891987);
+               }
+               if (empty($extensionName) || preg_match('/[A-Z][A-Za-z0-9]/', $extensionName) === 0) {
+                       throw new InvalidArgumentException('The extension name was invalid (must not be empty and must match /[A-Z]][A-Za-z0-9]/)', 1239891989);
+               }
+               $pluginSignature = strtolower($extensionName) . '_' . strtolower($pluginName);
+
+               $controllerCounter = 1;
+               $hasMultipleActionsCounter = 0;
+               $controllers = '';
+               foreach ($controllerActions as $controller => $actionsList) {
+                       $controllers .= '
+               ' . $controllerCounter . '.controller = ' . $controller . '
+               ' . $controllerCounter . '.actions = ' . $actionsList;
+                       $controllerCounter++;
+                       if (strpos($actionsList, ',') !== FALSE) {
+                               $hasMultipleActionsCounter++;
+                       }
+               }
+
+               $switchableControllerActions = '';
+               if ($controllerCounter > 1 || $hasMultipleActionsCounter > 0) {
+                               $switchableControllerActions = '
+       switchableControllerActions {' . $controllers . '
+       }';
+               }
+
+               reset($controllerActions);
+               $defaultController = key($controllerActions);
+               $controller = '
+       controller = ' . $defaultController;
+               $defaultAction = array_shift(t3lib_div::trimExplode(',', current($controllerActions)));
+               $action = '
+       action = ' . $defaultAction;
+
+               $nonCachableActions = array();
+               if (!empty($nonCachableControllerActions[$defaultController])) {
+                       $nonCachableActions = t3lib_div::trimExplode(',', $nonCachableControllerActions[$defaultController]);
+               }               
+               $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_' . $pluginSignature . '|controller = ' . $controllerName . '] && [globalString: GP = tx_' . $pluginSignature . '|action = /' . implode('|', $contentObjectType === 'USER' ? $nonCachableActions : $cachableActions) . '/]
+tt_content.list.20.' . $pluginSignature . ' = ' . ($contentObjectType === 'USER' ? 'USER_INT' : 'USER') . '
+[global]
+';
+                               }
+                       }
+               }
+
+               $pluginContent = trim('
+tt_content.list.20.' . $pluginSignature . ' = ' . $contentObjectType . '
+tt_content.list.20.' . $pluginSignature . ' {
+       userFunc = tx_extbase_dispatcher->dispatch
+       pluginName = ' . $pluginName . '
+       extensionName = ' . $extensionName .
+       $controller .
+       $action . 
+       $switchableControllerActions . '
+}
+' . $conditions);
+
+               t3lib_extMgm::addTypoScript($extensionName, 'setup', '
+# Setting ' . $extensionName . ' plugin TypoScript
+' . $pluginContent, 43);
+
+               t3lib_extMgm::addPlugin(array($pluginTitle, $pluginSignature), 'list_type');
+       }
+
+
+}
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Tests/Utility/Plugin_testcase.php b/typo3/sysext/extbase/Tests/Utility/Plugin_testcase.php
new file mode 100644 (file)
index 0000000..3197020
--- /dev/null
@@ -0,0 +1,357 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Oliver Hader <oliver@typo3.org>
+*  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
+ *
+ * @author     Oliver Hader <oliver@typo3.org>
+ * @package TYPO3
+ * @subpackage t3lib
+ */
+class t3lib_extmgm_testcase extends tx_phpunit_testcase {
+       
+       /**
+        * Contains backup of defined GLOBALS
+        * @var array
+        */
+       protected $globals = array();
+
+       /**
+        * Contains backup of $TYPO3_CONF_VARS
+        * @var array
+        */
+       protected $typo3ConfVars = array();
+
+       public function setUp() {
+               global $TYPO3_CONF_VARS;
+               $this->typo3ConfVars = $TYPO3_CONF_VARS;
+               $this->globals = array(
+                       'TYPO3_LOADED_EXT' => serialize($GLOBALS['TYPO3_LOADED_EXT']),
+               );
+       }
+       
+       public function tearDown() {
+               global $TYPO3_CONF_VARS;
+               $TYPO3_CONF_VARS = $this->typo3ConfVars;
+               foreach ($this->globals as $key => $value) {
+                       $GLOBALS[$key] = unserialize($value);
+               }
+       }
+       
+       /**
+        * @test
+        * @see t3lib_extMgm::getExtensionKeyByPrefix
+        */
+       public function checkGetExtensionKeyByPrefix() {
+               $uniqueSuffix = uniqid('test');
+               $GLOBALS['TYPO3_LOADED_EXT']['tt_news' . $uniqueSuffix] = array();
+               $GLOBALS['TYPO3_LOADED_EXT']['kickstarter' . $uniqueSuffix] = array();
+
+               $this->assertEquals(
+                       'tt_news' . $uniqueSuffix,
+                       t3lib_extMgm::getExtensionKeyByPrefix('tx_ttnews' . $uniqueSuffix)
+               );
+               $this->assertEquals(
+                       'kickstarter' . $uniqueSuffix,
+                       t3lib_extMgm::getExtensionKeyByPrefix('tx_kickstarter' . $uniqueSuffix)
+               );
+               $this->assertFalse(
+                       t3lib_extMgm::getExtensionKeyByPrefix('tx_unloadedextension' . $uniqueSuffix)
+               );
+       }
+       
+
+       /**
+        * @test
+        * @see Tx_Extbase_Utility_Plugin::registerPlugin
+        */
+       public function addingTsWorksForMinimalisticSetup() {
+               global $TYPO3_CONF_VARS;
+               $TYPO3_CONF_VARS['FE']['defaultTypoScript_setup.'] = array();
+               Tx_Extbase_Utility_Plugin::registerPlugin(
+                       'MyExtension',
+                       'Pi1',
+                       'My Plugin Title',
+                       array('Blog' => 'index')
+               );
+               $staticTypoScript = $TYPO3_CONF_VARS['FE']['defaultTypoScript_setup.']['43'];
+
+               $this->assertContains('tt_content.list.20.myextension_pi1 = USER', $staticTypoScript);
+               $this->assertContains('
+       pluginName = Pi1
+       extensionName = MyExtension', $staticTypoScript);
+       
+       $this->assertNotContains('USER_INT', $staticTypoScript);
+       }
+
+       /**
+        * @test
+        * @see Tx_Extbase_Utility_Plugin::registerPlugin
+        */
+       public function addingTsWorksForASingleControllerAction() {
+               global $TYPO3_CONF_VARS;
+               $TYPO3_CONF_VARS['FE']['defaultTypoScript_setup.'] = array();
+               Tx_Extbase_Utility_Plugin::registerPlugin(
+                       'MyExtension',
+                       'Pi1',
+                       'My Plugin Title',
+                       array(
+                               'FirstController' => 'index'
+                               )
+               );
+               $staticTypoScript = $TYPO3_CONF_VARS['FE']['defaultTypoScript_setup.']['43'];
+
+               $this->assertContains('tt_content.list.20.myextension_pi1 = USER', $staticTypoScript);
+               $this->assertContains('
+       pluginName = Pi1
+       extensionName = MyExtension
+       controller = FirstController
+       action = index', $staticTypoScript);
+               $this->assertNotContains('USER_INT', $staticTypoScript);
+       }
+
+       /**
+        * @test
+        * @see Tx_Extbase_Utility_Plugin::registerPlugin
+        */
+       public function addingPluginWithEmptyPluginNameResultsInAnError() {
+               $this->setExpectedException('InvalidArgumentException');
+               Tx_Extbase_Utility_Plugin::registerPlugin(
+                       'MyExtension',
+                       '',
+                       'My Plugin Title',
+                       array(
+                               'FirstController' => 'index'
+                               )
+               );
+       }
+
+       /**
+        * @test
+        * @see Tx_Extbase_Utility_Plugin::registerPlugin
+        */
+       public function addingPluginWithEmptyExtensionNameResultsInAnError() {
+               $this->setExpectedException('InvalidArgumentException');
+               Tx_Extbase_Utility_Plugin::registerPlugin(
+                       '',
+                       'Pi1',
+                       'My Plugin Title',
+                       array(
+                               'FirstController' => 'index'
+                               )
+               );
+       }
+
+       /**
+        * @test
+        * @see Tx_Extbase_Utility_Plugin::registerPlugin
+        */
+       public function addingPluginWithInvalidExtensionNameResultsInAnError() {
+               $this->setExpectedException('InvalidArgumentException');
+               Tx_Extbase_Utility_Plugin::registerPlugin(
+                       'my_extension',
+                       'Pi1',
+                       'My Plugin Title',
+                       array(
+                               'FirstController' => 'index'
+                               )
+               );
+       }
+
+       /**
+        * @test
+        * @see Tx_Extbase_Utility_Plugin::registerPlugin
+        */
+       public function addingPluginRespectsDefaultActionAsANonCachableAction() {
+               global $TYPO3_CONF_VARS;
+               $TYPO3_CONF_VARS['FE']['defaultTypoScript_setup.'] = array();
+               Tx_Extbase_Utility_Plugin::registerPlugin(
+                       'MyExtension',
+                       'Pi1',
+                       'My Plugin Title',
+                       array(
+                               'FirstController' => 'index,show,new,create,delete,edit,update'
+                               ),
+                       array(
+                               'FirstController' => 'index,show'
+                               )
+                       );
+               $staticTypoScript = $TYPO3_CONF_VARS['FE']['defaultTypoScript_setup.']['43'];
+
+               $this->assertContains('
+tt_content.list.20.myextension_pi1 = USER_INT
+tt_content.list.20.myextension_pi1 {', $staticTypoScript);
+               $this->assertContains('
+[globalString: GP = tx_myextension_pi1|controller = FirstController] && [globalString: GP = tx_myextension_pi1|action = /new|create|delete|edit|update/]
+tt_content.list.20.myextension_pi1 = USER', $staticTypoScript);
+       }
+
+       /**
+        * @test
+        * @see Tx_Extbase_Utility_Plugin::registerPlugin
+        */
+       public function addingPluginRespectsNonDefaultActionAsANonCachableAction() {
+               global $TYPO3_CONF_VARS;
+               $TYPO3_CONF_VARS['FE']['defaultTypoScript_setup.'] = array();
+               Tx_Extbase_Utility_Plugin::registerPlugin(
+                       'MyExtension',
+                       'Pi1',
+                       'My Plugin Title',
+                       array(
+                               'FirstController' => 'index,show,new,create,delete,edit,update'
+                               ),
+                       array(
+                               'FirstController' => 'show,new'
+                               )
+                       );
+               $staticTypoScript = $TYPO3_CONF_VARS['FE']['defaultTypoScript_setup.']['43'];
+
+               $this->assertContains('
+tt_content.list.20.myextension_pi1 = USER
+tt_content.list.20.myextension_pi1 {', $staticTypoScript);
+               $this->assertContains('
+[globalString: GP = tx_myextension_pi1|controller = FirstController] && [globalString: GP = tx_myextension_pi1|action = /show|new/]
+tt_content.list.20.myextension_pi1 = USER_INT', $staticTypoScript);
+       }
+
+       /**
+        * @test
+        * @see Tx_Extbase_Utility_Plugin::registerPlugin
+        */
+       public function addingPluginWorksForMultipleControllerActionsWithCachableActionAsDefault() {
+               global $TYPO3_CONF_VARS;
+               $TYPO3_CONF_VARS['FE']['defaultTypoScript_setup.'] = array();
+               Tx_Extbase_Utility_Plugin::registerPlugin(
+                       'MyExtension',
+                       'Pi1',
+                       'My Plugin Title',
+                       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.']['43'];
+
+               $this->assertContains('
+tt_content.list.20.myextension_pi1 = USER
+tt_content.list.20.myextension_pi1 {', $staticTypoScript);
+
+               $this->assertContains('
+[globalString: GP = tx_myextension_pi1|controller = FirstController] && [globalString: GP = tx_myextension_pi1|action = /new|create|edit|update/]
+tt_content.list.20.myextension_pi1 = USER_INT', $staticTypoScript);
+
+               $this->assertContains('
+[globalString: GP = tx_myextension_pi1|controller = SecondController] && [globalString: GP = tx_myextension_pi1|action = /delete/]
+tt_content.list.20.myextension_pi1 = USER_INT', $staticTypoScript);
+
+               $this->assertContains('
+[globalString: GP = tx_myextension_pi1|controller = ThirdController] && [globalString: GP = tx_myextension_pi1|action = /create/]
+tt_content.list.20.myextension_pi1 = USER_INT', $staticTypoScript);
+       }
+
+
+       /**
+        * @test
+        * @see Tx_Extbase_Utility_Plugin::registerPlugin
+        */
+       public function addingPluginWorksForMultipleControllerActionsWithNonCachableActionAsDefault() {
+               global $TYPO3_CONF_VARS;
+               $TYPO3_CONF_VARS['FE']['defaultTypoScript_setup.'] = array();
+               Tx_Extbase_Utility_Plugin::registerPlugin(
+                       'MyExtension',
+                       'Pi1',
+                       'My Plugin Title',
+                       array(
+                               'FirstController' => 'index,show,new,create,delete,edit,update',
+                               'SecondController' => 'index,show,delete',
+                               'ThirdController' => 'create'
+                               ),
+                       array(
+                               'FirstController' => 'index,new,create,edit,update',
+                               'SecondController' => 'delete',
+                               'ThirdController' => 'create'
+                               )
+                       );
+               $staticTypoScript = $TYPO3_CONF_VARS['FE']['defaultTypoScript_setup.']['43'];
+
+               $this->assertContains('
+tt_content.list.20.myextension_pi1 = USER_INT
+tt_content.list.20.myextension_pi1 {', $staticTypoScript);
+
+               $this->assertContains('
+[globalString: GP = tx_myextension_pi1|controller = FirstController] && [globalString: GP = tx_myextension_pi1|action = /show|delete/]
+tt_content.list.20.myextension_pi1 = USER', $staticTypoScript);
+
+               $this->assertContains('
+[globalString: GP = tx_myextension_pi1|controller = SecondController] && [globalString: GP = tx_myextension_pi1|action = /index|show/]
+tt_content.list.20.myextension_pi1 = USER', $staticTypoScript);
+
+               $this->assertNotContains('[globalString: GP = tx_myextension_pi1|controller = ThirdController]', $staticTypoScript);
+       }
+
+               /**
+                * @test
+                * @see Tx_Extbase_Utility_Plugin::registerPlugin
+                */
+               public function addingPluginWorksForMultipleControllerActionsWithNonCachableActionAsDefaultAndOnlyNonCachableActions() {
+                       global $TYPO3_CONF_VARS;
+                       $TYPO3_CONF_VARS['FE']['defaultTypoScript_setup.'] = array();
+                       Tx_Extbase_Utility_Plugin::registerPlugin(
+                               'MyExtension',
+                               'Pi1',
+                               'My Plugin Title',
+                               array(
+                                       'FirstController' => 'index,show,new,create,delete,edit,update',
+                                       'SecondController' => 'index,show,delete',
+                                       'ThirdController' => 'create'
+                                       ),
+                               array(
+                                       'FirstController' => 'index,show,new,create,delete,edit,update',
+                                       'SecondController' => 'index,show,delete',
+                                       'ThirdController' => 'create'
+                                       )
+                               );
+                       $staticTypoScript = $TYPO3_CONF_VARS['FE']['defaultTypoScript_setup.']['43'];
+
+                       $this->assertContains('
+tt_content.list.20.myextension_pi1 = USER_INT
+tt_content.list.20.myextension_pi1 {', $staticTypoScript);
+
+                       $this->assertNotContains('GP', $staticTypoScript);
+               }
+       
+       // TODO switchableControllerActionsIsSupressedIfOnlyOneControllerActionIsGiven()
+       // TODO switchableControllerDingsIsGeneratedWithMultipleControllersEachHavingOnlyOneAction
+
+}
+
+?>
\ No newline at end of file
index ef3bc33..49a9ffe 100644 (file)
@@ -19,7 +19,7 @@ $EM_CONF[$_EXTKEY] = array(
        'shy' => '',
        'dependencies' => '',
        'conflicts' => '',
        'shy' => '',
        'dependencies' => '',
        'conflicts' => '',
-       'priority' => '',
+       'priority' => 'top',
        'module' => '',
        'state' => 'alpha',
        'internal' => '',
        'module' => '',
        'state' => 'alpha',
        'internal' => '',