Commit a537a309 authored by effulgentsia's avatar effulgentsia

Issue #2571375 by alexpott, webflo, stefan.r, Xano, mr.baileys: Remove...

Issue #2571375 by alexpott, webflo, stefan.r, Xano, mr.baileys: Remove TranslationManager dependency from LanguageManager
parent 84a99b30
......@@ -671,9 +671,7 @@ services:
- { name: string_translator, priority: 30 }
string_translation:
class: Drupal\Core\StringTranslation\TranslationManager
arguments: ['@language_manager', '@state']
calls:
- [initLanguageManager]
arguments: ['@language.default']
tags:
- { name: service_collector, tag: string_translator, call: addTranslator }
database.replica:
......
......@@ -345,12 +345,9 @@ function install_begin_request($class_loader, &$install_state) {
$container
->register('language.default', 'Drupal\Core\Language\LanguageDefault')
->addArgument('%language.default_values%');
$container
->register('language_manager', 'Drupal\Core\Language\LanguageManager')
->addArgument(new Reference('language.default'));
$container
->register('string_translation', 'Drupal\Core\StringTranslation\TranslationManager')
->addArgument(new Reference('language_manager'));
->addArgument(new Reference('language.default'));
// Register the stream wrapper manager.
$container
......
......@@ -7,9 +7,7 @@
namespace Drupal\Core\Language;
use Drupal\Component\Utility\SafeMarkup;
use Drupal\Core\DependencyInjection\DependencySerializationTrait;
use Drupal\Core\StringTranslation\TranslationInterface;
use Drupal\Core\StringTranslation\TranslatableString;
use Drupal\Core\Url;
......@@ -19,13 +17,6 @@
class LanguageManager implements LanguageManagerInterface {
use DependencySerializationTrait;
/**
* The string translation service.
*
* @var \Drupal\Core\StringTranslation\TranslationInterface
*/
protected $translation;
/**
* A static cache of translated language lists.
*
......@@ -56,22 +47,6 @@ public function __construct(LanguageDefault $default_language) {
$this->defaultLanguage = $default_language;
}
/**
* {@inheritdoc}
*/
public function setTranslation(TranslationInterface $translation) {
$this->translation = $translation;
}
/**
* Translates a string to the current language or to a given language.
*
* @see \Drupal\Core\StringTranslation\TranslationInterface()
*/
protected function t($string, array $args = array(), array $options = array()) {
return $this->translation ? $this->translation->translate($string, $args, $options) : SafeMarkup::format($string, $args);
}
/**
* {@inheritdoc}
*/
......@@ -187,15 +162,15 @@ public function getLanguage($langcode) {
*/
public function getLanguageName($langcode) {
if ($langcode == LanguageInterface::LANGCODE_NOT_SPECIFIED) {
return $this->t('None');
return new TranslatableString('None');
}
if ($language = $this->getLanguage($langcode)) {
return $language->getName();
}
if (empty($langcode)) {
return $this->t('Unknown');
return new TranslatableString('Unknown');
}
return $this->t('Unknown (@langcode)', array('@langcode' => $langcode));
return new TranslatableString('Unknown (@langcode)', array('@langcode' => $langcode));
}
/**
......@@ -377,7 +352,6 @@ public function getConfigOverrideLanguage() {
return $this->getCurrentLanguage();
}
/**
* Filters the full list of languages based on the value of the flag.
*
......@@ -409,7 +383,7 @@ protected function filterLanguages(array $languages, $flags = LanguageInterface:
$default = new Language(
array(
'id' => $defaultLanguage->getId(),
'name' => $this->t("Site's default language (@lang_name)",
'name' => new TranslatableString("Site's default language (@lang_name)",
array('@lang_name' => $defaultLanguage->getName())),
'direction' => $defaultLanguage->getDirection(),
'weight' => $defaultLanguage->getWeight(),
......
......@@ -15,14 +15,6 @@
*/
interface LanguageManagerInterface {
/**
* Injects the string translation service.
*
* @param \Drupal\Core\StringTranslation\TranslationInterface $translation
* The string translation service.
*/
public function setTranslation(TranslationInterface $translation);
/**
* Returns whether or not the site has more than one language added.
*
......
......@@ -70,12 +70,17 @@ protected function formatPluralTranslated($count, $translated, array $args = arr
/**
* Returns the number of plurals supported by a given language.
*
* See the
* \Drupal\Core\StringTranslation\TranslationInterface::getNumberOfPlurals()
* See the \Drupal\locale\PluralFormulaInterface::getNumberOfPlurals()
* documentation for details.
*
* @see \Drupal\locale\PluralFormulaInterface::getNumberOfPlurals()
*/
protected function getNumberOfPlurals($langcode = NULL) {
return $this->getStringTranslation()->getNumberOfPlurals($langcode);
if (\Drupal::hasService('locale.plural.formula')) {
return \Drupal::service('locale.plural.formula')->getNumberOfPlurals($langcode);
}
// We assume 2 plurals if Locale's services are not available.
return 2;
}
/**
......
......@@ -102,16 +102,4 @@ public function translateString(TranslatableString $translated_string);
*/
public function formatPlural($count, $singular, $plural, array $args = array(), array $options = array());
/**
* Returns the number of plurals supported by a given language.
*
* @param null|string $langcode
* (optional) The language code. If not provided, the current language
* will be used.
*
* @return int
* Number of plural variants supported by the given language.
*/
public function getNumberOfPlurals($langcode = NULL);
}
......@@ -8,8 +8,7 @@
namespace Drupal\Core\StringTranslation;
use Drupal\Component\Utility\SafeMarkup;
use Drupal\Core\Language\LanguageManagerInterface;
use Drupal\Core\State\StateInterface;
use Drupal\Core\Language\LanguageDefault;
use Drupal\Core\StringTranslation\Translator\TranslatorInterface;
/**
......@@ -17,13 +16,6 @@
*/
class TranslationManager implements TranslationInterface, TranslatorInterface {
/**
* The language manager.
*
* @var \Drupal\Core\Language\LanguageManagerInterface
*/
protected $languageManager;
/**
* An array of active translators keyed by priority.
*
......@@ -53,36 +45,14 @@ class TranslationManager implements TranslationInterface, TranslatorInterface {
*/
protected $defaultLangcode;
/**
* The state service.
*
* @var \Drupal\Core\State\StateInterface
*/
protected $state;
/**
* Constructs a TranslationManager object.
*
* @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
* The language manager.
* @param \Drupal\Core\State\StateInterface $state
* (optional) The state service.
* @param \Drupal\Core\Language\LanguageDefault $default_language
* The default language.
*/
public function __construct(LanguageManagerInterface $language_manager, StateInterface $state = NULL) {
$this->languageManager = $language_manager;
$this->defaultLangcode = $language_manager->getDefaultLanguage()->getId();
$this->state = $state;
}
/**
* Initializes the injected language manager with the translation manager.
*
* This should be called right after instantiating the translation manager to
* make it available to the language manager without introducing a circular
* dependency.
*/
public function initLanguageManager() {
$this->languageManager->setTranslation($this);
public function __construct(LanguageDefault $default_language) {
$this->defaultLangcode = $default_language->get()->getId();
}
/**
......@@ -229,21 +199,4 @@ public function reset() {
}
}
/**
* @inheritdoc.
*/
public function getNumberOfPlurals($langcode = NULL) {
// If the state service is not injected, we assume 2 plural variants are
// allowed. This may happen in the installer for simplicity. We also assume
// 2 plurals if there is no explicit information yet.
if (isset($this->state)) {
$langcode = $langcode ?: $this->languageManager->getCurrentLanguage()->getId();
$plural_formulas = $this->state->get('locale.translation.plurals') ?: array();
if (isset($plural_formulas[$langcode]['plurals'])) {
return $plural_formulas[$langcode]['plurals'];
}
}
return 2;
}
}
......@@ -13,6 +13,7 @@
use Drupal\Core\Language\Language;
use Drupal\Core\Language\LanguageDefault;
use Drupal\Core\Language\LanguageManager;
use Drupal\Core\StringTranslation\TranslatableString;
use Drupal\Core\Url;
use Drupal\language\Config\LanguageConfigFactoryOverrideInterface;
use Drupal\language\Entity\ConfigurableLanguage;
......@@ -469,7 +470,7 @@ public function getStandardLanguageListWithoutConfigured() {
unset($predefined[$key]);
continue;
}
$predefined[$key] = $this->t($value[0]);
$predefined[$key] = new TranslatableString($value[0]);
}
asort($predefined);
return $predefined;
......
......@@ -276,8 +276,6 @@ function locale_translatable_language_list() {
function locale_get_plural($count, $langcode = NULL) {
$language_interface = \Drupal::languageManager()->getCurrentLanguage();
// Used to locally cache the plural formulas for all languages.
$plural_formulas = &drupal_static(__FUNCTION__, array());
// Used to store precomputed plural indexes corresponding to numbers
// individually for each language.
$plural_indexes = &drupal_static(__FUNCTION__ . ':plurals', array());
......@@ -286,18 +284,17 @@ function locale_get_plural($count, $langcode = NULL) {
if (!isset($plural_indexes[$langcode][$count])) {
// Retrieve and statically cache the plural formulas for all languages.
if (empty($plural_formulas)) {
$plural_formulas = \Drupal::state()->get('locale.translation.plurals') ?: array();
}
$plural_formulas = \Drupal::service('locale.plural.formula')->getFormula($langcode);
// If there is a plural formula for the language, evaluate it for the given
// $count and statically cache the result for the combination of language
// and count, since the result will always be identical.
if (!empty($plural_formulas[$langcode])) {
if (!empty($plural_formulas)) {
// Plural formulas are stored as an array for 0-199. 100 is the highest
// modulo used but storing 0-99 is not enough because below 100 we often
// find exceptions (1, 2, etc).
$index = $count > 199 ? 100 + ($count % 100) : $count;
$plural_indexes[$langcode][$count] = isset($plural_formulas[$langcode]['formula'][$index]) ? $plural_formulas[$langcode]['formula'][$index] : $plural_formulas[$langcode]['formula']['default'];
$plural_indexes[$langcode][$count] = isset($plural_formulas[$index]) ? $plural_formulas[$index] : $plural_formulas['default'];
}
// In case there is no plural formula for English (no imported translation
// for English), use a default formula.
......@@ -1272,9 +1269,9 @@ function _locale_rebuild_js($langcode = NULL) {
'strings' => $translations,
);
$locale_plurals = \Drupal::state()->get('locale.translation.plurals') ?: array();
if (!empty($locale_plurals[$language->getId()]['formula'])) {
$data['pluralFormula'] = $locale_plurals[$language->getId()]['formula'];
$locale_plurals = \Drupal::service('locale.plural.formula')->getFormula($language->getId());
if ($locale_plurals) {
$data['pluralFormula'] = $locale_plurals;
}
$data = 'window.drupalTranslations = ' . Json::encode($data) . ';';
......
......@@ -14,6 +14,9 @@ services:
locale.project:
class: Drupal\locale\LocaleProjectStorage
arguments: ['@keyvalue']
locale.plural.formula:
class: Drupal\locale\PluralFormula
arguments: ['@language_manager', '@state']
string_translator.locale.lookup:
class: Drupal\locale\LocaleTranslation
arguments: ['@locale.storage', '@cache.default', '@lock', '@config.factory', '@language_manager', '@request_stack']
......
<?php
/**
* @file
* Contains \Drupal\locale\PluralFormula.
*/
namespace Drupal\locale;
use Drupal\Core\Language\LanguageManagerInterface;
use Drupal\Core\State\StateInterface;
/**
* Manages the storage of plural formula per language in state.
*
* @see \Drupal\locale\PoDatabaseWriter::setHeader()
*/
class PluralFormula implements PluralFormulaInterface {
/**
* @var \Drupal\Core\Language\LanguageManagerInterface
*/
protected $languageManager;
/**
* @var \Drupal\Core\State\StateInterface
*/
protected $state;
/**
* The plural formula and count keyed by langcode.
*
* For example the structure looks like this:
* @code
* [
* 'de' => [
* 'plurals' => 2,
* 'formula' => [
* // @todo
* ]
* ],
* ]
* @endcode
* @var []
*/
protected $formulae;
/**
* @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
* @param \Drupal\Core\State\StateInterface $state
*/
public function __construct(LanguageManagerInterface $language_manager, StateInterface $state) {
$this->languageManager = $language_manager;
$this->state = $state;
}
/**
* {@inheritdoc}
*/
public function setPluralFormula($langcode, $plural_count, array $formula) {
// Ensure that the formulae are loaded.
$this->loadFormulae();
$this->formulae[$langcode] = [
'plurals' => $plural_count,
'formula' => $formula,
];
$this->state->set('locale.translation.formulae', $this->formulae);
return $this;
}
/**
* {@inheritdoc}
*/
public function getNumberOfPlurals($langcode = NULL) {
// Ensure that the formulae are loaded.
$this->loadFormulae();
// Set the langcode to use.
$langcode = $langcode ?: $this->languageManager->getCurrentLanguage()->getId();
// We assume 2 plurals if there is no explicit information yet.
if (!isset($this->formulae[$langcode]['plurals'])) {
return 2;
}
return $this->formulae[$langcode]['plurals'];
}
/**
* {@inheritdoc}
*/
public function getFormula($langcode) {
$this->loadFormulae();
return isset($this->formulae[$langcode]['formula']) ? $this->formulae[$langcode]['formula'] : FALSE;
}
/**
* Loads the formulae and stores them on the PluralFormula object if not set.
*
* @return []
*/
protected function loadFormulae() {
if (!isset($this->formulae)) {
$this->formulae = $this->state->get('locale.translation.formulae', []);
}
}
/**
* {@inheritdoc}
*/
public function reset() {
$this->formulae = NULL;
return $this;
}
}
<?php
/**
* @file
* Contains \Drupal\locale\PluralFormulaInterface.
*/
namespace Drupal\locale;
/**
* An interface for a service providing plural formulae.
*/
interface PluralFormulaInterface {
/**
* @param string $langcode
* The language code to get the formula for.
* @param int $plural_count
* The number of plural forms.
* @param array $formula
* An array of formulae.
*
* @return self
* The PluralFormula object.
*/
public function setPluralFormula($langcode, $plural_count, array $formula);
/**
* Returns the number of plurals supported by a given language.
*
* @param null|string $langcode
* (optional) The language code. If not provided, the current language
* will be used.
*
* @return int
* Number of plural variants supported by the given language.
*/
public function getNumberOfPlurals($langcode = NULL);
/**
* Gets the plural formula for a langcode.
*
* @param string $langcode
* The language code to get the formula for.
*
* @return array
* An array of formulae.
*/
public function getFormula($langcode);
/**
* Resets the static formulae cache.
*
* @return self
* The PluralFormula object.
*/
public function reset();
}
......@@ -175,11 +175,7 @@ public function setHeader(PoHeader $header) {
$plural = $header->getPluralForms();
if (isset($plural) && $p = $header->parsePluralForms($plural)) {
list($nplurals, $formula) = $p;
$locale_plurals[$langcode] = array(
'plurals' => $nplurals,
'formula' => $formula,
);
\Drupal::state()->set('locale.translation.plurals', $locale_plurals);
\Drupal::service('locale.plural.formula')->setPluralFormula($langcode, $nplurals, $formula);
}
}
}
......
......@@ -76,8 +76,8 @@ public function testStandalonePoFile() {
$this->assertRaw(t('One translation file imported. %number translations were added, %update translations were updated and %delete translations were removed.', array('%number' => 8, '%update' => 0, '%delete' => 0)), 'The translation file was successfully imported.');
// This import should have saved plural forms to have 2 variants.
$locale_plurals = \Drupal::state()->get('locale.translation.plurals') ?: array();
$this->assert($locale_plurals['fr']['plurals'] == 2, 'Plural number initialized.');
$locale_plurals = \Drupal::service('locale.plural.formula')->getNumberOfPlurals('fr');
$this->assertEqual(2, $locale_plurals, 'Plural number initialized.');
// Ensure we were redirected correctly.
$this->assertUrl(\Drupal::url('locale.translate_page', [], ['absolute' => TRUE]), [], 'Correct page redirection.');
......@@ -151,8 +151,8 @@ public function testStandalonePoFile() {
$this->assertText(t('No strings available.'), 'String not overwritten by imported string.');
// This import should not have changed number of plural forms.
$locale_plurals = \Drupal::state()->get('locale.translation.plurals') ?: array();
$this->assert($locale_plurals['fr']['plurals'] == 2, 'Plural numbers untouched.');
$locale_plurals = \Drupal::service('locale.plural.formula')->getNumberOfPlurals('fr');
$this->assertEqual(2, $locale_plurals, 'Plural numbers untouched.');
// Try importing a .po file with overriding strings, and ensure existing
// strings are overwritten.
......@@ -172,8 +172,8 @@ public function testStandalonePoFile() {
$this->drupalPostForm('admin/config/regional/translate', $search, t('Filter'));
$this->assertNoText(t('No strings available.'), 'String overwritten by imported string.');
// This import should have changed number of plural forms.
$locale_plurals = \Drupal::state()->get('locale.translation.plurals') ?: array();
$this->assert($locale_plurals['fr']['plurals'] == 3, 'Plural numbers changed.');
$locale_plurals = \Drupal::service('locale.plural.formula')->reset()->getNumberOfPlurals('fr');
$this->assertEqual(3, $locale_plurals, 'Plural numbers changed.');
// Importing a .po file and mark its strings as customized strings.
$this->importPoFile($this->getCustomPoFile(), array(
......
......@@ -111,12 +111,9 @@ protected function setUp() {
$this->container
->register('language.default', 'Drupal\Core\Language\LanguageDefault')
->addArgument('%language.default_values%');
$this->container
->register('language_manager', 'Drupal\Core\Language\LanguageManager')
->addArgument(new Reference('language.default'));
$this->container
->register('string_translation', 'Drupal\Core\StringTranslation\TranslationManager')
->addArgument(new Reference('language_manager'));
->addArgument(new Reference('language.default'));
$this->container
->set('app.root', DRUPAL_ROOT);
\Drupal::setContainer($this->container);
......
......@@ -7,6 +7,7 @@
namespace Drupal\system\Tests\Installer;
use Drupal\Core\Language\LanguageManager;
use Drupal\simpletest\InstallerTestBase;
/**
......@@ -26,7 +27,7 @@ protected function setUpLanguage() {
// Check that all predefined languages show up with their native names.
$this->drupalGet($GLOBALS['base_url'] . '/core/install.php');
foreach (\Drupal::languageManager()->getStandardLanguageList() as $langcode => $names) {
foreach (LanguageManager::getStandardLanguageList() as $langcode => $names) {
$this->assertOption('edit-langcode', $langcode);
$this->assertRaw('>' . $names[1] . '<');
}
......
......@@ -283,12 +283,9 @@ protected function runDbTasks() {
$container
->register('language.default', 'Drupal\Core\Language\LanguageDefault')
->addArgument('%language.default_values%');
$container
->register('language_manager', 'Drupal\Core\Language\LanguageManager')
->addArgument(new Reference('language.default'));
$container
->register('string_translation', 'Drupal\Core\StringTranslation\TranslationManager')
->addArgument(new Reference('language_manager'));
->addArgument(new Reference('language.default'));
\Drupal::setContainer($container);
require_once __DIR__ . '/../../../../../includes/install.inc';
......
......@@ -86,7 +86,7 @@ function testNumericFormatPlural() {
$formula = 'nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);';
$header = new PoHeader();
list($nplurals, $formula) = $header->parsePluralForms($formula);
\Drupal::state()->set('locale.translation.plurals', ['sl' => ['plurals' => $nplurals, 'formula' => $formula]]);
\Drupal::service('locale.plural.formula')->setPluralFormula('sl', $nplurals, $formula);
// Change the view to Slovenian.
$config = $this->config('views.view.numeric_test');
......
<?php
/**
* @file
* Contains \Drupal\KernelTests\Core\StringTranslation\TranslationStringTest.
*/
namespace Drupal\KernelTests\Core\StringTranslation;
use Drupal\Core\Site\Settings;
use Drupal\KernelTests\KernelTestBase;
use Drupal\language\Entity\ConfigurableLanguage;
/**
* Tests the TranslatableString class.
*
* @group StringTranslation
*/
class TranslationStringTest extends KernelTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = [
'language'
];
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
ConfigurableLanguage::createFromLangcode('de')->save();
}
/**
* Tests that TranslatableString objects can be compared.
*/
public function testComparison() {
$this->rebootAndPrepareSettings();
$a = \Drupal::service('string_translation')->translate('Example @number', ['@number' => 42], ['langcode' => 'de']);
$this->rebootAndPrepareSettings();
$b = \Drupal::service('string_translation')->translate('Example @number', ['@number' => 42], ['langcode' => 'de']);
$c = \Drupal::service('string_translation')->translate('Example @number', ['@number' => 43], ['langcode' => 'de']);
$d = \Drupal::service('string_translation')->translate('Example @number', ['@number' => 42], ['langcode' => 'en']);
// The two objects have the same settings so == comparison will work.
$this->assertEquals($a, $b);
// The two objects are not the same object.
$this->assertNotSame($a, $b);
// TranslationWrappers which have different settings are not equal.
$this->assertNotEquals($a, $c);
$this->assertNotEquals($a, $d);
}
/**
* Reboots the kernel to set custom translations in Settings.
*/
protected function rebootAndPrepareSettings() {
// Reboot the container so that different services are injected and the new
// settings are picked.
$kernel = $this->container->get('kernel');
$kernel->shutdown();
$kernel->boot();
$settings = Settings::getAll();
$settings['locale_custom_strings_de'] = ['' => ['Example @number' => 'Example @number translated']];
// Recreate the settings static.
new Settings($settings);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment