3 namespace Drupal\language\EventSubscriber;
5 use Drupal\Core\Config\ConfigFactoryInterface;
6 use Drupal\Core\Language\Language;
7 use Drupal\Core\Language\LanguageDefault;
8 use Drupal\Core\Language\LanguageManagerInterface;
9 use Drupal\Core\Config\ConfigCrudEvent;
10 use Drupal\Core\Config\ConfigEvents;
11 use Drupal\language\ConfigurableLanguageManager;
12 use Drupal\language\HttpKernel\PathProcessorLanguage;
13 use Drupal\language\LanguageNegotiatorInterface;
14 use Symfony\Component\EventDispatcher\EventSubscriberInterface;
17 * Deletes the container if default language has changed.
19 class ConfigSubscriber implements EventSubscriberInterface {
22 * The language manager.
24 * @var \Drupal\Core\Language\LanguageManagerInterface
26 protected $languageManager;
29 * The default language.
31 * @var \Drupal\Core\Language\LanguageDefault
33 protected $languageDefault;
36 * The configuration factory.
38 * @var \Drupal\Core\Config\ConfigFactoryInterface
40 protected $configFactory;
43 * The language negotiator.
45 * @var \Drupal\language\LanguageNegotiatorInterface
47 protected $languageNegotiator;
50 * The language path processor.
52 * @var \Drupal\language\HttpKernel\PathProcessorLanguage
54 protected $pathProcessorLanguage;
57 * Constructs a new class object.
59 * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
60 * The language manager.
61 * @param \Drupal\Core\Language\LanguageDefault $language_default
62 * The default language.
63 * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
64 * The configuration factory.
65 * @param \Drupal\language\LanguageNegotiatorInterface $language_negotiator
66 * The language negotiator.
68 public function __construct(LanguageManagerInterface $language_manager, LanguageDefault $language_default, ConfigFactoryInterface $config_factory, LanguageNegotiatorInterface $language_negotiator) {
69 $this->languageManager = $language_manager;
70 $this->languageDefault = $language_default;
71 $this->configFactory = $config_factory;
72 $this->languageNegotiator = $language_negotiator;
76 * Causes the container to be rebuilt on the next request.
78 * This event subscriber assumes that the new default langcode and old default
79 * langcode are valid langcodes. If the schema definition of either
80 * system.site:default_langcode or language.negotiation::url.prefixes changes
81 * then this event must be changed to work with both the old and new schema
82 * definition so this event is update safe.
84 * @param ConfigCrudEvent $event
85 * The configuration event.
87 public function onConfigSave(ConfigCrudEvent $event) {
88 $saved_config = $event->getConfig();
89 if ($saved_config->getName() == 'system.site' && $event->isChanged('default_langcode')) {
90 $new_default_langcode = $saved_config->get('default_langcode');
91 $default_language = $this->configFactory->get('language.entity.' . $new_default_langcode);
92 // During an import the language might not exist yet.
93 if (!$default_language->isNew()) {
94 $this->languageDefault->set(new Language($default_language->get()));
95 $this->languageManager->reset();
97 // Directly update language negotiation settings instead of calling
98 // language_negotiation_url_prefixes_update() to ensure that the code
99 // obeys the hook_update_N() restrictions.
100 $negotiation_config = $this->configFactory->getEditable('language.negotiation');
101 $negotiation_changed = FALSE;
102 $url_prefixes = $negotiation_config->get('url.prefixes');
103 $old_default_langcode = $saved_config->getOriginal('default_langcode');
104 if (empty($url_prefixes[$old_default_langcode])) {
105 $negotiation_config->set('url.prefixes.' . $old_default_langcode, $old_default_langcode);
106 $negotiation_changed = TRUE;
108 if (empty($url_prefixes[$new_default_langcode])) {
109 $negotiation_config->set('url.prefixes.' . $new_default_langcode, '');
110 $negotiation_changed = TRUE;
112 if ($negotiation_changed) {
113 $negotiation_config->save(TRUE);
116 // Trigger a container rebuild on the next request by invalidating it.
117 ConfigurableLanguageManager::rebuildServices();
119 elseif ($saved_config->getName() == 'language.types' && $event->isChanged('negotiation')) {
120 // If the negotiation configuration changed the language negotiator and
121 // the language path processor have to be reset so that they regenerate
122 // the method instances and also sort them accordingly to the new config.
123 $this->languageNegotiator->reset();
124 if (isset($this->pathProcessorLanguage)) {
125 $this->pathProcessorLanguage->reset();
131 * Injects the language path processors on multilingual site configuration.
133 * @param \Drupal\language\HttpKernel\PathProcessorLanguage $path_processor_language
134 * The language path processor.
136 public function setPathProcessorLanguage(PathProcessorLanguage $path_processor_language) {
137 $this->pathProcessorLanguage = $path_processor_language;
143 public static function getSubscribedEvents() {
144 $events[ConfigEvents::SAVE][] = ['onConfigSave', 0];