Commit c889f027 authored by Sam Oltz's avatar Sam Oltz Committed by Dmitry Kiselev
Browse files

Issue #2920119 by pianomansam, _dcre_, Prashant.c, stephenrodrigo@yahoo.com,...

Issue #2920119 by pianomansam, _dcre_, Prashant.c, stephenrodrigo@yahoo.com, bserem, t_d_d, kala4ek, johnpicozzi: Only display language switch block if translation available
parent 61f9d671
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -5,6 +5,9 @@ block.settings.language_dropdown_block:*:
    showall:
      type: boolean
      label: 'Show all enabled languages'
    hide_only_one:
      type: boolean
      label: 'Hide switcher if there is only one translation'
    tohome:
      type: boolean
      label: 'Redirect to home on switch'
+75 −1
Original line number Diff line number Diff line
@@ -17,6 +17,8 @@ use Drupal\Core\Session\AccountProxyInterface;
use Drupal\Core\Form\FormBuilderInterface;
use Drupal\lang_dropdown\Form\LanguageDropdownForm;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Cache\Cache;
use Drupal\Core\TypedData\TranslationStatusInterface;

/**
 * Provides a 'Language dropdown switcher' block.
@@ -127,6 +129,7 @@ class LanguageDropdownBlock extends BlockBase implements ContainerFactoryPluginI
  public function defaultConfiguration() {
    return [
      'showall' => 0,
      'hide_only_one' => 1,
      'tohome' => 0,
      'width' => 165,
      'display' => LANGDROPDOWN_DISPLAY_NATIVE,
@@ -185,6 +188,13 @@ class LanguageDropdownBlock extends BlockBase implements ContainerFactoryPluginI
      '#default_value' => $this->configuration['showall'],
    ];

    $form['lang_dropdown']['hide_only_one'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Hide if only one language is available'),
      '#description' => $this->t('If only a single language is available, go ahead and hide the block'),
      '#default_value' => $this->configuration['hide_only_one'],
    ];

    $form['lang_dropdown']['tohome'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Redirect to home on switch'),
@@ -636,6 +646,7 @@ class LanguageDropdownBlock extends BlockBase implements ContainerFactoryPluginI
    /** @var array[][] $lang_dropdown */
    $lang_dropdown = $form_state->getValue('lang_dropdown');
    $this->configuration['showall'] = $lang_dropdown['showall'];
    $this->configuration['hide_only_one'] = $lang_dropdown['hide_only_one'];
    $this->configuration['tohome'] = $lang_dropdown['tohome'];
    $this->configuration['width'] = $lang_dropdown['width'];
    $this->configuration['display'] = $lang_dropdown['display'];
@@ -710,7 +721,9 @@ class LanguageDropdownBlock extends BlockBase implements ContainerFactoryPluginI
    $languages = $this->languageManager->getLanguageSwitchLinks($type, $url);
    $roles = $this->currentUser->getRoles();

    foreach ($languages->links as $langcode => $link) {
    list($entities, $accessible_translations) = $this->getEntitiesAndTranslations();

    foreach (array_keys($languages->links) as $langcode) {
      $hide_language = TRUE;

      foreach ($roles as $role) {
@@ -720,6 +733,10 @@ class LanguageDropdownBlock extends BlockBase implements ContainerFactoryPluginI
        }
      }

      if ($entities && !$this->configuration['showall'] && !in_array($langcode, $accessible_translations)) {
        $hide_language = TRUE;
      }

      if ($hide_language) {
        unset($languages->links[$langcode]['href']);
        $languages->links[$langcode]['attributes']['class'][] = 'locale-untranslated';
@@ -731,6 +748,10 @@ class LanguageDropdownBlock extends BlockBase implements ContainerFactoryPluginI
      return [];
    }

    if ($this->configuration['hide_only_one'] && count($accessible_translations) === 1) {
      return [];
    }

    $form = $this->formBuilder->getForm(LanguageDropdownForm::class, $languages->links, $type, $this->configuration);

    return [
@@ -739,4 +760,57 @@ class LanguageDropdownBlock extends BlockBase implements ContainerFactoryPluginI
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function getCacheTags() {
    if (!$this->configuration['showall'] || $this->configuration['hide_only_one']) {
      list($entities,) = $this->getEntitiesAndTranslations();
      if (!empty($entities)) {
        $tags = parent::getCacheTags();
        foreach ($entities as $entity) {
          $tags = Cache::mergeTags($tags, $entity->getCacheTags());
        }
        return $tags;
      }
    }

    return parent::getCacheTags();
  }

  /**
   * {@inheritdoc}
   */
  public function getCacheContexts() {
    if ($this->configuration['hide_only_one']) {
      return Cache::mergeContexts(parent::getCacheContexts(), ['route']);
    }
    return parent::getCacheContexts();
  }

  /**
   * Get current route's translatable entities and accessible translations.
   */
  private function getEntitiesAndTranslations() {
    $entities = [];
    $accessible_translations = [];
    if (!$this->configuration['showall']) {
      foreach (\Drupal::routeMatch()->getParameters() as $param) {
        if ($param instanceof TranslationStatusInterface) {
          $entities[] = $param;
          $entity = $param;
          $accessible_translations = array_merge(
            $accessible_translations,
            array_filter(array_keys($entity->getTranslationLanguages()), function ($langcode) use ($entity) {
              $translation = method_exists($entity, 'getTranslation') ? $entity->getTranslation($langcode) : FALSE;
              return $translation && method_exists($translation, 'access') && $translation->access('view');
            })
          );
        }
      }
    }

    return [$entities, $accessible_translations];
  }

}
+4 −2
Original line number Diff line number Diff line
@@ -34,7 +34,7 @@ class LanguageSwitchingTest extends BrowserTestBase {
    parent::setUp();

    // Create and log in user.
    $admin_user = $this->drupalCreateUser([
    $admin_user = $this->createUser([
      'administer blocks',
      'administer languages',
      'access administration pages',
@@ -60,8 +60,10 @@ class LanguageSwitchingTest extends BrowserTestBase {
    $this->drupalPostForm('admin/config/regional/language/detection', $edit, t('Save settings'));

    // Enable the language switching block.
    $this->drupalPlaceBlock('language_dropdown_block:' . LanguageInterface::TYPE_INTERFACE, [
    $this->placeBlock('language_dropdown_block:' . LanguageInterface::TYPE_INTERFACE, [
      'id' => 'test_language_dropdown_block',
      'showall' => 1,
      'hide_only_one' => 0,
    ]);

    // Go to the homepage.