Verified Commit 91acedad authored by Alex Pott's avatar Alex Pott
Browse files

Issue #2904899 by FeyP, idflood, smustgrave, alexpott: Invalid argument...

Issue #2904899 by FeyP, idflood, smustgrave, alexpott: Invalid argument exception when changing language of node with menu link to und or zxx

(cherry picked from commit ff109038)
parent f807ceda
Loading
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -93,7 +93,7 @@ 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->isTranslatable() && $node->isTranslatable()) {
      if (!$entity->hasTranslation($node->language()->getId())) {
        $entity = $entity->addTranslation($node->language()->getId(), $entity->toArray());
      }
@@ -101,6 +101,11 @@ function _menu_ui_node_save(NodeInterface $node, array $values) {
        $entity = $entity->getTranslation($node->language()->getId());
      }
    }
    else {
      // Ensure the entity matches the node language.
      $entity = $entity->getUntranslated();
      $entity->set($entity->getEntityType()->getKey('langcode'), $node->language()->getId());
    }
  }
  else {
    // Create a new menu_link_content entity.
+183 −0
Original line number Diff line number Diff line
<?php

namespace Drupal\Tests\menu_ui\Functional;

use Drupal\Core\Language\LanguageInterface;
use Drupal\Tests\BrowserTestBase;
use Drupal\language\Entity\ConfigurableLanguage;

/**
 * Tests Menu UI and Content Translation integration for content entities.
 *
 * @group menu_ui
 */
class MenuUiContentTranslationTest extends BrowserTestBase {

  /**
   * {@inheritdoc}
   */
  protected $defaultTheme = 'stark';

  /**
   * Modules to install.
   *
   * @var array
   */
  protected static $modules = [
    'block',
    'language',
    'content_translation',
    'menu_ui',
    'node',
  ];

  /**
   * {@inheritdoc}
   */
  protected function setUp(): void {
    parent::setUp();

    // Place menu block and local tasks block.
    $this->drupalPlaceBlock('system_menu_block:main');
    $this->drupalPlaceBlock('local_tasks_block');

    // Create a 'page' content type.
    $this->drupalCreateContentType([
      'type' => 'page',
      'name' => 'Basic page',
      'display_submitted' => FALSE,
    ]);

    // Add a second language.
    ConfigurableLanguage::createFromLangcode('de')->save();

    // Create an account and login.
    $user = $this->drupalCreateUser([
      'administer site configuration',
      'administer nodes',
      'create page content',
      'edit any page content',
      'delete any page content',
      'administer content translation',
      'translate any entity',
      'create content translations',
      'administer languages',
      'administer content types',
      'administer menu',
    ]);
    $this->drupalLogin($user);

    // Enable translation for page nodes and menu link content.
    $edit = [
      'entity_types[node]' => TRUE,
      'settings[node][page][translatable]' => TRUE,
      'settings[node][page][settings][language][language_alterable]' => TRUE,
      'entity_types[menu_link_content]' => TRUE,
      'settings[menu_link_content][menu_link_content][translatable]' => TRUE,
      'settings[menu_link_content][menu_link_content][settings][language][language_alterable]' => TRUE,
    ];
    $this->drupalGet('admin/config/regional/content-language');
    $this->assertSession()->statusCodeEquals(200);
    $this->submitForm($edit, 'Save configuration');
    $this->assertSession()->statusCodeEquals(200);
  }

  /**
   * Gets a content entity object by title.
   *
   * @param string $entity_type_id
   *   Id of content entity type of content entity to load.
   * @param string $title
   *   Title of content entity to load.
   *
   * @return \Drupal\Core\Entity\ContentEntityInterface
   *   First found content entity with given title.
   */
  protected function getContentEntityByTitle($entity_type_id, $title) {
    $entity_type_manager = $this->container->get('entity_type.manager');
    $storage = $entity_type_manager->getStorage($entity_type_id);
    $storage->resetCache();
    $entities = $storage->loadByProperties([
      'title' => $title,
    ]);
    return reset($entities);
  }

  /**
   * Provides test data sets for testChangeContentToPseudoLanguage().
   *
   * @return array
   *   Data sets to test keyed by data set label.
   */
  public function provideChangeContentToPseudoLanguageData() {
    return [
      'und' => ['langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED],
      'zxx' => ['langcode' => LanguageInterface::LANGCODE_NOT_APPLICABLE],
    ];
  }

  /**
   * Tests changing content with menu link from language to pseudo language.
   *
   * @param string $langcode
   *   Language code of pseudo-language to change content language to.
   *   Either \Drupal\Core\LanguageInterface::LANGCODE_NOT_SPECIFIED or
   *   \Drupal\Core\LanguageInterface::LANGCODE_NOT_APPLICABLE.
   *
   * @dataProvider provideChangeContentToPseudoLanguageData
   */
  public function testChangeContentToPseudoLanguage($langcode) {
    $node_title = 'Test node';
    $menu_link_title_en = 'Test menu link EN';
    $menu_link_title_pseudo = 'Test menu link PSEUDO';

    // Create a page node in English.
    $this->drupalGet('node/add/page');
    $this->assertSession()->statusCodeEquals(200);
    $edit = [
      'title[0][value]' => $node_title,
      'menu[enabled]' => 1,
      'menu[title]' => $menu_link_title_en,
    ];
    $this->submitForm($edit, 'Save');
    $this->assertSession()->statusCodeEquals(200);

    // Assert that node exists and node language is English.
    $node = $this->getContentEntityByTitle('node', $node_title);
    $this->assertTrue(is_object($node));
    $this->assertTrue($node->language()->getId() == 'en');

    // Assert that menu link exists and menu link language is English.
    $menu_link = $this->getContentEntityByTitle('menu_link_content', $menu_link_title_en);
    $this->assertTrue(is_object($menu_link));
    $this->assertTrue($menu_link->language()->getId() == 'en');
    $this->assertTrue($menu_link->hasTranslation('en'));

    // Assert that menu link is visible with initial title.
    $this->assertSession()->linkExists($menu_link_title_en);

    // Change language of page node and title of its menu link.
    $this->clickLink('Edit');
    $edit = [
      'langcode[0][value]' => $langcode,
      'menu[title]' => $menu_link_title_pseudo,
    ];
    $this->submitForm($edit, 'Save');
    $this->assertSession()->statusCodeEquals(200);

    // Assert that node exists and node language is target language.
    $node = $this->getContentEntityByTitle('node', $node_title);
    $this->assertTrue(is_object($node));
    $this->assertTrue($node->language()->getId() == $langcode);

    // Assert that menu link exists and menu link language is target language.
    $menu_link = $this->getContentEntityByTitle('menu_link_content', $menu_link_title_pseudo);
    $this->assertTrue(is_object($menu_link));
    $this->assertTrue($menu_link->language()->getId() == $langcode);
    $this->assertFalse($menu_link->hasTranslation('en'));

    // Assert that menu link is visible with updated title.
    $this->assertSession()->linkExists($menu_link_title_pseudo);
  }

}