eca-1.0.x-dev/modules/language/src/Plugin/Action/SetCurrentLangcode.php
modules/language/src/Plugin/Action/SetCurrentLangcode.php
<?php
namespace Drupal\eca_language\Plugin\Action;
use Drupal\Core\Action\Attribute\Action;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Language\LanguageDefault;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\Core\StringTranslation\TranslationManager;
use Drupal\eca\Attribute\EcaAction;
use Drupal\eca\Plugin\CleanupInterface;
use Drupal\eca\Plugin\ECA\PluginFormTrait;
use Drupal\eca_language\Event\LanguageNegotiateEvent;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Set the currently used language code.
*/
#[Action(
id: 'eca_set_current_langcode',
label: new TranslatableMarkup('Language: set code'),
)]
#[EcaAction(
description: new TranslatableMarkup('Set the currently used or negotiated language code.'),
version_introduced: '2.0.0',
)]
class SetCurrentLangcode extends LanguageActionBase implements CleanupInterface {
use PluginFormTrait;
/**
* The default language object.
*
* @var \Drupal\Core\Language\LanguageDefault
*/
protected LanguageDefault $languageDefault;
/**
* Stack of used languages.
*
* @var array
*/
protected static array $languageStack = [];
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition): static {
$instance = parent::create($container, $configuration, $plugin_id, $plugin_definition);
$instance->languageDefault = $container->get('language.default');
$instance->setStringTranslation($container->get('string_translation'));
return $instance;
}
/**
* {@inheritdoc}
*/
public function defaultConfiguration(): array {
return [
'langcode' => '',
] + parent::defaultConfiguration();
}
/**
* {@inheritdoc}
*/
public function buildConfigurationForm(array $form, FormStateInterface $form_state): array {
$langcodes = [];
foreach ($this->languageManager->getLanguages() as $langcode => $language) {
$langcodes[$langcode] = $language->getName();
}
$langcodes['_interface'] = $this->t('Interface language');
$form['langcode'] = [
'#type' => 'select',
'#title' => $this->t('Language'),
'#options' => $langcodes,
'#default_value' => $this->configuration['langcode'],
'#description' => $this->t('The language code to be set.'),
'#weight' => -40,
'#eca_token_select_option' => TRUE,
];
return parent::buildConfigurationForm($form, $form_state);
}
/**
* {@inheritdoc}
*/
public function submitConfigurationForm(array &$form, FormStateInterface $form_state): void {
parent::submitConfigurationForm($form, $form_state);
$this->configuration['langcode'] = $form_state->getValue('langcode', '');
}
/**
* {@inheritdoc}
*/
public function execute(): void {
$langcode = trim($this->configuration['langcode']);
if (in_array($langcode, ['_interface', ''], TRUE)) {
$langcode = $this->languageManager->getCurrentLanguage()->getId();
}
elseif ($langcode === '_eca_token') {
$langcode = $this->getTokenValue('langcode', $this->languageManager->getCurrentLanguage()->getId());
}
if ($langcode === '') {
throw new \InvalidArgumentException("No language code specified.");
}
if (!($language = $this->languageManager->getLanguage($langcode))) {
throw new \InvalidArgumentException(sprintf("No language found for langcode %s.", $langcode));
}
if (isset($this->event) && ($this->event instanceof LanguageNegotiateEvent)) {
$this->event->langcode = $language->getId();
return;
}
$langInfo = [
'current' => $this->languageManager->getCurrentLanguage(),
'default' => $this->languageDefault->get(),
'override' => $this->languageManager->getConfigOverrideLanguage(),
];
$this->languageManager->reset();
$this->languageManager->setCurrentLangcode($language->getId());
$this->languageManager->setConfigOverrideLanguage($language);
$this->languageDefault->set($language);
if ($this->stringTranslation instanceof TranslationManager) {
$this->stringTranslation->setDefaultLangcode($language->getId());
}
self::$languageStack[] = $langInfo;
}
/**
* {@inheritdoc}
*/
public function cleanupAfterSuccessors(): void {
if (isset($this->event) && ($this->event instanceof LanguageNegotiateEvent)) {
return;
}
$langInfo = array_pop(self::$languageStack);
// Instead of resetting language negotiation, the previous langcode is being
// explicitly set here, to ensure that it does not potentially differ from
// what was set before.
$this->languageManager->setCurrentLangcode($langInfo['current']->getId());
$this->languageManager->setConfigOverrideLanguage($langInfo['override']);
$this->languageDefault->set($langInfo['default']);
if ($this->stringTranslation instanceof TranslationManager) {
$this->stringTranslation->setDefaultLangcode($langInfo['current']->getId());
}
}
}
