[BUGFIX] Fix dependencies for t3x upload 42/42642/3
authorHelmut Hummel <helmut.hummel@typo3.org>
Fri, 14 Aug 2015 16:03:02 +0000 (18:03 +0200)
committerNicole Cordes <typo3@cordes.co>
Sun, 16 Aug 2015 12:37:35 +0000 (14:37 +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/42642
Reviewed-by: Nicole Cordes <typo3@cordes.co>
Tested-by: Nicole Cordes <typo3@cordes.co>
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 3f11285..ef1908e 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;
 
 /**
@@ -27,6 +28,11 @@ use TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException;
 class UploadExtensionFileController extends AbstractController {
 
        /**
+        * @var \TYPO3\CMS\Extensionmanager\Domain\Repository\ExtensionRepository
+        */
+       protected $extensionRepository;
+
+       /**
         * @var \TYPO3\CMS\Extensionmanager\Utility\FileHandlingUtility
         * @inject
         */
@@ -55,6 +61,13 @@ class UploadExtensionFileController extends AbstractController {
        protected $removeFromOriginalPath = FALSE;
 
        /**
+        * @param \TYPO3\CMS\Extensionmanager\Domain\Repository\ExtensionRepository $extensionRepository
+        */
+       public function injectExtensionRepository(\TYPO3\CMS\Extensionmanager\Domain\Repository\ExtensionRepository $extensionRepository) {
+               $this->extensionRepository = $extensionRepository;
+       }
+
+       /**
         * Remove backup folder before destruction
         */
        public function __destruct() {
@@ -107,6 +120,8 @@ class UploadExtensionFileController extends AbstractController {
                        }
                } catch (\TYPO3\CMS\Extbase\Mvc\Exception\StopActionException $exception) {
                        throw $exception;
+               } catch (DependencyConfigurationNotFoundException $exception) {
+                       $this->addFlashMessage(htmlspecialchars($exception->getMessage()), '', FlashMessage::ERROR);
                } catch (\Exception $exception) {
                        $this->removeExtensionAndRestoreFromBackup($fileName);
                        $this->addFlashMessage(htmlspecialchars($exception->getMessage()), '', FlashMessage::ERROR);
@@ -138,7 +153,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);
@@ -166,6 +182,7 @@ class UploadExtensionFileController extends AbstractController {
         * @param string $file Path to uploaded file
         * @param boolean $overwrite Overwrite existing extension if TRUE
         * @throws ExtensionManagerException
+        * @throws DependencyConfigurationNotFoundException
         * @return array
         */
        protected function getExtensionFromT3xFile($file, $overwrite = FALSE) {
@@ -185,7 +202,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 0e3726b..c27584d 100644 (file)
@@ -13,6 +13,7 @@ namespace TYPO3\CMS\Extensionmanager\Service;
  *
  * The TYPO3 project - inspiring people to share!
  */
+
 use TYPO3\CMS\Extensionmanager\Domain\Model\Extension;
 
 /**
@@ -47,12 +48,6 @@ class ExtensionManagementService implements \TYPO3\CMS\Core\SingletonInterface {
        protected $extensionModelUtility;
 
        /**
-        * @var \TYPO3\CMS\Extensionmanager\Utility\ListUtility
-        * @inject
-        */
-       protected $listUtility;
-
-       /**
         * @var \TYPO3\CMS\Extensionmanager\Utility\DownloadUtility
         * @inject
         */
index 197cd3b..35bc9d7 100644 (file)
@@ -13,6 +13,7 @@ namespace TYPO3\CMS\Extensionmanager\Utility;
  *
  * The TYPO3 project - inspiring people to share!
  */
+
 /**
  * Utility for dealing with ext_emconf
  *
@@ -49,7 +50,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 53ef466..850e751 100644 (file)
@@ -1,10 +1,5 @@
 <?php
 namespace TYPO3\CMS\Extensionmanager\Utility;
-use TYPO3\CMS\Core\Utility\PathUtility;
-use TYPO3\CMS\Core\Utility\GeneralUtility;
-use TYPO3\CMS\Extensionmanager\Domain\Model\Extension;
-use TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException;
-use TYPO3\CMS\Lang\LanguageService;
 
 /**
  * This file is part of the TYPO3 CMS project.
@@ -18,6 +13,13 @@ use TYPO3\CMS\Lang\LanguageService;
  *
  * The TYPO3 project - inspiring people to share!
  */
+
+use TYPO3\CMS\Core\Utility\PathUtility;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Extensionmanager\Domain\Model\Extension;
+use TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException;
+use TYPO3\CMS\Lang\LanguageService;
+
 /**
  * Utility for dealing with files and folders
  *
@@ -269,6 +271,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
@@ -276,6 +279,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);
        }