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