[TASK] Migrate extension commands to Symfony 55/58055/12
authorBenni Mack <benni@typo3.org>
Mon, 27 Aug 2018 14:24:00 +0000 (16:24 +0200)
committerGeorg Ringer <georg.ringer@gmail.com>
Tue, 28 Aug 2018 17:01:33 +0000 (19:01 +0200)
The Extbase command controller from Extension Manager is the only
CommandController used in TYPO3 Core (apart from extbase:help), all
others have been migrated to symfony/console commands.

This however is now only possible due to the recent migration to define
these commands as "non-schedulable" so they do not show up in the
scheduler as a possible command to be called repeatedly.

For the "extensionmanager:extension:dumpclassloadinginformation"
call, the functionality is moved to EXT:core as this is not related to any
functionality in ExtensionManager, as it does not need any information
of this. This command has been made available under "dumpautoload"
to get closer on the naming scheme of native composer.

"install" and "uninstall" however rely on the DI concept of Extbase and
Extensionmanager to inject necessary components and is tightly
intertwined. These are now provided as "extension:activate" and
"extension:deactivate" respectively to convey their purpose and especially
show that the latter does not remove any data or code.

Releases: master
Resolves: #85996
Change-Id: I8025d8ba8f577c46815996bd3c7d13d17dec268a
Reviewed-on: https://review.typo3.org/58055
Tested-by: TYPO3com <no-reply@typo3.com>
Reviewed-by: Nicole Cordes <typo3@cordes.co>
Reviewed-by: Mathias Brodala <mbrodala@pagemachine.de>
Tested-by: Mathias Brodala <mbrodala@pagemachine.de>
Reviewed-by: Wouter Wolters <typo3@wouterwolters.nl>
Reviewed-by: Georg Ringer <georg.ringer@gmail.com>
Tested-by: Georg Ringer <georg.ringer@gmail.com>
typo3/sysext/core/Classes/Command/DumpAutoloadCommand.php [new file with mode: 0644]
typo3/sysext/core/Configuration/Commands.php
typo3/sysext/core/Documentation/Changelog/master/Deprecation-85996-ExtensionManagerCommandController.rst [new file with mode: 0644]
typo3/sysext/extensionmanager/Classes/Command/ActivateExtensionCommand.php [new file with mode: 0644]
typo3/sysext/extensionmanager/Classes/Command/DeactivateExtensionCommand.php [new file with mode: 0644]
typo3/sysext/extensionmanager/Classes/Command/ExtensionCommandController.php
typo3/sysext/extensionmanager/Configuration/Commands.php [new file with mode: 0644]
typo3/sysext/extensionmanager/ext_localconf.php
typo3/sysext/install/Configuration/ExtensionScanner/Php/ClassNameMatcher.php
typo3/sysext/install/Configuration/ExtensionScanner/Php/MethodCallMatcher.php

diff --git a/typo3/sysext/core/Classes/Command/DumpAutoloadCommand.php b/typo3/sysext/core/Classes/Command/DumpAutoloadCommand.php
new file mode 100644 (file)
index 0000000..6aae05f
--- /dev/null
@@ -0,0 +1,64 @@
+<?php
+declare(strict_types = 1);
+namespace TYPO3\CMS\Core\Command;
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Style\SymfonyStyle;
+use TYPO3\CMS\Core\Core\ClassLoadingInformation;
+use TYPO3\CMS\Core\Core\Environment;
+
+/**
+ * Command for dumping the class-loading information.
+ */
+class DumpAutoloadCommand extends Command
+{
+    /**
+     * Defines the allowed options for this command
+     */
+    protected function configure()
+    {
+        $this->setDescription('Updates class loading information in non-composer mode.');
+        $this->setHelp('This command is only needed during development. The extension manager takes care of creating or updating this info properly during extension (de-)activation.');
+        $this->setAliases([
+            'extensionmanager:extension:dumpclassloadinginformation',
+            'extension:dumpclassloadinginformation'
+        ]);
+    }
+
+    /**
+     * This command is not needed in composer mode.
+     *
+     * @inheritdoc
+     */
+    public function isEnabled()
+    {
+        return !Environment::isComposerMode();
+    }
+
+    /**
+     * Dumps the class loading information
+     *
+     * @inheritdoc
+     */
+    protected function execute(InputInterface $input, OutputInterface $output)
+    {
+        $io = new SymfonyStyle($input, $output);
+        ClassLoadingInformation::dumpClassLoadingInformation();
+        $io->success('Class loading information has been updated.');
+    }
+}
index 7f1d0ac..e182800 100644 (file)
@@ -1,7 +1,11 @@
 <?php
 
 return [
+    'dumpautoload' => [
+        'class' => \TYPO3\CMS\Core\Command\DumpAutoloadCommand::class,
+        'schedulable' => false,
+    ],
     'swiftmailer:spool:send' => [
-        'class' => \TYPO3\CMS\Core\Command\SendEmailCommand::class
+        'class' => \TYPO3\CMS\Core\Command\SendEmailCommand::class,
     ],
 ];
diff --git a/typo3/sysext/core/Documentation/Changelog/master/Deprecation-85996-ExtensionManagerCommandController.rst b/typo3/sysext/core/Documentation/Changelog/master/Deprecation-85996-ExtensionManagerCommandController.rst
new file mode 100644 (file)
index 0000000..001acb6
--- /dev/null
@@ -0,0 +1,46 @@
+.. include:: ../../Includes.txt
+
+========================================================
+Deprecation: #85996 - ExtensionManager CommandController
+========================================================
+
+See :issue:`85996`
+
+Description
+===========
+
+The following Extension Manager CLI commands have been reimplemented internally with Symfony console
+commands:
+
+* :bash:`extensionmanager:extension:install`, now :bash:`extension:activate`
+* :bash:`extensionmanager:extension:uninstall`, now :bash:`extension:deactivate`
+* :bash:`extensionmanager:extension:dumpclassloadinginformation`, now :bash:`dumpautoload`
+
+The left-over command controller PHP class :php:`TYPO3\CMS\Extensionmanager\Command\ExtensionCommandController`
+is now not in use anymore, and therefore marked as deprecated.
+
+
+Impact
+======
+
+Calling any of the commands within the PHP class will trigger a deprecation warning.
+
+
+Affected Installations
+======================
+
+TYPO3 installations that extend the command controller directly in an extension. Installations
+simply using the CLI entrypoint are not affected.
+
+
+Migration
+=========
+
+* use :bash:`extension:activate` instead of :bash:`extensionmanager:extension:install`
+* use :bash:`extension:deactivate` instead of :bash:`extensionmanager:extension:uninstall`
+* use :bash:`dumpautoload` instead of :bash:`extensionmanager:extension:dumpclassloadinginformation`
+
+In order to achieve the same functionality within custom PHP code, it is encouraged to use the
+underlying logic within the commands instead of calling or extending the command controller class.
+
+.. index:: CLI, FullyScanned, ext:extensionmanager
diff --git a/typo3/sysext/extensionmanager/Classes/Command/ActivateExtensionCommand.php b/typo3/sysext/extensionmanager/Classes/Command/ActivateExtensionCommand.php
new file mode 100644 (file)
index 0000000..94afb6b
--- /dev/null
@@ -0,0 +1,69 @@
+<?php
+declare(strict_types = 1);
+namespace TYPO3\CMS\Extensionmanager\Command;
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Style\SymfonyStyle;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Extbase\Object\ObjectManager;
+use TYPO3\CMS\Extbase\SignalSlot\Dispatcher;
+use TYPO3\CMS\Extensionmanager\Utility\InstallUtility;
+
+/**
+ * Command for activating an existing extension via CLI.
+ */
+class ActivateExtensionCommand extends Command
+{
+    /**
+     * Defines the allowed options for this command
+     */
+    protected function configure()
+    {
+        $this
+            ->setDescription('Activates an extension by key')
+            ->setHelp('The extension files must be present in one of the recognized extension folder paths in TYPO3.')
+            ->setAliases(['extensionmanager:extension:install', 'extension:install'])
+            ->addArgument(
+                'extensionkey',
+                InputArgument::REQUIRED,
+                'The extension key of a currently deactivated extension, located in one of TYPO3\'s extension paths.'
+            );
+    }
+
+    /**
+     * Installs an extension
+     *
+     * @inheritdoc
+     */
+    protected function execute(InputInterface $input, OutputInterface $output)
+    {
+        $io = new SymfonyStyle($input, $output);
+        $extensionKey = $input->getArgument('extensionkey');
+
+        $objectManager = GeneralUtility::makeInstance(ObjectManager::class);
+        // Emits packages may have changed signal
+        $signalSlotDispatcher = $objectManager->get(Dispatcher::class);
+        $signalSlotDispatcher->dispatch('PackageManagement', 'packagesMayHaveChanged');
+
+        // Do the installation process
+        $objectManager->get(InstallUtility::class)->install($extensionKey);
+
+        $io->success('Activated extension ' . $extensionKey . ' successfully.');
+    }
+}
diff --git a/typo3/sysext/extensionmanager/Classes/Command/DeactivateExtensionCommand.php b/typo3/sysext/extensionmanager/Classes/Command/DeactivateExtensionCommand.php
new file mode 100644 (file)
index 0000000..692fbbc
--- /dev/null
@@ -0,0 +1,62 @@
+<?php
+declare(strict_types = 1);
+namespace TYPO3\CMS\Extensionmanager\Command;
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Style\SymfonyStyle;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Extbase\Object\ObjectManager;
+use TYPO3\CMS\Extensionmanager\Utility\InstallUtility;
+
+/**
+ * Command for deactivating an extension via CLI.
+ */
+class DeactivateExtensionCommand extends Command
+{
+    /**
+     * Defines the allowed options for this command
+     */
+    protected function configure()
+    {
+        $this
+            ->setDescription('Deactivates an extension by extension key')
+            ->setAliases(['extensionmanager:extension:uninstall', 'extension:uninstall'])
+            ->addArgument(
+                'extensionkey',
+                InputArgument::REQUIRED,
+                'The extension key of a currently activated extension.'
+            );
+    }
+
+    /**
+     * Installs an extension
+     *
+     * @inheritdoc
+     */
+    protected function execute(InputInterface $input, OutputInterface $output)
+    {
+        $io = new SymfonyStyle($input, $output);
+        $extensionKey = $input->getArgument('extensionkey');
+
+        $objectManager = GeneralUtility::makeInstance(ObjectManager::class);
+        $objectManager->get(InstallUtility::class)->uninstall($extensionKey);
+
+        $io->success('Deactivated extension "' . $extensionKey . '" successfully.');
+    }
+}
index b972138..b701c96 100644 (file)
@@ -20,6 +20,8 @@ use TYPO3\CMS\Extbase\Mvc\Controller\CommandController;
 
 /**
  * CommandController for working with extension management through CLI/scheduler
+ *
+ * @deprecated since TYPO3 v9, will be removed in TYPO3 v10. Use Symfony Command alternatives instead.
  */
 class ExtensionCommandController extends CommandController
 {
@@ -49,9 +51,11 @@ class ExtensionCommandController extends CommandController
      *
      * @param string $extensionKey
      * @cli
+     * @deprecated since TYPO3 v9, will be removed in TYPO3 v10. Use the equivalent Symfony Command instead.
      */
     public function installCommand($extensionKey)
     {
+        trigger_error('Calling ExtensionCommandController->installCommand() is deprecated and will be removed in TYPO3 v10. Use the Symfony command "extension:activate" instead, to be called via the "typo3" CLI entrypoint.', E_USER_DEPRECATED);
         $this->emitPackagesMayHaveChangedSignal();
 
         /** @var $service \TYPO3\CMS\Extensionmanager\Utility\InstallUtility */
@@ -67,9 +71,11 @@ class ExtensionCommandController extends CommandController
      *
      * @param string $extensionKey
      * @cli
+     * @deprecated since TYPO3 v9, will be removed in TYPO3 v10. Use the equivalent Symfony Command instead.
      */
     public function uninstallCommand($extensionKey)
     {
+        trigger_error('Calling ExtensionCommandController->uninstallCommand() is deprecated and will be removed in TYPO3 v10. Use the Symfony command "extension:deactivate" instead, to be called via the "typo3" CLI entrypoint.', E_USER_DEPRECATED);
         /** @var $service \TYPO3\CMS\Extensionmanager\Utility\InstallUtility */
         $service = $this->objectManager->get(\TYPO3\CMS\Extensionmanager\Utility\InstallUtility::class);
         $service->uninstall($extensionKey);
@@ -82,9 +88,11 @@ class ExtensionCommandController extends CommandController
      * creating or updating this info properly during extension (de-)activation.
      *
      * @cli
+     * @deprecated since TYPO3 v9, will be removed in TYPO3 v10. Use the equivalent Symfony Command instead.
      */
     public function dumpClassLoadingInformationCommand()
     {
+        trigger_error('Calling ExtensionCommandController->dumpClassLoadingInformationCommand() is deprecated and will be removed in TYPO3 v10. Use the Symfony command "dumpautoload" instead, to be called via the "typo3" CLI entrypoint.', E_USER_DEPRECATED);
         if (Environment::isComposerMode()) {
             $this->output->outputLine('<error>Class loading information is managed by composer. Use "composer dump-autoload" command to update the information.</error>');
             $this->quit(1);
diff --git a/typo3/sysext/extensionmanager/Configuration/Commands.php b/typo3/sysext/extensionmanager/Configuration/Commands.php
new file mode 100644 (file)
index 0000000..22dd86b
--- /dev/null
@@ -0,0 +1,17 @@
+<?php
+/**
+ * Commands to be executed by typo3, where the key of the array
+ * is the name of the command (to be called as the first argument after typo3).
+ * Required parameter is the "class" of the command which needs to be a subclass
+ * of Symfony/Console/Command.
+ */
+return [
+    'extension:activate' => [
+        'class' => \TYPO3\CMS\Extensionmanager\Command\ActivateExtensionCommand::class,
+        'schedulable' => false,
+    ],
+    'extension:deactivate' => [
+        'class' => \TYPO3\CMS\Extensionmanager\Command\DeactivateExtensionCommand::class,
+        'schedulable' => false,
+    ],
+];
index b8f0899..a3a7d51 100644 (file)
@@ -15,8 +15,6 @@ if (!$offlineMode) {
 }
 unset($offlineMode);
 
-$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['extbase']['commandControllers'][] = \TYPO3\CMS\Extensionmanager\Command\ExtensionCommandController::class;
-
 if (TYPO3_REQUESTTYPE & TYPO3_REQUESTTYPE_BE) {
     $signalSlotDispatcher = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Extbase\SignalSlot\Dispatcher::class);
     $signalSlotDispatcher->connect(
index c2835eb..2239150 100644 (file)
@@ -824,4 +824,9 @@ return [
             'Deprecation-86001-WorkspacesTasksMigratedToSymfonyCommands.rst',
         ],
     ],
+    'TYPO3\CMS\Extensionmanager\Command\ExtensionCommandController' => [
+        'restFiles' => [
+            'Deprecation-85996-ExtensionManagerCommandController.rst'
+        ],
+    ],
 ];
index 7eeea6b..9ce7f2b 100644 (file)
@@ -3026,4 +3026,25 @@ return [
             'Deprecation-85971-DeprecatePageRepository-getFirstWebPage.rst'
         ],
     ],
+    'TYPO3\CMS\Extensionmanager\Command\ExtensionCommandController->installCommand' => [
+        'numberOfMandatoryArguments' => 1,
+        'maximumNumberOfArguments' => 1,
+        'restFiles' => [
+            'Deprecation-85996-ExtensionManagerCommandController.rst'
+        ],
+    ],
+    'TYPO3\CMS\Extensionmanager\Command\ExtensionCommandController->uninstallCommand' => [
+        'numberOfMandatoryArguments' => 1,
+        'maximumNumberOfArguments' => 1,
+        'restFiles' => [
+            'Deprecation-85996-ExtensionManagerCommandController.rst'
+        ],
+    ],
+    'TYPO3\CMS\Extensionmanager\Command\ExtensionCommandController->dumpClassLoadingInformationCommand' => [
+        'numberOfMandatoryArguments' => 0,
+        'maximumNumberOfArguments' => 0,
+        'restFiles' => [
+            'Deprecation-85996-ExtensionManagerCommandController.rst'
+        ],
+    ],
 ];