[FEATURE] Add option to disable automatic installation of extensions 72/30972/8
authorSusanne Moog <typo3@susannemoog.de>
Fri, 20 Jun 2014 19:47:51 +0000 (21:47 +0200)
committerMarkus Klein <klein.t3@reelworx.at>
Tue, 24 Mar 2015 09:55:06 +0000 (10:55 +0100)
The extension manager currently downloads and installs an extension
from TER or after file upload directly. Some people want to do some
audits or modifications before installing an extension, therefore there
should be an option to disable the automatic installation process and
just download an extension like it was default in older extension managers.

Like suggested in the related UX/forge issue this patch implements
a simple switch in the configuration of the extension manager itself.

Resolves: #50501
Related: #50582
Releases: master
Change-Id: I538306fd9a067abebe0ffd36704f95eb52c3c454
Reviewed-on: http://review.typo3.org/30972
Reviewed-by: Nicole Cordes <typo3@cordes.co>
Tested-by: Nicole Cordes <typo3@cordes.co>
Reviewed-by: Markus Klein <klein.t3@reelworx.at>
Tested-by: Markus Klein <klein.t3@reelworx.at>
typo3/sysext/core/Documentation/Changelog/master/Feature-50501-DisableAutomaticExtInstallation.rst [new file with mode: 0644]
typo3/sysext/extensionmanager/Classes/Controller/DownloadController.php
typo3/sysext/extensionmanager/Classes/Controller/UploadExtensionFileController.php
typo3/sysext/extensionmanager/Classes/Service/ExtensionManagementService.php
typo3/sysext/extensionmanager/Resources/Private/Language/locallang.xlf
typo3/sysext/extensionmanager/Resources/Private/Templates/Download/InstallFromTer.json
typo3/sysext/extensionmanager/Resources/Public/JavaScript/Main.js
typo3/sysext/extensionmanager/Tests/Unit/Service/ExtensionManagementServiceTest.php
typo3/sysext/extensionmanager/ext_conf_template.txt [new file with mode: 0644]

diff --git a/typo3/sysext/core/Documentation/Changelog/master/Feature-50501-DisableAutomaticExtInstallation.rst b/typo3/sysext/core/Documentation/Changelog/master/Feature-50501-DisableAutomaticExtInstallation.rst
new file mode 100644 (file)
index 0000000..8064c00
--- /dev/null
@@ -0,0 +1,12 @@
+===================================================================
+Feature: #50501 - Extension Manager: Disable automatic installation
+===================================================================
+
+Description
+===========
+
+The extension manager currently downloads and installs an extension from TER directly. Some people want to do
+audits or modifications before installing an extension, therefore there is now an option to disable the automatic
+installation process and just download an extension.
+
+The option is located in the settings of the extension manager itself (Extensions > Installed > Extension Manager).
index f27bded..815255b 100644 (file)
@@ -54,6 +54,12 @@ class DownloadController extends AbstractController {
        protected $downloadUtility;
 
        /**
+        * @var \TYPO3\CMS\Extensionmanager\Utility\ConfigurationUtility
+        * @inject
+        */
+       protected $configurationUtility;
+
+       /**
         * Check extension dependencies
         *
         * @param \TYPO3\CMS\Extensionmanager\Domain\Model\Extension $extension
@@ -104,9 +110,11 @@ class DownloadController extends AbstractController {
         */
        public function installFromTerAction(\TYPO3\CMS\Extensionmanager\Domain\Model\Extension $extension, $downloadPath) {
                list($result, $errorMessages) = $this->installFromTer($extension, $downloadPath);
+               $emConfiguration = $this->configurationUtility->getCurrentConfiguration('extensionmanager');
                $this->view
                        ->assign('result', $result)
                        ->assign('extension', $extension)
+                       ->assign('installationTypeLanguageKey', (bool)$emConfiguration['automaticInstallation']['value'] ? '' : '.downloadOnly')
                        ->assign('unresolvedDependencies', $errorMessages);
        }
 
index c032bd2..b4515df 100644 (file)
@@ -27,6 +27,12 @@ use TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException;
 class UploadExtensionFileController extends AbstractController {
 
        /**
+        * @var \TYPO3\CMS\Extensionmanager\Utility\ConfigurationUtility
+        * @inject
+        */
+       protected $configurationUtility;
+
+       /**
         * @var \TYPO3\CMS\Extensionmanager\Utility\FileHandlingUtility
         * @inject
         */
@@ -91,17 +97,20 @@ class UploadExtensionFileController extends AbstractController {
                                );
                        }
                        $extensionData = $this->extractExtensionFromFile($tempFile, $fileName, $overwrite);
-                       $this->activateExtension($extensionData['extKey']);
                        $this->addFlashMessage(
                                htmlspecialchars($this->translate('extensionList.uploadFlashMessage.message', array($extensionData['extKey']))),
                                htmlspecialchars($this->translate('extensionList.uploadFlashMessage.title')),
                                FlashMessage::OK
                        );
-                       $this->addFlashMessage(
-                               htmlspecialchars($this->translate('extensionList.installedFlashMessage.message', array($extensionData['extKey']))),
-                               '',
-                               FlashMessage::OK
-                       );
+                       $emConfiguration = $this->configurationUtility->getCurrentConfiguration('extensionmanager');
+                       if ($emConfiguration['automaticInstallation']['value']) {
+                               $this->activateExtension($extensionData['extKey']);
+                               $this->addFlashMessage(
+                                       htmlspecialchars($this->translate('extensionList.installedFlashMessage.message', array($extensionData['extKey']))),
+                                       '',
+                                       FlashMessage::OK
+                               );
+                       }
                } catch (\Exception $exception) {
                        $this->removeExtensionAndRestoreFromBackup($fileName);
                        $this->addFlashMessage(htmlspecialchars($exception->getMessage()), '', FlashMessage::ERROR);
index 8edc745..1821c5f 100644 (file)
@@ -60,6 +60,12 @@ class ExtensionManagementService implements \TYPO3\CMS\Core\SingletonInterface {
        protected $downloadUtility;
 
        /**
+        * @var \TYPO3\CMS\Extensionmanager\Utility\ConfigurationUtility
+        * @inject
+        */
+       protected $configurationUtility;
+
+       /**
         * @var bool
         */
        protected $skipSystemDependencyCheck = FALSE;
@@ -124,6 +130,16 @@ class ExtensionManagementService implements \TYPO3\CMS\Core\SingletonInterface {
        }
 
        /**
+        * Returns whether automatic installation is enabled.
+        *
+        * @return array
+        */
+       protected function isAutomaticInstallationEnabled() {
+               $emConfiguration = $this->configurationUtility->getCurrentConfiguration('extensionmanager');
+               return (bool)$emConfiguration['automaticInstallation']['value'];
+       }
+
+       /**
         * Install the extension
         *
         * @param Extension $extension
@@ -131,7 +147,6 @@ class ExtensionManagementService implements \TYPO3\CMS\Core\SingletonInterface {
         */
        public function installExtension(Extension $extension) {
                $this->downloadExtension($extension);
-
                if (!$this->checkDependencies($extension)) {
                        return FALSE;
                }
@@ -148,15 +163,17 @@ class ExtensionManagementService implements \TYPO3\CMS\Core\SingletonInterface {
                if (array_key_exists('download', $queue)) {
                        $downloadedDependencies = $this->downloadDependencies($queue['download']);
                }
-               if (array_key_exists('update', $queue)) {
-                       $this->downloadDependencies($queue['update']);
-                       $updatedDependencies = $this->uninstallDependenciesToBeUpdated($queue['update']);
-               }
-               // add extension at the end of the download queue
-               $this->downloadQueue->addExtensionToInstallQueue($extension->getExtensionKey());
-               $installQueue = $this->downloadQueue->getExtensionInstallStorage();
-               if (count($installQueue) > 0) {
-                       $installedDependencies = $this->installDependencies($installQueue);
+               if ($this->isAutomaticInstallationEnabled()) {
+                       if (array_key_exists('update', $queue)) {
+                               $this->downloadDependencies($queue['update']);
+                               $updatedDependencies = $this->uninstallDependenciesToBeUpdated($queue['update']);
+                       }
+                       // add extension at the end of the download queue
+                       $this->downloadQueue->addExtensionToInstallQueue($extension->getExtensionKey());
+                       $installQueue = $this->downloadQueue->getExtensionInstallStorage();
+                       if (count($installQueue) > 0) {
+                               $installedDependencies = $this->installDependencies($installQueue);
+                       }
                }
                return array_merge($downloadedDependencies, $updatedDependencies, $installedDependencies);
        }
index 6bf4bd0..9e23bed 100644 (file)
                        <trans-unit id="extensionList.dependenciesResolveDownloadSuccess.message" xml:space="preserve">
                                <source>Your installation of {0} was successful.</source>
                        </trans-unit>
+                       <trans-unit id="extensionList.dependenciesResolveDownloadSuccess.message.downloadOnly" xml:space="preserve">
+                               <source>Your download of {0} was successful.</source>
+                       </trans-unit>
                        <trans-unit id="extensionList.dependenciesResolveDownloadSuccess.header" xml:space="preserve">
                                <source>Log</source>
                        </trans-unit>
                        <trans-unit id="extensionList.dependenciesResolveFlashMessage.title" xml:space="preserve">
                                <source>{0} installed.</source>
                        </trans-unit>
+                       <trans-unit id="extensionList.dependenciesResolveFlashMessage.title.downloadOnly" xml:space="preserve">
+                               <source>{0} downloaded.</source>
+                       </trans-unit>
                        <trans-unit id="extensionList.uploadFlashMessage.title" xml:space="preserve">
                                <source>Extension Upload</source>
                        </trans-unit>
                                <source>Author:</source>
                        </trans-unit>
                        <trans-unit id="extensionList.distribution.title" xml:space="preserve">
-                       <source>Title:</source>
+                               <source>Title:</source>
                        </trans-unit>
                        <trans-unit id="extensionList.distribution.version" xml:space="preserve">
                                <source>Version:</source>
                        <trans-unit id="fileHandling.installPathWasNoDirectory" xml:space="preserve">
                                <source>ERROR: The extension install path "%s" was no directory!</source>
                        </trans-unit>
+                       <trans-unit id="config.automaticInstallation">
+                               <source>Install extensions automatically after download from TER or file upload</source>
+                       </trans-unit>
                </body>
        </file>
 </xliff>
index 79e5ee4..2e161dd 100644 (file)
@@ -2,6 +2,7 @@
 <em:format.jsonEncode additionalAttributes="{
        result: result,
        extension: extension.extensionKey,
+       installationTypeLanguageKey: installationTypeLanguageKey,
        errorCount: '{f:count(subject: unresolvedDependencies)}',
        errorTitle: '{f:translate(key: \'downloadExtension.dependencies.errorTitle\')}',
        errorMessage: '{f:render(partial: \'List/UnresolvedDependencies\', arguments: \'{_all}\')}',
index 91adca3..9c2ab3c 100644 (file)
@@ -424,7 +424,7 @@ define(['jquery', 'datatables', 'jquery/jquery.clearable'], function($) {
                                                }
                                        ]);
                                } else {
-                                       var successMessage = TYPO3.lang['extensionList.dependenciesResolveDownloadSuccess.message'].replace(/\{0\}/g, data.extension) + ' <br />';
+                                       var successMessage = TYPO3.lang['extensionList.dependenciesResolveDownloadSuccess.message' + data.installationTypeLanguageKey].replace(/\{0\}/g, data.extension) + ' <br />';
                                        successMessage += '<br /><h3>' + TYPO3.lang['extensionList.dependenciesResolveDownloadSuccess.header'] + ':</h3>';
                                        $.each(data.result, function(index, value) {
                                                successMessage += TYPO3.lang['extensionList.dependenciesResolveDownloadSuccess.item'] + ' ' + index + ':<br /><ul>';
@@ -433,7 +433,7 @@ define(['jquery', 'datatables', 'jquery/jquery.clearable'], function($) {
                                                });
                                                successMessage += '</ul>';
                                        });
-                                       top.TYPO3.Flashmessage.display(top.TYPO3.Severity.info, TYPO3.lang['extensionList.dependenciesResolveFlashMessage.title'].replace(/\{0\}/g, data.extension), successMessage, 15);
+                                       top.TYPO3.Flashmessage.display(top.TYPO3.Severity.info, TYPO3.lang['extensionList.dependenciesResolveFlashMessage.title' + data.installationTypeLanguageKey].replace(/\{0\}/g, data.extension), successMessage, 15);
                                        top.TYPO3.ModuleMenu.App.refreshMenu();
                                }
                        }
index dccc94c..72334ce 100644 (file)
@@ -27,9 +27,10 @@ class ExtensionManagementServiceTest extends \TYPO3\CMS\Core\Tests\UnitTestCase
        public function resolveDependenciesCallsDownloadDependenciesIfDownloadKeyExistsInQueue() {
                $managementMock = $this->getAccessibleMock(
                        \TYPO3\CMS\Extensionmanager\Service\ExtensionManagementService::class,
-                       array('downloadDependencies', 'uninstallDependenciesToBeUpdated', 'setInExtensionRepository', 'downloadMainExtension')
+                       array('downloadDependencies', 'uninstallDependenciesToBeUpdated', 'setInExtensionRepository', 'downloadMainExtension', 'isAutomaticInstallationEnabled')
                );
                $managementMock->expects($this->any())->method('downloadMainExtension')->will($this->returnValue(array()));
+               $managementMock->expects($this->any())->method('isAutomaticInstallationEnabled')->will($this->returnValue(array(false)));
                $extensionModelMock = $this->getAccessibleMock(\TYPO3\CMS\Extensionmanager\Domain\Model\Extension::class);
                $extensionModelMock->_set('extensionKey', 'foobar');
                $extensionModelMock->_set('version', '1.0.0');
@@ -54,9 +55,10 @@ class ExtensionManagementServiceTest extends \TYPO3\CMS\Core\Tests\UnitTestCase
        public function resolveDependenciesCallsUpdateAndDownloadDependenciesIfUpdateKeyExistsInQueue() {
                $managementMock = $this->getAccessibleMock(
                        \TYPO3\CMS\Extensionmanager\Service\ExtensionManagementService::class,
-                       array('downloadDependencies', 'uninstallDependenciesToBeUpdated', 'setInExtensionRepository', 'downloadMainExtension')
+                       array('downloadDependencies', 'uninstallDependenciesToBeUpdated', 'setInExtensionRepository', 'downloadMainExtension', 'isAutomaticInstallationEnabled')
                );
                $managementMock->expects($this->any())->method('downloadMainExtension')->will($this->returnValue(array()));
+               $managementMock->expects($this->any())->method('isAutomaticInstallationEnabled')->will($this->returnValue(true));
                $extensionModelMock = $this->getAccessibleMock(\TYPO3\CMS\Extensionmanager\Domain\Model\Extension::class);
                $extensionModelMock->_set('extensionKey', 'foobar');
                $extensionModelMock->_set('version', '1.0.0');
diff --git a/typo3/sysext/extensionmanager/ext_conf_template.txt b/typo3/sysext/extensionmanager/ext_conf_template.txt
new file mode 100644 (file)
index 0000000..dc57e1d
--- /dev/null
@@ -0,0 +1,2 @@
+  # cat=basic/enable; type=boolean; label=LLL:EXT:extensionmanager/Resources/Private/Language/locallang.xlf:config.automaticInstallation
+automaticInstallation = 1
\ No newline at end of file