From ebeda1098402cbd6b034b808436fa4929193b167 Mon Sep 17 00:00:00 2001 From: Patrick Fey <14024-feyp@users.noreply.drupalcode.org> Date: Sat, 20 Jul 2024 19:52:38 +0000 Subject: [PATCH] Issue #3458373 by FeyP, lelkneralfaro, dshields: [10.3 Regression] Menu containing language switcher link non-editable --- language_switcher_menu.info.yml | 2 +- language_switcher_menu.services.yml | 1 + src/Form/SettingsForm.php | 8 ++- src/LanguageLinkAccessMenuTreeManipulator.php | 7 +- src/Plugin/Menu/LanguageSwitcherLink.php | 2 +- .../test_language_switcher_menu.info.yml | 5 ++ .../test_language_switcher_menu.module | 20 ++++++ .../Functional/LanguageSwitcherMenuTest.php | 72 ++++++++++++++++--- 8 files changed, 103 insertions(+), 14 deletions(-) create mode 100644 tests/modules/test_language_switcher_menu/test_language_switcher_menu.info.yml create mode 100644 tests/modules/test_language_switcher_menu/test_language_switcher_menu.module diff --git a/language_switcher_menu.info.yml b/language_switcher_menu.info.yml index e942428..c2b613f 100644 --- a/language_switcher_menu.info.yml +++ b/language_switcher_menu.info.yml @@ -4,7 +4,7 @@ description: "Allows you to add language switcher links to a menu." configure: language_switcher_menu.configure type: module -core_version_requirement: ^9 || ^10 +core_version_requirement: ^10.1 php: 7.4 dependencies: diff --git a/language_switcher_menu.services.yml b/language_switcher_menu.services.yml index 1fd2257..ebb4c1d 100644 --- a/language_switcher_menu.services.yml +++ b/language_switcher_menu.services.yml @@ -5,4 +5,5 @@ services: - '@access_manager' - '@current_user' - '@entity_type.manager' + - '@module_handler' - '@path.validator' diff --git a/src/Form/SettingsForm.php b/src/Form/SettingsForm.php index 2b7a8ea..6db2a9a 100644 --- a/src/Form/SettingsForm.php +++ b/src/Form/SettingsForm.php @@ -3,6 +3,7 @@ namespace Drupal\language_switcher_menu\Form; use Drupal\Core\Config\ConfigFactoryInterface; +use Drupal\Core\Config\TypedConfigManagerInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Form\ConfigFormBase; use Drupal\Core\Form\FormStateInterface; @@ -49,6 +50,8 @@ class SettingsForm extends ConfigFormBase { * * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory * The factory for configuration objects. + * @param \Drupal\Core\Config\TypedConfigManagerInterface $typed_config_manager + * The typed config manager. * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager * The entity type manager. * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager @@ -58,8 +61,8 @@ class SettingsForm extends ConfigFormBase { * @param \Drupal\Core\Menu\MenuParentFormSelectorInterface $menu_parent_form_selector * The menu parent form selector. */ - public function __construct(ConfigFactoryInterface $config_factory, EntityTypeManagerInterface $entity_type_manager, LanguageManagerInterface $language_manager, MenuLinkManagerInterface $menu_link_manager, MenuParentFormSelectorInterface $menu_parent_form_selector) { - parent::__construct($config_factory); + public function __construct(ConfigFactoryInterface $config_factory, TypedConfigManagerInterface $typed_config_manager, EntityTypeManagerInterface $entity_type_manager, LanguageManagerInterface $language_manager, MenuLinkManagerInterface $menu_link_manager, MenuParentFormSelectorInterface $menu_parent_form_selector) { + parent::__construct($config_factory, $typed_config_manager); $this->entityTypeManager = $entity_type_manager; $this->languageManager = $language_manager; $this->menuLinkManager = $menu_link_manager; @@ -74,6 +77,7 @@ class SettingsForm extends ConfigFormBase { public static function create(ContainerInterface $container) { return new static( $container->get('config.factory'), + $container->get('config.typed'), $container->get('entity_type.manager'), $container->get('language_manager'), $container->get('plugin.manager.menu.link'), diff --git a/src/LanguageLinkAccessMenuTreeManipulator.php b/src/LanguageLinkAccessMenuTreeManipulator.php index 58e2294..67985ba 100644 --- a/src/LanguageLinkAccessMenuTreeManipulator.php +++ b/src/LanguageLinkAccessMenuTreeManipulator.php @@ -5,6 +5,7 @@ namespace Drupal\language_switcher_menu; use Drupal\Core\Access\AccessManagerInterface; use Drupal\Core\Access\AccessResult; use Drupal\Core\Entity\EntityTypeManagerInterface; +use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Menu\DefaultMenuLinkTreeManipulators; use Drupal\Core\Menu\MenuLinkInterface; use Drupal\Core\Path\PathValidatorInterface; @@ -35,11 +36,13 @@ class LanguageLinkAccessMenuTreeManipulator extends DefaultMenuLinkTreeManipulat * The current user. * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager * The entity type manager. + * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler + * The module handler. * @param \Drupal\Core\Path\PathValidatorInterface $path_validator * The path validator. */ - public function __construct(AccessManagerInterface $access_manager, AccountInterface $account, EntityTypeManagerInterface $entity_type_manager, PathValidatorInterface $path_validator) { - parent::__construct($access_manager, $account, $entity_type_manager); + public function __construct(AccessManagerInterface $access_manager, AccountInterface $account, EntityTypeManagerInterface $entity_type_manager, ModuleHandlerInterface $module_handler, PathValidatorInterface $path_validator) { + parent::__construct($access_manager, $account, $entity_type_manager, $module_handler); $this->pathValidator = $path_validator; } diff --git a/src/Plugin/Menu/LanguageSwitcherLink.php b/src/Plugin/Menu/LanguageSwitcherLink.php index 8c7a46f..746f8d6 100644 --- a/src/Plugin/Menu/LanguageSwitcherLink.php +++ b/src/Plugin/Menu/LanguageSwitcherLink.php @@ -173,7 +173,7 @@ class LanguageSwitcherLink extends MenuLinkDefault { */ public function getRouteName() { $link = $this->getLink(); - return isset($link['url']) ? $link['url']->getRouteName() : ''; + return isset($link['url']) ? $link['url']->getRouteName() : '<nolink>'; } /** diff --git a/tests/modules/test_language_switcher_menu/test_language_switcher_menu.info.yml b/tests/modules/test_language_switcher_menu/test_language_switcher_menu.info.yml new file mode 100644 index 0000000..597733a --- /dev/null +++ b/tests/modules/test_language_switcher_menu/test_language_switcher_menu.info.yml @@ -0,0 +1,5 @@ +name: "Test Language Switcher Menu" +description: "Support testing of Language Switcher Menu." +type: module +package: Testing +core_version_requirement: ^10.1 diff --git a/tests/modules/test_language_switcher_menu/test_language_switcher_menu.module b/tests/modules/test_language_switcher_menu/test_language_switcher_menu.module new file mode 100644 index 0000000..3d79e43 --- /dev/null +++ b/tests/modules/test_language_switcher_menu/test_language_switcher_menu.module @@ -0,0 +1,20 @@ +<?php + +/** + * @file + * Hook implementations by Test Language Switcher Menu module. + */ + +use Drupal\Core\Url; + +/** + * Implements hook_language_switch_links_alter(). + */ +function test_language_switcher_menu_language_switch_links_alter(array &$links, $type, Url $url) { + if (!\Drupal::state()->get('test_language_switcher_menu.remove_current_language_switch_link')) { + return; + } + // Unset language switch link for current language. + $current_language = \Drupal::languageManager()->getCurrentLanguage()->getId(); + unset($links[$current_language]); +} diff --git a/tests/src/Functional/LanguageSwitcherMenuTest.php b/tests/src/Functional/LanguageSwitcherMenuTest.php index 24fa669..5072e75 100644 --- a/tests/src/Functional/LanguageSwitcherMenuTest.php +++ b/tests/src/Functional/LanguageSwitcherMenuTest.php @@ -2,6 +2,7 @@ namespace Drupal\Tests\language_switcher_menu\Functional; +use Drupal\Component\Utility\DeprecationHelper; use Drupal\Core\Url; use Drupal\Tests\BrowserTestBase; @@ -24,6 +25,7 @@ class LanguageSwitcherMenuTest extends BrowserTestBase { 'menu_ui', 'language_switcher_menu', 'menu_test', + 'test_language_switcher_menu', ]; /** @@ -58,6 +60,7 @@ class LanguageSwitcherMenuTest extends BrowserTestBase { ]); $this->users['admin_menu_regular'] = $this->drupalCreateUser([ 'administer menu', + 'view language_switcher_menu links', ]); $this->users['access_content'] = $this->drupalCreateUser([ 'access content', @@ -65,6 +68,9 @@ class LanguageSwitcherMenuTest extends BrowserTestBase { $this->users['view_links'] = $this->drupalCreateUser([ 'view language_switcher_menu links', ]); + + // Initialize state for test language switcher module. + \Drupal::state()->set('test_language_switcher_menu.remove_current_language_switch_link', FALSE); } /** @@ -182,6 +188,42 @@ class LanguageSwitcherMenuTest extends BrowserTestBase { '/fr' => 'Home', ], 'The menu links are correct in a non-standard language.'); + // Assert that main menu management page doesn't show a white page. + $this->drupalLogin($this->users['admin_menu_regular']); + $this->drupalGet('admin/structure/menu/manage/main'); + $this->assertSession()->statusCodeEquals(200); + + // Assert that menu switch links are visible. + $this->assertMenuLinks([ + '/admin/structure/menu/manage/main' => 'English', + '/fr/admin/structure/menu/manage/main' => 'French', + '/' => 'Home', + ], 'Both language links are shown.'); + + // Enable removal of current language switch link in test module. + \Drupal::state()->set('test_language_switcher_menu.remove_current_language_switch_link', TRUE); + + // Assert that main menu management page still doesn't show a white page. + $this->drupalGet('admin/structure/menu/manage/main'); + $this->assertSession()->statusCodeEquals(200); + + // Assert that menu switch link in current language has been removed. + $this->assertMenuLinks([ + '/fr/admin/structure/menu/manage/main' => 'French', + '/' => 'Home', + ], 'The language link for the current language is not shown.'); + + // Disable removal of current language switch link in test module. + \Drupal::state()->set('test_language_switcher_menu.remove_current_language_switch_link', FALSE); + + // Assert that menu switch links are visible. + $this->drupalGet('admin/structure/menu/manage/main'); + $this->assertMenuLinks([ + '/admin/structure/menu/manage/main' => 'English', + '/fr/admin/structure/menu/manage/main' => 'French', + '/' => 'Home', + ], 'Both language links are visible in the menu.'); + // Reconfigure to disable. $this->drupalLogin($this->users['admin_user']); $edit = [ @@ -229,17 +271,31 @@ class LanguageSwitcherMenuTest extends BrowserTestBase { $this->assertSession()->pageTextNotContains('Error message'); $this->assertSession()->pageTextNotContains("The path '<current>' is inaccessible."); $this->assertSession()->pageTextContains('The menu link has been saved.'); - $this->assertMenuLinks([ - '/' => 'Home', - '/admin/structure/menu/item/1/edit' => 'link_current', - ], 'Custom link targeting <current> is visible in menu with permission to link to any page.'); + DeprecationHelper::backwardsCompatibleCall( + currentVersion: \Drupal::VERSION, + deprecatedVersion: '10.3', + currentCallable: fn() => $this->assertMenuLinks([ + '/' => 'Home', + ], 'Custom link targeting <current> is not visible in menu with permission to link to any page.'), + deprecatedCallable: fn() => $this->assertMenuLinks([ + '/' => 'Home', + '/admin/structure/menu/item/1/edit' => 'link_current', + ], 'Custom link targeting <current> is visible in menu with permission to link to any page.'), + ); $this->drupalGet(''); $this->assertSession()->statusCodeEquals(200); - $this->assertMenuLinks([ - '/' => 'Home', - '/user/' . $this->users['admin_menu_any']->id() => 'link_current', - ], 'Custom link targeting <current> is visible in menu with permission to link to any page.'); + DeprecationHelper::backwardsCompatibleCall( + currentVersion: \Drupal::VERSION, + deprecatedVersion: '10.3', + currentCallable: fn() => $this->assertMenuLinks([ + '/' => 'Home', + ], 'Custom link targeting <current> is not visible in menu with permission to link to any page.'), + deprecatedCallable: fn() => $this->assertMenuLinks([ + '/' => 'Home', + '/user/' . $this->users['admin_menu_any']->id() => 'link_current', + ], 'Custom link targeting <current> is visible in menu with permission to link to any page.'), + ); $this->drupalLogin($this->users['view_links']); $this->assertMenuLinks([ -- GitLab