Drupal 8.0.0 beta 12. More info: https://www.drupal.org/node/2514176
This commit is contained in:
commit
9921556621
13277 changed files with 1459781 additions and 0 deletions
|
@ -0,0 +1,105 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Core\StringTranslation\StringTranslationTrait.
|
||||
*/
|
||||
|
||||
namespace Drupal\Core\StringTranslation;
|
||||
|
||||
/**
|
||||
* Wrapper methods for \Drupal\Core\StringTranslation\TranslationInterface.
|
||||
*
|
||||
* Using this trait will add t() and formatPlural() methods to the class. These
|
||||
* must be used for every translatable string, similar to how procedural code
|
||||
* must use the global functions t() and \Drupal::translation()->formatPlural().
|
||||
* This allows string extractor tools to find translatable strings.
|
||||
*
|
||||
* If the class is capable of injecting services from the container, it should
|
||||
* inject the 'string_translation' service and assign it to
|
||||
* $this->stringTranslation.
|
||||
*
|
||||
* @see \Drupal\Core\StringTranslation\TranslationInterface
|
||||
* @see container
|
||||
*
|
||||
* @ingroup i18n
|
||||
*/
|
||||
trait StringTranslationTrait {
|
||||
|
||||
/**
|
||||
* The string translation service.
|
||||
*
|
||||
* @var \Drupal\Core\StringTranslation\TranslationInterface
|
||||
*/
|
||||
protected $stringTranslation;
|
||||
|
||||
/**
|
||||
* Translates a string to the current language or to a given language.
|
||||
*
|
||||
* See the t() documentation for details.
|
||||
*/
|
||||
protected function t($string, array $args = array(), array $options = array()) {
|
||||
return $this->getStringTranslation()->translate($string, $args, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a string containing a count of items.
|
||||
*
|
||||
* See the \Drupal\Core\StringTranslation\TranslationInterface::formatPlural()
|
||||
* documentation for details.
|
||||
*/
|
||||
protected function formatPlural($count, $singular, $plural, array $args = array(), array $options = array()) {
|
||||
return $this->getStringTranslation()->formatPlural($count, $singular, $plural, $args, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a translated string containing a count of items.
|
||||
*
|
||||
* See the
|
||||
* \Drupal\Core\StringTranslation\TranslationInterface::formatPluralTranslated()
|
||||
* documentation for details.
|
||||
*/
|
||||
protected function formatPluralTranslated($count, $translated, array $args = array(), array $options = array()) {
|
||||
return $this->getStringTranslation()->formatPluralTranslated($count, $translated, $args, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of plurals supported by a given language.
|
||||
*
|
||||
* See the
|
||||
* \Drupal\Core\StringTranslation\TranslationInterface::getNumberOfPlurals()
|
||||
* documentation for details.
|
||||
*/
|
||||
protected function getNumberOfPlurals($langcode = NULL) {
|
||||
return $this->getStringTranslation()->getNumberOfPlurals($langcode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the string translation service.
|
||||
*
|
||||
* @return \Drupal\Core\StringTranslation\TranslationInterface
|
||||
* The string translation service.
|
||||
*/
|
||||
protected function getStringTranslation() {
|
||||
if (!$this->stringTranslation) {
|
||||
$this->stringTranslation = \Drupal::service('string_translation');
|
||||
}
|
||||
|
||||
return $this->stringTranslation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the string translation service to use.
|
||||
*
|
||||
* @param \Drupal\Core\StringTranslation\TranslationInterface $translation
|
||||
* The string translation service.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setStringTranslation(TranslationInterface $translation) {
|
||||
$this->stringTranslation = $translation;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
}
|
135
core/lib/Drupal/Core/StringTranslation/TranslationInterface.php
Normal file
135
core/lib/Drupal/Core/StringTranslation/TranslationInterface.php
Normal file
|
@ -0,0 +1,135 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Core\StringTranslation\TranslationInterface.
|
||||
*/
|
||||
|
||||
namespace Drupal\Core\StringTranslation;
|
||||
|
||||
/**
|
||||
* Interface for the translation.manager translation service.
|
||||
*
|
||||
* @ingroup i18n
|
||||
*/
|
||||
interface TranslationInterface {
|
||||
|
||||
/**
|
||||
* Translates a string to the current language or to a given language.
|
||||
*
|
||||
* @param string $string
|
||||
* A string containing the English string to translate.
|
||||
* @param array $args
|
||||
* An associative array of replacements to make after translation. Based
|
||||
* on the first character of the key, the value is escaped and/or themed.
|
||||
* See \Drupal\Component\Utility\SafeMarkup::format() for details.
|
||||
* @param array $options
|
||||
* An associative array of additional options, with the following elements:
|
||||
* - 'langcode': The language code to translate to a language other than
|
||||
* what is used to display the page.
|
||||
* - 'context': The context the source string belongs to.
|
||||
*
|
||||
* @return string
|
||||
* The translated string.
|
||||
*
|
||||
* @see \Drupal\Component\Utility\SafeMarkup::format()
|
||||
*/
|
||||
public function translate($string, array $args = array(), array $options = array());
|
||||
|
||||
/**
|
||||
* Formats a string containing a count of items.
|
||||
*
|
||||
* This function ensures that the string is pluralized correctly. Since t() is
|
||||
* called by this function, make sure not to pass already-localized strings to
|
||||
* it. See formatPluralTranslated() for that.
|
||||
*
|
||||
* For example:
|
||||
* @code
|
||||
* $output = $string_translation->formatPlural($node->comment_count, '1 comment', '@count comments');
|
||||
* @endcode
|
||||
*
|
||||
* Example with additional replacements:
|
||||
* @code
|
||||
* $output = $string_translation->formatPlural($update_count,
|
||||
* 'Changed the content type of 1 post from %old-type to %new-type.',
|
||||
* 'Changed the content type of @count posts from %old-type to %new-type.',
|
||||
* array('%old-type' => $info->old_type, '%new-type' => $info->new_type));
|
||||
* @endcode
|
||||
*
|
||||
* @param int $count
|
||||
* The item count to display.
|
||||
* @param string $singular
|
||||
* The string for the singular case. Make sure it is clear this is singular,
|
||||
* to ease translation (e.g. use "1 new comment" instead of "1 new"). Do not
|
||||
* use @count in the singular string.
|
||||
* @param string $plural
|
||||
* The string for the plural case. Make sure it is clear this is plural, to
|
||||
* ease translation. Use @count in place of the item count, as in
|
||||
* "@count new comments".
|
||||
* @param array $args
|
||||
* An associative array of replacements to make after translation. Instances
|
||||
* of any key in this array are replaced with the corresponding value.
|
||||
* Based on the first character of the key, the value is escaped and/or
|
||||
* themed. See \Drupal\Component\Utility\SafeMarkup::format(). Note that you do
|
||||
* not need to include @count in this array; this replacement is done
|
||||
* automatically for the plural cases.
|
||||
* @param array $options
|
||||
* An associative array of additional options. See t() for allowed keys.
|
||||
*
|
||||
* @return string
|
||||
* A translated string.
|
||||
*
|
||||
* @see self::translate()
|
||||
* @see t()
|
||||
* @see \Drupal\Component\Utility\SafeMarkup::format()
|
||||
* @see self::formatPluralTranslated
|
||||
*/
|
||||
public function formatPlural($count, $singular, $plural, array $args = array(), array $options = array());
|
||||
|
||||
/**
|
||||
* Formats an already translated string containing a count of items.
|
||||
*
|
||||
* This function ensures that the string is pluralized correctly. As opposed
|
||||
* to the formatPlural() method, this method is designed to be invoked with
|
||||
* a string already translated (such as with configuration translation).
|
||||
*
|
||||
* @param int $count
|
||||
* The item count to display.
|
||||
* @param string $translation
|
||||
* The string containing the translation of a singular/plural pair. It may
|
||||
* contain any number of possible variants (depending on the language
|
||||
* translated to) separated by the value of the LOCALE_PLURAL_DELIMITER
|
||||
* constant.
|
||||
* @param array $args
|
||||
* Associative array of replacements to make in the translation. Instances
|
||||
* of any key in this array are replaced with the corresponding value.
|
||||
* Based on the first character of the key, the value is escaped and/or
|
||||
* themed. See \Drupal\Component\Utility\SafeMarkup::format(). Note that you do
|
||||
* not need to include @count in this array; this replacement is done
|
||||
* automatically for the plural cases.
|
||||
* @param array $options
|
||||
* An associative array of additional options. The 'context' key is not
|
||||
* supported because the passed string is already translated. Use the
|
||||
* 'langcode' key to ensure the proper plural logic is used.
|
||||
*
|
||||
* @return string
|
||||
* The correct substring for the given $count with $args replaced.
|
||||
*
|
||||
* @see self::formatPlural()
|
||||
* @see \Drupal\Component\Utility\SafeMarkup::format()
|
||||
*/
|
||||
public function formatPluralTranslated($count, $translation, 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);
|
||||
|
||||
}
|
260
core/lib/Drupal/Core/StringTranslation/TranslationManager.php
Normal file
260
core/lib/Drupal/Core/StringTranslation/TranslationManager.php
Normal file
|
@ -0,0 +1,260 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Core\StringTranslation\TranslationManager.
|
||||
*/
|
||||
|
||||
namespace Drupal\Core\StringTranslation;
|
||||
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Core\Language\LanguageManagerInterface;
|
||||
use Drupal\Core\State\StateInterface;
|
||||
use Drupal\Core\StringTranslation\Translator\TranslatorInterface;
|
||||
|
||||
/**
|
||||
* Defines a chained translation implementation combining multiple translators.
|
||||
*/
|
||||
class TranslationManager implements TranslationInterface, TranslatorInterface {
|
||||
|
||||
/**
|
||||
* The language manager.
|
||||
*
|
||||
* @var \Drupal\Core\Language\LanguageManagerInterface
|
||||
*/
|
||||
protected $languageManager;
|
||||
|
||||
/**
|
||||
* An array of active translators keyed by priority.
|
||||
*
|
||||
* @var array
|
||||
* Array of \Drupal\Core\StringTranslation\Translator\TranslatorInterface objects
|
||||
*/
|
||||
protected $translators = array();
|
||||
|
||||
/**
|
||||
* Holds the array of translators sorted by priority.
|
||||
*
|
||||
* If this is NULL a rebuild will be triggered.
|
||||
*
|
||||
* @var array
|
||||
* An array of path processor objects.
|
||||
*
|
||||
* @see \Drupal\Core\StringTranslation\TranslationManager::addTranslator()
|
||||
* @see \Drupal\Core\StringTranslation\TranslationManager::sortTranslators()
|
||||
*/
|
||||
protected $sortedTranslators = NULL;
|
||||
|
||||
/**
|
||||
* The default langcode used in translations.
|
||||
*
|
||||
* @var string
|
||||
* A language code.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a translation system to the translation chain.
|
||||
*
|
||||
* @param \Drupal\Core\StringTranslation\Translator\TranslatorInterface $translator
|
||||
* The translation interface to be appended to the translation chain.
|
||||
* @param int $priority
|
||||
* The priority of the logger being added.
|
||||
*
|
||||
* @return \Drupal\Core\StringTranslation\TranslationManager
|
||||
* The called object.
|
||||
*/
|
||||
public function addTranslator(TranslatorInterface $translator, $priority = 0) {
|
||||
$this->translators[$priority][] = $translator;
|
||||
// Reset sorted translators property to trigger rebuild.
|
||||
$this->sortedTranslators = NULL;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts translators according to priority.
|
||||
*
|
||||
* @return array
|
||||
* A sorted array of translators objects.
|
||||
*/
|
||||
protected function sortTranslators() {
|
||||
$sorted = array();
|
||||
krsort($this->translators);
|
||||
|
||||
foreach ($this->translators as $translators) {
|
||||
$sorted = array_merge($sorted, $translators);
|
||||
}
|
||||
return $sorted;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getStringTranslation($langcode, $string, $context) {
|
||||
if ($this->sortedTranslators === NULL) {
|
||||
$this->sortedTranslators = $this->sortTranslators();
|
||||
}
|
||||
foreach ($this->sortedTranslators as $translator) {
|
||||
$translation = $translator->getStringTranslation($langcode, $string, $context);
|
||||
if ($translation !== FALSE) {
|
||||
return $translation;
|
||||
}
|
||||
}
|
||||
// No translator got a translation.
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function translate($string, array $args = array(), array $options = array()) {
|
||||
$string = $this->doTranslate($string, $options);
|
||||
if (empty($args)) {
|
||||
return SafeMarkup::set($string);
|
||||
}
|
||||
else {
|
||||
return SafeMarkup::format($string, $args);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates a string to the current language or to a given language.
|
||||
*
|
||||
* @param string $string
|
||||
* A string containing the English string to translate.
|
||||
* @param array $options
|
||||
* An associative array of additional options, with the following elements:
|
||||
* - 'langcode': The language code to translate to a language other than
|
||||
* what is used to display the page.
|
||||
* - 'context': The context the source string belongs to.
|
||||
*
|
||||
* @return string
|
||||
* The translated string.
|
||||
*/
|
||||
protected function doTranslate($string, array $options = array()) {
|
||||
// Merge in defaults.
|
||||
if (empty($options['langcode'])) {
|
||||
$options['langcode'] = $this->defaultLangcode;
|
||||
}
|
||||
if (empty($options['context'])) {
|
||||
$options['context'] = '';
|
||||
}
|
||||
$translation = $this->getStringTranslation($options['langcode'], $string, $options['context']);
|
||||
return $translation === FALSE ? $string : $translation;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function formatPlural($count, $singular, $plural, array $args = array(), array $options = array()) {
|
||||
$translatable_string = implode(LOCALE_PLURAL_DELIMITER, array($singular, $plural));
|
||||
$translated_strings = $this->doTranslate($translatable_string, $options);
|
||||
return $this->formatPluralTranslated($count, $translated_strings, $args, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function formatPluralTranslated($count, $translation, array $args = array(), array $options = array()) {
|
||||
$args['@count'] = $count;
|
||||
$translated_array = explode(LOCALE_PLURAL_DELIMITER, $translation);
|
||||
|
||||
if ($count == 1) {
|
||||
return SafeMarkup::format($translated_array[0], $args);
|
||||
}
|
||||
|
||||
// Get the plural index through the gettext formula.
|
||||
// @todo implement static variable to minimize function_exists() usage.
|
||||
$index = (function_exists('locale_get_plural')) ? locale_get_plural($count, isset($options['langcode']) ? $options['langcode'] : NULL) : -1;
|
||||
if ($index == 0) {
|
||||
// Singular form.
|
||||
$return = $translated_array[0];
|
||||
}
|
||||
else {
|
||||
if (isset($translated_array[$index])) {
|
||||
// N-th plural form.
|
||||
$return = $translated_array[$index];
|
||||
}
|
||||
else {
|
||||
// If the index cannot be computed or there's no translation, use
|
||||
// the second plural form as a fallback (which allows for most flexibility
|
||||
// with the replaceable @count value).
|
||||
$return = $translated_array[1];
|
||||
}
|
||||
}
|
||||
|
||||
return SafeMarkup::format($return, $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the default langcode.
|
||||
*
|
||||
* @param string $langcode
|
||||
* A language code.
|
||||
*/
|
||||
public function setDefaultLangcode($langcode) {
|
||||
$this->defaultLangcode = $langcode;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function reset() {
|
||||
if ($this->sortedTranslators === NULL) {
|
||||
$this->sortedTranslators = $this->sortTranslators();
|
||||
}
|
||||
foreach ($this->sortedTranslators as $translator) {
|
||||
$translator->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;
|
||||
}
|
||||
|
||||
}
|
109
core/lib/Drupal/Core/StringTranslation/TranslationWrapper.php
Normal file
109
core/lib/Drupal/Core/StringTranslation/TranslationWrapper.php
Normal file
|
@ -0,0 +1,109 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Core\StringTranslation\TranslationWrapper.
|
||||
*/
|
||||
|
||||
namespace Drupal\Core\StringTranslation;
|
||||
|
||||
/**
|
||||
* Provides a class to wrap a translatable string.
|
||||
*
|
||||
* This class can be used to delay translating strings until the translation
|
||||
* system is ready. This is useful for using translation in very low level
|
||||
* subsystems like entity definition and stream wrappers.
|
||||
*
|
||||
* @see \Drupal\Core\Annotation\Translation
|
||||
*/
|
||||
class TranslationWrapper {
|
||||
use StringTranslationTrait;
|
||||
|
||||
/**
|
||||
* The string to be translated.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $string;
|
||||
|
||||
/**
|
||||
* The translation arguments.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $arguments;
|
||||
|
||||
/**
|
||||
* The translation options.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $options;
|
||||
|
||||
/**
|
||||
* Constructs a new class instance.
|
||||
*
|
||||
* Parses values passed into this class through the t() function in Drupal and
|
||||
* handles an optional context for the string.
|
||||
*
|
||||
* @param string $string
|
||||
* The string that is to be translated.
|
||||
* @param array $arguments
|
||||
* (optional) An array with placeholder replacements, keyed by placeholder.
|
||||
* @param array $options
|
||||
* (optional) An array of additional options.
|
||||
*/
|
||||
public function __construct($string, array $arguments = array(), array $options = array()) {
|
||||
$this->string = $string;
|
||||
$this->arguments = $arguments;
|
||||
$this->options = $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the untranslated string value stored in this translation wrapper.
|
||||
*
|
||||
* @return string
|
||||
* The string stored in this wrapper.
|
||||
*/
|
||||
public function getUntranslatedString() {
|
||||
return $this->string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a specific option from this translation wrapper.
|
||||
*
|
||||
* @param $name
|
||||
* Option name.
|
||||
*
|
||||
* @return mixed
|
||||
* The value of this option or empty string of option is not set.
|
||||
*/
|
||||
public function getOption($name) {
|
||||
return isset($this->options[$name]) ? $this->options[$name] : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements the magic __toString() method.
|
||||
*/
|
||||
public function __toString() {
|
||||
return $this->render();
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the object as a string.
|
||||
*
|
||||
* @return string
|
||||
* The translated string.
|
||||
*/
|
||||
public function render() {
|
||||
return $this->t($this->string, $this->arguments, $this->options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic __sleep() method to avoid serializing the string translator.
|
||||
*/
|
||||
public function __sleep() {
|
||||
return array('string', 'arguments', 'options');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Core\StringTranslation\Translator\CustomStrings.
|
||||
*/
|
||||
|
||||
namespace Drupal\Core\StringTranslation\Translator;
|
||||
|
||||
use Drupal\Core\Site\Settings;
|
||||
|
||||
/**
|
||||
* String translator using overrides from variables.
|
||||
*
|
||||
* This is a high performance way to provide a handful of string replacements.
|
||||
* See settings.php for examples.
|
||||
*/
|
||||
class CustomStrings extends StaticTranslation {
|
||||
|
||||
/**
|
||||
* The settings read only object.
|
||||
*
|
||||
* @var \Drupal\Core\Site\Settings
|
||||
*/
|
||||
protected $settings;
|
||||
|
||||
/**
|
||||
* Constructs a CustomStrings object.
|
||||
*
|
||||
* @param \Drupal\Core\Site\Settings $settings
|
||||
* The settings read only object.
|
||||
*/
|
||||
public function __construct(Settings $settings) {
|
||||
parent::__construct();
|
||||
$this->settings = $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getLanguage($langcode) {
|
||||
return $this->settings->get('locale_custom_strings_' . $langcode, array());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,124 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Core\StringTranslation\Translator\FileTranslation.
|
||||
*/
|
||||
|
||||
namespace Drupal\Core\StringTranslation\Translator;
|
||||
|
||||
use Drupal\Component\Gettext\PoStreamReader;
|
||||
use Drupal\Component\Gettext\PoMemoryWriter;
|
||||
|
||||
/**
|
||||
* File based string translation.
|
||||
*
|
||||
* Translates a string when some systems are not available.
|
||||
*
|
||||
* Used during the install process, when database, theme, and localization
|
||||
* system is possibly not yet available.
|
||||
*/
|
||||
class FileTranslation extends StaticTranslation {
|
||||
|
||||
/**
|
||||
* Directory to find translation files in the file system.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $directory;
|
||||
|
||||
/**
|
||||
* Constructs a StaticTranslation object.
|
||||
*
|
||||
* @param string $directory
|
||||
* The directory to retrieve file translations from.
|
||||
*/
|
||||
public function __construct($directory) {
|
||||
parent::__construct();
|
||||
$this->directory = $directory;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getLanguage($langcode) {
|
||||
// If the given langcode was selected, there should be at least one .po
|
||||
// file with its name in the pattern drupal-$version.$langcode.po.
|
||||
// This might or might not be the entire filename. It is also possible
|
||||
// that multiple files end with the same suffix, even if unlikely.
|
||||
$files = $this->findTranslationFiles($langcode);
|
||||
|
||||
if (!empty($files)) {
|
||||
return $this->filesToArray($langcode, $files);
|
||||
}
|
||||
else {
|
||||
return array();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds installer translations either for a specific or all languages.
|
||||
*
|
||||
* Filenames must match the pattern:
|
||||
* - 'drupal-[version].[langcode].po (if langcode is provided)
|
||||
* - 'drupal-[version].*.po (if no langcode is provided)
|
||||
*
|
||||
* @param string $langcode
|
||||
* (optional) The language code corresponding to the language for which we
|
||||
* want to find translation files. If omitted, information on all available
|
||||
* files will be returned.
|
||||
*
|
||||
* @return array
|
||||
* An associative array of file information objects keyed by file URIs as
|
||||
* returned by file_scan_directory().
|
||||
*
|
||||
* @see file_scan_directory()
|
||||
*/
|
||||
public function findTranslationFiles($langcode = NULL) {
|
||||
$files = file_scan_directory($this->directory, $this->getTranslationFilesPattern($langcode), array('recurse' => FALSE));
|
||||
return $files;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides translation file name pattern.
|
||||
*
|
||||
* @param string $langcode
|
||||
* (optional) The language code corresponding to the language for which we
|
||||
* want to find translation files.
|
||||
*
|
||||
* @return string
|
||||
* String file pattern.
|
||||
*/
|
||||
protected function getTranslationFilesPattern($langcode = NULL) {
|
||||
// The file name matches: drupal-[release version].[language code].po
|
||||
// When provided the $langcode is use as language code. If not provided all
|
||||
// language codes will match.
|
||||
return '!drupal-[0-9a-z\.-]+\.' . (!empty($langcode) ? preg_quote($langcode, '!') : '[^\.]+') . '\.po$!';
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the given Gettext PO files into a data structure.
|
||||
*
|
||||
* @param string $langcode
|
||||
* Language code string.
|
||||
* @param array $files
|
||||
* List of file objects with URI properties pointing to read.
|
||||
*
|
||||
* @return array
|
||||
* Structured array as produced by a PoMemoryWriter.
|
||||
*
|
||||
* @see \Drupal\Component\Gettext\PoMemoryWriter
|
||||
*/
|
||||
public static function filesToArray($langcode, array $files) {
|
||||
$writer = new PoMemoryWriter();
|
||||
$writer->setLangcode($langcode);
|
||||
foreach ($files as $file) {
|
||||
$reader = new PoStreamReader();
|
||||
$reader->setURI($file->uri);
|
||||
$reader->setLangcode($langcode);
|
||||
$reader->open();
|
||||
$writer->writeItems($reader, -1);
|
||||
}
|
||||
return $writer->getData();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Core\StringTranslation\Translator\StaticTranslation.
|
||||
*/
|
||||
|
||||
namespace Drupal\Core\StringTranslation\Translator;
|
||||
|
||||
/**
|
||||
* String translator with a static cache for translations.
|
||||
*
|
||||
* This is a high performance way to provide a handful of string replacements.
|
||||
*/
|
||||
class StaticTranslation implements TranslatorInterface {
|
||||
|
||||
/**
|
||||
* String translations
|
||||
*
|
||||
* @var array
|
||||
* Array of cached translations indexed by language and context.
|
||||
*/
|
||||
protected $translations;
|
||||
|
||||
/**
|
||||
* Constructs a translator from an array of translations.
|
||||
*
|
||||
* @param array $translations
|
||||
* Array of override strings indexed by language and context
|
||||
*/
|
||||
public function __construct($translations = array()) {
|
||||
$this->translations = $translations;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getStringTranslation($langcode, $string, $context) {
|
||||
if (!isset($this->translations[$langcode])) {
|
||||
$this->translations[$langcode] = $this->getLanguage($langcode);
|
||||
}
|
||||
if (isset($this->translations[$langcode][$context][$string])) {
|
||||
return $this->translations[$langcode][$context][$string];
|
||||
}
|
||||
else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function reset() {
|
||||
$this->translations = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add translations for new language.
|
||||
*
|
||||
* @param string $langcode
|
||||
* The langcode of the language.
|
||||
*/
|
||||
protected function getLanguage($langcode) {
|
||||
// This class is usually a base class but we do not declare as abstract
|
||||
// because it can be used on its own, by passing a simple array on the
|
||||
// constructor. This can be useful while testing, but it does not support
|
||||
// loading specific languages. All available languages should be passed
|
||||
// in the constructor array.
|
||||
return array();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Core\StringTranslation\Translator\TranslatorInterface.
|
||||
*/
|
||||
|
||||
namespace Drupal\Core\StringTranslation\Translator;
|
||||
|
||||
/**
|
||||
* Interface for objects capable of string translation.
|
||||
*/
|
||||
interface TranslatorInterface {
|
||||
|
||||
/**
|
||||
* Retrieves English string to given language.
|
||||
*
|
||||
* @param string $langcode
|
||||
* Language code to translate to.
|
||||
* @param string $string
|
||||
* The source string.
|
||||
* @param string $context
|
||||
* The string context.
|
||||
*
|
||||
* @return string|FALSE
|
||||
* Translated string if there is a translation, FALSE if not.
|
||||
*/
|
||||
public function getStringTranslation($langcode, $string, $context);
|
||||
|
||||
/**
|
||||
* Resets translation cache.
|
||||
*
|
||||
* Since most translation systems implement some form of caching, this
|
||||
* provides a way to delete that cache.
|
||||
*/
|
||||
public function reset();
|
||||
|
||||
}
|
Reference in a new issue