Patched to Drupal 8.4.8 level. See https://www.drupal.org/sa-core-2018-004 and patch...
[yaffs-website] / web / core / lib / Drupal / Core / StringTranslation / TranslationManager.php
1 <?php
2
3 namespace Drupal\Core\StringTranslation;
4
5 use Drupal\Core\Language\LanguageDefault;
6 use Drupal\Core\StringTranslation\Translator\TranslatorInterface;
7
8 /**
9  * Defines a chained translation implementation combining multiple translators.
10  */
11 class TranslationManager implements TranslationInterface, TranslatorInterface {
12
13   /**
14    * An unsorted array of arrays of active translators.
15    *
16    * An associative array. The keys are integers that indicate priority. Values
17    * are arrays of TranslatorInterface objects.
18    *
19    * @var \Drupal\Core\StringTranslation\Translator\TranslatorInterface[][]
20    *
21    * @see \Drupal\Core\StringTranslation\TranslationManager::addTranslator()
22    * @see \Drupal\Core\StringTranslation\TranslationManager::sortTranslators()
23    */
24   protected $translators = [];
25
26   /**
27    * An array of translators, sorted by priority.
28    *
29    * If this is NULL a rebuild will be triggered.
30    *
31    * @var null|\Drupal\Core\StringTranslation\Translator\TranslatorInterface[]
32    *
33    * @see \Drupal\Core\StringTranslation\TranslationManager::addTranslator()
34    * @see \Drupal\Core\StringTranslation\TranslationManager::sortTranslators()
35    */
36   protected $sortedTranslators = NULL;
37
38   /**
39    * The default langcode used in translations.
40    *
41    * @var string
42    *   A language code.
43    */
44   protected $defaultLangcode;
45
46   /**
47    * Constructs a TranslationManager object.
48    *
49    * @param \Drupal\Core\Language\LanguageDefault $default_language
50    *   The default language.
51    */
52   public function __construct(LanguageDefault $default_language) {
53     $this->defaultLangcode = $default_language->get()->getId();
54   }
55
56   /**
57    * Appends a translation system to the translation chain.
58    *
59    * @param \Drupal\Core\StringTranslation\Translator\TranslatorInterface $translator
60    *   The translation interface to be appended to the translation chain.
61    * @param int $priority
62    *   The priority of the logger being added.
63    *
64    * @return $this
65    */
66   public function addTranslator(TranslatorInterface $translator, $priority = 0) {
67     $this->translators[$priority][] = $translator;
68     // Reset sorted translators property to trigger rebuild.
69     $this->sortedTranslators = NULL;
70     return $this;
71   }
72
73   /**
74    * Sorts translators according to priority.
75    *
76    * @return \Drupal\Core\StringTranslation\Translator\TranslatorInterface[]
77    *   A sorted array of translator objects.
78    */
79   protected function sortTranslators() {
80     $sorted = [];
81     krsort($this->translators);
82
83     foreach ($this->translators as $translators) {
84       $sorted = array_merge($sorted, $translators);
85     }
86     return $sorted;
87   }
88
89   /**
90    * {@inheritdoc}
91    */
92   public function getStringTranslation($langcode, $string, $context) {
93     if ($this->sortedTranslators === NULL) {
94       $this->sortedTranslators = $this->sortTranslators();
95     }
96     foreach ($this->sortedTranslators as $translator) {
97       $translation = $translator->getStringTranslation($langcode, $string, $context);
98       if ($translation !== FALSE) {
99         return $translation;
100       }
101     }
102     // No translator got a translation.
103     return FALSE;
104   }
105
106   /**
107    * {@inheritdoc}
108    */
109   public function translate($string, array $args = [], array $options = []) {
110     return new TranslatableMarkup($string, $args, $options, $this);
111   }
112
113   /**
114    * {@inheritdoc}
115    */
116   public function translateString(TranslatableMarkup $translated_string) {
117     return $this->doTranslate($translated_string->getUntranslatedString(), $translated_string->getOptions());
118   }
119
120   /**
121    * Translates a string to the current language or to a given language.
122    *
123    * @param string $string
124    *   A string containing the English text to translate.
125    * @param array $options
126    *   An associative array of additional options, with the following elements:
127    *   - 'langcode': The language code to translate to a language other than
128    *      what is used to display the page.
129    *   - 'context': The context the source string belongs to.
130    *
131    * @return string
132    *   The translated string.
133    */
134   protected function doTranslate($string, array $options = []) {
135     // If a NULL langcode has been provided, unset it.
136     if (!isset($options['langcode']) && array_key_exists('langcode', $options)) {
137       unset($options['langcode']);
138     }
139
140     // Merge in options defaults.
141     $options = $options + [
142       'langcode' => $this->defaultLangcode,
143       'context' => '',
144     ];
145     $translation = $this->getStringTranslation($options['langcode'], $string, $options['context']);
146     return $translation === FALSE ? $string : $translation;
147   }
148
149   /**
150    * {@inheritdoc}
151    */
152   public function formatPlural($count, $singular, $plural, array $args = [], array $options = []) {
153     return new PluralTranslatableMarkup($count, $singular, $plural, $args, $options, $this);
154   }
155
156   /**
157    * Sets the default langcode.
158    *
159    * @param string $langcode
160    *   A language code.
161    */
162   public function setDefaultLangcode($langcode) {
163     $this->defaultLangcode = $langcode;
164   }
165
166   /**
167    * {@inheritdoc}
168    */
169   public function reset() {
170     if ($this->sortedTranslators === NULL) {
171       $this->sortedTranslators = $this->sortTranslators();
172     }
173     foreach ($this->sortedTranslators as $translator) {
174       $translator->reset();
175     }
176   }
177
178 }