From 0d69c2d9e7b89ea63522d0b5e54aadf20ec1245d Mon Sep 17 00:00:00 2001 From: Wouter Wolters <typo3@wouterwolters.nl> Date: Sun, 28 Apr 2013 22:28:23 +0200 Subject: [PATCH] [FEATURE] Add task to auto update languages Add a command controller to update the translation of extensions for selected languages. It is possible to override the selected languages to have the full control over the languages and how many there will be updated. This setting allow to set a comma separated list of locales. Change-Id: I9b0b5e1ab1aeffce30db45bb68fdd1421cf68bd2 Resolves: #43703 Releases: 6.2 Reviewed-on: https://review.typo3.org/20277 Reviewed-by: Philipp Gampe Tested-by: Philipp Gampe Reviewed-by: Eric Chavaillaz Tested-by: Eric Chavaillaz Reviewed-by: Xavier Perseguers Tested-by: Xavier Perseguers Reviewed-by: Stefan Neufeind Reviewed-by: Anja Leichsenring Tested-by: Anja Leichsenring --- .../Command/UpdateCommandController.php | 65 +++++++ .../Classes/Controller/LanguageController.php | 134 +------------ .../Service/UpdateTranslationService.php | 184 ++++++++++++++++++ .../Resources/Private/Language/locallang.xlf | 1 - typo3/sysext/lang/ext_localconf.php | 3 + 5 files changed, 255 insertions(+), 132 deletions(-) create mode 100644 typo3/sysext/lang/Classes/Command/UpdateCommandController.php create mode 100644 typo3/sysext/lang/Classes/Service/UpdateTranslationService.php diff --git a/typo3/sysext/lang/Classes/Command/UpdateCommandController.php b/typo3/sysext/lang/Classes/Command/UpdateCommandController.php new file mode 100644 index 000000000000..f89c5c16125f --- /dev/null +++ b/typo3/sysext/lang/Classes/Command/UpdateCommandController.php @@ -0,0 +1,65 @@ +<?php +namespace TYPO3\CMS\Lang\Command; + +/*************************************************************** + * Copyright notice + * + * (c) 2013 Wouter Wolters <typo3@wouterwolters.nl> + * All rights reserved + * + * This script is part of the TYPO3 project. The TYPO3 project is + * free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * The GNU General Public License can be found at + * http://www.gnu.org/copyleft/gpl.html. + * + * This script is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * This copyright notice MUST APPEAR in all copies of the script! + ***************************************************************/ + +/** + * Update languages translation command + */ +class UpdateCommandController extends \TYPO3\CMS\Extbase\Mvc\Controller\CommandController { + + /** + * Update language file for each extension + * + * @param string $localesToUpdate Comma separated list of locales that needs to be updated + * @return void + */ + public function updateCommand($localesToUpdate = '') { + /** @var $listUtility \TYPO3\CMS\Extensionmanager\Utility\ListUtility */ + $listUtility = $this->objectManager->get('TYPO3\\CMS\\Extensionmanager\\Utility\\ListUtility'); + $availableExtensions = $listUtility->getAvailableExtensions(); + $extensions = $listUtility->getAvailableAndInstalledExtensions($availableExtensions); + + /** @var $updateTranslationService \TYPO3\CMS\Lang\Service\UpdateTranslationService */ + $updateTranslationService = $this->objectManager->get('TYPO3\\CMS\\Lang\Service\\UpdateTranslationService'); + /** @var $languageRepository \TYPO3\CMS\Lang\Domain\Repository\LanguageRepository */ + $languageRepository = $this->objectManager->get('TYPO3\\CMS\\Lang\\Domain\\Repository\\LanguageRepository'); + + $locales = array(); + if (!empty($localesToUpdate)) { + $locales = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $localesToUpdate, TRUE); + } else { + $languages = $languageRepository->findSelected(); + foreach ($languages as $language) { + $locales[] = $language->getLocale(); + } + } + + foreach ($extensions as $extension) { + $updateTranslationService->updateTranslation($extension['key'], $locales); + } + } + +} +?> \ No newline at end of file diff --git a/typo3/sysext/lang/Classes/Controller/LanguageController.php b/typo3/sysext/lang/Classes/Controller/LanguageController.php index dcbd144af8a5..6228ac886a3a 100644 --- a/typo3/sysext/lang/Classes/Controller/LanguageController.php +++ b/typo3/sysext/lang/Classes/Controller/LanguageController.php @@ -33,16 +33,6 @@ namespace TYPO3\CMS\Lang\Controller; */ class LanguageController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionController { - /** - * Status codes for AJAX response - */ - const TRANSLATION_NOT_AVAILABLE = 0; - const TRANSLATION_AVAILABLE = 1; - const TRANSLATION_FAILED = 2; - const TRANSLATION_OK = 3; - const TRANSLATION_INVALID = 4; - const TRANSLATION_UPDATED = 5; - /** * @var \TYPO3\CMS\Lang\Domain\Repository\LanguageRepository * @inject @@ -56,21 +46,10 @@ class LanguageController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionControl protected $extensionRepository; /** - * @var \TYPO3\CMS\Extensionmanager\Utility\Repository\Helper - * @inject - */ - protected $repositoryHelper; - - /** - * @var \TYPO3\CMS\Lang\Utility\Connection\Ter + * @var \TYPO3\CMS\Lang\Service\UpdateTranslationService * @inject */ - protected $terConnection; - - /** - * @var array - */ - protected $translationStates = array(); + protected $updateTranslationService; /** * JSON actions @@ -141,117 +120,10 @@ class LanguageController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionControl * @return void */ public function updateTranslationAction($extension, $locales) { - if (is_string($locales)) { - $locales = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $locales); - } - $locales = array_flip((array) $locales); - - foreach ($locales as $locale => $key) { - $state = static::TRANSLATION_INVALID; - try { - $state = $this->getTranslationStateForExtension($extension, $locale); - if ($state === static::TRANSLATION_AVAILABLE) { - $state = $this->updateTranslationForExtension($extension, $locale); - } - } catch (\Exception $exception) { - $error = $exception->getMessage(); - } - $locales[$locale] = array( - 'state' => $state, - 'error' => $error, - ); - } - + $locales = $this->updateTranslationService->updateTranslation($extension, $locales); $this->view->assign('extension', $extension); $this->view->assign('locales', $locales); } - /** - * Returns the translation state for an extension - * - * @param string $extensionKey The extension key - * @param string $locale Locale to return - * @return integer Translation state - */ - protected function getTranslationStateForExtension($extensionKey, $locale) { - if (empty($extensionKey) || empty($locale)) { - return static::TRANSLATION_INVALID; - } - - $identifier = $extensionKey . '-' . $locale; - if (isset($this->translationStates[$identifier])) { - return $this->translationStates[$identifier]; - } - - $selectedLanguages = $this->languageRepository->findSelected(); - if (empty($selectedLanguages) || !is_array($selectedLanguages)) { - return static::TRANSLATION_INVALID; - } - - $mirrorUrl = $this->repositoryHelper->getMirrors()->getMirrorUrl(); - $status = $this->terConnection->fetchTranslationStatus($extensionKey, $mirrorUrl); - - foreach ($selectedLanguages as $language) { - $stateLocale = $language->getLocale(); - $stateIdentifier = $extensionKey . '-' . $stateLocale; - $this->translationStates[$stateIdentifier] = static::TRANSLATION_INVALID; - - if (empty($status[$stateLocale]) || !is_array($status[$stateLocale])) { - $this->translationStates[$stateIdentifier] = static::TRANSLATION_NOT_AVAILABLE; - continue; - } - - $md5 = $this->getTranslationFileMd5($extensionKey, $stateLocale); - if ($md5 !== $status[$stateLocale]['md5']) { - $this->translationStates[$stateIdentifier] = static::TRANSLATION_AVAILABLE; - continue; - } - - $this->translationStates[$stateIdentifier] = static::TRANSLATION_OK; - } - - return $this->translationStates[$identifier]; - } - - /** - * Returns the md5 of a translation file - * - * @param string $extensionKey The extension key - * @param string $locale The locale - * @return string The md5 value - */ - protected function getTranslationFileMd5($extensionKey, $locale) { - if (empty($extensionKey) || empty($locale)) { - return ''; - } - $fileName = PATH_site . 'typo3temp' . DIRECTORY_SEPARATOR . $extensionKey . '-l10n-' . $locale . '.zip'; - if (is_file($fileName)) { - return md5_file($fileName); - } - return ''; - } - - /** - * Update the translation for an extension - * - * @param string $extensionKey The extension key - * @param string $locale Locale to update - * @return integer Translation state - */ - protected function updateTranslationForExtension($extensionKey, $locale) { - if (empty($extensionKey) || empty($locale)) { - return static::TRANSLATION_INVALID; - } - - $state = static::TRANSLATION_FAILED; - $mirrorUrl = $this->repositoryHelper->getMirrors()->getMirrorUrl(); - $updateResult = $this->terConnection->updateTranslation($extensionKey, $locale, $mirrorUrl); - if ($updateResult === TRUE) { - $state = static::TRANSLATION_UPDATED; - } - - return $state; - } - } ?> \ No newline at end of file diff --git a/typo3/sysext/lang/Classes/Service/UpdateTranslationService.php b/typo3/sysext/lang/Classes/Service/UpdateTranslationService.php new file mode 100644 index 000000000000..3d01bc48b89e --- /dev/null +++ b/typo3/sysext/lang/Classes/Service/UpdateTranslationService.php @@ -0,0 +1,184 @@ +<?php +namespace TYPO3\CMS\Lang\Service; + +/*************************************************************** + * Copyright notice + * + * (c) 2013 Wouter Wolters <typo3@wouterwolters.nl> + * All rights reserved + * + * This script is part of the TYPO3 project. The TYPO3 project is + * free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * The GNU General Public License can be found at + * http://www.gnu.org/copyleft/gpl.html. + * + * This script is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * This copyright notice MUST APPEAR in all copies of the script! + ***************************************************************/ + +/** + * Update languages service + */ +class UpdateTranslationService { + + /** + * Status codes for AJAX response + */ + const TRANSLATION_NOT_AVAILABLE = 0; + const TRANSLATION_AVAILABLE = 1; + const TRANSLATION_FAILED = 2; + const TRANSLATION_OK = 3; + const TRANSLATION_INVALID = 4; + const TRANSLATION_UPDATED = 5; + + /** + * @var \TYPO3\CMS\Lang\Domain\Repository\LanguageRepository + * @inject + */ + protected $languageRepository; + + /** + * @var \TYPO3\CMS\Extensionmanager\Utility\Repository\Helper + * @inject + */ + protected $repositoryHelper; + + /** + * @var \TYPO3\CMS\Lang\Utility\Connection\Ter + * @inject + */ + protected $terConnection; + + /** + * @var array + */ + protected $translationStates = array(); + + /** + * Update translation for given extension + * + * @param string $extension The extension key + * @param string $locales Comma separated list of locales to update + * @return array + */ + public function updateTranslation($extension, $locales) { + if (is_string($locales)) { + $locales = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $locales); + } + $locales = array_flip((array) $locales); + + foreach ($locales as $locale => $key) { + $state = static::TRANSLATION_INVALID; + try { + $state = $this->getTranslationStateForExtension($extension, $locale); + if ($state === static::TRANSLATION_AVAILABLE) { + $state = $this->updateTranslationForExtension($extension, $locale); + } + } catch (\Exception $exception) { + $error = $exception->getMessage(); + } + $locales[$locale] = array( + 'state' => $state, + 'error' => $error, + ); + } + return $locales; + } + + /** + * Returns the translation state for an extension + * + * @param string $extensionKey The extension key + * @param string $locale Locale to return + * @return integer Translation state + */ + protected function getTranslationStateForExtension($extensionKey, $locale) { + if (empty($extensionKey) || empty($locale)) { + return static::TRANSLATION_INVALID; + } + + $identifier = $extensionKey . '-' . $locale; + if (isset($this->translationStates[$identifier])) { + return $this->translationStates[$identifier]; + } + + $selectedLanguages = $this->languageRepository->findSelected(); + if (empty($selectedLanguages) || !is_array($selectedLanguages)) { + return static::TRANSLATION_INVALID; + } + + $mirrorUrl = $this->repositoryHelper->getMirrors()->getMirrorUrl(); + $status = $this->terConnection->fetchTranslationStatus($extensionKey, $mirrorUrl); + + foreach ($selectedLanguages as $language) { + $stateLocale = $language->getLocale(); + $stateIdentifier = $extensionKey . '-' . $stateLocale; + $this->translationStates[$stateIdentifier] = static::TRANSLATION_INVALID; + + if (empty($status[$stateLocale]) || !is_array($status[$stateLocale])) { + $this->translationStates[$stateIdentifier] = static::TRANSLATION_NOT_AVAILABLE; + continue; + } + + $md5 = $this->getTranslationFileMd5($extensionKey, $stateLocale); + if ($md5 !== $status[$stateLocale]['md5']) { + $this->translationStates[$stateIdentifier] = static::TRANSLATION_AVAILABLE; + continue; + } + + $this->translationStates[$stateIdentifier] = static::TRANSLATION_OK; + } + + return $this->translationStates[$identifier]; + } + + /** + * Returns the md5 of a translation file + * + * @param string $extensionKey The extension key + * @param string $locale The locale + * @return string The md5 value + */ + protected function getTranslationFileMd5($extensionKey, $locale) { + if (empty($extensionKey) || empty($locale)) { + return ''; + } + $fileName = PATH_site . 'typo3temp' . DIRECTORY_SEPARATOR . $extensionKey . '-l10n-' . $locale . '.zip'; + if (is_file($fileName)) { + return md5_file($fileName); + } + return ''; + } + + /** + * Update the translation for an extension + * + * @param string $extensionKey The extension key + * @param string $locale Locale to update + * @return integer Translation state + */ + protected function updateTranslationForExtension($extensionKey, $locale) { + if (empty($extensionKey) || empty($locale)) { + return static::TRANSLATION_INVALID; + } + + $state = static::TRANSLATION_FAILED; + $mirrorUrl = $this->repositoryHelper->getMirrors()->getMirrorUrl(); + $updateResult = $this->terConnection->updateTranslation($extensionKey, $locale, $mirrorUrl); + if ($updateResult === TRUE) { + $state = static::TRANSLATION_UPDATED; + } + + return $state; + } + +} +?> \ No newline at end of file diff --git a/typo3/sysext/lang/Resources/Private/Language/locallang.xlf b/typo3/sysext/lang/Resources/Private/Language/locallang.xlf index fe0742278441..4781ff76887c 100644 --- a/typo3/sysext/lang/Resources/Private/Language/locallang.xlf +++ b/typo3/sysext/lang/Resources/Private/Language/locallang.xlf @@ -63,7 +63,6 @@ <trans-unit id="flashmessage.canceled" xml:space="preserve"> <source>The process has been canceled.</source> </trans-unit> - </body> </file> </xliff> \ No newline at end of file diff --git a/typo3/sysext/lang/ext_localconf.php b/typo3/sysext/lang/ext_localconf.php index be9ab19dfff3..f8fdec13a42f 100644 --- a/typo3/sysext/lang/ext_localconf.php +++ b/typo3/sysext/lang/ext_localconf.php @@ -18,4 +18,7 @@ if (isset($GLOBALS['TYPO3_CONF_VARS']['SYS']['lang']['cache']['clear_menu']) && } // Register Ajax call $GLOBALS['TYPO3_CONF_VARS']['BE']['AJAX']['lang::clearCache'] = 'TYPO3\CMS\Lang\LanguageCacheClearer->clearCache'; + +// Register language update command controller +$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['extbase']['commandControllers'][] = 'TYPO3\\CMS\\Lang\\Command\\UpdateCommandController'; ?> \ No newline at end of file -- GitLab