[!!!][TASK] Remove path-based backend module registration 17/45417/6
authorBenni Mack <benni@typo3.org>
Wed, 23 Dec 2015 01:13:43 +0000 (02:13 +0100)
committerAndreas Fernandez <typo3@scripting-base.de>
Wed, 23 Dec 2015 18:22:47 +0000 (19:22 +0100)
In prior versions of TYPO3 it was possible to access
a backend module via a custom script (index.php) in a folder configured by a configuration file (conf.php) which
held information about the module and the access rights
to it.

The logic is removed.

Resolves: #72405
Releases: master
Change-Id: I3c84f89278f7cea9849821744b9dd14632aaca62
Reviewed-on: https://review.typo3.org/45417
Reviewed-by: Wouter Wolters <typo3@wouterwolters.nl>
Reviewed-by: Daniel Goerz <ervaude@gmail.com>
Tested-by: Wouter Wolters <typo3@wouterwolters.nl>
Reviewed-by: Andreas Fernandez <typo3@scripting-base.de>
Tested-by: Andreas Fernandez <typo3@scripting-base.de>
typo3/sysext/backend/Classes/Http/BackendModuleRequestHandler.php
typo3/sysext/backend/Classes/Module/ModuleLoader.php
typo3/sysext/backend/Classes/Template/DocumentTemplate.php
typo3/sysext/backend/Classes/Template/ModuleTemplate.php
typo3/sysext/backend/Tests/Unit/Fixtures/ModuleFixture/conf.php [deleted file]
typo3/sysext/backend/Tests/Unit/Fixtures/ModuleFixture/index.php [deleted file]
typo3/sysext/backend/Tests/Unit/Http/BackendModuleRequestHandlerTest.php [deleted file]
typo3/sysext/core/Classes/Utility/ExtensionManagementUtility.php
typo3/sysext/core/Documentation/Changelog/master/Breaking-72405-RemoveTraditionalBEModulesHandling.rst [new file with mode: 0644]

index 1fbcc90..8f8a91c 100644 (file)
@@ -88,16 +88,7 @@ class BackendModuleRequestHandler implements RequestHandlerInterface
         $this->backendUserAuthentication = $GLOBALS['BE_USER'];
 
         $moduleName = (string)$this->request->getQueryParams()['M'];
-        if ($this->isDispatchedModule($moduleName)) {
-            return $this->dispatchModule($moduleName);
-        } else {
-            // @deprecated: This else path is deprecated and throws deprecations logs at registration time. Can be removed with TYPO3 CMS 8.
-            $isDispatched = $this->callTraditionalModule($moduleName);
-            if (!$isDispatched) {
-                throw new Exception('No module "' . $moduleName . '" could be found.', 1294585070);
-            }
-        }
-        return null;
+        return $this->dispatchModule($moduleName);
     }
 
     /**
@@ -152,18 +143,6 @@ class BackendModuleRequestHandler implements RequestHandlerInterface
     }
 
     /**
-     * A dispatched module is used, when no PATH is given.
-     * Traditional modules have a module path set.
-     *
-     * @param string $moduleName
-     * @return bool
-     */
-    protected function isDispatchedModule($moduleName)
-    {
-        return empty($this->moduleRegistry['_PATHS'][$moduleName]);
-    }
-
-    /**
      * Executes the modules configured via Extbase
      *
      * @param string $moduleName
@@ -215,36 +194,6 @@ class BackendModuleRequestHandler implements RequestHandlerInterface
     }
 
     /**
-     * Calls traditional modules which are identified by having an index.php in their directory
-     * and were previously located within the global scope.
-     *
-     * @param string $moduleName
-     * @return bool Returns TRUE if the module was executed
-     */
-    protected function callTraditionalModule($moduleName)
-    {
-        $moduleBasePath = $this->moduleRegistry['_PATHS'][$moduleName];
-        // Some modules still rely on this global configuration array in a conf.php file
-        // load configuration from an existing conf.php file inside the same directory
-        if (file_exists($moduleBasePath . 'conf.php')) {
-            require $moduleBasePath . 'conf.php';
-            $moduleConfiguration = $MCONF;
-        } else {
-            $moduleConfiguration = $this->getModuleConfiguration($moduleName);
-        }
-        $GLOBALS['MCONF'] = $moduleConfiguration;
-        if (!empty($moduleConfiguration['access'])) {
-            $this->backendUserAuthentication->modAccess($moduleConfiguration, true);
-        }
-        if (file_exists($moduleBasePath . 'index.php')) {
-            global $SOBE;
-            require $moduleBasePath . 'index.php';
-            return true;
-        }
-        return false;
-    }
-
-    /**
      * Returns the module configuration which is provided during module registration
      *
      * @param string $moduleName
index d0047a7..3d12824 100644 (file)
@@ -41,13 +41,6 @@ class ModuleLoader
     public $modules = array();
 
     /**
-     * Array with paths pointing to the location of modules from extensions
-     *
-     * @var array
-     */
-    public $absPathArray = array();
-
-    /**
      * This array will hold the elements that should go into the select-list of modules for groups...
      *
      * @var array
@@ -96,102 +89,33 @@ class ModuleLoader
         // Setting the backend user for use internally
         $this->BE_USER = $beUser ?: $GLOBALS['BE_USER'];
 
-        /*$modulesArray might look like this when entering this function.
-        Notice the two modules added by extensions - they have a path attachedArray
-        (
-        [web] => list,info,perm,func
-        [file] => list
-        [user] =>
-        [tools] => em,install,txphpmyadmin
-        [help] => about
-        [_PATHS] => Array
-        (
-        [system_install] => /www/htdocs/typo3/32/coreinstall/typo3/ext/install/mod/
-        [tools_txphpmyadmin] => /www/htdocs/typo3/32/coreinstall/typo3/ext/phpmyadmin/modsub/
-        ))
-         */
-        $this->absPathArray = $modulesArray['_PATHS'];
-        unset($modulesArray['_PATHS']);
-        // Unset the array for calling external backend module dispatchers in typo3/index.php
-        // (unused in Core, but in case some extension still sets this, we unset that)
-        unset($modulesArray['_dispatcher']);
         // Unset the array for calling backend modules based on external backend module dispatchers in typo3/index.php
         unset($modulesArray['_configuration']);
         $this->navigationComponents = $modulesArray['_navigationComponents'];
         unset($modulesArray['_navigationComponents']);
-        $theMods = $this->parseModulesArray($modulesArray);
-        // Originally modules were found in typo3/mod/
-        // User defined modules were found in ../typo3conf/
-        // Today almost all modules reside in extensions and they are found by the _PATHS array of the incoming $TBE_MODULES array
-        // Setting paths for 1) core modules (old concept from mod/) and 2) user-defined modules (from ../typo3conf)
-        $paths = array();
-        // Path of static modules
-        $paths['defMods'] = PATH_typo3 . 'mod/';
-        // Local modules (maybe frontend specific)
-        $paths['userMods'] = PATH_typo3 . '../typo3conf/';
+        $mainModules = $this->parseModulesArray($modulesArray);
+
         // Traverses the module setup and creates the internal array $this->modules
-        foreach ($theMods as $mods => $subMod) {
-            $path = null;
-            $extModRelPath = $this->checkExtensionModule($mods);
-            // EXTENSION module:
-            if ($extModRelPath) {
-                $theMainMod = $this->checkMod($mods, PATH_site . $extModRelPath);
-                if (is_array($theMainMod) || $theMainMod != 'notFound') {
-                    // ... just so it goes on... submodules cannot be within this path!
-                    $path = 1;
-                }
-            } else {
-                // 'CLASSIC' module
-                // Checking for typo3/mod/ module existence...
-                $theMainMod = $this->checkMod($mods, $paths['defMods'] . $mods);
-                if (is_array($theMainMod) || $theMainMod != 'notFound') {
-                    $path = $paths['defMods'];
-                } else {
-                    // If not typo3/mod/ then it could be user-defined in typo3conf/ ...?
-                    $theMainMod = $this->checkMod($mods, $paths['userMods'] . $mods);
-                    if (is_array($theMainMod) || $theMainMod != 'notFound') {
-                        $path = $paths['userMods'];
-                    }
-                }
-            }
-            // If $theMainMod is not set (FALSE) there is no access to the module !(?)
-            if ($theMainMod && !is_null($path)) {
-                $this->modules[$mods] = $theMainMod;
-                // SUBMODULES - if any - are loaded
-                if (is_array($subMod)) {
-                    foreach ($subMod as $valsub) {
-                        $extModRelPath = $this->checkExtensionModule($mods . '_' . $valsub);
-                        if ($extModRelPath) {
-                            // EXTENSION submodule:
-                            $theTempSubMod = $this->checkMod($mods . '_' . $valsub, PATH_site . $extModRelPath);
-                            // Default sub-module in either main-module-path, be it the default or the userdefined.
-                            if (is_array($theTempSubMod)) {
-                                $this->modules[$mods]['sub'][$valsub] = $theTempSubMod;
-                            }
-                        } else {
-                            // 'CLASSIC' submodule
-                            // Checking for typo3/mod/xxx/ module existence...
-                            // @todo what about $path = 1; from above and using $path as string here?
-                            $theTempSubMod = $this->checkMod($mods . '_' . $valsub, $path . $mods . '/' . $valsub);
-                            // Default sub-module in either main-module-path, be it the default or the userdefined.
-                            if (is_array($theTempSubMod)) {
-                                $this->modules[$mods]['sub'][$valsub] = $theTempSubMod;
-                            } elseif ($path == $paths['defMods']) {
-                                // If the submodule did not exist in the default module path, then check if there is a submodule in the submodule path!
-                                $theTempSubMod = $this->checkMod($mods . '_' . $valsub, $paths['userMods'] . $mods . '/' . $valsub);
-                                if (is_array($theTempSubMod)) {
-                                    $this->modules[$mods]['sub'][$valsub] = $theTempSubMod;
-                                }
-                            }
+        foreach ($mainModules as $mainModuleName => $subModules) {
+            $mainModuleConfiguration = $this->checkMod($mainModuleName);
+            // If $mainModuleConfiguration is not set (FALSE) there is no access to the module !(?)
+            if (is_array($mainModuleConfiguration)) {
+                $this->modules[$mainModuleName] = $mainModuleConfiguration;
+                // Load the submodules
+                if (is_array($subModules)) {
+                    foreach ($subModules as $subModuleName) {
+                        $subModuleConfiguration = $this->checkMod($mainModuleName . '_' . $subModuleName);
+                        if (is_array($subModuleConfiguration)) {
+                            $this->modules[$mainModuleName]['sub'][$subModuleName] = $subModuleConfiguration;
                         }
                     }
                 }
-            } else {
+            } elseif ($mainModuleConfiguration !== false) {
+                // Although the configuration was not found, still check if there are submodules
                 // This must be done in order to fill out the select-lists for modules correctly!!
-                if (is_array($subMod)) {
-                    foreach ($subMod as $valsub) {
-                        // @todo path can only be NULL here, or not?
-                        $this->checkMod($mods . '_' . $valsub, $path . $mods . '/' . $valsub);
+                if (is_array($subModules)) {
+                    foreach ($subModules as $subModuleName) {
+                        $this->checkMod($mainModuleName . '_' . $subModuleName);
                     }
                 }
             }
@@ -199,21 +123,6 @@ class ModuleLoader
     }
 
     /**
-     * If the module name ($name) is a module from an extension (has path in $this->absPathArray)
-     * then that path is returned relative to PATH_site
-     *
-     * @param string $name Module name
-     * @return string If found, the relative path from PATH_site
-     */
-    public function checkExtensionModule($name)
-    {
-        if (isset($this->absPathArray[$name])) {
-            return rtrim(PathUtility::stripPathSitePrefix($this->absPathArray[$name]), '/');
-        }
-        return '';
-    }
-
-    /**
      * Here we check for the module.
      *
      * Return values:
@@ -222,10 +131,9 @@ class ModuleLoader
      * array():            Configuration array, in case a valid module where access IS granted exists.
      *
      * @param string $name Module name
-     * @param string $fullPath Absolute path to module
      * @return string|bool|array See description of function
      */
-    public function checkMod($name, $fullPath)
+    public function checkMod($name)
     {
         if ($name === 'user_ws' && !ExtensionManagementUtility::isLoaded('version')) {
             return false;
@@ -234,7 +142,7 @@ class ModuleLoader
         if (is_array($GLOBALS['TBE_MODULES']['_configuration'][$name]['configureModuleFunction'])) {
             $obj = $GLOBALS['TBE_MODULES']['_configuration'][$name]['configureModuleFunction'];
             if (is_callable($obj)) {
-                $MCONF = call_user_func($obj, $name, $fullPath);
+                $MCONF = call_user_func($obj, $name);
                 if ($this->checkModAccess($name, $MCONF) !== true) {
                     return false;
                 }
@@ -242,10 +150,9 @@ class ModuleLoader
             }
         }
 
-        // merges $MCONF and $MLANG from conf.php and the additional configuration of the module
-        $setupInformation = $this->getModuleSetupInformation($name, $fullPath);
+        // merge configuration and labels into one array
+        $setupInformation = $this->getModuleSetupInformation($name);
 
-        // Because 'path/../path' does not work
         // clean up the configuration part
         if (empty($setupInformation['configuration'])) {
             return 'notFound';
@@ -268,29 +175,9 @@ class ModuleLoader
 
             // Here the path is transformed to an absolute reference.
             if ($defaultLabels['tabs_images']['tab']) {
-                // Initializing search for alternative icon:
-                // Alternative icon key (might have an alternative set in $TBE_STYLES['skinImg']
-                $altIconKey = 'MOD:' . $name . '/' . $defaultLabels['tabs_images']['tab'];
-                $altIconAbsPath = is_array($GLOBALS['TBE_STYLES']['skinImg'][$altIconKey]) ? GeneralUtility::resolveBackPath(PATH_typo3 . $GLOBALS['TBE_STYLES']['skinImg'][$altIconKey][0]) : '';
-                // Setting icon, either default or alternative:
-                if ($altIconAbsPath && @is_file($altIconAbsPath)) {
-                    $defaultLabels['tabs_images']['tab'] = $altIconAbsPath;
-                } else {
-                    if (\TYPO3\CMS\Core\Utility\StringUtility::beginsWith($defaultLabels['tabs_images']['tab'], 'EXT:')) {
-                        list($extensionKey, $relativePath) = explode('/', substr($defaultLabels['tabs_images']['tab'], 4), 2);
-                        $defaultLabels['tabs_images']['tab'] = ExtensionManagementUtility::extPath($extensionKey) . $relativePath;
-                    } else {
-                        $defaultLabels['tabs_images']['tab'] = $fullPath . '/' . $defaultLabels['tabs_images']['tab'];
-                    }
-                }
-
-                $defaultLabels['tabs_images']['tab'] = $this->getRelativePath(PATH_typo3, $defaultLabels['tabs_images']['tab']);
-
-                // Finally, setting the icon with correct path:
-                if (substr($defaultLabels['tabs_images']['tab'], 0, 3) === '../') {
-                    $defaultLabels['tabs_images']['tab'] = PATH_site . substr($defaultLabels['tabs_images']['tab'], 3);
-                } else {
-                    $defaultLabels['tabs_images']['tab'] = PATH_typo3 . $defaultLabels['tabs_images']['tab'];
+                if (\TYPO3\CMS\Core\Utility\StringUtility::beginsWith($defaultLabels['tabs_images']['tab'], 'EXT:')) {
+                    list($extensionKey, $relativePath) = explode('/', substr($defaultLabels['tabs_images']['tab'], 4), 2);
+                    $defaultLabels['tabs_images']['tab'] = ExtensionManagementUtility::extPath($extensionKey) . $relativePath;
                 }
             }
 
@@ -316,9 +203,6 @@ class ModuleLoader
                 // just go through BackendModuleRequestHandler where the routeTarget is resolved
                 $finalModuleConfiguration['script'] = BackendUtility::getModuleUrl($name);
             }
-        } elseif ($setupInformation['configuration']['script'] && file_exists($setupInformation['path'] . '/' . $setupInformation['configuration']['script'])) {
-            GeneralUtility::deprecationLog('Loading module "' . $name . '" as a standalone script. Script-based modules are deprecated since TYPO3 CMS 7. Support will be removed with TYPO3 CMS 8, use the "routeTarget" option or dispatched modules instead.');
-            $finalModuleConfiguration['script'] = $this->getRelativePath(PATH_typo3, $fullPath . '/' . $setupInformation['configuration']['script']);
         } else {
             $finalModuleConfiguration['script'] = BackendUtility::getModuleUrl('dummy');
         }
@@ -330,18 +214,6 @@ class ModuleLoader
                     ? $setupInformation['configuration']['navigationFrameModuleParameters']
                     : array()
             );
-        } elseif (!empty($setupInformation['configuration']['navFrameScript'])) {
-            GeneralUtility::deprecationLog('Loading navFrameScript "' . $setupInformation['configuration']['navFrameScript'] . '" as a standalone script. Script-based navigation frames are deprecated since TYPO3 CMS 7. Support will be removed with TYPO3 CMS 8, use "navigationFrameModule" option or the "navigationComponentId" option instead.');
-            // Navigation Frame Script (GET params could be added)
-            $navFrameScript = explode('?', $setupInformation['configuration']['navFrameScript']);
-            $navFrameScript = $navFrameScript[0];
-            if (file_exists($setupInformation['path'] . '/' . $navFrameScript)) {
-                $finalModuleConfiguration['navFrameScript'] = $this->getRelativePath(PATH_typo3, $fullPath . '/' . $setupInformation['configuration']['navFrameScript']);
-            }
-            // Additional params for Navigation Frame Script: "&anyParam=value&moreParam=1"
-            if ($setupInformation['configuration']['navFrameScriptParam']) {
-                $finalModuleConfiguration['navFrameScriptParam'] = $setupInformation['configuration']['navFrameScriptParam'];
-            }
         }
 
         // Check if this is a submodule
@@ -365,37 +237,15 @@ class ModuleLoader
      * some additional configuration
      *
      * @param \string $moduleName the combined name of the module, can be "web", "web_info", or "tools_log"
-     * @param \string $pathToModuleDirectory the path where the module data is put, used for the conf.php or the modScript
      * @return array an array with subarrays, named "configuration" (aka $MCONF), "labels" (previously known as $MLANG) and the stripped path
      */
-    protected function getModuleSetupInformation($moduleName, $pathToModuleDirectory)
+    protected function getModuleSetupInformation($moduleName)
     {
-
-        // Because 'path/../path' does not work
-        $path = preg_replace('/\\/[^\\/.]+\\/\\.\\.\\//', '/', $pathToModuleDirectory);
-
         $moduleSetupInformation = array(
             'configuration' => array(),
-            'labels' => array(),
-            'path' => $path
+            'labels' => array()
         );
 
-        if (@is_dir($path) && file_exists($path . '/conf.php')) {
-            $MCONF = array();
-            $MLANG = array();
-
-            // The conf-file is included. This must be valid PHP.
-            include $path . '/conf.php';
-
-            // Move the global variables defined in conf.php into the local method
-            if (is_array($MCONF)) {
-                $moduleSetupInformation['configuration'] = $MCONF;
-            } else {
-                $moduleSetupInformation['configuration'] = array();
-            }
-            $moduleSetupInformation['labels'] = $MLANG;
-        }
-
         $moduleConfiguration = !empty($GLOBALS['TBE_MODULES']['_configuration'][$moduleName])
             ? $GLOBALS['TBE_MODULES']['_configuration'][$moduleName]
             : null;
index 6489f25..506e1bd 100644 (file)
@@ -286,15 +286,7 @@ function jumpToUrl(URL) {
         $this->templateService = GeneralUtility::makeInstance(MarkerBasedTemplateService::class);
 
         // Setting default scriptID:
-        if (($temp_M = (string)GeneralUtility::_GET('M')) && $GLOBALS['TBE_MODULES']['_PATHS'][$temp_M]) {
-            $this->scriptID = preg_replace('/^.*\\/(sysext|ext)\\//', 'ext/', $GLOBALS['TBE_MODULES']['_PATHS'][$temp_M] . 'index.php');
-        } else {
-            $this->scriptID = preg_replace('/^.*\\/(sysext|ext)\\//', 'ext/', \TYPO3\CMS\Core\Utility\PathUtility::stripPathSitePrefix(PATH_thisScript));
-        }
-        if (TYPO3_mainDir != 'typo3/' && substr($this->scriptID, 0, strlen(TYPO3_mainDir)) == TYPO3_mainDir) {
-            // This fixes if TYPO3_mainDir has been changed so the script ids are STILL "typo3/..."
-            $this->scriptID = 'typo3/' . substr($this->scriptID, strlen(TYPO3_mainDir));
-        }
+        $this->scriptID = GeneralUtility::_GET('M') !== null ? GeneralUtility::_GET('M') : GeneralUtility::_GET('route');
         $this->bodyTagId = preg_replace('/[^A-Za-z0-9-]/', '-', $this->scriptID);
         // Individual configuration per script? If so, make a recursive merge of the arrays:
         if (is_array($GLOBALS['TBE_STYLES']['scriptIDindex'][$this->scriptID])) {
@@ -477,7 +469,7 @@ function jumpToUrl(URL) {
         // We still need to pass the xMOD name to createShortcut below, since this is used for icons.
         $moduleName = $modName === 'xMOD_alt_doc.php' ? 'record_edit' : $modName;
         // Add the module identifier automatically if typo3/index.php is used:
-        if (GeneralUtility::_GET('M') !== null && isset($GLOBALS['TBE_MODULES']['_PATHS'][$moduleName])) {
+        if (GeneralUtility::_GET('M') !== null) {
             $storeUrl = '&M=' . $moduleName . $storeUrl;
         }
         if ((int)$motherModName === 1) {
index 1d918cb..ffa1122 100644 (file)
@@ -528,7 +528,7 @@ class ModuleTemplate
         // since this is used for icons.
         $moduleName = $modName === 'xMOD_alt_doc.php' ? 'record_edit' : $modName;
         // Add the module identifier automatically if typo3/index.php is used:
-        if (GeneralUtility::_GET('M') !== null && isset($GLOBALS['TBE_MODULES']['_PATHS'][$moduleName])) {
+        if (GeneralUtility::_GET('M') !== null) {
             $storeUrl = '&M=' . $moduleName . $storeUrl;
         }
         if ((int)$motherModName === 1) {
diff --git a/typo3/sysext/backend/Tests/Unit/Fixtures/ModuleFixture/conf.php b/typo3/sysext/backend/Tests/Unit/Fixtures/ModuleFixture/conf.php
deleted file mode 100644 (file)
index 6073f69..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-<?php
-$MCONF = array();
-$MCONF['name'] = 'module_fixture';
diff --git a/typo3/sysext/backend/Tests/Unit/Fixtures/ModuleFixture/index.php b/typo3/sysext/backend/Tests/Unit/Fixtures/ModuleFixture/index.php
deleted file mode 100644 (file)
index f946048..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-<?php
-throw new \InvalidArgumentException('ModuleFixture loaded', 1425236663);
diff --git a/typo3/sysext/backend/Tests/Unit/Http/BackendModuleRequestHandlerTest.php b/typo3/sysext/backend/Tests/Unit/Http/BackendModuleRequestHandlerTest.php
deleted file mode 100644 (file)
index c1858c0..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-<?php
-namespace TYPO3\CMS\Backend\Tests\Unit\Http;
-
-/*
- * 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 PHPUnit_Framework_MockObject_MockObject;
-use TYPO3\CMS\Backend\Http\BackendModuleRequestHandler;
-use TYPO3\CMS\Core\FormProtection\BackendFormProtection;
-use TYPO3\CMS\Core\Tests\AccessibleObjectInterface;
-use TYPO3\CMS\Core\Tests\UnitTestCase;
-
-/**
- * Class BackendModuleRequestHandlerTest
- */
-class BackendModuleRequestHandlerTest extends UnitTestCase
-{
-    /**
-     * @var BackendModuleRequestHandler|\PHPUnit_Framework_MockObject_MockObject|AccessibleObjectInterface
-     */
-    protected $subject;
-
-    /**
-     * @var \TYPO3\CMS\Core\FormProtection\AbstractFormProtection|PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $formProtectionMock;
-
-    /**
-     * @var \TYPO3\CMS\Core\Http\ServerRequest|PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $requestMock;
-
-    protected function setUp()
-    {
-        $this->requestMock = $this->getAccessibleMock(\TYPO3\CMS\Core\Http\ServerRequest::class, array(), array(), '', false);
-        $this->formProtectionMock = $this->getMockForAbstractClass(BackendFormProtection::class, array(), '', false, true, true, array('validateToken'));
-        $this->subject = $this->getAccessibleMock(BackendModuleRequestHandler::class, array('boot', 'getFormProtection'), array(\TYPO3\CMS\Core\Core\Bootstrap::getInstance()), '', true);
-    }
-
-    /**
-     * @test
-     * @expectedException \InvalidArgumentException
-     * @expectedExceptionCode 1425236663
-     */
-    public function moduleIndexIsCalled()
-    {
-        $GLOBALS['TBE_MODULES'] = array(
-            '_PATHS' => array(
-                'module_fixture' => __DIR__ . '/../Fixtures/ModuleFixture/'
-            )
-        );
-
-        $this->requestMock->expects($this->any())->method('getQueryParams')->will($this->returnValue(array('M' => 'module_fixture')));
-        $this->formProtectionMock->expects($this->once())->method('validateToken')->will($this->returnValue(true));
-        $this->subject->expects($this->once())->method('boot');
-        $this->subject->expects($this->atLeastOnce())->method('getFormProtection')->will($this->returnValue($this->formProtectionMock));
-
-        $this->subject->handleRequest($this->requestMock);
-    }
-
-    /**
-     * @test
-     * @expectedException \TYPO3\CMS\Core\Exception
-     * @expectedExceptionCode 1417988921
-     */
-    public function throwsExceptionIfTokenIsInvalid()
-    {
-        $this->formProtectionMock->expects($this->once())->method('validateToken')->will($this->returnValue(false));
-        $this->subject->expects($this->once())->method('boot');
-        $this->subject->expects($this->atLeastOnce())->method('getFormProtection')->will($this->returnValue($this->formProtectionMock));
-
-        $this->subject->handleRequest($this->requestMock);
-    }
-
-    /**
-     * @test
-     * @expectedException \InvalidArgumentException
-     * @expectedExceptionCode 1425236663
-     */
-    public function moduleDispatcherIsCalled()
-    {
-        $GLOBALS['TBE_MODULES'] = array(
-            '_PATHS' => array(
-                'module_fixture' => __DIR__ . '/../Fixtures/ModuleFixture/'
-            )
-        );
-        $this->requestMock->expects($this->any())->method('getQueryParams')->will($this->returnValue(array('M' => 'module_fixture')));
-        $this->formProtectionMock->expects($this->once())->method('validateToken')->will($this->returnValue(true));
-        $this->subject->expects($this->once())->method('boot');
-        $this->subject->expects($this->atLeastOnce())->method('getFormProtection')->will($this->returnValue($this->formProtectionMock));
-
-        $this->subject->handleRequest($this->requestMock);
-    }
-}
index 2fe318a..240996f 100644 (file)
@@ -866,10 +866,9 @@ class ExtensionManagementUtility
      * and it replaces old conf.php.
      *
      * @param string $moduleSignature The module name
-     * @param string $modulePath Absolute path to module (not used by Extbase currently)
      * @return array Configuration of the module
      */
-    public static function configureModule($moduleSignature, $modulePath)
+    public static function configureModule($moduleSignature)
     {
         $moduleConfiguration = $GLOBALS['TBE_MODULES']['_configuration'][$moduleSignature];
         $iconPathAndFilename = $moduleConfiguration['icon'];
@@ -877,7 +876,6 @@ class ExtensionManagementUtility
             list($extensionKey, $relativePath) = explode('/', substr($iconPathAndFilename, 4), 2);
             $iconPathAndFilename = self::extPath($extensionKey) . $relativePath;
         }
-        // @todo skin support
         $moduleLabels = array(
             'tabs_images' => array(
                 'tab' => $iconPathAndFilename
@@ -901,11 +899,11 @@ class ExtensionManagementUtility
      * @param string $main The main module key, $sub is the submodule key. So $main would be an index in the $TBE_MODULES array and $sub could be an element in the lists there.
      * @param string $sub The submodule key. If $sub is not set a blank $main module is created.
      * @param string $position Can be used to set the position of the $sub module within the list of existing submodules for the main module. $position has this syntax: [cmd]:[submodule-key]. cmd can be "after", "before" or "top" (or blank which is default). If "after"/"before" then submodule will be inserted after/before the existing submodule with [submodule-key] if found. If not found, the bottom of list. If "top" the module is inserted in the top of the submodule list.
-     * @param string $path The absolute path to the module. If this value is defined the path is added as an entry in $TBE_MODULES['_PATHS'][  main_sub  ] = $path; and thereby tells the backend where the newly added modules is found in the system. This option is deprecated as of TYPO3 CMS 7, and will have no effect in TYPO3 CMS 8 anymore.
+     * @param string $path The absolute path to the module. Was used prior to TYPO3 v8, use $moduleConfiguration[routeTarget] now
      * @param array $moduleConfiguration additional configuration, previously put in "conf.php" of the module directory
      * @return void
      */
-    public static function addModule($main, $sub = '', $position = '', $path = '', $moduleConfiguration = array())
+    public static function addModule($main, $sub = '', $position = '', $path = null, $moduleConfiguration = array())
     {
         // If there is already a main module by this name:
         // Adding the submodule to the correct position:
@@ -938,15 +936,10 @@ class ExtensionManagementUtility
             // Create new main modules with only one submodule, $sub (or none if $sub is blank)
             $GLOBALS['TBE_MODULES'][$main] = $sub;
         }
-        $fullModuleSignature = $main . ($sub ? '_' . $sub : '');
-        // Adding path:
-        if ($path) {
-            GeneralUtility::deprecationLog('Registered "' . $fullModuleSignature . '" as a script-based module. Script-based modules are deprecated since TYPO3 CMS 7. Support will be removed with TYPO3 CMS 8, use the "routeTarget" option or dispatched modules instead.');
-            self::addModulePath($fullModuleSignature, $path);
-        }
 
         // add additional configuration
         if (is_array($moduleConfiguration) && !empty($moduleConfiguration)) {
+            $fullModuleSignature = $main . ($sub ? '_' . $sub : '');
             $GLOBALS['TBE_MODULES']['_configuration'][$fullModuleSignature] = $moduleConfiguration;
         }
     }
@@ -985,28 +978,6 @@ class ExtensionManagementUtility
     }
 
     /**
-     * Adds a module path to $GLOBALS['TBE_MODULES'] for used with the module dispatcher, index.php
-     * Used only for modules that are not placed in the main/sub menu hierarchy by the traditional mechanism of addModule()
-     * Examples for this is context menu functionality (like import/export) which runs as an independent module through index.php
-     * FOR USE IN ext_tables.php FILES
-     * Example:  \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addModulePath('xMOD_tximpexp', \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extPath($_EXTKEY).'app/');
-     *
-     * @param string $name The name of the module, refer to conf.php of the module.
-     * @param string $path The absolute path to the module directory inside of which "index.php" and "conf.php" is found.
-     * @return void
-     * @deprecated since TYPO3 CMS 7, will be removed in TYPO3 CMS 8, use routeTarget or dispatched modules instead.
-     */
-    public static function addModulePath($name, $path)
-    {
-        GeneralUtility::logDeprecatedFunction();
-        if (StringUtility::beginsWith($path, 'EXT:')) {
-            list($extensionKey, $relativePath) = explode('/', substr($path, 4), 2);
-            $path = ExtensionManagementUtility::extPath($extensionKey) . $relativePath;
-        }
-        $GLOBALS['TBE_MODULES']['_PATHS'][$name] = $path;
-    }
-
-    /**
      * Adds a "Function menu module" ('third level module') to an existing function menu for some other backend module
      * The arguments values are generally determined by which function menu this is supposed to interact with
      * See Inside TYPO3 for information on how to use this function.
@@ -1025,7 +996,6 @@ class ExtensionManagementUtility
     {
         $GLOBALS['TBE_MODULES_EXT'][$modname]['MOD_MENU'][$MM_key][$className] = array(
             'name' => $className,
-            'path' => null,
             'title' => $title,
             'ws' => $WS
         );
diff --git a/typo3/sysext/core/Documentation/Changelog/master/Breaking-72405-RemoveTraditionalBEModulesHandling.rst b/typo3/sysext/core/Documentation/Changelog/master/Breaking-72405-RemoveTraditionalBEModulesHandling.rst
new file mode 100644 (file)
index 0000000..3ffe7cf
--- /dev/null
@@ -0,0 +1,31 @@
+=========================================================
+Breaking: #72405 - Remove traditional BE modules handling
+=========================================================
+
+Description
+===========
+
+The traditional way of registering backend modules done via custom ``mod1/index.php`` and ``mod1/conf.php`` has been removed.
+
+
+Impact
+======
+
+Calling ``ExtensionManagementUtility::addModulePath()`` will result in a fatal error. Additionally, all modules that
+are registered via ``ExtensionManagementUtility::addModule()`` and setting a path will not be registered properly
+anymore.
+
+``$TBE_MODULES['_PATHS']`` is always empty now. Additionally, the options ``script`` and ``navFrameScript`` and
+``navFrameScriptParam`` will have no effect anymore when registering a module.
+
+
+Affected Installations
+======================
+
+Any installation using an extension that registers a module via the traditional way using standalone scripts.
+
+
+Migration
+=========
+
+Use the option ``routeTarget`` when registering a module, and PSR-7 equivalent entry-points in module controllers.
\ No newline at end of file