diff --git a/core/modules/menu_ui/menu_ui.module b/core/modules/menu_ui/menu_ui.module index f32608c..8a5cb9e 100644 --- a/core/modules/menu_ui/menu_ui.module +++ b/core/modules/menu_ui/menu_ui.module @@ -139,12 +139,20 @@ function _menu_ui_node_save(NodeInterface $node, array $values) { /** @var \Drupal\menu_link_content\MenuLinkContentInterface $entity */ if (!empty($values['entity_id'])) { $entity = MenuLinkContent::load($values['entity_id']); + if ($entity->isTranslatable()) { + if (!$entity->hasTranslation($node->language()->getId())) { + $entity = $entity->addTranslation($node->language()->getId(), $entity->toArray()); + } + else { + $entity = $entity->getTranslation($node->language()->getId()); + } + } } else { // Create a new menu_link_content entity. $entity = entity_create('menu_link_content', array( 'link' => ['uri' => 'entity:node/' . $node->id()], - 'langcode' => $node->getUntranslated()->language()->getId(), + 'langcode' => $node->language()->getId(), )); $entity->enabled->value = 1; } @@ -216,6 +224,7 @@ function menu_ui_get_menu_link_defaults(NodeInterface $node) { } if ($id) { $menu_link = MenuLinkContent::load($id); + $menu_link = \Drupal::service('entity.repository')->getTranslationFromContext($menu_link); $defaults = array( 'entity_id' => $menu_link->id(), 'id' => $menu_link->getPluginId(), diff --git a/core/modules/menu_ui/src/Tests/MenuNodeTest.php b/core/modules/menu_ui/src/Tests/MenuNodeTest.php index b57cc9d..9521836 100644 --- a/core/modules/menu_ui/src/Tests/MenuNodeTest.php +++ b/core/modules/menu_ui/src/Tests/MenuNodeTest.php @@ -8,7 +8,9 @@ namespace Drupal\menu_ui\Tests; use Drupal\simpletest\WebTestBase; +use Drupal\language\Entity\ConfigurableLanguage; use Drupal\menu_link_content\Entity\MenuLinkContent; +use Drupal\node\Entity\Node; /** * Add, edit, and delete a node with menu link. @@ -29,7 +31,7 @@ class MenuNodeTest extends WebTestBase { * * @var array */ - public static $modules = array('menu_ui', 'test_page_test', 'node', 'block'); + public static $modules = array('menu_ui', 'test_page_test', 'node', 'block', 'locale', 'language', 'content_translation'); protected function setUp() { parent::setUp(); @@ -46,6 +48,10 @@ protected function setUp() { 'create page content', 'edit any page content', 'delete any page content', + 'create content translations', + 'update content translations', + 'delete content translations', + 'translate any entity', )); $this->drupalLogin($this->editor); } @@ -235,4 +241,105 @@ function testMenuNodeFormWidget() { // Assert that unallowed Administration menu is not available in options. $this->assertNoOption('edit-menu-menu-parent', 'admin:'); } + + /** + * Testing correct loading and saving of menu links via node form widget in a multilingual environment. + */ + function testMultilingualMenuNodeFormWidget() { + // Setup languages. + $langcodes = array('de'); + foreach ($langcodes as $langcode) { + ConfigurableLanguage::createFromLangcode($langcode)->save(); + } + array_unshift($langcodes, \Drupal::languageManager()->getDefaultLanguage()->getId()); + + $config = \Drupal::service('config.factory')->getEditable('language.negotiation'); + // Ensure path prefix is used to determine the language. + $config->set('url.source', 'path_prefix'); + // Ensure that there's a path prefix set for english as well. + $config->set('url.prefixes.' . $langcodes[0], $langcodes[0]); + $config->save(); + + $this->rebuildContainer(); + + $languages = array(); + foreach ($langcodes as $langcode) { + $languages[$langcode] = ConfigurableLanguage::load($langcode); + } + + // Use a UI form submission to make the node type and menu link content entity translatable. + $this->drupalLogout(); + $this->drupalLogin($this->rootUser); + $edit = array( + 'entity_types[node]' => TRUE, + 'entity_types[menu_link_content]' => TRUE, + 'settings[node][page][settings][language][language_alterable]' => TRUE, + 'settings[node][page][translatable]' => TRUE, + 'settings[node][page][fields][title]' => TRUE, + 'settings[menu_link_content][menu_link_content][translatable]' => TRUE, + ); + $this->drupalPostForm('admin/config/regional/content-language', $edit, t('Save configuration')); + + // Log out and back in as normal user. + $this->drupalLogout(); + $this->drupalLogin($this->editor); + + // Create a node. + $node_title = $this->randomMachineName(8); + $node = Node::create([ + 'type' => 'page', + 'title' => $node_title, + 'body' => $this->randomMachineName(16), + 'uid' => $this->editor->id(), + 'status' => 1, + 'langcode' => $langcodes[0], + ]); + $node->save(); + + // Create translation. + $translated_node_title = $this->randomMachineName(8); + $node->addTranslation($langcodes[1], ['title' => $translated_node_title, 'body' => $this->randomMachineName(16), 'status' => 1]); + $node->save(); + + // Edit the node and create a menu link. + $edit = array( + 'menu[enabled]' => 1, + 'menu[title]' => $node_title, + 'menu[weight]' => 17, + ); + $options = array('language' => $languages[$langcodes[0]]); + $url = $node->toUrl('edit-form', $options); + $this->drupalPostForm($url, $edit, t('Save') . ' ' . t('(this translation)')); + + // Edit the node in a different language and translate the menu link. + $edit = array( + 'menu[enabled]' => 1, + 'menu[title]' => $translated_node_title, + 'menu[weight]' => 17, + ); + $options = array('language' => $languages[$langcodes[1]]); + $url = $node->toUrl('edit-form', $options); + $this->drupalPostForm($url, $edit, t('Save') . ' ' . t('(this translation)')); + + // Assert that the original link exists in the frontend. + $this->drupalGet('node/' . $node->id(), array('language' => $languages[$langcodes[0]])); + $this->assertLink($node_title); + + // Assert that the translated link exists in the frontend. + $this->drupalGet('node/' . $node->id(), array('language' => $languages[$langcodes[1]])); + $this->assertLink($translated_node_title); + + // Revisit the edit page in original language, check the loaded menu item title and save. + $options = array('language' => $languages[$langcodes[0]]); + $url = $node->toUrl('edit-form', $options); + $this->drupalGet($url); + $this->assertFieldById('edit-menu-title', $node_title); + $this->drupalPostForm(NULL, [], t('Save') . ' ' . t('(this translation)')); + + // Revisit the edit page of the translation and check the loaded menu item title. + $options = array('language' => $languages[$langcodes[1]]); + $url = $node->toUrl('edit-form', $options); + $this->drupalGet($url); + $this->assertFieldById('edit-menu-title', $translated_node_title); + } }