View source
<?php
namespace Drupal\lang_dropdown\Form;
use Drupal\Component\Render\FormattableMarkup;
use Drupal\Component\Utility\Html;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Language\Language;
use Drupal\Core\Url;
use Drupal\Core\Routing\TrustedRedirectResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Language\LanguageManagerInterface;
use Symfony\Component\HttpFoundation\RequestStack;
use Drupal\Core\Path\PathMatcherInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
class LanguageDropdownForm extends FormBase {
protected $languages;
protected $type;
protected $settings;
protected $languageManager;
protected $requestStack;
protected $pathMatcher;
protected $routeMatch;
protected $moduleHandler;
public function getFormId() {
return 'lang_dropdown_form';
}
public function __construct(LanguageManagerInterface $language_manager, RequestStack $request_stack, PathMatcherInterface $path_matcher, RouteMatchInterface $route_match, ModuleHandlerInterface $module_handler) {
$this->languageManager = $language_manager;
$this->requestStack = $request_stack;
$this->pathMatcher = $path_matcher;
$this->routeMatch = $route_match;
$this->moduleHandler = $module_handler;
}
public static function create(ContainerInterface $container) {
return new static($container
->get('language_manager'), $container
->get('request_stack'), $container
->get('path.matcher'), $container
->get('current_route_match'), $container
->get('module_handler'));
}
public function buildForm(array $form, FormStateInterface $form_state, array $languages = [], $type = '', array $settings = []) {
$this->languages = $languages;
$this->type = $type;
$this->settings = $settings;
$language_url = $this->languageManager
->getCurrentLanguage(Language::TYPE_URL);
$unique_id = Html::getId('lang_dropdown_form');
$options = $hidden_elements = [];
$js_settings = [
'key' => $unique_id,
];
$selected_option_language_icon = $language_selected = $language_session_selected = '';
$form['lang_dropdown_type'] = [
'#type' => 'value',
'#default_value' => $this->type,
];
$form['lang_dropdown_tohome'] = [
'#type' => 'value',
'#default_value' => $this->settings['tohome'],
];
foreach ($this->languages as $lang_code => $lang_options) {
$language = $lang_options['language'];
if (!$this->settings['showall'] && in_array('locale-untranslated', $lang_options['attributes']['class'], TRUE)) {
continue;
}
switch ($this->settings['display']) {
case LANGDROPDOWN_DISPLAY_TRANSLATED:
default:
$options += [
$lang_code => $this
->t($language
->getName()),
];
break;
case LANGDROPDOWN_DISPLAY_NATIVE:
$native_language = $this->languageManager
->getNativeLanguages()[$lang_code];
$options += [
$lang_code => $native_language
->getName(),
];
break;
case LANGDROPDOWN_DISPLAY_LANGCODE:
$options += [
$lang_code => $lang_code,
];
break;
}
if (isset($lang_options['url'])) {
$url = $lang_options['url'];
if ($url
->isRouted()) {
$route_name = $url
->getRouteName();
$is_current_path = $route_name === '<current>' || $route_name == $this->routeMatch
->getRouteName() || $route_name === '<front>' && $this->pathMatcher
->isFrontPage();
$is_current_language = empty($language) || $language
->getId() == $language_url
->getId();
if ($is_current_path && $is_current_language) {
$language_selected = $lang_code;
}
}
}
if (in_array('session-active', $lang_options['attributes']['class'], TRUE)) {
$language_session_selected = $lang_code;
}
$url = isset($lang_options['url']) && $this->settings['tohome'] == 0 ? $lang_options['url'] : Url::fromRoute('<front>');
if (!isset($lang_options['query'])) {
$lang_options['query'] = $this->requestStack->query
->all();
}
$hidden_elements[$lang_code] = [
'#type' => 'hidden',
'#value' => $url
->setOptions($url
->getOptions() + $lang_options)
->toString(),
];
if (isset($this->settings['widget']) && $this->moduleHandler
->moduleExists('languageicons')) {
$languageicons_config = $this
->configFactory()
->get('languageicons.settings');
$languageicons_path = $languageicons_config
->get('path');
$js_settings['languageicons'][$lang_code] = file_create_url(str_replace('*', $lang_code, $languageicons_path));
}
}
$selected_option = $language_session_selected === '' ? $language_selected : $language_session_selected;
if (!$this->settings['widget'] && $this->moduleHandler
->moduleExists('languageicons')) {
$language = $this->languages[$selected_option]['language'];
$selected_option_language_icon = [
'#theme' => 'languageicons_link_content',
'#language' => $language,
'#title' => $language
->getName(),
];
$selected_option_language_icon = \Drupal::service('renderer')
->renderPlain($selected_option_language_icon);
}
if ($this->settings['widget'] == LANGDROPDOWN_MSDROPDOWN) {
$js_settings += [
'widget' => 'msdropdown',
'visibleRows' => $this->settings['msdropdown']['visible_rows'],
'roundedCorner' => $this->settings['msdropdown']['rounded'],
'animStyle' => $this->settings['msdropdown']['animation'],
'event' => $this->settings['msdropdown']['event'],
];
$selected_skin = $this->settings['msdropdown']['skin'];
if ($selected_skin === 'custom') {
$custom_skin = Html::escape($this->settings['msdropdown']['custom_skin']);
$form['#attached']['library'][] = 'lang_dropdown/ms-dropdown';
$js_settings += [
'mainCSS' => $custom_skin,
];
}
else {
$skins = _lang_dropdown_get_msdropdown_skins();
$skin_data = $skins[$selected_skin];
$form['#attached']['library'][] = 'lang_dropdown/' . $selected_skin;
$js_settings += [
'mainCSS' => $skin_data['mainCSS'],
];
}
$form['#attached']['library'][] = 'lang_dropdown/ms-dropdown';
$form['#attached']['drupalSettings']['lang_dropdown'][$unique_id] = $js_settings;
}
elseif ($this->settings['widget'] == LANGDROPDOWN_CHOSEN) {
$js_settings += [
'widget' => 'chosen',
'disable_search' => $this->settings['chosen']['disable_search'],
'no_results_text' => $this->settings['chosen']['no_results_text'],
];
$form['#attached']['library'][] = 'lang_dropdown/chosen';
$form['#attached']['drupalSettings']['lang_dropdown'][$unique_id] = $js_settings;
}
elseif ($this->settings['widget'] == LANGDROPDOWN_DDSLICK) {
$form['#attached']['library'][] = 'lang_dropdown/ddslick';
$selected_skin = $this->settings['ddslick']['skin'];
$js_settings += [
'widget' => 'ddslick',
'width' => $this->settings['width'],
'height' => $this->settings['ddslick']['ddslick_height'],
'showSelectedHTML' => $this->settings['ddslick']['showSelectedHTML'],
'imagePosition' => $this->settings['ddslick']['imagePosition'],
];
$form['#attributes']['class'][] = $selected_skin === 'custom' ? Html::escape($this->settings['ddslick']['custom_skin']) : $selected_skin;
$form['#attached']['library'][] = 'lang_dropdown/' . $selected_skin;
$form['#attached']['drupalSettings']['lang_dropdown'][$unique_id] = $js_settings;
}
else {
$form['#attached']['drupalSettings']['lang_dropdown']['lang-dropdown-form'] = $js_settings;
}
$flag_position = $this->settings['languageicons']['flag_position'] ? '#suffix' : '#prefix';
$form['lang_dropdown_select'] = [
'#title' => $this
->t('Select your language'),
'#title_display' => 'invisible',
'#type' => 'select',
'#default_value' => $selected_option ? $selected_option : key($options),
'#options' => $options,
'#attributes' => [
'style' => 'width:' . $this->settings['width'] . 'px',
'class' => [
'lang-dropdown-select-element',
],
'data-lang-dropdown-id' => $unique_id,
],
'#attached' => [
'library' => [
'lang_dropdown/lang-dropdown-form',
],
],
];
if (empty($hidden_elements)) {
return [];
}
$form += $hidden_elements;
if ($this->moduleHandler
->moduleExists('languageicons')) {
$form['lang_dropdown_select'][$flag_position] = $selected_option_language_icon;
}
$form['#attributes']['class'][] = 'lang_dropdown_form';
$form['#attributes']['class'][] = 'clearfix';
$form['#attributes']['class'][] = $this->type;
$form['#attributes']['id'] = 'lang_dropdown_form_' . $unique_id;
$form['submit'] = [
'#type' => 'submit',
'#value' => $this
->t('Go'),
'#noscript' => TRUE,
'#prefix' => new FormattableMarkup('<noscript><div>', []),
'#suffix' => new FormattableMarkup('</div></noscript>', []),
];
return $form;
}
public function submitForm(array &$form, FormStateInterface $form_state) {
$language_code = $form_state
->getValue('lang_dropdown_select');
$type = $form_state
->getValue('lang_dropdown_type');
$tohome = $form_state
->getValue('lang_dropdown_tohome');
$language_codes = $this->languageManager
->getLanguages();
if (!array_key_exists($language_code, $language_codes)) {
return;
}
$types = $this->languageManager
->getDefinedLanguageTypesInfo();
if (!array_key_exists($type, $types)) {
return;
}
$route = $this->pathMatcher
->isFrontPage() ? '<front>' : '<current>';
$url = Url::fromRoute($route);
$languages = $this->languageManager
->getLanguageSwitchLinks($type, $url);
$language = $languages->links[$language_code];
$newurl = isset($language['url']) && $tohome == 0 ? $language['url'] : Url::fromRoute('<front>');
if (!isset($language['query'])) {
$language['query'] = $this->requestStack->query
->all();
}
$url = new Url($newurl
->getRouteName(), $newurl
->getRouteParameters(), $language);
$form_state
->setResponse(new TrustedRedirectResponse($url
->toString(), Response::HTTP_SEE_OTHER));
}
}