From 1873b9ab41ffc347c4d9abbe3902f029d5be9142 Mon Sep 17 00:00:00 2001
From: Alexander Schnitzler <git@alexanderschnitzler.de>
Date: Wed, 6 Sep 2017 13:44:36 +0200
Subject: [PATCH] [TASK] Make "lang:language:update" a symfony console command

This commit migrates the command "lang:language:update" from
an extbase command controller to a symfony console command.

Also, the alias language:update will be flagged deprecated.

Resolves: #82315
Releases: master
Change-Id: If9fd08981ee8286bd8187fe5eaa5b36f625bd576
Reviewed-on: https://review.typo3.org/53928
Reviewed-by: Stefan Neufeind <typo3.neufeind@speedpartner.de>
Tested-by: TYPO3com <no-reply@typo3.com>
Tested-by: Stefan Neufeind <typo3.neufeind@speedpartner.de>
Reviewed-by: Benni Mack <benni@typo3.org>
Tested-by: Benni Mack <benni@typo3.org>
---
 ...-82315-DeprecateBinTypo3LanguageUpdate.rst |  32 ++++
 .../Command/LanguageCommandController.php     | 108 ------------
 .../Classes/Command/LanguageUpdateCommand.php | 159 ++++++++++++++++++
 typo3/sysext/lang/Configuration/Commands.php  |  17 ++
 typo3/sysext/lang/ext_localconf.php           |   5 -
 5 files changed, 208 insertions(+), 113 deletions(-)
 create mode 100644 typo3/sysext/core/Documentation/Changelog/master/Deprecation-82315-DeprecateBinTypo3LanguageUpdate.rst
 delete mode 100644 typo3/sysext/lang/Classes/Command/LanguageCommandController.php
 create mode 100644 typo3/sysext/lang/Classes/Command/LanguageUpdateCommand.php
 create mode 100644 typo3/sysext/lang/Configuration/Commands.php
 delete mode 100644 typo3/sysext/lang/ext_localconf.php

diff --git a/typo3/sysext/core/Documentation/Changelog/master/Deprecation-82315-DeprecateBinTypo3LanguageUpdate.rst b/typo3/sysext/core/Documentation/Changelog/master/Deprecation-82315-DeprecateBinTypo3LanguageUpdate.rst
new file mode 100644
index 000000000000..e881a7fe8c61
--- /dev/null
+++ b/typo3/sysext/core/Documentation/Changelog/master/Deprecation-82315-DeprecateBinTypo3LanguageUpdate.rst
@@ -0,0 +1,32 @@
+.. include:: ../../Includes.txt
+
+=========================================================
+Deprecation: #82315 - Deprecate bin/typo3 language:update
+=========================================================
+
+See :issue:`82315`
+
+Description
+===========
+
+The command language:update is an alias of lang:language:update, therefore it's superfluous and will be removed in the future.
+
+
+Impact
+======
+
+The command language:update will not work any more.
+
+
+Affected Installations
+======================
+
+All installations that make use of the command language:update. Most likely there are cronjobs that need to be adjusted.
+
+
+Migration
+=========
+
+Use bin/typo3 lang:language:update instead.
+
+.. index:: CLI, NotScanned
diff --git a/typo3/sysext/lang/Classes/Command/LanguageCommandController.php b/typo3/sysext/lang/Classes/Command/LanguageCommandController.php
deleted file mode 100644
index bbe979596b9e..000000000000
--- a/typo3/sysext/lang/Classes/Command/LanguageCommandController.php
+++ /dev/null
@@ -1,108 +0,0 @@
-<?php
-namespace TYPO3\CMS\Lang\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 TYPO3\CMS\Core\Cache\CacheManager;
-use TYPO3\CMS\Core\Package\PackageInterface;
-use TYPO3\CMS\Core\Package\PackageManager;
-use TYPO3\CMS\Core\Utility\GeneralUtility;
-use TYPO3\CMS\Extbase\Mvc\Controller\CommandController;
-use TYPO3\CMS\Extbase\SignalSlot\Dispatcher;
-use TYPO3\CMS\Lang\Domain\Repository\LanguageRepository;
-use TYPO3\CMS\Lang\Service\RegistryService;
-use TYPO3\CMS\Lang\Service\TranslationService;
-
-/**
- * Language command controller updates translation packages
- */
-class LanguageCommandController extends CommandController
-{
-    /**
-     * @var \TYPO3\CMS\Extbase\SignalSlot\Dispatcher
-     */
-    protected $signalSlotDispatcher;
-
-    /**
-     * @var \TYPO3\CMS\Lang\Service\RegistryService
-     */
-    protected $registryService;
-
-    /**
-     * @param \TYPO3\CMS\Extbase\SignalSlot\Dispatcher $signalSlotDispatcher
-     */
-    public function injectSignalSlotDispatcher(Dispatcher $signalSlotDispatcher)
-    {
-        $this->signalSlotDispatcher = $signalSlotDispatcher;
-    }
-
-    /**
-     * @param \TYPO3\CMS\Lang\Service\RegistryService $registryService
-     */
-    public function injectRegistryService(RegistryService $registryService)
-    {
-        $this->registryService = $registryService;
-    }
-
-    /**
-     * Update language file for each extension
-     *
-     * @param string $localesToUpdate Comma separated list of locales that needs to be updated
-     */
-    public function updateCommand($localesToUpdate = '')
-    {
-        /** @var $translationService \TYPO3\CMS\Lang\Service\TranslationService */
-        $translationService = $this->objectManager->get(TranslationService::class);
-        /** @var $languageRepository \TYPO3\CMS\Lang\Domain\Repository\LanguageRepository */
-        $languageRepository = $this->objectManager->get(LanguageRepository::class);
-        $locales = [];
-        if (!empty($localesToUpdate)) {
-            $locales = GeneralUtility::trimExplode(',', $localesToUpdate, true);
-        } else {
-            $languages = $languageRepository->findSelected();
-            foreach ($languages as $language) {
-                /** @var $language \TYPO3\CMS\Lang\Domain\Model\Language */
-                $locales[] = $language->getLocale();
-            }
-        }
-        /** @var PackageManager $packageManager */
-        $packageManager = $this->objectManager->get(PackageManager::class);
-        $this->emitPackagesMayHaveChangedSignal();
-        $packages = $packageManager->getAvailablePackages();
-        $this->outputLine((sprintf('Updating language packs of all activated extensions for locales "%s"', implode(', ', $locales))));
-        $this->output->progressStart(count($locales) * count($packages));
-        foreach ($locales as $locale) {
-            /** @var PackageInterface $package */
-            foreach ($packages as $package) {
-                $extensionKey = $package->getPackageKey();
-                $result = $translationService->updateTranslation($extensionKey, $locale);
-                if (empty($result[$extensionKey][$locale]['error'])) {
-                    $this->registryService->set($locale, $GLOBALS['EXEC_TIME']);
-                }
-                $this->output->progressAdvance();
-            }
-        }
-        // Flush language cache
-        GeneralUtility::makeInstance(CacheManager::class)->getCache('l10n')->flush();
-        $this->output->progressFinish();
-    }
-
-    /**
-     * Emits packages may have changed signal
-     */
-    protected function emitPackagesMayHaveChangedSignal()
-    {
-        $this->signalSlotDispatcher->dispatch('PackageManagement', 'packagesMayHaveChanged');
-    }
-}
diff --git a/typo3/sysext/lang/Classes/Command/LanguageUpdateCommand.php b/typo3/sysext/lang/Classes/Command/LanguageUpdateCommand.php
new file mode 100644
index 000000000000..00664ce31e9c
--- /dev/null
+++ b/typo3/sysext/lang/Classes/Command/LanguageUpdateCommand.php
@@ -0,0 +1,159 @@
+<?php
+namespace TYPO3\CMS\Lang\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\Helper\ProgressBar;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use TYPO3\CMS\Core\Cache\CacheManager;
+use TYPO3\CMS\Core\Package\PackageInterface;
+use TYPO3\CMS\Core\Package\PackageManager;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Extbase\Object\ObjectManager;
+use TYPO3\CMS\Extbase\Object\ObjectManagerInterface;
+use TYPO3\CMS\Extbase\SignalSlot\Dispatcher as SignalSlotDispatcher;
+use TYPO3\CMS\Lang\Domain\Repository\LanguageRepository;
+use TYPO3\CMS\Lang\Service\RegistryService;
+use TYPO3\CMS\Lang\Service\TranslationService;
+
+/**
+ * Core function for updating the language files
+ */
+class LanguageUpdateCommand extends Command
+{
+    /**
+     * @var ObjectManagerInterface
+     */
+    protected $objectManager;
+
+    /**
+     * @param string $name
+     * @throws \Symfony\Component\Console\Exception\LogicException
+     * @throws \InvalidArgumentException
+     */
+    public function __construct($name = null)
+    {
+        parent::__construct($name);
+
+        $this->objectManager = GeneralUtility::makeInstance(ObjectManager::class);
+    }
+
+    /**
+     * Configure the command by defining the name, options and arguments
+     */
+    protected function configure()
+    {
+        $description = ($this->getName() === 'language:update')
+            ? '[Deprecated] Use lang:language:update instead'
+            : 'Update the language files of all activated extensions';
+
+        $this
+            ->setDescription($description)
+            ->addArgument(
+                'locales',
+                InputArgument::IS_ARRAY | InputArgument::OPTIONAL
+            );
+    }
+
+    /**
+     * @param InputInterface $input
+     * @param OutputInterface $output
+     *
+     * @throws \InvalidArgumentException
+     * @throws \TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException
+     *
+     * @return int
+     */
+    protected function execute(InputInterface $input, OutputInterface $output)
+    {
+        if ($this->getName() === 'language:update') {
+            $message = 'bin/typo3 language:update is deprecated, use bin/typo3 lang:language:update instead';
+            GeneralUtility::deprecationLog($message);
+            $output->writeln('<error>' . $message . '</error>');
+        }
+
+        try {
+            $localesToUpdate = $input->getArgument('locales');
+        } catch (\Exception $e) {
+            $localesToUpdate = [];
+        }
+
+        /** @var $translationService \TYPO3\CMS\Lang\Service\TranslationService */
+        $translationService = $this->objectManager->get(TranslationService::class);
+        /** @var $languageRepository \TYPO3\CMS\Lang\Domain\Repository\LanguageRepository */
+        $languageRepository = $this->objectManager->get(LanguageRepository::class);
+
+        $allLocales = array_map(function ($language) {
+            /** @var $language \TYPO3\CMS\Lang\Domain\Model\Language */
+            return $language->getLocale();
+        }, $languageRepository->findSelected());
+
+        $nonUpdatableLocales = array_diff($localesToUpdate, $allLocales);
+        $updatableLocales = array_intersect($localesToUpdate, $allLocales);
+
+        $locales = empty($updatableLocales) ? $allLocales : $updatableLocales;
+
+        foreach ($nonUpdatableLocales as $nonUpdatableLocale) {
+            $output->writeln(sprintf(
+                '<error>Skipping locale "%s" as it is not activated in the backend</error>',
+                $nonUpdatableLocale
+            ));
+        }
+
+        $output->writeln(sprintf(
+            '<info>Updating language packs of all activated extensions for locale(s) "%s"</info>',
+            implode('", "', $locales)
+        ));
+
+        /** @var RegistryService $registryService */
+        $registryService = $this->objectManager->get(RegistryService::class);
+
+        /** @var PackageManager $packageManager */
+        $packageManager = $this->objectManager->get(PackageManager::class);
+        $this->emitPackagesMayHaveChangedSignal();
+        $packages = $packageManager->getAvailablePackages();
+
+        $progressBar = new ProgressBar($output, count($locales) * count($packages));
+        foreach ($locales as $locale) {
+            /** @var PackageInterface $package */
+            foreach ($packages as $package) {
+                $extensionKey = $package->getPackageKey();
+                $result = $translationService->updateTranslation($extensionKey, $locale);
+                if (empty($result[$extensionKey][$locale]['error'])) {
+                    $registryService->set($locale, $GLOBALS['EXEC_TIME']);
+                }
+                $progressBar->advance();
+            }
+        }
+        $progressBar->finish();
+
+        // Flush language cache
+        GeneralUtility::makeInstance(CacheManager::class)->getCache('l10n')->flush();
+
+        return 0;
+    }
+
+    /**
+     * Emits packages may have changed signal
+     *
+     * @throws \TYPO3\CMS\Extbase\SignalSlot\Exception\InvalidSlotException
+     * @throws \TYPO3\CMS\Extbase\SignalSlot\Exception\InvalidSlotReturnException
+     */
+    protected function emitPackagesMayHaveChangedSignal()
+    {
+        $this->objectManager->get(SignalSlotDispatcher::class)->dispatch('PackageManagement', 'packagesMayHaveChanged');
+    }
+}
diff --git a/typo3/sysext/lang/Configuration/Commands.php b/typo3/sysext/lang/Configuration/Commands.php
new file mode 100644
index 000000000000..39d8b7a0fc95
--- /dev/null
+++ b/typo3/sysext/lang/Configuration/Commands.php
@@ -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.
+ *
+ * example: bin/typo3 lang:language:update
+ */
+return [
+    'lang:language:update' => [
+        'class' => \TYPO3\CMS\Lang\Command\LanguageUpdateCommand::class
+    ],
+    'language:update' => [
+        'class' => \TYPO3\CMS\Lang\Command\LanguageUpdateCommand::class
+    ]
+];
diff --git a/typo3/sysext/lang/ext_localconf.php b/typo3/sysext/lang/ext_localconf.php
deleted file mode 100644
index 0daf44d876cd..000000000000
--- a/typo3/sysext/lang/ext_localconf.php
+++ /dev/null
@@ -1,5 +0,0 @@
-<?php
-defined('TYPO3_MODE') or die();
-
-// Register language update command controller
-$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['extbase']['commandControllers'][] = \TYPO3\CMS\Lang\Command\LanguageCommandController::class;
-- 
GitLab