diff --git a/core/modules/menu/lib/Drupal/menu/MenuFormController.php b/core/modules/menu/lib/Drupal/menu/MenuFormController.php index 4eeab27..35832e8 100644 --- a/core/modules/menu/lib/Drupal/menu/MenuFormController.php +++ b/core/modules/menu/lib/Drupal/menu/MenuFormController.php @@ -8,6 +8,7 @@ namespace Drupal\menu; use Drupal\Core\Entity\EntityFormController; +use Drupal\Core\Language\Language; /** * Base form controller for menu edit forms. @@ -18,7 +19,6 @@ class MenuFormController extends EntityFormController { * Overrides Drupal\Core\Entity\EntityFormController::form(). */ public function form(array $form, array &$form_state) { - $form = parent::form($form, $form_state); $menu = $this->entity; $system_menus = menu_list_system_menus(); $form_state['menu'] = &$menu; @@ -35,6 +35,7 @@ public function form(array $form, array &$form_state) { '#default_value' => $menu->id(), '#maxlength' => MENU_MAX_MENU_NAME_LENGTH_UI, '#description' => t('A unique name to construct the URL for the menu. It must only contain lowercase letters, numbers and hyphens.'), + '#field_prefix' => 'menu-', '#machine_name' => array( 'exists' => 'menu_edit_menu_name_exists', 'source' => array('label'), @@ -63,7 +64,32 @@ public function form(array $form, array &$form_state) { $form['links'] = menu_overview_form($form['links'], $form_state); } - return $form; + // $form['langcode'] is not wrapped in a check if language module exists + // check because the language_select form element works also without the + // language module being installed. + // http://drupal.org/node/1749954 documents the new element. + $form['langcode'] = array( + '#type' => 'language_select', + '#title' => t('Menu language'), + '#languages' => Language::STATE_ALL, + '#default_value' => $menu->langcode, + ); + if (\Drupal::moduleHandler()->moduleExists('language')) { + $form['default_menu_links_language'] = array( + '#type' => 'details', + '#title' => t('Menu links language'), + ); + $form['default_menu_links_language']['default_language'] = array( + '#type' => 'language_configuration', + '#entity_information' => array( + 'entity_type' => 'menu_link', + 'bundle' => $menu->id(), + ), + '#default_value' => language_get_default_configuration('menu_link', $menu->id()), + ); + } + + return parent::form($form, $form_state); } /** @@ -76,10 +102,38 @@ protected function actions(array $form, array &$form_state) { $system_menus = menu_list_system_menus(); $actions['delete']['#access'] = !$menu->isNew() && !isset($system_menus[$menu->id()]); + // Add the language configuration submit handler. This is needed because the + // submit button has custom submit handlers. + if (\Drupal::moduleHandler()->moduleExists('language')) { + array_unshift($actions['submit']['#submit'],'language_configuration_element_submit'); + array_unshift($actions['submit']['#submit'], array($this, 'languageConfigurationSubmit')); + } + // We cannot leverage the regular submit handler definition because we have + // button-specific ones here. Hence we need to explicitly set it for the + // submit action, otherwise it would be ignored. + if (\Drupal::moduleHandler()->moduleExists('translation_entity')) { + array_unshift($actions['submit']['#submit'], 'translation_entity_language_configuration_element_submit'); + } return $actions; } /** + * Submit handler to update the bundle for the default language configuration. + */ + public function languageConfigurationSubmit(array &$form, array &$form_state) { + $menu = $this->entity; + // Delete the old language settings for the menu, if the machine name + // is changed. + if ($menu && $menu->id() && $menu->id() != $form_state['values']['id']) { + language_clear_default_configuration('menu_item', $menu->id()); + } + // Since the machine name is not known yet, and it can be changed anytime, + // we have to also update the bundle property for the default language + // configuration in order to have the correct bundle value. + $form_state['language']['default_language']['bundle'] = $form_state['values']['id']; + } + + /** * Overrides Drupal\Core\Entity\EntityFormController::save(). */ public function save(array $form, array &$form_state) { @@ -90,11 +144,6 @@ public function save(array $form, array &$form_state) { menu_overview_form_submit($form, $form_state); } - if ($menu->isNew()) { - // Add 'menu-' to the menu name to help avoid name-space conflicts. - $menu->set('id', 'menu-' . $menu->id()); - } - $status = $menu->save(); $uri = $menu->uri(); diff --git a/core/modules/menu/lib/Drupal/menu/Tests/MenuLanguageTest.php b/core/modules/menu/lib/Drupal/menu/Tests/MenuLanguageTest.php new file mode 100644 index 0000000..c274d99 --- /dev/null +++ b/core/modules/menu/lib/Drupal/menu/Tests/MenuLanguageTest.php @@ -0,0 +1,169 @@ + 'Menu language', + 'description' => 'Create menu in non-English language and menu link item.', + 'group' => 'Menu' + ); + } + + function setUp() { + parent::setUp(); + + // Create user. + $this->admin_user = $this->drupalCreateUser(array('access administration pages', 'administer menu')); + $this->drupalLogin($this->admin_user); + + // Add some custom languages. + foreach (array('aa', 'bb', 'cc') as $language_code) { + $language = new Language(array( + 'langcode' => $language_code, + 'name' => $this->randomName(), + )); + language_save($language); + } + } + + /** + * Tests menu language settings. + */ + function testMenuLanguage() { + // Create a test menu to decouple looking for Translate operations + // link so this does not test more than necessary. + // Lowercase the machine name. Find the issue that is supposed to be making + // randomMachineName(). + $menu_name = drupal_strtolower($this->randomName(16)); + $label = $this->randomName(16); + $edit = array( + 'id' => $menu_name, + 'description' => '', + 'label' => $label, + 'langcode' => 'aa', + 'default_language[langcode]' => 'bb', + 'default_language[language_show]' => TRUE, + ); + $this->drupalPost('admin/structure/menu/add', $edit, t('Save')); + // Assert the new menu is in that language and the default menu link info. + $this->assertOptionSelected('edit-langcode', $edit['langcode'], 'The menu language was correctly selected.'); + $this->assertOptionSelected('edit-default-language-langcode', $edit['default_language[langcode]'], 'The menu link default language was correctly selected.'); + $this->assertFieldChecked('edit-default-language-language-show'); + + // Check that the language settings were saved. + $language_settings = language_get_default_configuration('menu_link', $menu_name); + $this->assertEqual($language_settings['langcode'], 'bb'); + $this->assertEqual($language_settings['language_show'], TRUE); + + // Start testing menu link things. + // Just link to front page. + $sample_link_path=''; + + // Add a menu link. + $title = $this->randomName(16); + $edit = array( + 'link_title' => $title, + 'link_path' => $sample_link_path, + ); + $this->drupalPost('admin/structure/menu/manage/' . $menu_name . '/add', $edit, t('Save')); + // Check the link was added with the correct language. + $menu_links = entity_load_multiple_by_properties('menu_link', array('link_title' => $title)); + $menu_link = reset($menu_links); + $this->assertTrue('Menu link was found in database.'); + $this->assertMenuLink($menu_link->id(), array('menu_name' => $menu_name, 'link_path' => $sample_link_path, 'langcode' => 'bb')); + + // Edit menu link default, changing it to cc. + $edit = array( + 'default_language[langcode]' => 'cc', + ); + $this->drupalPost('admin/structure/menu/manage/' . $menu_name, $edit, t('Save')); + + // Check cc is the menu link default. + $this->assertOptionSelected('edit-default-language-langcode', $edit['default_language[langcode]'], 'The menu link default language was correctly selected.'); + + // Add a menu link. + $title = $this->randomName(16); + $edit = array( + 'link_title' => $title, + 'link_path' => $sample_link_path, + ); + $this->drupalPost('admin/structure/menu/manage/' . $menu_name . '/add', $edit, t('Save')); + // Check the link was added with the correct language. + $menu_links = entity_load_multiple_by_properties('menu_link', array('link_title' => $title)); + $menu_link = reset($menu_links); + $this->assertTrue('Menu link was found in database.'); + $this->assertMenuLink($menu_link->id(), array('menu_name' => $menu_name, 'link_path' => $sample_link_path, 'langcode' => 'cc')); + + // Edit menu to change hide language select on menu link item add. + $edit = array( + 'default_language[language_show]' => FALSE, + ); + $this->drupalPost('admin/structure/menu/manage/' . $menu_name, $edit, t('Save')); + $this->assertNoFieldChecked('edit-default-language-language-show'); + + // Check that the language settings were saved. + $language_settings = language_get_default_configuration('menu_link', $menu_name); + $this->assertEqual($language_settings['langcode'], 'cc'); + $this->assertEqual($language_settings['language_show'], FALSE); + + // Check that the language selector is not available on menu link add page. + $this->drupalGet('admin/structure/menu/manage/' . $menu_name . '/add'); + $this->assertNoField('edit-langcode', 'The language selector field was hidden the page'); + + // Delete custom menu. + // @todo Make an issue to add tests for deleting, and verifying config is + // also removed. + // Check that the language settings are not still there. + // $language_settings = language_get_default_configuration('taxonomy_term', $edit['vid']); + // $this->assertEqual($language_settings['langcode'], 'bb'); + } + + /** + * Gets a menu item from the database and compare it to the specified array. + * + * @param int $mlid + * Menu item id. + * @param array $expected_item + * Array containing properties to verify. + * + * @see \Drupal\menu\Tests\MenuTest::assertMenuLink() + */ + function assertMenuLink($mlid, array $expected_item) { + // Retrieve menu link. + $item = entity_load('menu_link', $mlid); + $options = $item->options; + if (!empty($options['query'])) { + $item['link_path'] .= '?' . drupal_http_build_query($options['query']); + } + if (!empty($options['fragment'])) { + $item['link_path'] .= '#' . $options['fragment']; + } + foreach ($expected_item as $key => $value) { + $this->assertEqual($item[$key], $value, format_string('Parameter %key had expected value.', array('%key' => $key))); + } + } + +} diff --git a/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkFormController.php b/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkFormController.php index 9aa76d4..974ea30 100644 --- a/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkFormController.php +++ b/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkFormController.php @@ -156,11 +156,28 @@ public function form(array $form, array &$form_state) { '#description' => t('Optional. In the menu, the heavier links will sink and the lighter links will be positioned nearer the top.'), ); + // Get the default langcode and show language select value. + // @todo Make this work with bundle instead of menu_name. Uses menu_name + // right now to get around ->bundle being 'tools' for all new menu items. + // http://drupal.org/node/2014617 + $language_configuration = \Drupal::moduleHandler()->invoke('language', 'get_default_configuration', array('menu_link', $menu_link->menu_name)); + + if ($menu_link->isNew()) { + // Adding a new menu link, use the default from language settings config. + // If no default for menu links, default to the language of the menu. + $default_langcode = (!is_null($language_configuration['langcode']) ? $language_configuration['langcode'] : $menu->langcode); + } + else { + // Editing an already existing menu link, so use it's saved language. + $default_langcode = $menu_link->langcode; + } + $form['langcode'] = array( '#type' => 'language_select', '#title' => t('Language'), '#languages' => Language::STATE_ALL, - '#default_value' => $menu_link->langcode, + '#default_value' => $default_langcode, + '#access' => !is_null($language_configuration['language_show']) && $language_configuration['language_show'], ); return parent::form($form, $form_state, $menu_link); diff --git a/core/modules/menu_link/lib/Drupal/menu_link/Plugin/Core/Entity/MenuLink.php b/core/modules/menu_link/lib/Drupal/menu_link/Plugin/Core/Entity/MenuLink.php index 5af23d7..484f5d0 100644 --- a/core/modules/menu_link/lib/Drupal/menu_link/Plugin/Core/Entity/MenuLink.php +++ b/core/modules/menu_link/lib/Drupal/menu_link/Plugin/Core/Entity/MenuLink.php @@ -32,6 +32,7 @@ * static_cache = FALSE, * base_table = "menu_links", * uri_callback = "menu_link_uri", + * translatable = TRUE, * entity_keys = { * "id" = "mlid", * "label" = "link_title",