View source
<?php
namespace Drupal\language;
use Drupal\Core\Language\LanguageInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Language\Language;
use Drupal\Core\Language\LanguageDefault;
use Drupal\Core\Language\LanguageManager;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\Core\Url;
use Drupal\language\Config\LanguageConfigFactoryOverrideInterface;
use Drupal\language\Entity\ConfigurableLanguage;
use Symfony\Component\HttpFoundation\RequestStack;
class ConfigurableLanguageManager extends LanguageManager implements ConfigurableLanguageManagerInterface {
protected $configFactory;
protected $moduleHandler;
protected $configFactoryOverride;
protected $requestStack;
protected $negotiator;
protected $languageTypes;
protected $languageTypesInfo;
protected $negotiatedLanguages;
protected $negotiatedMethods;
protected $initialized = FALSE;
protected $initializing = [];
public static function rebuildServices() {
\Drupal::service('kernel')
->invalidateContainer();
}
public function __construct(LanguageDefault $default_language, ConfigFactoryInterface $config_factory, ModuleHandlerInterface $module_handler, LanguageConfigFactoryOverrideInterface $config_override, RequestStack $request_stack) {
$this->defaultLanguage = $default_language;
$this->configFactory = $config_factory;
$this->moduleHandler = $module_handler;
$this->configFactoryOverride = $config_override;
$this->requestStack = $request_stack;
}
public function init() {
if (!$this->initialized) {
foreach ($this
->getDefinedLanguageTypes() as $type) {
$this
->getCurrentLanguage($type);
}
$this->initialized = TRUE;
}
}
public function isMultilingual() {
return count($this
->getLanguages(LanguageInterface::STATE_CONFIGURABLE)) > 1;
}
public function getLanguageTypes() {
$this
->loadLanguageTypesConfiguration();
return $this->languageTypes['configurable'];
}
public function getDefinedLanguageTypes() {
$this
->loadLanguageTypesConfiguration();
return $this->languageTypes['all'];
}
protected function loadLanguageTypesConfiguration() {
if (!$this->languageTypes) {
$this->languageTypes = $this->configFactory
->get('language.types')
->get() ?: [
'configurable' => [],
'all' => parent::getLanguageTypes(),
];
}
return $this->languageTypes;
}
public function getDefinedLanguageTypesInfo() {
if (!isset($this->languageTypesInfo)) {
$defaults = parent::getDefinedLanguageTypesInfo();
$info = $this->moduleHandler
->invokeAll('language_types_info');
$language_info = $info + $defaults;
$this->moduleHandler
->alter('language_types_info', $language_info);
$this->languageTypesInfo = $language_info;
}
return $this->languageTypesInfo;
}
public function saveLanguageTypesConfiguration(array $values) {
$config = $this->configFactory
->getEditable('language.types');
if (isset($values['configurable'])) {
$config
->set('configurable', $values['configurable']);
}
if (isset($values['all'])) {
$config
->set('all', $values['all']);
}
$config
->save(TRUE);
}
public function getCurrentLanguage($type = LanguageInterface::TYPE_INTERFACE) {
if (!isset($this->negotiatedLanguages[$type])) {
$this->negotiatedLanguages[$type] = $this
->getDefaultLanguage();
if ($this->negotiator && $this
->isMultilingual()) {
if (!isset($this->initializing[$type])) {
$this->initializing[$type] = TRUE;
$negotiation = $this->negotiator
->initializeType($type);
$this->negotiatedLanguages[$type] = reset($negotiation);
$this->negotiatedMethods[$type] = key($negotiation);
unset($this->initializing[$type]);
}
elseif ($type == LanguageInterface::TYPE_INTERFACE) {
return new Language([
'id' => LanguageInterface::LANGCODE_SYSTEM,
]);
}
}
}
return $this->negotiatedLanguages[$type];
}
public function reset($type = NULL) {
if (!isset($type)) {
$this->initialized = FALSE;
$this->negotiatedLanguages = [];
$this->negotiatedMethods = [];
$this->languageTypes = NULL;
$this->languageTypesInfo = NULL;
$this->languages = [];
if ($this->negotiator) {
$this->negotiator
->reset();
}
}
elseif (isset($this->negotiatedLanguages[$type])) {
unset($this->negotiatedLanguages[$type]);
unset($this->negotiatedMethods[$type]);
}
return $this;
}
public function getNegotiator() {
return $this->negotiator;
}
public function setNegotiator(LanguageNegotiatorInterface $negotiator) {
$this->negotiator = $negotiator;
$this->initialized = FALSE;
$this->negotiatedLanguages = [];
}
public function getLanguages($flags = LanguageInterface::STATE_CONFIGURABLE) {
if ($override_language = $this
->getConfigOverrideLanguage()) {
$static_cache_id = $override_language
->getId();
}
else {
$static_cache_id = $this
->getCurrentLanguage()
->getId();
}
if (!isset($this->languages[$static_cache_id][$flags])) {
$default = $this
->getDefaultLanguage();
$languages = [
$default
->getId() => $default,
];
$languages += $this
->getDefaultLockedLanguages($default
->getWeight());
$config_ids = $this->configFactory
->listAll('language.entity.');
foreach ($this->configFactory
->loadMultiple($config_ids) as $config) {
$data = $config
->get();
$data['name'] = $data['label'];
$languages[$data['id']] = new Language($data);
}
Language::sort($languages);
$this->languages[$static_cache_id][$flags] = $this
->filterLanguages($languages, $flags);
}
return $this->languages[$static_cache_id][$flags];
}
public function getNativeLanguages() {
$languages = $this
->getLanguages(LanguageInterface::STATE_CONFIGURABLE);
$natives = [];
$original_language = $this
->getConfigOverrideLanguage();
foreach ($languages as $langcode => $language) {
$this
->setConfigOverrideLanguage($language);
$natives[$langcode] = ConfigurableLanguage::load($langcode);
}
$this
->setConfigOverrideLanguage($original_language);
Language::sort($natives);
return $natives;
}
public function updateLockedLanguageWeights() {
$configurable_languages = $this
->getLanguages(LanguageInterface::STATE_CONFIGURABLE);
$max_weight = end($configurable_languages)
->getWeight();
$locked_languages = $this
->getLanguages(LanguageInterface::STATE_LOCKED);
if (reset($locked_languages)
->getWeight() <= $max_weight) {
foreach ($locked_languages as $language) {
$max_weight++;
ConfigurableLanguage::load($language
->getId())
->setWeight($max_weight)
->save();
}
}
}
public function getFallbackCandidates(array $context = []) {
if ($this
->isMultilingual()) {
$candidates = [];
if (empty($context['operation']) || $context['operation'] != 'locale_lookup') {
$candidates = array_keys($this
->getLanguages());
$candidates[] = LanguageInterface::LANGCODE_NOT_SPECIFIED;
$candidates = array_combine($candidates, $candidates);
if (!empty($context['langcode'])) {
$candidates = [
$context['langcode'] => $context['langcode'],
] + $candidates;
}
}
$type = 'language_fallback_candidates';
$types = [];
if (!empty($context['operation'])) {
$types[] = $type . '_' . $context['operation'];
}
$types[] = $type;
$this->moduleHandler
->alter($types, $candidates, $context);
}
else {
$candidates = parent::getFallbackCandidates($context);
}
return $candidates;
}
public function getLanguageSwitchLinks($type, Url $url) {
$links = FALSE;
if ($this->negotiator) {
foreach ($this->negotiator
->getNegotiationMethods($type) as $method_id => $method) {
$reflector = new \ReflectionClass($method['class']);
if ($reflector
->implementsInterface('\\Drupal\\language\\LanguageSwitcherInterface')) {
$result = $this->negotiator
->getNegotiationMethodInstance($method_id)
->getLanguageSwitchLinks($this->requestStack
->getCurrentRequest(), $type, $url);
if (!empty($result)) {
$this->moduleHandler
->alter('language_switch_links', $result, $type, $url);
$links = (object) [
'links' => $result,
'method_id' => $method_id,
];
break;
}
}
}
}
return $links;
}
public function setConfigOverrideLanguage(LanguageInterface $language = NULL) {
$this->configFactoryOverride
->setLanguage($language);
return $this;
}
public function getConfigOverrideLanguage() {
return $this->configFactoryOverride
->getLanguage();
}
public function getLanguageConfigOverride($langcode, $name) {
return $this->configFactoryOverride
->getOverride($langcode, $name);
}
public function getLanguageConfigOverrideStorage($langcode) {
return $this->configFactoryOverride
->getStorage($langcode);
}
public function getStandardLanguageListWithoutConfigured() {
$languages = $this
->getLanguages();
$predefined = $this
->getStandardLanguageList();
foreach ($predefined as $key => $value) {
if (isset($languages[$key])) {
unset($predefined[$key]);
continue;
}
$predefined[$key] = new TranslatableMarkup($value[0]);
}
natcasesort($predefined);
return $predefined;
}
public function getNegotiatedLanguageMethod($type = LanguageInterface::TYPE_INTERFACE) {
if (isset($this->negotiatedLanguages[$type]) && isset($this->negotiatedMethods[$type])) {
return $this->negotiatedMethods[$type];
}
}
}