[TASK] Release installation procedure from LocalConfiguration file 06/19506/4
authorChristian Kuhn <lolli@schwarzbu.ch>
Mon, 1 Apr 2013 20:53:36 +0000 (22:53 +0200)
committerChristian Kuhn <lolli@schwarzbu.ch>
Tue, 2 Apr 2013 18:38:45 +0000 (20:38 +0200)
The dummy, government and introduction packages deliver with a
default typo3conf/LocalConfiguration.php file to set defaults. If
the installation was not yet completed, those files do not contain
database settings. The bootstrap loads LocalConfiguration and
redirects to the install tool in 123 mode, if those db credentials
are missing. This is ugly and leads to several headaches.

The patch introduces a new file called "FactoryConfiguration.php"
within ext:core Configuration directory to set those defaults now.
The packages can overload these settings with an own file in
typo3conf called "AdditionalFactoryConfiguration", eg. to load the
specific extensions needed during the install process.

This way, the packages do not deliver a "LocalConfiguration" file
anymore. The boostrap now just checks for the existence of the file
and redirects to the install tool if it doesn't exist. The install
tool then creates the "LocalConfiguration" from the factory files
at an early point in the process.

The patch has to deal with different side effect of this:
* ConfigurationManager is no singleton anymore, there was no reason
  for that in the first place anyway.
* ConfigurationManager has a new method to deal with the factory
  files.
* ConfigurationManager got some refactoring to get rid of constants
* Bootstrap is adapted to the new file existance handling.
* GeneralUtility::fixPermissions now can give default permission
  values for files if the settings do not exist yet.
* GeneralUtility::writeFile now accepts a new argument to force
  setting permissions. This is used in ConfigurationManager to
  end up with a LocalConfigurationFile with correct permissions
  as soon as installation is completed.
* As usual, the patch has a good test coverage to show everything
  works as expected.

Change-Id: Icb644534e6d1f426bc9512a941a69d3ee3727223
Resolves: #46854
Releases: 6.1
Reviewed-on: https://review.typo3.org/19506
Reviewed-by: Oliver Hader
Tested-by: Oliver Hader
Reviewed-by: Anja Leichsenring
Tested-by: Anja Leichsenring
Reviewed-by: Jigal van Hemert
Tested-by: Jigal van Hemert
Reviewed-by: Christian Kuhn
Tested-by: Christian Kuhn
15 files changed:
index.php
typo3/init.php
typo3/install/index.php
typo3/sysext/core/Classes/Configuration/ConfigurationManager.php
typo3/sysext/core/Classes/Core/Bootstrap.php
typo3/sysext/core/Classes/Database/DatabaseConnection.php
typo3/sysext/core/Classes/Utility/ExtensionManagementUtility.php
typo3/sysext/core/Classes/Utility/GeneralUtility.php
typo3/sysext/core/Configuration/FactoryConfiguration.php [new file with mode: 0644]
typo3/sysext/core/Tests/Unit/Configuration/ConfigurationManagerTest.php
typo3/sysext/core/Tests/Unit/Utility/GeneralUtilityTest.php
typo3/sysext/frontend/Classes/Controller/TypoScriptFrontendController.php
typo3/sysext/install/Classes/CoreUpdates/LocalConfigurationUpdate.php
typo3/sysext/install/Classes/InstallBootstrap.php
typo3/sysext/install/Classes/Installer.php

index afad2a3..74cdf99 100644 (file)
--- a/index.php
+++ b/index.php
@@ -34,7 +34,9 @@
  */
 
 require 'typo3/sysext/core/Classes/Core/Bootstrap.php';
-\TYPO3\CMS\Core\Core\Bootstrap::getInstance()->baseSetup('');
+\TYPO3\CMS\Core\Core\Bootstrap::getInstance()
+       ->baseSetup('')
+       ->redirectToInstallToolIfLocalConfigurationFileDoesNotExist();
 
 require(PATH_tslib . 'index_ts.php');
 ?>
\ No newline at end of file
index cf7ad32..76077a9 100644 (file)
@@ -56,6 +56,7 @@ require 'sysext/core/Classes/Core/Bootstrap.php';
 
 \TYPO3\CMS\Core\Core\Bootstrap::getInstance()
        ->baseSetup('typo3/')
+       ->redirectToInstallToolIfLocalConfigurationFileDoesNotExist('../')
        ->startOutputBuffering()
        ->loadConfigurationAndInitialize()
        ->loadTypo3LoadedExtAndExtLocalconf(TRUE)
@@ -64,7 +65,6 @@ require 'sysext/core/Classes/Core/Bootstrap.php';
        ->checkLockedBackendAndRedirectOrDie()
        ->checkBackendIpOrDie()
        ->checkSslBackendAndRedirectIfNeeded()
-       ->redirectToInstallToolIfDatabaseCredentialsAreMissing()
        ->checkValidBrowserOrDie()
        ->establishDatabaseConnection()
        ->loadExtensionTables(TRUE)
index 4f26962..08a402b 100755 (executable)
@@ -39,6 +39,7 @@ require '../sysext/core/Classes/Core/Bootstrap.php';
 
 require '../sysext/install/Classes/InstallBootstrap.php';
 \TYPO3\CMS\Install\InstallBootstrap::checkEnabledInstallToolOrDie();
+\TYPO3\CMS\Install\InstallBootstrap::createLocalConfigurationIfNotExists();
 
 \TYPO3\CMS\Core\Core\Bootstrap::getInstance()
        ->startOutputBuffering()
index 3c46b61..971337f 100644 (file)
@@ -36,27 +36,42 @@ use TYPO3\CMS\Core\Utility;
  *
  * @author Helge Funk <helge.funk@e-net.info>
  */
-class ConfigurationManager implements \TYPO3\CMS\Core\SingletonInterface {
+class ConfigurationManager {
 
        /**
-        * Path to default TYPO3_CONF_VARS file, relative to PATH_site
+        * @var string Path to default TYPO3_CONF_VARS file, relative to PATH_site
         */
-       const DEFAULT_CONFIGURATION_FILE = 'typo3/sysext/core/Configuration/DefaultConfiguration.php';
+       protected $defaultConfigurationFile = 'typo3/sysext/core/Configuration/DefaultConfiguration.php';
 
        /**
-        * Path to local overload TYPO3_CONF_VARS file, relative to PATH_site
+        * @var string Path to local overload TYPO3_CONF_VARS file, relative to PATH_site
         */
-       const LOCAL_CONFIGURATION_FILE = 'typo3conf/LocalConfiguration.php';
+       protected $localConfigurationFile = 'typo3conf/LocalConfiguration.php';
 
        /**
-        * Path to additional local file, relative to PATH_site
+        * @var string Path to additional local file, relative to PATH_site
         */
-       const ADDITIONAL_CONFIGURATION_FILE = 'typo3conf/AdditionalConfiguration.php';
+       protected $additionalConfigurationFile = 'typo3conf/AdditionalConfiguration.php';
 
        /**
-        * Path to legacy localconf.php file, relative to PATH_site
+        * @var string Path to factory configuration file used during installation as LocalConfiguration boilerplate
         */
-       const LOCALCONF_FILE = 'typo3conf/localconf.php';
+       protected $factoryConfigurationFile = 'typo3/sysext/core/Configuration/FactoryConfiguration.php';
+
+       /**
+        * @var string Path to possible additional factory configuration file delivered by packages
+        */
+       protected $additionalFactoryConfigurationFile = 'typo3conf/AdditionalFactoryConfiguration.php';
+
+       /**
+        * @var string Path to legacy localconf.php file, relative to PATH_site
+        */
+       protected $localconfFile = 'typo3conf/localconf.php';
+
+       /**
+        * @var string Absolute path to typo3conf directory
+        */
+       protected $pathTypo3Conf = PATH_typo3conf;
 
        /**
         * Writing to these configuration pathes is always allowed,
@@ -77,18 +92,18 @@ class ConfigurationManager implements \TYPO3\CMS\Core\SingletonInterface {
         * @return array
         */
        public function getDefaultConfiguration() {
-               return require $this->getDefaultConfigurationFileResource();
+               return require $this->getDefaultConfigurationFileLocation();
        }
 
        /**
-        * Get the file resource of the default configuration file,
+        * Get the file location of the default configuration file,
         * currently the path and filename.
         *
         * @return string
         * @access private
         */
-       public function getDefaultConfigurationFileResource() {
-               return PATH_site . self::DEFAULT_CONFIGURATION_FILE;
+       public function getDefaultConfigurationFileLocation() {
+               return PATH_site . $this->defaultConfigurationFile;
        }
 
        /**
@@ -97,29 +112,57 @@ class ConfigurationManager implements \TYPO3\CMS\Core\SingletonInterface {
         * @return array Content array of local configuration file
         */
        public function getLocalConfiguration() {
-               return require $this->getLocalConfigurationFileResource();
+               return require $this->getLocalConfigurationFileLocation();
        }
 
        /**
-        * Get the file resource of the local configuration file,
+        * Get the file location of the local configuration file,
         * currently the path and filename.
         *
         * @return string
         * @access private
         */
-       public function getLocalConfigurationFileResource() {
-               return PATH_site . self::LOCAL_CONFIGURATION_FILE;
+       public function getLocalConfigurationFileLocation() {
+               return PATH_site . $this->localConfigurationFile;
        }
 
        /**
-        * Get the file resource of the aditional configuration file,
+        * Get the file location of the additional configuration file,
         * currently the path and filename.
         *
         * @return string
         * @access private
         */
-       public function getAdditionalConfigurationFileResource() {
-               return PATH_site . self::ADDITIONAL_CONFIGURATION_FILE;
+       public function getAdditionalConfigurationFileLocation() {
+               return PATH_site . $this->additionalConfigurationFile;
+       }
+
+       /**
+        * Get absolute file location of factory configuration file
+        *
+        * @return string
+        */
+       protected function getFactoryConfigurationFileLocation() {
+               return PATH_site . $this->factoryConfigurationFile;
+       }
+
+       /**
+        * Get absolute file location of factory configuration file
+        *
+        * @return string
+        */
+       protected function getAdditionalFactoryConfigurationFileLocation() {
+               return PATH_site . $this->additionalFactoryConfigurationFile;
+       }
+
+       /**
+        * Get the file resource
+        *
+        * @return string
+        * @deprecated since 6.1, will be removed if the compatibily layer for localconf.php is dropped
+        */
+       public function getLocalconfFileLocation() {
+               return PATH_site . $this->localconfFile;
        }
 
        /**
@@ -129,7 +172,10 @@ class ConfigurationManager implements \TYPO3\CMS\Core\SingletonInterface {
         * @return void
         */
        public function updateLocalConfiguration(array $configurationToMerge) {
-               $newLocalConfiguration = Utility\GeneralUtility::array_merge_recursive_overrule($this->getLocalConfiguration(), $configurationToMerge);
+               $newLocalConfiguration = Utility\GeneralUtility::array_merge_recursive_overrule(
+                       $this->getLocalConfiguration(),
+                       $configurationToMerge
+               );
                $this->writeLocalConfiguration($newLocalConfiguration);
        }
 
@@ -161,7 +207,12 @@ class ConfigurationManager implements \TYPO3\CMS\Core\SingletonInterface {
         * @return mixed
         */
        public function getConfigurationValueByPath($path) {
-               return Utility\ArrayUtility::getValueByPath(Utility\GeneralUtility::array_merge_recursive_overrule($this->getDefaultConfiguration(), $this->getLocalConfiguration()), $path);
+               return Utility\ArrayUtility::getValueByPath(
+                       Utility\GeneralUtility::array_merge_recursive_overrule(
+                               $this->getDefaultConfiguration(), $this->getLocalConfiguration()
+                       ),
+                       $path
+               );
        }
 
        /**
@@ -198,17 +249,26 @@ class ConfigurationManager implements \TYPO3\CMS\Core\SingletonInterface {
        }
 
        /**
-        * Checks if the configuration can be written
+        * Checks if the configuration can be written.
         *
         * @return boolean
         * @access private
         */
        public function canWriteConfiguration() {
                $result = TRUE;
-               if (!@is_writable(PATH_typo3conf)) {
+               if (!@is_writable($this->pathTypo3Conf)) {
+                       $result = FALSE;
+               }
+               if (
+                       file_exists($this->getLocalConfigurationFileLocation())
+                       && !@is_writable($this->getLocalConfigurationFileLocation())
+               ) {
                        $result = FALSE;
                }
-               if (!@is_writable(($this->getLocalConfigurationFileResource())) && !@is_writable((PATH_site . self::LOCALCONF_FILE))) {
+               if (
+                       file_exists($this->getLocalconfFileLocation())
+                       && !@is_writable($this->getLocalconfFileLocation())
+               ) {
                        $result = FALSE;
                }
                return $result;
@@ -218,27 +278,29 @@ class ConfigurationManager implements \TYPO3\CMS\Core\SingletonInterface {
         * Reads the configuration array and exports it to the global variable
         *
         * @access private
+        * @throws \RuntimeException
+        * @throws \UnexpectedValueException
         * @return void
         */
        public function exportConfiguration() {
-               if (@is_file(($this->getLocalConfigurationFileResource()))) {
+               if (@is_file($this->getLocalConfigurationFileLocation())) {
                        $localConfiguration = $this->getLocalConfiguration();
                        if (is_array($localConfiguration)) {
                                $GLOBALS['TYPO3_CONF_VARS'] = Utility\GeneralUtility::array_merge_recursive_overrule($this->getDefaultConfiguration(), $localConfiguration);
                        } else {
                                throw new \UnexpectedValueException('LocalConfiguration invalid.', 1349272276);
                        }
-                       if (@is_file((PATH_site . self::ADDITIONAL_CONFIGURATION_FILE))) {
-                               require PATH_site . self::ADDITIONAL_CONFIGURATION_FILE;
+                       if (@is_file($this->getAdditionalConfigurationFileLocation())) {
+                               require $this->getAdditionalConfigurationFileLocation();
                        }
                        // @deprecated since 6.0: Simulate old 'extList' as comma separated list of 'extListArray'
                        $GLOBALS['TYPO3_CONF_VARS']['EXT']['extList'] = implode(',', $GLOBALS['TYPO3_CONF_VARS']['EXT']['extListArray']);
-               } elseif (@is_file((PATH_site . self::LOCALCONF_FILE))) {
+               } elseif (@is_file($this->getLocalconfFileLocation())) {
                        $GLOBALS['TYPO3_CONF_VARS'] = $this->getDefaultConfiguration();
                        // Legacy localconf.php handling
                        // @deprecated: Can be removed if old localconf.php is not supported anymore
                        global $TYPO3_CONF_VARS, $typo_db, $typo_db_username, $typo_db_password, $typo_db_host, $typo_db_extTableDef_script;
-                       require PATH_site . self::LOCALCONF_FILE;
+                       require $this->getLocalconfFileLocation();
                        // If the localconf.php was not upgraded to LocalConfiguration.php, the default extListArray
                        // from EXT:core/Configuration/DefaultConfiguration.php is still set. In this case we just unset
                        // this key here, so \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getLoadedExtensionListArray() falls back to use extList string
@@ -257,7 +319,10 @@ class ConfigurationManager implements \TYPO3\CMS\Core\SingletonInterface {
                        unset($GLOBALS['typo_db_host']);
                        unset($GLOBALS['typo_db_extTableDef_script']);
                } else {
-                       throw new \RuntimeException('Neither ' . self::LOCAL_CONFIGURATION_FILE . ' (recommended) nor ' . self::LOCALCONF_FILE . ' (obsolete) could be found!', 1349272337);
+                       throw new \RuntimeException(
+                               'Neither ' . $this->localConfigurationFile . ' (recommended) nor ' . $this->localconfFile . ' (obsolete) could be found!',
+                               1349272337
+                       );
                }
        }
 
@@ -270,14 +335,23 @@ class ConfigurationManager implements \TYPO3\CMS\Core\SingletonInterface {
         * @access private
         */
        public function writeLocalConfiguration(array $configuration) {
-               $localConfigurationFile = $this->getLocalConfigurationFileResource();
-               if (!@is_file($localConfigurationFile) || !@is_writable($localConfigurationFile)) {
-                       throw new \RuntimeException($localConfigurationFile . ' does not exist or is not writable.', 1346323822);
+               $localConfigurationFile = $this->getLocalConfigurationFileLocation();
+               if (!$this->canWriteConfiguration()) {
+                       throw new \RuntimeException(
+                               $localConfigurationFile . ' does is not writable.', 1346323822
+                       );
                }
                $configuration = Utility\ArrayUtility::sortByKeyRecursive($configuration);
                $result = Utility\GeneralUtility::writeFile(
                        $localConfigurationFile,
-                       '<?php' . LF . 'return ' . Utility\ArrayUtility::arrayExport(Utility\ArrayUtility::renumberKeysToAvoidLeapsIfKeysAreAllNumeric($configuration)) . ';' . LF . '?>'
+                       '<?php' . LF .
+                               'return ' .
+                                       Utility\ArrayUtility::arrayExport(
+                                               Utility\ArrayUtility::renumberKeysToAvoidLeapsIfKeysAreAllNumeric($configuration)
+                                       ) .
+                               ';' . LF .
+                       '?>',
+                       TRUE
                );
                return $result === FALSE ? FALSE : TRUE;
        }
@@ -291,11 +365,42 @@ class ConfigurationManager implements \TYPO3\CMS\Core\SingletonInterface {
         * @access private
         */
        public function writeAdditionalConfiguration(array $additionalConfigurationLines) {
-               $result = Utility\GeneralUtility::writeFile(PATH_site . self::ADDITIONAL_CONFIGURATION_FILE, '<?php' . LF . implode(LF, $additionalConfigurationLines) . LF . '?>');
+               $result = Utility\GeneralUtility::writeFile(
+                       PATH_site . $this->additionalConfigurationFile,
+                       '<?php' . LF .
+                               implode(LF, $additionalConfigurationLines) . LF .
+                       '?>'
+               );
                return $result === FALSE ? FALSE : TRUE;
        }
 
        /**
+        * Uses FactoryConfiguration file and a possible AdditionalFactoryConfiguration
+        * file in typo3conf to create a basic LocalConfiguration.php. This is used
+        * by the install tool in an early step.
+        *
+        * @return void
+        * @access private
+        */
+       public function createLocalConfigurationFromFactoryConfiguration() {
+               if (file_exists($this->getLocalConfigurationFileLocation())) {
+                       throw new \RuntimeException(
+                               'LocalConfiguration.php exists already', 1364836026
+                       );
+               }
+               $localConfigurationArray = require $this->getFactoryConfigurationFileLocation();
+               $additionalFactoryConfigurationFileLocation = $this->getAdditionalFactoryConfigurationFileLocation();
+               if (file_exists($additionalFactoryConfigurationFileLocation)) {
+                       $additionalFactoryConfigurationArray = require $additionalFactoryConfigurationFileLocation;
+                       $localConfigurationArray = Utility\GeneralUtility::array_merge_recursive_overrule(
+                               $localConfigurationArray,
+                               $additionalFactoryConfigurationArray
+                       );
+               }
+               $this->writeLocalConfiguration($localConfigurationArray);
+       }
+
+       /**
         * Check if access / write to given path in local configuration is allowed.
         *
         * @param string $path Path to search for
index 76c9c07..4e70663 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 namespace TYPO3\CMS\Core\Core;
+use \TYPO3\CMS\Core\Utility;
 
 /***************************************************************
  *  Copyright notice
@@ -121,6 +122,26 @@ class Bootstrap {
        }
 
        /**
+        * Redirect to install tool if LocalConfiguration.php is missing
+        *
+        * @param string $pathUpToDocumentRoot Can contain eg. '../' if called from a sub directory
+        * @return \TYPO3\CMS\Core\Core\Bootstrap
+        * @internal This is not a public API method, do not use in own extensions
+        */
+       public function redirectToInstallToolIfLocalConfigurationFileDoesNotExist($pathUpToDocumentRoot = '') {
+               /** @var $configurationManager \TYPO3\CMS\Core\Configuration\ConfigurationManager */
+               $configurationManager = Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Configuration\\ConfigurationManager');
+               if (
+                       !file_exists($configurationManager->getLocalConfigurationFileLocation())
+                       && !file_exists($configurationManager->getLocalconfFileLocation())
+               ) {
+                       require_once __DIR__ . '/../Utility/HttpUtility.php';
+                       Utility\HttpUtility::redirect($pathUpToDocumentRoot . 'typo3/install/index.php?mode=123&step=1&password=joh316');
+               }
+               return $this;
+       }
+
+       /**
         * Includes LocalConfiguration.php and sets several
         * global settings depending on configuration.
         *
@@ -218,12 +239,8 @@ class Bootstrap {
         */
        protected function populateLocalConfiguration() {
                try {
-                       // We need an early instance of the configuration manager.
-                       // Since makeInstance relies on the object configuration, we create it here with new instead
-                       // and register it as singleton instance for later use.
-                       $configuarationManager = new \TYPO3\CMS\Core\Configuration\ConfigurationManager();
-                       \TYPO3\CMS\Core\Utility\GeneralUtility::setSingletonInstance('TYPO3\\CMS\\Core\\Configuration\\ConfigurationManager', $configuarationManager);
-                       $configuarationManager->exportConfiguration();
+                       Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Configuration\\ConfigurationManager')
+                               ->exportConfiguration();
                } catch (\Exception $e) {
                        die($e->getMessage());
                }
@@ -247,28 +264,17 @@ class Bootstrap {
         */
        protected function registerExtDirectComponents() {
                if (TYPO3_MODE === 'BE') {
-                       \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::registerExtDirectComponent('TYPO3.Components.PageTree.DataProvider', 'TYPO3\\CMS\\Backend\\Tree\\Pagetree\\ExtdirectTreeDataProvider', 'web', 'user,group');
-                       \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::registerExtDirectComponent('TYPO3.Components.PageTree.Commands', 'TYPO3\\CMS\\Backend\\Tree\\Pagetree\\ExtdirectTreeCommands', 'web', 'user,group');
-                       \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::registerExtDirectComponent('TYPO3.Components.PageTree.ContextMenuDataProvider', 'TYPO3\\CMS\\Backend\\ContextMenu\\Pagetree\\Extdirect\\ContextMenuConfiguration', 'web', 'user,group');
-                       \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::registerExtDirectComponent('TYPO3.LiveSearchActions.ExtDirect', 'TYPO3\\CMS\\Backend\\Search\\LiveSearch\\ExtDirect\\LiveSearchDataProvider', 'web_list', 'user,group');
-                       \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::registerExtDirectComponent('TYPO3.BackendUserSettings.ExtDirect', 'TYPO3\\CMS\\Backend\\User\\ExtDirect\\BackendUserSettingsDataProvider');
-                       \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::registerExtDirectComponent('TYPO3.CSH.ExtDirect', 'TYPO3\\CMS\\ContextHelp\\ExtDirect\\ContextHelpDataProvider');
-                       \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::registerExtDirectComponent('TYPO3.ExtDirectStateProvider.ExtDirect', 'TYPO3\\CMS\\Backend\\InterfaceState\\ExtDirect\\DataProvider');
-                       \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::registerExtDirectComponent('TYPO3.Components.DragAndDrop.CommandController',
-                               \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extPath('backend') . 'Classes/View/PageLayout/Extdirect/ExtdirectPageCommands.php:TYPO3\\CMS\\Backend\\View\\PageLayout\\ExtDirect\\ExtdirectPageCommands', 'web', 'user,group');
-               }
-               return $this;
-       }
-
-       /**
-        * Redirect to install tool if database host and database are not defined
-        *
-        * @return \TYPO3\CMS\Core\Core\Bootstrap
-        * @internal This is not a public API method, do not use in own extensions
-        */
-       public function redirectToInstallToolIfDatabaseCredentialsAreMissing() {
-               if (!TYPO3_db_host && !TYPO3_db) {
-                       \TYPO3\CMS\Core\Utility\HttpUtility::redirect('install/index.php?mode=123&step=1&password=joh316');
+                       Utility\ExtensionManagementUtility::registerExtDirectComponent('TYPO3.Components.PageTree.DataProvider', 'TYPO3\\CMS\\Backend\\Tree\\Pagetree\\ExtdirectTreeDataProvider', 'web', 'user,group');
+                       Utility\ExtensionManagementUtility::registerExtDirectComponent('TYPO3.Components.PageTree.Commands', 'TYPO3\\CMS\\Backend\\Tree\\Pagetree\\ExtdirectTreeCommands', 'web', 'user,group');
+                       Utility\ExtensionManagementUtility::registerExtDirectComponent('TYPO3.Components.PageTree.ContextMenuDataProvider', 'TYPO3\\CMS\\Backend\\ContextMenu\\Pagetree\\Extdirect\\ContextMenuConfiguration', 'web', 'user,group');
+                       Utility\ExtensionManagementUtility::registerExtDirectComponent('TYPO3.LiveSearchActions.ExtDirect', 'TYPO3\\CMS\\Backend\\Search\\LiveSearch\\ExtDirect\\LiveSearchDataProvider', 'web_list', 'user,group');
+                       Utility\ExtensionManagementUtility::registerExtDirectComponent('TYPO3.BackendUserSettings.ExtDirect', 'TYPO3\\CMS\\Backend\\User\\ExtDirect\\BackendUserSettingsDataProvider');
+                       Utility\ExtensionManagementUtility::registerExtDirectComponent('TYPO3.CSH.ExtDirect', 'TYPO3\\CMS\\ContextHelp\\ExtDirect\\ContextHelpDataProvider');
+                       Utility\ExtensionManagementUtility::registerExtDirectComponent('TYPO3.ExtDirectStateProvider.ExtDirect', 'TYPO3\\CMS\\Backend\\InterfaceState\\ExtDirect\\DataProvider');
+                       Utility\ExtensionManagementUtility::registerExtDirectComponent(
+                               'TYPO3.Components.DragAndDrop.CommandController',
+                               Utility\ExtensionManagementUtility::extPath('backend') . 'Classes/View/PageLayout/Extdirect/ExtdirectPageCommands.php:TYPO3\\CMS\\Backend\\View\\PageLayout\\ExtDirect\\ExtdirectPageCommands', 'web', 'user,group'
+                       );
                }
                return $this;
        }
@@ -371,14 +377,14 @@ class Bootstrap {
         */
        protected function setCacheHashOptions() {
                $GLOBALS['TYPO3_CONF_VARS']['FE']['cacheHash'] = array(
-                       'cachedParametersWhiteList' => \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $GLOBALS['TYPO3_CONF_VARS']['FE']['cHashOnlyForParameters'], TRUE),
-                       'excludedParameters' => \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $GLOBALS['TYPO3_CONF_VARS']['FE']['cHashExcludedParameters'], TRUE),
-                       'requireCacheHashPresenceParameters' => \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $GLOBALS['TYPO3_CONF_VARS']['FE']['cHashRequiredParameters'], TRUE)
+                       'cachedParametersWhiteList' => Utility\GeneralUtility::trimExplode(',', $GLOBALS['TYPO3_CONF_VARS']['FE']['cHashOnlyForParameters'], TRUE),
+                       'excludedParameters' => Utility\GeneralUtility::trimExplode(',', $GLOBALS['TYPO3_CONF_VARS']['FE']['cHashExcludedParameters'], TRUE),
+                       'requireCacheHashPresenceParameters' => Utility\GeneralUtility::trimExplode(',', $GLOBALS['TYPO3_CONF_VARS']['FE']['cHashRequiredParameters'], TRUE)
                );
                if (trim($GLOBALS['TYPO3_CONF_VARS']['FE']['cHashExcludedParametersIfEmpty']) === '*') {
                        $GLOBALS['TYPO3_CONF_VARS']['FE']['cacheHash']['excludeAllEmptyParameters'] = TRUE;
                } else {
-                       $GLOBALS['TYPO3_CONF_VARS']['FE']['cacheHash']['excludedParametersIfEmpty'] = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $GLOBALS['TYPO3_CONF_VARS']['FE']['cHashExcludedParametersIfEmpty'], TRUE);
+                       $GLOBALS['TYPO3_CONF_VARS']['FE']['cacheHash']['excludedParametersIfEmpty'] = Utility\GeneralUtility::trimExplode(',', $GLOBALS['TYPO3_CONF_VARS']['FE']['cHashExcludedParametersIfEmpty'], TRUE);
                }
                return $this;
        }
@@ -508,7 +514,7 @@ class Bootstrap {
                if (($displayErrors = intval($GLOBALS['TYPO3_CONF_VARS']['SYS']['displayErrors'])) != '-1') {
                        // Special value "2" enables this feature only if $GLOBALS['TYPO3_CONF_VARS'][SYS][devIPmask] matches
                        if ($displayErrors == 2) {
-                               if (\TYPO3\CMS\Core\Utility\GeneralUtility::cmpIP(\TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('REMOTE_ADDR'), $GLOBALS['TYPO3_CONF_VARS']['SYS']['devIPmask'])) {
+                               if (Utility\GeneralUtility::cmpIP(Utility\GeneralUtility::getIndpEnv('REMOTE_ADDR'), $GLOBALS['TYPO3_CONF_VARS']['SYS']['devIPmask'])) {
                                        $displayErrors = 1;
                                } else {
                                        $displayErrors = 0;
@@ -522,7 +528,7 @@ class Bootstrap {
                                define('TYPO3_ERRORHANDLER_MODE', 'debug');
                        }
                        @ini_set('display_errors', $displayErrors);
-               } elseif (\TYPO3\CMS\Core\Utility\GeneralUtility::cmpIP(\TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('REMOTE_ADDR'), $GLOBALS['TYPO3_CONF_VARS']['SYS']['devIPmask'])) {
+               } elseif (Utility\GeneralUtility::cmpIP(Utility\GeneralUtility::getIndpEnv('REMOTE_ADDR'), $GLOBALS['TYPO3_CONF_VARS']['SYS']['devIPmask'])) {
                        // With displayErrors = -1 (default), turn on debugging if devIPmask matches:
                        $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['errors']['exceptionHandler'] = $GLOBALS['TYPO3_CONF_VARS']['SYS']['debugExceptionHandler'];
                }
@@ -566,7 +572,7 @@ class Bootstrap {
         * @return \TYPO3\CMS\Core\Core\Bootstrap
         */
        protected function populateTypo3LoadedExtGlobal($allowCaching = TRUE) {
-               $GLOBALS['TYPO3_LOADED_EXT'] = \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::loadTypo3LoadedExtensionInformation($allowCaching);
+               $GLOBALS['TYPO3_LOADED_EXT'] = Utility\ExtensionManagementUtility::loadTypo3LoadedExtensionInformation($allowCaching);
                return $this;
        }
 
@@ -580,7 +586,7 @@ class Bootstrap {
         * @return \TYPO3\CMS\Core\Core\Bootstrap
         */
        protected function loadAdditionalConfigurationFromExtensions($allowCaching = TRUE) {
-               \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::loadExtLocalconf($allowCaching);
+               Utility\ExtensionManagementUtility::loadExtLocalconf($allowCaching);
                return $this;
        }
 
@@ -592,7 +598,7 @@ class Bootstrap {
         */
        protected function deprecationLogForOldExtCacheSetting() {
                if (isset($GLOBALS['TYPO3_CONF_VARS']['SYS']['extCache']) && $GLOBALS['TYPO3_CONF_VARS']['SYS']['extCache'] !== -1) {
-                       \TYPO3\CMS\Core\Utility\GeneralUtility::deprecationLog('Setting $GLOBALS[\'TYPO3_CONF_VARS\'][\'SYS\'][\'extCache\'] is unused and can be removed from localconf.php');
+                       Utility\GeneralUtility::deprecationLog('Setting $GLOBALS[\'TYPO3_CONF_VARS\'][\'SYS\'][\'extCache\'] is unused and can be removed from localconf.php');
                }
                return $this;
        }
@@ -606,13 +612,13 @@ class Bootstrap {
                if ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['errors']['exceptionHandler'] !== '') {
                        if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['errorHandler'] !== '') {
                                // Register an error handler for the given errorHandlerErrors
-                               $errorHandler = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance($GLOBALS['TYPO3_CONF_VARS']['SYS']['errorHandler'], $GLOBALS['TYPO3_CONF_VARS']['SYS']['errorHandlerErrors']);
+                               $errorHandler = Utility\GeneralUtility::makeInstance($GLOBALS['TYPO3_CONF_VARS']['SYS']['errorHandler'], $GLOBALS['TYPO3_CONF_VARS']['SYS']['errorHandlerErrors']);
                                // Set errors which will be converted in an exception
                                $errorHandler->setExceptionalErrors($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['errors']['exceptionalErrors']);
                        }
                        // Instantiate the exception handler once to make sure object is registered
                        // @TODO: Figure out if this is really needed
-                       \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['errors']['exceptionHandler']);
+                       Utility\GeneralUtility::makeInstance($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['errors']['exceptionHandler']);
                }
                return $this;
        }
@@ -673,7 +679,7 @@ class Bootstrap {
         */
        public function initializeTypo3DbGlobal($connect = TRUE) {
                /** @var TYPO3_DB TYPO3\CMS\Core\Database\DatabaseConnection */
-               $GLOBALS['TYPO3_DB'] = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Database\\DatabaseConnection');
+               $GLOBALS['TYPO3_DB'] = Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Database\\DatabaseConnection');
                $GLOBALS['TYPO3_DB']->debugOutput = $GLOBALS['TYPO3_CONF_VARS']['SYS']['sqlDebug'];
                if ($connect) {
                        $this->establishDatabaseConnection();
@@ -697,7 +703,7 @@ class Bootstrap {
                        if (TYPO3_PROCEED_IF_NO_USER === 2) {
 
                        } else {
-                               $fileContent = \TYPO3\CMS\Core\Utility\GeneralUtility::getUrl(PATH_typo3conf . 'LOCK_BACKEND');
+                               $fileContent = Utility\GeneralUtility::getUrl(PATH_typo3conf . 'LOCK_BACKEND');
                                if ($fileContent) {
                                        header('Location: ' . $fileContent);
                                } else {
@@ -718,7 +724,7 @@ class Bootstrap {
         */
        public function checkBackendIpOrDie() {
                if (trim($GLOBALS['TYPO3_CONF_VARS']['BE']['IPmaskList'])) {
-                       if (!\TYPO3\CMS\Core\Utility\GeneralUtility::cmpIP(\TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('REMOTE_ADDR'), $GLOBALS['TYPO3_CONF_VARS']['BE']['IPmaskList'])) {
+                       if (!Utility\GeneralUtility::cmpIP(Utility\GeneralUtility::getIndpEnv('REMOTE_ADDR'), $GLOBALS['TYPO3_CONF_VARS']['BE']['IPmaskList'])) {
                                // Send Not Found header - if the webserver can make use of it
                                header('Status: 404 Not Found');
                                // Just point us away from here...
@@ -745,16 +751,16 @@ class Bootstrap {
                                $sslPortSuffix = '';
                        }
                        if ($GLOBALS['TYPO3_CONF_VARS']['BE']['lockSSL'] == 3) {
-                               $requestStr = substr(\TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('TYPO3_REQUEST_SCRIPT'), strlen(\TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('TYPO3_SITE_URL') . TYPO3_mainDir));
-                               if ($requestStr === 'index.php' && !\TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('TYPO3_SSL')) {
-                                       list(, $url) = explode('://', \TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('TYPO3_REQUEST_URL'), 2);
+                               $requestStr = substr(Utility\GeneralUtility::getIndpEnv('TYPO3_REQUEST_SCRIPT'), strlen(Utility\GeneralUtility::getIndpEnv('TYPO3_SITE_URL') . TYPO3_mainDir));
+                               if ($requestStr === 'index.php' && !Utility\GeneralUtility::getIndpEnv('TYPO3_SSL')) {
+                                       list(, $url) = explode('://', Utility\GeneralUtility::getIndpEnv('TYPO3_REQUEST_URL'), 2);
                                        list($server, $address) = explode('/', $url, 2);
                                        header('Location: https://' . $server . $sslPortSuffix . '/' . $address);
                                        die;
                                }
-                       } elseif (!\TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('TYPO3_SSL')) {
+                       } elseif (!Utility\GeneralUtility::getIndpEnv('TYPO3_SSL')) {
                                if (intval($GLOBALS['TYPO3_CONF_VARS']['BE']['lockSSL']) === 2) {
-                                       list(, $url) = explode('://', \TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('TYPO3_SITE_URL') . TYPO3_mainDir, 2);
+                                       list(, $url) = explode('://', Utility\GeneralUtility::getIndpEnv('TYPO3_SITE_URL') . TYPO3_mainDir, 2);
                                        list($server, $address) = explode('/', $url, 2);
                                        header('Location: https://' . $server . $sslPortSuffix . '/' . $address);
                                } else {
@@ -803,7 +809,7 @@ class Bootstrap {
                } else {
                        $this->loadExtensionTables(TRUE);
                        $phpCodeToCache = '$GLOBALS[\'TCA\'] = ';
-                       $phpCodeToCache .= \TYPO3\CMS\Core\Utility\ArrayUtility::arrayExport($GLOBALS['TCA']);
+                       $phpCodeToCache .= Utility\ArrayUtility::arrayExport($GLOBALS['TCA']);
                        $phpCodeToCache .= ';';
                        $codeCache->set($cacheIdentifier, $phpCodeToCache);
                }
@@ -823,8 +829,8 @@ class Bootstrap {
         * @internal This is not a public API method, do not use in own extensions
         */
        public function loadExtensionTables($allowCaching = TRUE) {
-               \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::loadBaseTca($allowCaching);
-               \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::loadExtTables($allowCaching);
+               Utility\ExtensionManagementUtility::loadBaseTca($allowCaching);
+               Utility\ExtensionManagementUtility::loadExtTables($allowCaching);
                $this->executeExtTablesAdditionalFile();
                $this->runExtTablesPostProcessingHooks();
                return $this;
@@ -868,7 +874,7 @@ class Bootstrap {
                if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['extTablesInclusion-PostProcessing'])) {
                        foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['extTablesInclusion-PostProcessing'] as $classReference) {
                                /** @var $hookObject \TYPO3\CMS\Core\Database\TableConfigurationPostProcessingHookInterface */
-                               $hookObject = \TYPO3\CMS\Core\Utility\GeneralUtility::getUserObj($classReference);
+                               $hookObject = Utility\GeneralUtility::getUserObj($classReference);
                                if (!$hookObject instanceof \TYPO3\CMS\Core\Database\TableConfigurationPostProcessingHookInterface) {
                                        throw new \UnexpectedValueException('$hookObject must implement interface TYPO3\\CMS\\Core\\Database\\TableConfigurationPostProcessingHookInterface', 1320585902);
                                }
@@ -896,7 +902,7 @@ class Bootstrap {
         */
        public function initializeBackendUser() {
                /** @var $backendUser \TYPO3\CMS\Core\Authentication\BackendUserAuthentication */
-               $backendUser = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Authentication\\BackendUserAuthentication');
+               $backendUser = Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Authentication\\BackendUserAuthentication');
                $backendUser->warningEmail = $GLOBALS['TYPO3_CONF_VARS']['BE']['warning_email_addr'];
                $backendUser->lockIP = $GLOBALS['TYPO3_CONF_VARS']['BE']['lockIP'];
                $backendUser->auth_timeout_field = intval($GLOBALS['TYPO3_CONF_VARS']['BE']['sessionTimeout']);
@@ -935,7 +941,7 @@ class Bootstrap {
         */
        public function initializeLanguageObject() {
                /** @var $GLOBALS['LANG'] \TYPO3\CMS\Lang\LanguageService */
-               $GLOBALS['LANG'] = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\CMS\Lang\LanguageService');
+               $GLOBALS['LANG'] = Utility\GeneralUtility::makeInstance('TYPO3\CMS\Lang\LanguageService');
                $GLOBALS['LANG']->init($GLOBALS['BE_USER']->uc['lang']);
                return $this;
        }
@@ -959,7 +965,7 @@ class Bootstrap {
         */
        public function initializeOutputCompression() {
                if (extension_loaded('zlib') && $GLOBALS['TYPO3_CONF_VARS']['BE']['compressionLevel']) {
-                       if (\TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($GLOBALS['TYPO3_CONF_VARS']['BE']['compressionLevel'])) {
+                       if (Utility\MathUtility::canBeInterpretedAsInteger($GLOBALS['TYPO3_CONF_VARS']['BE']['compressionLevel'])) {
                                @ini_set('zlib.output_compression_level', $GLOBALS['TYPO3_CONF_VARS']['BE']['compressionLevel']);
                        }
                        ob_start('ob_gzhandler');
@@ -974,8 +980,8 @@ class Bootstrap {
         * @internal This is not a public API method, do not use in own extensions
         */
        public function initializeModuleMenuObject() {
-               /** @var $moduleMenuUtility Typo3_BackendModule_Utility */
-               $moduleMenuUtility = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Backend\\Module\\ModuleController');
+               /** @var $moduleMenuUtility \TYPO3\CMS\Backend\Module\ModuleController */
+               $moduleMenuUtility = Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Backend\\Module\\ModuleController');
                $moduleMenuUtility->createModuleMenu();
                return $this;
        }
@@ -1005,11 +1011,11 @@ class Bootstrap {
         * @internal This is not a public API method, do not use in own extensions
         */
        public function initializeBackendTemplate() {
-               $GLOBALS['TBE_TEMPLATE'] = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Backend\\Template\\DocumentTemplate');
+               $GLOBALS['TBE_TEMPLATE'] = Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Backend\\Template\\DocumentTemplate');
                return $this;
        }
 
 }
 
 
-?>
+?>
\ No newline at end of file
index 23c5b4c..f9e0ce2 100644 (file)
@@ -1313,8 +1313,6 @@ class DatabaseConnection {
         * @todo Define visibility
         */
        public function connectDB($host = TYPO3_db_host, $user = TYPO3_db_username, $password = TYPO3_db_password, $db = TYPO3_db) {
-               // If no db is given we throw immediately. This is a sign for a fresh (not configured)
-               // TYPO3 installation and is used in FE to redirect to 1-2-3 install tool
                if (!$db) {
                        throw new \RuntimeException('TYPO3 Fatal Error: No database selected!', 1270853882);
                }
index 13262df..a8fbb99 100644 (file)
@@ -1881,9 +1881,12 @@ tt_content.' . $key . $prefix . ' {
         *
         * @return boolean TRUE if at least one configuration file in typo3conf/ is writable
         * @internal
+        * @deprecated since 6.1, will be removed in two versions
         */
        static public function isLocalconfWritable() {
-               return \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Configuration\\ConfigurationManager')->canWriteConfiguration();
+               \TYPO3\CMS\Core\Utility\GeneralUtility::logDeprecatedFunction();
+               return \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Configuration\\ConfigurationManager')
+                       ->canWriteConfiguration();
        }
 
        /**
@@ -2193,4 +2196,4 @@ tt_content.' . $key . $prefix . ' {
        }
 
 }
-?>
+?>
\ No newline at end of file
index 2eae6c9..2974e50 100644 (file)
@@ -2451,9 +2451,10 @@ Connection: close
         *
         * @param string $file Filepath to write to
         * @param string $content Content to write
+        * @param boolean $changePermissions If TRUE, permissions are forced to be set
         * @return boolean TRUE if the file was successfully opened and written to.
         */
-       static public function writeFile($file, $content) {
+       static public function writeFile($file, $content, $changePermissions = FALSE) {
                if (!@is_file($file)) {
                        $changePermissions = TRUE;
                }
@@ -2488,11 +2489,17 @@ Connection: close
                        }
                        if (self::isAllowedAbsPath($path)) {
                                if (@is_file($path)) {
+                                       $targetFilePermissions = isset($GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'])
+                                               ? octdec($GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'])
+                                               : octdec('0644');
                                        // "@" is there because file is not necessarily OWNED by the user
-                                       $result = @chmod($path, octdec($GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask']));
+                                       $result = @chmod($path, $targetFilePermissions);
                                } elseif (@is_dir($path)) {
+                                       $targetDirectoryPermissions = isset($GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask'])
+                                               ? octdec($GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask'])
+                                               : octdec('0755');
                                        // "@" is there because file is not necessarily OWNED by the user
-                                       $result = @chmod($path, octdec($GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask']));
+                                       $result = @chmod($path, $targetDirectoryPermissions);
                                }
                                // Set createGroup if not empty
                                if (
@@ -3654,7 +3661,11 @@ Connection: close
        static public function unlink_tempfile($uploadedTempFileName) {
                if ($uploadedTempFileName) {
                        $uploadedTempFileName = self::fixWindowsFilePath($uploadedTempFileName);
-                       if (self::validPathStr($uploadedTempFileName) && self::isFirstPartOfStr($uploadedTempFileName, PATH_site . 'typo3temp/') && @is_file($uploadedTempFileName)) {
+                       if (
+                               self::validPathStr($uploadedTempFileName)
+                               && self::isFirstPartOfStr($uploadedTempFileName, PATH_site . 'typo3temp/')
+                               && @is_file($uploadedTempFileName)
+                       ) {
                                if (unlink($uploadedTempFileName)) {
                                        return TRUE;
                                }
@@ -4072,7 +4083,10 @@ Connection: close
                        return self::$singletonInstances[$finalClassName];
                }
                // Return instance if it has been injected by addInstance()
-               if (isset(self::$nonSingletonInstances[$finalClassName]) && !empty(self::$nonSingletonInstances[$finalClassName])) {
+               if (
+                       isset(self::$nonSingletonInstances[$finalClassName])
+                       && !empty(self::$nonSingletonInstances[$finalClassName])
+               ) {
                        return array_shift(self::$nonSingletonInstances[$finalClassName]);
                }
                // Create new instance and call constructor with parameters
diff --git a/typo3/sysext/core/Configuration/FactoryConfiguration.php b/typo3/sysext/core/Configuration/FactoryConfiguration.php
new file mode 100644 (file)
index 0000000..131753b
--- /dev/null
@@ -0,0 +1,58 @@
+<?php
+/**
+ * This is a boilerplate of typo3conf/LocalConfiguration.php. It is
+ * used as base file during installation and can be overloaded with
+ * a package specific file typo3conf/AdditionalFactoryConfiguration.php
+ * from eg. the government or introduction package.
+ */
+return array(
+       'BE' => array(
+               'installToolPassword' => 'bacb98acf97e0b6112b1d1b650b84971',
+       ),
+       'DB' => array(
+               'extTablesDefinitionScript' => 'extTables.php',
+       ),
+       'EXT' => array(
+               'extListArray' => array(
+                       'info',
+                       'perm',
+                       'func',
+                       'filelist',
+                       'about',
+                       'version',
+                       'tsconfig_help',
+                       'context_help',
+                       'extra_page_cm_options',
+                       'impexp',
+                       'sys_note',
+                       'tstemplate',
+                       'tstemplate_ceditor',
+                       'tstemplate_info',
+                       'tstemplate_objbrowser',
+                       'tstemplate_analyzer',
+                       'func_wizards',
+                       'wizard_crpages',
+                       'wizard_sortpages',
+                       'lowlevel',
+                       'install',
+                       'belog',
+                       'beuser',
+                       'aboutmodules',
+                       'setup',
+                       'taskcenter',
+                       'info_pagetsconfig',
+                       'viewpage',
+                       'rtehtmlarea',
+                       'css_styled_content',
+                       't3skin',
+                       't3editor',
+                       'reports',
+                       'felogin',
+                       'form',
+               ),
+       ),
+       'SYS' => array(
+               'sitename' => 'New TYPO3 site',
+       ),
+);
+?>
\ No newline at end of file
index aec8c45..3427acf 100644 (file)
@@ -25,7 +25,7 @@ namespace TYPO3\CMS\Core\Tests\Unit\Configuration;
  ***************************************************************/
 
 /**
- * Testcase for class \TYPO3\CMS\Core\Configuration\ConfigurationManager
+ * Test case
  *
  * @author Christian Kuhn <lolli@schwarzbu.ch>
  */
@@ -45,8 +45,8 @@ class ConfigurationManagerTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
        public function setUp() {
                $this->createFixtureWithMockedMethods(
                        array(
-                               'getDefaultConfigurationFileResource',
-                               'getLocalConfigurationFileResource',
+                               'getDefaultConfigurationFileLocation',
+                               'getLocalConfigurationFileLocation',
                        )
                );
        }
@@ -68,46 +68,47 @@ class ConfigurationManagerTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
                        'TYPO3\\CMS\\Core\\Configuration\\ConfigurationManager',
                        $methods
                );
-
        }
 
        /**
-        * Tests concerning getDefaultConfiguration
-        *
-        */
-       /**
         * @test
         * @expectedException \RuntimeException
         */
        public function getDefaultConfigurationExecutesDefinedDefaultConfigurationFile() {
                $defaultConfigurationFile = PATH_site . 'typo3temp/' . uniqid('defaultConfiguration');
-               file_put_contents($defaultConfigurationFile, '<?php throw new \RuntimeException(\'foo\', 1310203814); ?>');
+               file_put_contents(
+                       $defaultConfigurationFile,
+                       '<?php throw new \RuntimeException(\'foo\', 1310203814); ?>'
+               );
                $this->testFilesToDelete[] = $defaultConfigurationFile;
 
-               $this->fixture->expects($this->once())->method('getDefaultConfigurationFileResource')->will($this->returnValue($defaultConfigurationFile));
+               $this->fixture
+                       ->expects($this->once())
+                       ->method('getDefaultConfigurationFileLocation')
+                       ->will($this->returnValue($defaultConfigurationFile));
                $this->fixture->getDefaultConfiguration();
        }
 
        /**
-        * Tests concerning getLocalConfiguration
-        */
-       /**
         * @test
         * @expectedException \RuntimeException
         */
        public function getLocalConfigurationExecutesDefinedConfigurationFile() {
                $configurationFile = PATH_site . 'typo3temp/' . uniqid('localConfiguration');
-               file_put_contents($configurationFile, '<?php throw new \RuntimeException(\'foo\', 1310203815); ?>');
+               file_put_contents(
+                       $configurationFile,
+                       '<?php throw new \RuntimeException(\'foo\', 1310203815); ?>'
+               );
                $this->testFilesToDelete[] = $configurationFile;
 
-               $this->fixture->expects($this->once())->method('getLocalConfigurationFileResource')->will($this->returnValue($configurationFile));
+               $this->fixture
+                       ->expects($this->once())
+                       ->method('getLocalConfigurationFileLocation')
+                       ->will($this->returnValue($configurationFile));
                $this->fixture->getLocalConfiguration();
        }
 
        /**
-        * Tests concerning updateLocalConfiguration
-        */
-       /**
         * @test
         */
        public function updateLocalConfigurationWritesNewMergedLocalConfigurationArray() {
@@ -125,10 +126,12 @@ class ConfigurationManagerTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
                        'new' => 'new',
                );
 
-               $this->createFixtureWithMockedMethods(array(
+               $this->createFixtureWithMockedMethods(
+                       array(
                                'getLocalConfiguration',
                                'writeLocalConfiguration',
-                       ));
+                       )
+               );
                $this->fixture->expects($this->once())
                                ->method('getLocalConfiguration')
                                ->will($this->returnValue($currentLocalConfiguration));
@@ -140,15 +143,14 @@ class ConfigurationManagerTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
        }
 
        /**
-        * Tests concerning getDefaultConfigurationValueByPath
-        */
-       /**
         * @test
         */
        public function getDefaultConfigurationValueByPathReturnsCorrectValue() {
-               $this->createFixtureWithMockedMethods(array(
+               $this->createFixtureWithMockedMethods(
+                       array(
                                'getDefaultConfiguration',
-                       ));
+                       )
+               );
                $this->fixture->expects($this->once())
                                ->method('getDefaultConfiguration')
                                ->will($this->returnValue(array(
@@ -160,15 +162,14 @@ class ConfigurationManagerTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
        }
 
        /**
-        * Tests concerning getLocalConfigurationValueByPath
-        */
-       /**
         * @test
         */
        public function getLocalConfigurationValueByPathReturnsCorrectValue() {
-               $this->createFixtureWithMockedMethods(array(
+               $this->createFixtureWithMockedMethods(
+                       array(
                                'getLocalConfiguration',
-                       ));
+                       )
+               );
                $this->fixture->expects($this->once())
                                ->method('getLocalConfiguration')
                                ->will($this->returnValue(array(
@@ -180,16 +181,15 @@ class ConfigurationManagerTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
        }
 
        /**
-        * Tests concerning getConfigurationValueByPath
-        */
-       /**
         * @test
         */
        public function getConfigurationValueByPathReturnsCorrectValue() {
-               $this->createFixtureWithMockedMethods(array(
+               $this->createFixtureWithMockedMethods(
+                       array(
                                'getDefaultConfiguration',
                                'getLocalConfiguration',
-                       ));
+                       )
+               );
                $this->fixture->expects($this->once())
                                ->method('getDefaultConfiguration')
                                ->will($this->returnValue(array(
@@ -207,9 +207,6 @@ class ConfigurationManagerTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
        }
 
        /**
-        * Tests concerning setLocalConfigurationValueByPath
-        */
-       /**
         * @test
         */
        public function setLocalConfigurationValueByPathReturnFalseIfPathIsNotValid() {
@@ -236,11 +233,13 @@ class ConfigurationManagerTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
                        'toUpdate' => 'updated',
                );
 
-               $this->createFixtureWithMockedMethods(array(
+               $this->createFixtureWithMockedMethods(
+                       array(
                                'isValidLocalConfigurationPath',
                                'getLocalConfiguration',
                                'writeLocalConfiguration',
-                       ));
+                       )
+               );
                $this->fixture->expects($this->once())
                                ->method('isValidLocalConfigurationPath')
                                ->will($this->returnValue(TRUE));
@@ -255,9 +254,6 @@ class ConfigurationManagerTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
        }
 
        /**
-        * Tests concerning setLocalConfigurationValuesByPathValuePairs
-        */
-       /**
         * @test
         */
        public function setLocalConfigurationValuesByPathValuePairsSetsPathValuePairs() {
@@ -271,11 +267,13 @@ class ConfigurationManagerTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
                        'new' => 'new',
                );
 
-               $this->createFixtureWithMockedMethods(array(
+               $this->createFixtureWithMockedMethods(
+                       array(
                                'isValidLocalConfigurationPath',
                                'getLocalConfiguration',
                                'writeLocalConfiguration',
-                       ));
+                       )
+               );
                $this->fixture->expects($this->any())
                                ->method('isValidLocalConfigurationPath')
                                ->will($this->returnValue(TRUE));
@@ -294,21 +292,112 @@ class ConfigurationManagerTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
        }
 
        /**
-        * Tests concerning writeLocalConfiguration
+        * @test
         */
+       public function canWriteConfigurationReturnsFalseIfDirectoryIsNotWritable() {
+               if (TYPO3_OS == 'WIN') {
+                       $this->markTestSkipped('Not available on Windows');
+               }
+               /** @var $fixture \TYPO3\CMS\Core\Configuration\ConfigurationManager|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface */
+               $fixture = $this->getAccessibleMock('TYPO3\\CMS\\Core\\Configuration\\ConfigurationManager', array('dummy'));
+
+               $directory = 'typo3temp/' . uniqid('test_');
+               $absoluteDirectory = PATH_site . $directory;
+               mkdir($absoluteDirectory);
+               chmod($absoluteDirectory, 0544);
+               clearstatcache();
+
+               $fixture->_set('pathTypo3Conf', $directory);
+
+               $result = $fixture->canWriteConfiguration();
+
+               chmod($absoluteDirectory, 0755);
+               rmdir($absoluteDirectory);
+
+               $this->assertFalse($result);
+       }
+
        /**
         * @test
-        * @expectedException \RuntimeException
         */
-       public function writeLocalConfigurationThrowsExceptionForInvalidFile() {
-               $configurationFile = 'typo3temp/' . uniqid('localConfiguration');
-               $this->fixture->expects($this->once())->method('getLocalConfigurationFileResource')->will($this->returnValue($configurationFile));
+       public function canWriteConfigurationReturnsFalseIfLocalConfigurationFileIsNotWritable() {
+               if (TYPO3_OS == 'WIN') {
+                       $this->markTestSkipped('Not available on Windows');
+               }
+               /** @var $fixture \TYPO3\CMS\Core\Configuration\ConfigurationManager|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface */
+               $fixture = $this->getAccessibleMock('TYPO3\\CMS\\Core\\Configuration\\ConfigurationManager', array('dummy'));
 
-               $pairs = array(
-                       'foo' => 42,
-                       'bar' => 23
-               );
-               $this->fixture->writeLocalConfiguration($pairs);
+               $file = 'typo3temp/' . uniqid('test_');
+               $absoluteFile = PATH_site . $file;
+               touch($absoluteFile);
+               $this->testFilesToDelete[] = $absoluteFile;
+               chmod($absoluteFile, 0444);
+               clearstatcache();
+
+               $fixture->_set('localConfigurationFile', $file);
+
+               $result = $fixture->canWriteConfiguration();
+
+               chmod($absoluteFile, 0644);
+
+               $this->assertFalse($result);
+       }
+
+       /**
+        * @test
+        */
+       public function canWriteConfigurationReturnsFalseIfLocalconfFileIsNotWritable() {
+               if (TYPO3_OS == 'WIN') {
+                       $this->markTestSkipped('Not available on Windows');
+               }
+               /** @var $fixture \TYPO3\CMS\Core\Configuration\ConfigurationManager|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface */
+               $fixture = $this->getAccessibleMock('TYPO3\\CMS\\Core\\Configuration\\ConfigurationManager', array('dummy'));
+
+               $file = 'typo3temp/' . uniqid('test_');
+               $absoluteFile = PATH_site . $file;
+               touch($absoluteFile);
+               $this->testFilesToDelete[] = $absoluteFile;
+               chmod($absoluteFile, 0444);
+               clearstatcache();
+
+               $fixture->_set('localconfFile', $file);
+
+               $result = $fixture->canWriteConfiguration();
+
+               chmod($absoluteFile, 0644);
+
+               $this->assertFalse($result);
+       }
+
+       /**
+        * @test
+        */
+       public function canWriteConfigurationReturnsTrueIfDirectoryAndFilesAreWritable() {
+               /** @var $fixture \TYPO3\CMS\Core\Configuration\ConfigurationManager|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface */
+               $fixture = $this->getAccessibleMock('TYPO3\\CMS\\Core\\Configuration\\ConfigurationManager', array('dummy'));
+
+               $directory = 'typo3temp/' . uniqid('test_');
+               $absoluteDirectory = PATH_site . $directory;
+               mkdir($absoluteDirectory);
+               $fixture->_set('pathTypo3Conf', $directory);
+
+               $file1 = 'typo3temp/' . uniqid('test_');
+               $absoluteFile1 = PATH_site . $file1;
+               touch($absoluteFile1);
+               $this->testFilesToDelete[] = $absoluteFile1;
+               $fixture->_set('localConfigurationFile', $file1);
+
+               $file2 = 'typo3temp/' . uniqid('test_');
+               $absoluteFile2 = PATH_site . $file2;
+               touch($absoluteFile2);
+               $this->testFilesToDelete[] = $absoluteFile2;
+               $fixture->_set('localconfFile', $file2);
+
+               clearstatcache();
+
+               $result = $fixture->canWriteConfiguration();
+
+               $this->assertTrue($result);
        }
 
        /**
@@ -328,7 +417,10 @@ class ConfigurationManagerTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
                }
                $this->testFilesToDelete[] = $configurationFile;
 
-               $this->fixture->expects($this->once())->method('getLocalConfigurationFileResource')->will($this->returnValue($configurationFile));
+               $this->fixture
+                       ->expects($this->any())
+                       ->method('getLocalConfigurationFileLocation')
+                       ->will($this->returnValue($configurationFile));
 
                $pairs = array(
                        'foo' => 42,
@@ -347,8 +439,98 @@ class ConfigurationManagerTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
        }
 
        /**
-        * Tests concerning isValidLocalConfigurationPath
+        * @test
+        * @expectedException \RuntimeException
         */
+       public function createLocalConfigurationFromFactoryConfigurationThrowsExceptionIfFileExists() {
+               /** @var $fixture \TYPO3\CMS\Core\Configuration\ConfigurationManager|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface */
+               $fixture = $this->getAccessibleMock('TYPO3\\CMS\\Core\\Configuration\\ConfigurationManager', array('dummy'));
+
+               $file = 'typo3temp/' . uniqid('test_');
+               $absoluteFile = PATH_site . $file;
+               touch($absoluteFile);
+               $this->testFilesToDelete[] = $absoluteFile;
+               $fixture->_set('localConfigurationFile', $file);
+
+               $fixture->createLocalConfigurationFromFactoryConfiguration();
+       }
+
+       /**
+        * @test
+        */
+       public function createLocalConfigurationFromFactoryConfigurationWritesContentFromFactoryFile() {
+               /** @var $fixture \TYPO3\CMS\Core\Configuration\ConfigurationManager|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface */
+               $fixture = $this->getAccessibleMock('TYPO3\\CMS\\Core\\Configuration\\ConfigurationManager', array('writeLocalConfiguration'));
+               $fixture->_set('localConfigurationFile', 'typo3temp/' . uniqid('dummy_'));
+
+               $factoryConfigurationFile = 'typo3temp/' . uniqid('test_') . '.php';
+               $factoryConfigurationAbsoluteFile = PATH_site . $factoryConfigurationFile;
+               $uniqueContentString = uniqid('string_');
+               $validFactoryConfigurationFileContent =
+                       '<?php' . LF .
+                               'return array(' . LF .
+                                       $uniqueContentString . ' => foo,' . LF .
+                               ');' . LF .
+                       '?>';
+               file_put_contents(
+                       $factoryConfigurationAbsoluteFile,
+                       $validFactoryConfigurationFileContent
+               );
+               $this->testFilesToDelete[] = $factoryConfigurationAbsoluteFile;
+
+               $fixture->_set('factoryConfigurationFile', $factoryConfigurationFile);
+
+               $fixture
+                       ->expects($this->once())
+                       ->method('writeLocalConfiguration')
+                       ->with($this->arrayHasKey($uniqueContentString));
+               $fixture->createLocalConfigurationFromFactoryConfiguration();
+       }
+
+       /**
+        * @test
+        */
+       public function createLocalConfigurationFromFactoryConfigurationMergesConfigurationWithAdditionalFactoryFile() {
+               /** @var $fixture \TYPO3\CMS\Core\Configuration\ConfigurationManager|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface */
+               $fixture = $this->getAccessibleMock('TYPO3\\CMS\\Core\\Configuration\\ConfigurationManager', array('writeLocalConfiguration'));
+               $fixture->_set('localConfigurationFile', 'typo3temp/' . uniqid('dummy_'));
+
+               $factoryConfigurationFile = 'typo3temp/' . uniqid('test_') . '.php';
+               $factoryConfigurationAbsoluteFile = PATH_site . $factoryConfigurationFile;
+               $validFactoryConfigurationFileContent =
+                       '<?php' . LF .
+                               'return array();' . LF .
+                       '?>';
+               file_put_contents(
+                       $factoryConfigurationAbsoluteFile,
+                       $validFactoryConfigurationFileContent
+               );
+               $this->testFilesToDelete[] = $factoryConfigurationAbsoluteFile;
+               $fixture->_set('factoryConfigurationFile', $factoryConfigurationFile);
+
+               $additionalFactoryConfigurationFile = 'typo3temp/' . uniqid('test_') . '.php';
+               $additionalFactoryConfigurationAbsoluteFile = PATH_site . $additionalFactoryConfigurationFile;
+               $uniqueContentString = uniqid('string_');
+               $validAdditionalFactoryConfigurationFileContent =
+                       '<?php' . LF .
+                               'return array(' . LF .
+                                       $uniqueContentString . ' => foo,' . LF .
+                               ');' . LF .
+                       '?>';
+               file_put_contents(
+                       $additionalFactoryConfigurationAbsoluteFile,
+                       $validAdditionalFactoryConfigurationFileContent
+               );
+               $this->testFilesToDelete[] = $additionalFactoryConfigurationAbsoluteFile;
+               $fixture->_set('additionalFactoryConfigurationFile', $additionalFactoryConfigurationFile);
+
+               $fixture
+                       ->expects($this->once())
+                       ->method('writeLocalConfiguration')
+                       ->with($this->arrayHasKey($uniqueContentString));
+               $fixture->createLocalConfigurationFromFactoryConfiguration();
+       }
+
        /**
         * @test
         */
index db7a3ec..caf2161 100644 (file)
@@ -1875,6 +1875,19 @@ class GeneralUtilityTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
        /**
         * @test
         */
+       public function unlink_tempfileRemovesHiddenFile() {
+               $fixtureFile = __DIR__ . '/Fixtures/clear.gif';
+               $testFilename = PATH_site . 'typo3temp/' . uniqid('.test_') . '.gif';
+               @copy($fixtureFile, $testFilename);
+               Utility\GeneralUtility::unlink_tempfile($testFilename);
+               $fileExists = file_exists($testFilename);
+               @unlink($testFilename);
+               $this->assertFalse($fileExists);
+       }
+
+       /**
+        * @test
+        */
        public function unlink_tempfileReturnsTrueIfFileWasRemoved() {
                $fixtureFile = __DIR__ . '/Fixtures/clear.gif';
                $testFilename = PATH_site . 'typo3temp/' . uniqid('test_') . '.gif';
@@ -2603,14 +2616,13 @@ class GeneralUtilityTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
                // Create and prepare test file
                $filename = PATH_site . 'typo3temp/' . uniqid('test_');
                Utility\GeneralUtility::writeFileToTypo3tempDir($filename, '42');
+               $this->testFilesToDelete[] = $filename;
                $currentGroupId = posix_getegid();
                // Set target group and run method
                $GLOBALS['TYPO3_CONF_VARS']['BE']['createGroup'] = $currentGroupId;
-               $fixPermissionsResult = Utility\GeneralUtility::fixPermissions($filename);
+               Utility\GeneralUtility::fixPermissions($filename);
                clearstatcache();
-               $resultFileGroup = filegroup($filename);
-               unlink($filename);
-               $this->assertEquals($currentGroupId, $resultFileGroup);
+               $this->assertEquals($currentGroupId, filegroup($filename));
        }
 
        /**
@@ -2623,17 +2635,14 @@ class GeneralUtilityTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
                // Create and prepare test file
                $filename = PATH_site . 'typo3temp/' . uniqid('test_');
                Utility\GeneralUtility::writeFileToTypo3tempDir($filename, '42');
+               $this->testFilesToDelete[] = $filename;
                chmod($filename, 482);
                // Set target permissions and run method
                $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0660';
                $fixPermissionsResult = Utility\GeneralUtility::fixPermissions($filename);
-               // Get actual permissions and clean up
                clearstatcache();
-               $resultFilePermissions = substr(decoct(fileperms($filename)), 2);
-               unlink($filename);
-               // Test if everything was ok
                $this->assertTrue($fixPermissionsResult);
-               $this->assertEquals($resultFilePermissions, '0660');
+               $this->assertEquals('0660', substr(decoct(fileperms($filename)), 2));
        }
 
        /**
@@ -2646,17 +2655,14 @@ class GeneralUtilityTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
                // Create and prepare test file
                $filename = PATH_site . 'typo3temp/' . uniqid('.test_');
                Utility\GeneralUtility::writeFileToTypo3tempDir($filename, '42');
+               $this->testFilesToDelete[] = $filename;
                chmod($filename, 482);
                // Set target permissions and run method
                $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0660';
                $fixPermissionsResult = Utility\GeneralUtility::fixPermissions($filename);
-               // Get actual permissions and clean up
                clearstatcache();
-               $resultFilePermissions = substr(decoct(fileperms($filename)), 2);
-               unlink($filename);
-               // Test if everything was ok
                $this->assertTrue($fixPermissionsResult);
-               $this->assertEquals($resultFilePermissions, '0660');
+               $this->assertEquals('0660', substr(decoct(fileperms($filename)), 2));
        }
 
        /**
@@ -2679,7 +2685,7 @@ class GeneralUtilityTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
                Utility\GeneralUtility::rmdir($directory);
                // Test if everything was ok
                $this->assertTrue($fixPermissionsResult);
-               $this->assertEquals($resultDirectoryPermissions, '0770');
+               $this->assertEquals('0770', $resultDirectoryPermissions);
        }
 
        /**
@@ -2702,7 +2708,7 @@ class GeneralUtilityTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
                Utility\GeneralUtility::rmdir($directory);
                // Test if everything was ok
                $this->assertTrue($fixPermissionsResult);
-               $this->assertEquals($resultDirectoryPermissions, '0770');
+               $this->assertEquals('0770', $resultDirectoryPermissions);
        }
 
        /**
@@ -2725,7 +2731,7 @@ class GeneralUtilityTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
                Utility\GeneralUtility::rmdir($directory);
                // Test if everything was ok
                $this->assertTrue($fixPermissionsResult);
-               $this->assertEquals($resultDirectoryPermissions, '0770');
+               $this->assertEquals('0770', $resultDirectoryPermissions);
        }
 
        /**
@@ -2777,13 +2783,13 @@ class GeneralUtilityTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
                Utility\GeneralUtility::rmdir($baseDirectory);
                // Test if everything was ok
                $this->assertTrue($fixPermissionsResult);
-               $this->assertEquals($resultBaseDirectoryPermissions, '0770');
-               $this->assertEquals($resultBaseFilePermissions, '0660');
-               $this->assertEquals($resultFooDirectoryPermissions, '0770');
-               $this->assertEquals($resultFooFilePermissions, '0660');
-               $this->assertEquals($resultBarDirectoryPermissions, '0770');
-               $this->assertEquals($resultBarFilePermissions, '0660');
-               $this->assertEquals($resultBarFile2Permissions, '0660');
+               $this->assertEquals('0770', $resultBaseDirectoryPermissions);
+               $this->assertEquals('0660', $resultBaseFilePermissions);
+               $this->assertEquals('0770', $resultFooDirectoryPermissions);
+               $this->assertEquals('0660', $resultFooFilePermissions);
+               $this->assertEquals('0770', $resultBarDirectoryPermissions);
+               $this->assertEquals('0660', $resultBarFilePermissions);
+               $this->assertEquals('0660', $resultBarFile2Permissions);
        }
 
        /**
@@ -2827,7 +2833,44 @@ class GeneralUtilityTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
                unlink(PATH_site . $filename);
                // Test if everything was ok
                $this->assertTrue($fixPermissionsResult);
-               $this->assertEquals($resultFilePermissions, '0660');
+               $this->assertEquals('0660', $resultFilePermissions);
+       }
+
+       /**
+        * @test
+        */
+       public function fixPermissionsSetsDefaultPermissionsToFile() {
+               if (TYPO3_OS == 'WIN') {
+                       $this->markTestSkipped('fixPermissions() tests not available on Windows');
+               }
+               $filename = PATH_site . 'typo3temp/' . uniqid('test_');
+               Utility\GeneralUtility::writeFileToTypo3tempDir($filename, '42');
+               $this->testFilesToDelete[] = $filename;
+               chmod($filename, 482);
+               unset($GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask']);
+               $fixPermissionsResult = Utility\GeneralUtility::fixPermissions($filename);
+               clearstatcache();
+               $this->assertTrue($fixPermissionsResult);
+               $this->assertEquals('0644', substr(decoct(fileperms($filename)), 2));
+       }
+
+       /**
+        * @test
+        */
+       public function fixPermissionsSetsDefaultPermissionsToDirectory() {
+               if (TYPO3_OS == 'WIN') {
+                       $this->markTestSkipped('fixPermissions() tests not available on Windows');
+               }
+               $directory = PATH_site . 'typo3temp/' . uniqid('test_');
+               Utility\GeneralUtility::mkdir($directory);
+               chmod($directory, 1551);
+               unset($GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask']);
+               $fixPermissionsResult = Utility\GeneralUtility::fixPermissions($directory);
+               clearstatcache();
+               $resultDirectoryPermissions = substr(decoct(fileperms($directory)), 1);
+               Utility\GeneralUtility::rmdir($directory);
+               $this->assertTrue($fixPermissionsResult);
+               $this->assertEquals('0755', $resultDirectoryPermissions);
        }
 
        ///////////////////////////////
index 737ecea..b113a37 100644 (file)
@@ -805,10 +805,6 @@ class TypoScriptFrontendController {
                        $GLOBALS['TYPO3_DB']->connectDB();
                } catch (\RuntimeException $exception) {
                        switch ($exception->getCode()) {
-                       case 1270853882:
-                               // No database selected: Redirect to Install Tool 1-2-3 mode (fresh installation)
-                               \TYPO3\CMS\Core\Utility\HttpUtility::redirect(TYPO3_mainDir . 'install/index.php?mode=123&step=1&password=joh316');
-                               break;
                        case 1270853883:
                                // Cannot connect to current database
                                $message = 'Cannot connect to the configured database "' . TYPO3_db . '"';
index 2a927bb..e69c5d5 100644 (file)
@@ -68,6 +68,7 @@ class LocalConfigurationUpdate extends \TYPO3\CMS\Install\Updates\AbstractUpdate
                $result = FALSE;
                try {
                        $localConfigurationContent = file(PATH_typo3conf . 'localconf.php');
+
                        // Line array for the three categories: localConfiguration, db settings, additionalConfiguration
                        $typo3ConfigurationVariables = array();
                        $typo3DatabaseVariables = array();
@@ -99,25 +100,25 @@ class LocalConfigurationUpdate extends \TYPO3\CMS\Install\Updates\AbstractUpdate
                                        $additionalConfiguration[] = $line;
                                }
                        }
+
                        // Build new TYPO3_CONF_VARS array
                        $TYPO3_CONF_VARS = NULL;
                        eval(implode(LF, $typo3ConfigurationVariables));
+
                        // Add db settings to array
                        $TYPO3_CONF_VARS['DB'] = $typo3DatabaseVariables;
                        $TYPO3_CONF_VARS = \TYPO3\CMS\Core\Utility\ArrayUtility::sortByKeyRecursive($TYPO3_CONF_VARS);
-                       // Build new (empty) LocalConfiguration file if not exists as the function writeLocalConfiguration depends on it
-                       \TYPO3\CMS\Core\Utility\GeneralUtility::writeFile(
-                               \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Configuration\\ConfigurationManager')->getLocalConfigurationFileResource(),
-                               ''
-                       );
+
                        // Write out new LocalConfiguration file
                        \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Configuration\\ConfigurationManager')->writeLocalConfiguration($TYPO3_CONF_VARS);
+
                        // Write out new AdditionalConfiguration file
                        if (sizeof($additionalConfiguration) > 0) {
                                \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Configuration\\ConfigurationManager')->writeAdditionalConfiguration($additionalConfiguration);
                        } else {
-                               @unlink(\TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Configuration\\ConfigurationManager')->getAdditionalConfigurationFileResource());
+                               @unlink(\TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Configuration\\ConfigurationManager')->getAdditionalConfigurationFileLocation());
                        }
+
                        rename(PATH_site . 'typo3conf/localconf.php', PATH_site . 'typo3conf/localconf.obsolete.php');
                        $result = TRUE;
                } catch (\Exception $e) {
index 915f6dc..4f82972 100644 (file)
@@ -38,6 +38,25 @@ namespace TYPO3\CMS\Install;
 class InstallBootstrap {
 
        /**
+        * During first install, typo3conf/LocalConfiguration.php does not
+        * exist. It is created now based on factory configuration as a
+        * first action in the install process.
+        *
+        * @return void
+        * @internal This is not a public API method, do not use in own extensions
+        */
+       static public function createLocalConfigurationIfNotExists() {
+               /** @var $configurationManager \TYPO3\CMS\Core\Configuration\ConfigurationManager */
+               $configurationManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Configuration\\ConfigurationManager');
+               if (
+                       !file_exists($configurationManager->getLocalConfigurationFileLocation())
+                       && !file_exists($configurationManager->getLocalconfFileLocation())
+               ) {
+                       $configurationManager->createLocalConfigurationFromFactoryConfiguration();
+               }
+       }
+
+       /**
         * Check ENABLE_INSTALL_TOOL and FIRST_INSTALL file in typo3conf
         * or exit the script if conditions to access the install tool are not met.
         *
index 83ca9dd..7401bcc 100644 (file)
@@ -1736,7 +1736,9 @@ REMOTE_ADDR was \'' . \TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('REMOTE
         * @todo Define visibility
         */
        public function generateConfigForm($type = '') {
-               $default_config_content = \TYPO3\CMS\Core\Utility\GeneralUtility::getUrl(\TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Configuration\\ConfigurationManager')->getDefaultConfigurationFileResource());
+               $default_config_content = \TYPO3\CMS\Core\Utility\GeneralUtility::getUrl(
+                       \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Configuration\\ConfigurationManager')->getDefaultConfigurationFileLocation()
+               );
                $commentArr = $this->getDefaultConfigArrayComments($default_config_content);
                switch ($type) {
                case 'get_form':
@@ -6608,4 +6610,4 @@ REMOTE_ADDR was \'' . \TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('REMOTE
        }
 
 }
-?>
+?>
\ No newline at end of file