[BUGFIX] Fix dependencies for t3x upload 19/42619/6
authorHelmut Hummel <helmut.hummel@typo3.org>
Fri, 14 Aug 2015 16:03:02 +0000 (18:03 +0200)
committerMarkus Klein <markus.klein@typo3.org>
Sat, 15 Aug 2015 12:03:21 +0000 (14:03 +0200)
When extracting the t3x archive, the EM_CONF data is taken to
create a new ext_emconf.php file.
An already extracted ext_emconf.php file is overwritten in this process.

Since those t3x files are created by TER server and this TER server
does not include the extension constraints in this array,
all constraints are lost in this process.

To fix this, it is needed to use a present ext_emconf.php file
and merge the meta properties with its properties to construct
the final ext_emconf.php.

Resolves: #69070
Releases: master, 6.2
Change-Id: I3997bee05f256a3ff23f0eee516ecf0a323017c3
Reviewed-on: http://review.typo3.org/42619
Reviewed-by: Nicole Cordes <typo3@cordes.co>
Tested-by: Nicole Cordes <typo3@cordes.co>
Reviewed-by: Markus Klein <markus.klein@typo3.org>
Tested-by: Markus Klein <markus.klein@typo3.org>
typo3/sysext/extensionmanager/Classes/Controller/UploadExtensionFileController.php
typo3/sysext/extensionmanager/Classes/Exception/DependencyConfigurationNotFoundException.php [new file with mode: 0644]
typo3/sysext/extensionmanager/Classes/Service/ExtensionManagementService.php
typo3/sysext/extensionmanager/Classes/Utility/EmConfUtility.php
typo3/sysext/extensionmanager/Classes/Utility/FileHandlingUtility.php

index 7af8583..c85eb6d 100644 (file)
@@ -16,6 +16,7 @@ namespace TYPO3\CMS\Extensionmanager\Controller;
 
 use TYPO3\CMS\Core\Messaging\FlashMessage;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Extensionmanager\Exception\DependencyConfigurationNotFoundException;
 use TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException;
 
 /**
@@ -30,6 +31,11 @@ class UploadExtensionFileController extends AbstractController {
        protected $configurationUtility;
 
        /**
+        * @var \TYPO3\CMS\Extensionmanager\Domain\Repository\ExtensionRepository
+        */
+       protected $extensionRepository;
+
+       /**
         * @var \TYPO3\CMS\Extensionmanager\Utility\FileHandlingUtility
         */
        protected $fileHandlingUtility;
@@ -62,6 +68,13 @@ class UploadExtensionFileController extends AbstractController {
        }
 
        /**
+        * @param \TYPO3\CMS\Extensionmanager\Domain\Repository\ExtensionRepository $extensionRepository
+        */
+       public function injectExtensionRepository(\TYPO3\CMS\Extensionmanager\Domain\Repository\ExtensionRepository $extensionRepository) {
+               $this->extensionRepository = $extensionRepository;
+       }
+
+       /**
         * @param \TYPO3\CMS\Extensionmanager\Utility\FileHandlingUtility $fileHandlingUtility
         */
        public function injectFileHandlingUtility(\TYPO3\CMS\Extensionmanager\Utility\FileHandlingUtility $fileHandlingUtility) {
@@ -139,6 +152,8 @@ class UploadExtensionFileController extends AbstractController {
                        }
                } catch (\TYPO3\CMS\Extbase\Mvc\Exception\StopActionException $exception) {
                        throw $exception;
+               } catch (DependencyConfigurationNotFoundException $exception) {
+                       $this->addFlashMessage($exception->getMessage(), '', FlashMessage::ERROR);
                } catch (\Exception $exception) {
                        $this->removeExtensionAndRestoreFromBackup($fileName);
                        $this->addFlashMessage($exception->getMessage(), '', FlashMessage::ERROR);
@@ -170,7 +185,8 @@ class UploadExtensionFileController extends AbstractController {
         * @param string $fileName Filename of the uploaded file
         * @param bool $overwrite If true, extension will be replaced
         * @return array Extension data
-        * @throws \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException
+        * @throws ExtensionManagerException
+        * @throws DependencyConfigurationNotFoundException
         */
        public function extractExtensionFromFile($uploadPath, $fileName, $overwrite) {
                $fileExtension = pathinfo($fileName, PATHINFO_EXTENSION);
@@ -198,6 +214,7 @@ class UploadExtensionFileController extends AbstractController {
         * @param string $file Path to uploaded file
         * @param bool $overwrite Overwrite existing extension if TRUE
         * @throws ExtensionManagerException
+        * @throws DependencyConfigurationNotFoundException
         * @return array
         */
        protected function getExtensionFromT3xFile($file, $overwrite = FALSE) {
@@ -217,7 +234,16 @@ class UploadExtensionFileController extends AbstractController {
                        $this->copyExtensionFolderToTempFolder($extensionData['extKey']);
                }
                $this->removeFromOriginalPath = TRUE;
-               $this->fileHandlingUtility->unpackExtensionFromExtensionDataArray($extensionData);
+               $extension = $this->extensionRepository->findOneByExtensionKeyAndVersion($extensionData['extKey'], $extensionData['EM_CONF']['version']);
+               $this->fileHandlingUtility->unpackExtensionFromExtensionDataArray($extensionData, $extension);
+
+               if (empty($extension)
+                       && empty($extensionData['EM_CONF']['constraints'])
+                       && !isset($extensionData['FILES']['ext_emconf.php'])
+                       && !isset($extensionData['FILES']['/ext_emconf.php'])
+               ) {
+                       throw new DependencyConfigurationNotFoundException('Extension cannot be installed automatically because no dependencies could be found! Please check dependencies manually (on typo3.org) before installing the extension.', 1439587168);
+               }
 
                return $extensionData;
        }
diff --git a/typo3/sysext/extensionmanager/Classes/Exception/DependencyConfigurationNotFoundException.php b/typo3/sysext/extensionmanager/Classes/Exception/DependencyConfigurationNotFoundException.php
new file mode 100644 (file)
index 0000000..ee51355
--- /dev/null
@@ -0,0 +1,22 @@
+<?php
+namespace TYPO3\CMS\Extensionmanager\Exception;
+
+/*
+ * 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!
+ */
+
+/**
+ * An exception when dependency configuration could not be found after uploading a t3x file
+ */
+class DependencyConfigurationNotFoundException extends ExtensionManagerException {
+
+}
index 7284d96..fb313fc 100644 (file)
@@ -45,11 +45,6 @@ class ExtensionManagementService implements \TYPO3\CMS\Core\SingletonInterface {
        protected $extensionModelUtility;
 
        /**
-        * @var \TYPO3\CMS\Extensionmanager\Utility\ListUtility
-        */
-       protected $listUtility;
-
-       /**
         * @var \TYPO3\CMS\Extensionmanager\Utility\DownloadUtility
         */
        protected $downloadUtility;
@@ -93,13 +88,6 @@ class ExtensionManagementService implements \TYPO3\CMS\Core\SingletonInterface {
        }
 
        /**
-        * @param \TYPO3\CMS\Extensionmanager\Utility\ListUtility $listUtility
-        */
-       public function injectListUtility(\TYPO3\CMS\Extensionmanager\Utility\ListUtility $listUtility) {
-               $this->listUtility = $listUtility;
-       }
-
-       /**
         * @param \TYPO3\CMS\Extensionmanager\Utility\DownloadUtility $downloadUtility
         */
        public function injectDownloadUtility(\TYPO3\CMS\Extensionmanager\Utility\DownloadUtility $downloadUtility) {
index 73f53b1..68464f4 100644 (file)
@@ -48,7 +48,7 @@ class EmConfUtility implements \TYPO3\CMS\Core\SingletonInterface {
         * @return string
         */
        public function constructEmConf(array $extensionData, \TYPO3\CMS\Extensionmanager\Domain\Model\Extension $extension = NULL) {
-               if (is_object($extension)) {
+               if (is_object($extension) && empty($extensionData['EM_CONF']['constraints'])) {
                        $extensionData['EM_CONF']['constraints'] = unserialize($extension->getSerializedDependencies());
                }
                $emConf = $this->fixEmConf($extensionData['EM_CONF']);
index 31c5919..e25cf1b 100644 (file)
@@ -296,6 +296,7 @@ class FileHandlingUtility implements \TYPO3\CMS\Core\SingletonInterface {
 
        /**
         * Constructs emConf and writes it to corresponding file
+        * In case the file has been extracted already, the properties of the meta data take precedence but are merged with the present ext_emconf.php
         *
         * @param array $extensionData
         * @param string $rootPath
@@ -303,6 +304,16 @@ class FileHandlingUtility implements \TYPO3\CMS\Core\SingletonInterface {
         * @return void
         */
        protected function writeEmConfToFile(array $extensionData, $rootPath, Extension $extension = NULL) {
+               $emConfFileData = array();
+               if (file_exists($rootPath . 'ext_emconf.php')) {
+                       $emConfFileData = $this->emConfUtility->includeEmConf(
+                               array(
+                                       'key' => $extensionData['extKey'],
+                                       'siteRelPath' => PathUtility::stripPathSitePrefix($rootPath)
+                               )
+                       );
+               }
+               $extensionData['EM_CONF'] = array_replace_recursive($emConfFileData, $extensionData['EM_CONF']);
                $emConfContent = $this->emConfUtility->constructEmConf($extensionData, $extension);
                GeneralUtility::writeFile($rootPath . 'ext_emconf.php', $emConfContent);
        }