LanguageManager.php 13.5 KB
Newer Older
1 2 3 4
<?php

/**
 * @file
5
 * Contains \Drupal\Core\Language\LanguageManager.
6 7 8 9
 */

namespace Drupal\Core\Language;

10
use Drupal\Component\Utility\String;
11
use Drupal\Core\DependencyInjection\DependencySerializationTrait;
12
use Drupal\Core\StringTranslation\TranslationInterface;
13
use Drupal\Core\StringTranslation\TranslationWrapper;
14
use Drupal\Core\Url;
15 16

/**
17
 * Class responsible for providing language support on language-unaware sites.
18
 */
19 20
class LanguageManager implements LanguageManagerInterface {
  use DependencySerializationTrait;
21

22
  /**
23
   * The string translation service.
24
   *
25
   * @var \Drupal\Core\StringTranslation\TranslationInterface
26
   */
27
  protected $translation;
28

29
  /**
30
   * An array of all the available languages keyed by language code.
31
   *
32
   * @var \Drupal\Core\Language\LanguageInterface[]
33
   */
34
  protected $languages;
35

36
  /**
37
   * The default language object.
38
   *
39
   * @var \Drupal\Core\Language\LanguageDefault
40
   */
41
  protected $defaultLanguage;
42

43 44 45
  /**
   * Constructs the language manager.
   *
46
   * @param \Drupal\Core\Language\LanguageDefault $default_language
47 48 49 50 51 52
   *   The default language.
   */
  public function __construct(LanguageDefault $default_language) {
    $this->defaultLanguage = $default_language;
  }

53
  /**
54
   * {@inheritdoc}
55
   */
56
  public function setTranslation(TranslationInterface $translation) {
57 58
    $this->translation = $translation;
  }
59 60

  /**
61
   * Translates a string to the current language or to a given language.
62
   *
63
   * @see \Drupal\Core\StringTranslation\TranslationInterface()
64
   */
65 66 67
  protected function t($string, array $args = array(), array $options = array()) {
    return $this->translation ? $this->translation->translate($string, $args, $options) : String::format($string, $args);
  }
68

69
  /**
70
   * {@inheritdoc}
71
   */
72 73
  public function isMultilingual() {
    return FALSE;
74 75
  }

76
  /**
77
   * {@inheritdoc}
78
   */
79
  public function getLanguageTypes() {
80
    return array(LanguageInterface::TYPE_INTERFACE, LanguageInterface::TYPE_CONTENT, LanguageInterface::TYPE_URL);
81 82
  }

83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
  /**
   * {@inheritdoc}
   */
  public function getDefinedLanguageTypesInfo() {
    // This needs to have the same return value as
    // language_language_type_info(), so that even if the Language module is
    // not defined, users of this information, such as the Views module, can
    // access names and descriptions of the default language types.
    return array(
      LanguageInterface::TYPE_INTERFACE => array(
        'name' => $this->t('User interface text'),
        'description' => $this->t('Order of language detection methods for user interface text. If a translation of user interface text is available in the detected language, it will be displayed.'),
        'locked' => TRUE,
      ),
      LanguageInterface::TYPE_CONTENT => array(
        'name' => $this->t('Content'),
        'description' => $this->t('Order of language detection methods for content. If a version of content is available in the detected language, it will be displayed.'),
        'locked' => TRUE,
      ),
      LanguageInterface::TYPE_URL => array(
        'locked' => TRUE,
      ),
    );
  }

108
  /**
109
   * {@inheritdoc}
110
   */
111
  public function getCurrentLanguage($type = LanguageInterface::TYPE_INTERFACE) {
112
    return $this->getDefaultLanguage();
113 114
  }

115
  /**
116
   * {@inheritdoc}
117
   */
118
  public function reset($type = NULL) {
119
    return $this;
120
  }
121

122 123 124 125
  /**
   * {@inheritdoc}
   */
  public function getDefaultLanguage() {
126
    return $this->defaultLanguage->get();
127 128
  }

129
  /**
130
   * {@inheritdoc}
131
   */
132
  public function getLanguages($flags = LanguageInterface::STATE_CONFIGURABLE) {
133 134 135 136 137 138
    // Initialize master language list.
    if (!isset($this->languages)) {
      // No language module, so use the default language only.
      $default = $this->getDefaultLanguage();
      $this->languages = array($default->id => $default);
      // Add the special languages, they will be filtered later if needed.
139
      $this->languages += $this->getDefaultLockedLanguages($default->getWeight());
140
    }
141 142 143 144 145 146 147

    // Filter the full list of languages based on the value of the $all flag. By
    // default we remove the locked languages, but the caller may request for
    // those languages to be added as well.
    $filtered_languages = array();

    // Add the site's default language if flagged as allowed value.
148
    if ($flags & LanguageInterface::STATE_SITE_DEFAULT) {
149
      $default = isset($default) ? $default : $this->getDefaultLanguage();
150 151 152
      // Rename the default language. But we do not want to do this globally,
      // if we're acting on a global object, so clone the object first.
      $default = clone $default;
153
      $default->name = $this->t("Site's default language (@lang_name)", array('@lang_name' => $default->name));
154
      $filtered_languages[LanguageInterface::LANGCODE_SITE_DEFAULT] = $default;
155
    }
156 157

    foreach ($this->languages as $id => $language) {
158
      if (($language->isLocked() && ($flags & LanguageInterface::STATE_LOCKED)) || (!$language->isLocked() && ($flags & LanguageInterface::STATE_CONFIGURABLE))) {
159 160 161 162 163
        $filtered_languages[$id] = $language;
      }
    }

    return $filtered_languages;
164
  }
165

166 167 168 169 170 171 172 173
  /**
   * {@inheritdoc}
   */
  public function getNativeLanguages() {
    // In a language unaware site we don't have translated languages.
    return $this->getLanguages();
  }

174
  /**
175
   * {@inheritdoc}
176
   */
177
  public function getLanguage($langcode) {
178
    $languages = $this->getLanguages(LanguageInterface::STATE_ALL);
179
    return isset($languages[$langcode]) ? $languages[$langcode] : NULL;
180 181
  }

182
  /**
183
   * {@inheritdoc}
184
   */
185
  public function getLanguageName($langcode) {
186
    if ($langcode == LanguageInterface::LANGCODE_NOT_SPECIFIED) {
187 188 189 190
      return $this->t('None');
    }
    if ($language = $this->getLanguage($langcode)) {
      return $language->name;
191
    }
192 193
    if (empty($langcode)) {
      return $this->t('Unknown');
194
    }
195 196 197 198 199 200 201 202 203 204 205 206
    return $this->t('Unknown (@langcode)', array('@langcode' => $langcode));
  }

  /**
   * {@inheritdoc}
   */
  public function getDefaultLockedLanguages($weight = 0) {
    $languages = array();

    $locked_language = array(
      'default' => FALSE,
      'locked' => TRUE,
207
    );
208 209
    // This is called very early while initializing the language system. Prevent
    // early t() calls by using the TranslationWrapper.
210 211
    $languages[LanguageInterface::LANGCODE_NOT_SPECIFIED] = new Language(array(
      'id' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
212
      'name' => new TranslationWrapper('Not specified'),
213 214 215
      'weight' => ++$weight,
    ) + $locked_language);

216 217
    $languages[LanguageInterface::LANGCODE_NOT_APPLICABLE] = new Language(array(
      'id' => LanguageInterface::LANGCODE_NOT_APPLICABLE,
218
      'name' => new TranslationWrapper('Not applicable'),
219 220 221 222 223
      'weight' => ++$weight,
    ) + $locked_language);

    return $languages;
  }
224

225 226 227 228 229
  /**
   * {@inheritdoc}
   */
  public function isLanguageLocked($langcode) {
    $language = $this->getLanguage($langcode);
230
    return ($language ? $language->isLocked() : FALSE);
231 232
  }

233
  /**
234
   * {@inheritdoc}
235
   */
236
  public function getFallbackCandidates(array $context = array()) {
237
    return array(LanguageInterface::LANGCODE_DEFAULT);
238 239 240
  }

  /**
241
   * {@inheritdoc}
242
   */
243
  public function getLanguageSwitchLinks($type, Url $url) {
244
    return array();
245 246
  }

247 248 249 250
  /**
   * Some common languages with their English and native names.
   *
   * Language codes are defined by the W3C language tags document for
251 252 253 254
   * interoperability. Language codes typically have a language and, optionally,
   * a script or regional variant name. See:
   * http://www.w3.org/International/articles/language-tags/ for more
   * information.
255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271
   *
   * This list is based on languages available from localize.drupal.org. See
   * http://localize.drupal.org/issues for information on how to add languages
   * there.
   *
   * The "Left-to-right marker" comments and the enclosed UTF-8 markers are to
   * make otherwise strange looking PHP syntax natural (to not be displayed in
   * right to left). See http://drupal.org/node/128866#comment-528929.
   *
   * @return array
   *   An array of language code to language name information.
   *   Language name information itself is an array of English and native names.
   */
  public static function getStandardLanguageList() {
    return array(
      'af' => array('Afrikaans', 'Afrikaans'),
      'am' => array('Amharic', 'አማርኛ'),
272
      'ar' => array('Arabic', /* Left-to-right marker "‭" */ 'العربية', LanguageInterface::DIRECTION_RTL),
273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291
      'ast' => array('Asturian', 'Asturianu'),
      'az' => array('Azerbaijani', 'Azərbaycanca'),
      'be' => array('Belarusian', 'Беларуская'),
      'bg' => array('Bulgarian', 'Български'),
      'bn' => array('Bengali', 'বাংলা'),
      'bo' => array('Tibetan', 'བོད་སྐད་'),
      'bs' => array('Bosnian', 'Bosanski'),
      'ca' => array('Catalan', 'Català'),
      'cs' => array('Czech', 'Čeština'),
      'cy' => array('Welsh', 'Cymraeg'),
      'da' => array('Danish', 'Dansk'),
      'de' => array('German', 'Deutsch'),
      'dz' => array('Dzongkha', 'རྫོང་ཁ'),
      'el' => array('Greek', 'Ελληνικά'),
      'en' => array('English', 'English'),
      'eo' => array('Esperanto', 'Esperanto'),
      'es' => array('Spanish', 'Español'),
      'et' => array('Estonian', 'Eesti'),
      'eu' => array('Basque', 'Euskera'),
292
      'fa' => array('Persian, Farsi', /* Left-to-right marker "‭" */ 'فارسی', LanguageInterface::DIRECTION_RTL),
293 294 295 296
      'fi' => array('Finnish', 'Suomi'),
      'fil' => array('Filipino', 'Filipino'),
      'fo' => array('Faeroese', 'Føroyskt'),
      'fr' => array('French', 'Français'),
297 298
      'fy' => array('Frisian, Western', 'Frysk'),
      'ga' => array('Irish', 'Gaeilge'),
299 300 301 302
      'gd' => array('Scots Gaelic', 'Gàidhlig'),
      'gl' => array('Galician', 'Galego'),
      'gsw-berne' => array('Swiss German', 'Schwyzerdütsch'),
      'gu' => array('Gujarati', 'ગુજરાતી'),
303
      'he' => array('Hebrew', /* Left-to-right marker "‭" */ 'עברית', LanguageInterface::DIRECTION_RTL),
304 305 306 307
      'hi' => array('Hindi', 'हिन्दी'),
      'hr' => array('Croatian', 'Hrvatski'),
      'ht' => array('Haitian Creole', 'Kreyòl ayisyen'),
      'hu' => array('Hungarian', 'Magyar'),
308
      'hy' => array('Armenian', 'Հայերեն'),
309 310 311 312 313 314 315
      'id' => array('Indonesian', 'Bahasa Indonesia'),
      'is' => array('Icelandic', 'Íslenska'),
      'it' => array('Italian', 'Italiano'),
      'ja' => array('Japanese', '日本語'),
      'jv' => array('Javanese', 'Basa Java'),
      'ka' => array('Georgian', 'ქართული ენა'),
      'kk' => array('Kazakh', 'Қазақ'),
316
      'km' => array('Khmer', 'ភាសាខ្មែរ'),
317 318 319 320 321 322 323 324 325 326 327 328
      'kn' => array('Kannada', 'ಕನ್ನಡ'),
      'ko' => array('Korean', '한국어'),
      'ku' => array('Kurdish', 'Kurdî'),
      'ky' => array('Kyrgyz', 'Кыргызча'),
      'lo' => array('Lao', 'ພາສາລາວ'),
      'lt' => array('Lithuanian', 'Lietuvių'),
      'lv' => array('Latvian', 'Latviešu'),
      'mg' => array('Malagasy', 'Malagasy'),
      'mk' => array('Macedonian', 'Македонски'),
      'ml' => array('Malayalam', 'മലയാളം'),
      'mn' => array('Mongolian', 'монгол'),
      'mr' => array('Marathi', 'मराठी'),
329
      'ms' => array('Bahasa Malaysia', 'بهاس ملايو'),
330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349
      'my' => array('Burmese', 'ဗမာစကား'),
      'ne' => array('Nepali', 'नेपाली'),
      'nl' => array('Dutch', 'Nederlands'),
      'nb' => array('Norwegian Bokmål', 'Bokmål'),
      'nn' => array('Norwegian Nynorsk', 'Nynorsk'),
      'oc' => array('Occitan', 'Occitan'),
      'pa' => array('Punjabi', 'ਪੰਜਾਬੀ'),
      'pl' => array('Polish', 'Polski'),
      'pt-pt' => array('Portuguese, Portugal', 'Português, Portugal'),
      'pt-br' => array('Portuguese, Brazil', 'Português, Brasil'),
      'ro' => array('Romanian', 'Română'),
      'ru' => array('Russian', 'Русский'),
      'sco' => array('Scots', 'Scots'),
      'se' => array('Northern Sami', 'Sámi'),
      'si' => array('Sinhala', 'සිංහල'),
      'sk' => array('Slovak', 'Slovenčina'),
      'sl' => array('Slovenian', 'Slovenščina'),
      'sq' => array('Albanian', 'Shqip'),
      'sr' => array('Serbian', 'Српски'),
      'sv' => array('Swedish', 'Svenska'),
350
      'sw' => array('Swahili', 'Kiswahili'),
351 352 353 354 355 356 357 358
      'ta' => array('Tamil', 'தமிழ்'),
      'ta-lk' => array('Tamil, Sri Lanka', 'தமிழ், இலங்கை'),
      'te' => array('Telugu', 'తెలుగు'),
      'th' => array('Thai', 'ภาษาไทย'),
      'tr' => array('Turkish', 'Türkçe'),
      'tyv' => array('Tuvan', 'Тыва дыл'),
      'ug' => array('Uyghur', 'Уйғур'),
      'uk' => array('Ukrainian', 'Українська'),
359
      'ur' => array('Urdu', /* Left-to-right marker "‭" */ 'اردو', LanguageInterface::DIRECTION_RTL),
360 361 362 363 364 365 366
      'vi' => array('Vietnamese', 'Tiếng Việt'),
      'xx-lolspeak' => array('Lolspeak', 'Lolspeak'),
      'zh-hans' => array('Chinese, Simplified', '简体中文'),
      'zh-hant' => array('Chinese, Traditional', '繁體中文'),
    );
  }

367 368 369
  /**
   * {@inheritdoc}
   *
370
   * This function is a noop since the configuration cannot be overridden by
371
   * language unless the Language module is enabled. That replaces the default
372
   * language manager with a configurable language manager.
373 374 375
   *
   * @see \Drupal\language\ConfigurableLanguageManager::setConfigOverrideLanguage()
   */
376
  public function setConfigOverrideLanguage(LanguageInterface $language = NULL) {
377 378 379 380 381 382 383 384 385 386
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function getConfigOverrideLanguage() {
    return $this->getCurrentLanguage();
  }

Crell's avatar
Crell committed
387
}