diff --git a/facets.module b/facets.module index 40b6366..82fe6b6 100644 --- a/facets.module +++ b/facets.module @@ -7,6 +7,7 @@ use Drupal\Component\Utility\Html; use Drupal\Core\Breadcrumb\Breadcrumb; +use Drupal\Core\Language\LanguageInterface; use Drupal\Core\Link; use Drupal\Core\Routing\RouteMatchInterface; use Drupal\facets\Entity\Facet; @@ -345,3 +346,58 @@ function facets_system_breadcrumb_alter(Breadcrumb &$breadcrumb, RouteMatchInter } } } + +/** + * Implements hook_language_switch_links_alter + */ +function facets_language_switch_links_alter(array &$links, $type, \Drupal\Core\Url $url) { + /** @var \Drupal\Core\Language\LanguageManagerInterface $languageManager */ + $languageManager = \Drupal::languageManager(); + $language_interface = $languageManager->getCurrentLanguage(); + /** @var \Drupal\facets\FacetInterface[] $allFacets */ + $allFacets = \Drupal::entityTypeManager() + ->getStorage('facets_facet') + ->loadMultiple(); + + /** @var \Drupal\facets\UrlProcessor\UrlProcessorPluginManager $urlProcessorManager */ + $urlProcessorManager = \Drupal::service('plugin.manager.facets.url_processor'); + + foreach ($links as &$link) { + if ($link['language']->getId() === $language_interface->getId()) { + continue; + } + + foreach ($allFacets as $facet) { + if (!isset($link['query'][$facet->getFacetSourceConfig()->getFilterKey()])) { + continue; + } + + $configName = 'facets.facet.' . $facet->id(); + $untranslatedAlias = $languageManager->getLanguageConfigOverride($language_interface->getId(), $configName)->get('url_alias'); + $translatedAlias = $languageManager->getLanguageConfigOverride($link['language']->getId(), $configName)->get('url_alias'); + + if ($translatedAlias === NULL) { + $translatedAlias = \Drupal::config($configName)->getOriginal('url_alias', FALSE); + } + if ($untranslatedAlias === NULL) { + $untranslatedAlias = \Drupal::config($configName)->getOriginal('url_alias', FALSE); + } + + /** @var \Drupal\facets\UrlProcessor\UrlProcessorInterface $urlProcessor */ + $urlProcessor = $urlProcessorManager + ->createInstance($facet + ->getFacetSourceConfig() + ->getUrlProcessorName(), ['facet' => $facet] + ); + + foreach ($link['query'][$facet->getFacetSourceConfig()->getFilterKey()] as &$filters) { + $separator = $urlProcessor->getSeparator(); + $filters = preg_replace( + '/(' . $untranslatedAlias . ")$separator/", + $translatedAlias . $separator, + $filters + ); + } + } + } +} diff --git a/tests/src/Functional/LanguageIntegrationTest.php b/tests/src/Functional/LanguageIntegrationTest.php index 920f698..ad1de37 100644 --- a/tests/src/Functional/LanguageIntegrationTest.php +++ b/tests/src/Functional/LanguageIntegrationTest.php @@ -2,6 +2,7 @@ namespace Drupal\Tests\facets\Functional; +use Drupal\Core\Language\LanguageInterface; use Drupal\language\Entity\ConfigurableLanguage; /** @@ -42,7 +43,18 @@ public function setUp() { ]); $this->drupalLogin($this->adminUser); - ConfigurableLanguage::create(['id' => 'xx-lolspeak'])->save(); + ConfigurableLanguage::create([ + 'id' => 'xx-lolspeak', + 'label' => 'Lolspeak', + ])->save(); + ConfigurableLanguage::create([ + 'id' => 'nl', + 'label' => 'Dutch', + ])->save(); + ConfigurableLanguage::create([ + 'id' => 'es', + 'label' => 'Spanish', + ])->save(); $this->setUpExampleStructure(); $this->insertExampleContent(); @@ -137,20 +149,74 @@ public function testUrlAliasTranslation() { $this->clickLink('item'); // Check that the language code is still in the url. - $this->assertTrue(strpos($this->getUrl(), 'xx-lolspeak/'), 'Found the language code in the url'); - $this->assertTrue(strpos($this->getUrl(), 'barn_owl'), 'Found the facet in the url'); + $this->assertTrue((bool) strpos($this->getUrl(), 'xx-lolspeak/'), 'Found the language code in the url'); + $this->assertTrue((bool) strpos($this->getUrl(), 'barn_owl'), 'Found the facet in the url'); // Translate the facet. $this->drupalGet('admin/config/search/facets/' . $facet_id . '/edit/translate/xx-lolspeak/add'); $this->drupalPostForm(NULL, ['translation[config_names][facets.facet.barn_owl][url_alias]' => 'tyto_alba'], 'Save translation'); + $this->drupalGet('admin/config/search/facets/' . $facet_id . '/edit/translate/nl/add'); + $this->drupalPostForm(NULL, ['translation[config_names][facets.facet.barn_owl][url_alias]' => 'uil'], 'Save translation'); + $this->drupalGet('admin/config/search/facets/' . $facet_id . '/edit/translate/es/add'); + $this->drupalPostForm(NULL, ['translation[config_names][facets.facet.barn_owl][url_alias]' => 'buho'], 'Save translation'); // Go to the search view again and check that we now have the translated // facet in the url. $this->drupalGet('xx-lolspeak/search-api-test-fulltext'); $this->assertFacetBlocksAppear(); $this->clickLink('item'); - $this->assertTrue(strpos($this->getUrl(), 'xx-lolspeak/'), 'Found the language code in the url'); - $this->assertTrue(strpos($this->getUrl(), 'tyto_alba'), 'Found the facet in the url'); + $this->assertTrue((bool) strpos($this->getUrl(), 'xx-lolspeak/'), 'Found the language code in the url'); + $this->assertTrue((bool) strpos($this->getUrl(), 'tyto_alba'), 'Found the facet in the url'); + + \Drupal::service('module_installer')->install(['locale']); + $block = $this->drupalPlaceBlock('language_block:' . LanguageInterface::TYPE_INTERFACE, [ + 'id' => 'test_language_block', + ]); + + $this->drupalGet('xx-lolspeak/search-api-test-fulltext'); + $this->assertSession()->pageTextContains($block->label()); + $this->clickLink('item'); + + /** @var \Behat\Mink\Element\NodeElement[] $links */ + $links = $this->findFacetLink('item'); + $this->assertEquals('is-active', $links[0]->getParent()->getAttribute('class')); + + $this->clickLink('English'); + /** @var \Behat\Mink\Element\NodeElement[] $links */ + $links = $this->findFacetLink('item'); + $this->assertEquals('is-active', $links[0]->getParent()->getAttribute('class')); + $this->assertFalse((bool) strpos($this->getUrl(), 'xx-lolspeak/'), 'Found the language code in the url'); + $this->assertFalse((bool) strpos($this->getUrl(), 'tyto_alba'), 'Found the facet in the url'); + $this->assertTrue((bool) strpos($this->getUrl(), 'barn_owl'), 'Found the facet in the url'); + + $this->clickLink('Lolspeak'); + /** @var \Behat\Mink\Element\NodeElement[] $links */ + $links = $this->findFacetLink('item'); + $this->assertEquals('is-active', $links[0]->getParent()->getAttribute('class')); + $this->assertTrue((bool) strpos($this->getUrl(), 'xx-lolspeak/'), 'Found the language code in the url'); + $this->assertTrue((bool) strpos($this->getUrl(), 'tyto_alba'), 'Found the facet in the url'); + $this->assertFalse((bool) strpos($this->getUrl(), 'barn_owl'), 'Found the facet in the url'); + + $this->clickLink('Dutch'); + /** @var \Behat\Mink\Element\NodeElement[] $links */ + $links = $this->findFacetLink('item'); + $this->assertEquals('is-active', $links[0]->getParent()->getAttribute('class')); + $this->assertTrue((bool) strpos($this->getUrl(), 'nl/'), 'Found the language code in the url'); + $this->assertTrue((bool) strpos($this->getUrl(), 'uil'), 'Found the facet in the url'); + + $this->clickLink('Spanish'); + /** @var \Behat\Mink\Element\NodeElement[] $links */ + $links = $this->findFacetLink('item'); + $this->assertEquals('is-active', $links[0]->getParent()->getAttribute('class')); + $this->assertTrue((bool) strpos($this->getUrl(), 'es/'), 'Found the language code in the url'); + $this->assertTrue((bool) strpos($this->getUrl(), 'buho'), 'Found the facet in the url'); + + $this->clickLink('English'); + /** @var \Behat\Mink\Element\NodeElement[] $links */ + $links = $this->findFacetLink('item'); + $this->assertEquals('is-active', $links[0]->getParent()->getAttribute('class')); + $this->assertTrue((bool) strpos($this->getUrl(), 'barn_owl'), 'Found the facet in the url'); + } /**