diff --git a/core/lib/Drupal/Core/Menu/MenuParentFormSelector.php b/core/lib/Drupal/Core/Menu/MenuParentFormSelector.php index a9ca7be..e5a1264 100644 --- a/core/lib/Drupal/Core/Menu/MenuParentFormSelector.php +++ b/core/lib/Drupal/Core/Menu/MenuParentFormSelector.php @@ -80,8 +80,8 @@ public function getParentSelectOptions($id = '', array $menus = NULL) { /** * {@inheritdoc} */ - public function parentSelectElement($menu_parent, $exclude_id = '', array $menus = NULL) { - $options = $this->getParentSelectOptions($exclude_id, $menus); + public function parentSelectElement($menu_parent, $id = '', array $menus = NULL) { + $options = $this->getParentSelectOptions($id, $menus); // If no options were found, there is nothing to select. if ($options) { $element = array( diff --git a/core/lib/Drupal/Core/Menu/MenuParentFormSelectorInterface.php b/core/lib/Drupal/Core/Menu/MenuParentFormSelectorInterface.php index 7e607b3..33ada87 100644 --- a/core/lib/Drupal/Core/Menu/MenuParentFormSelectorInterface.php +++ b/core/lib/Drupal/Core/Menu/MenuParentFormSelectorInterface.php @@ -38,7 +38,7 @@ public function getParentSelectOptions($id = '', array $menus = NULL); * @param string $menu_parent * A menu name and parent ID concatenated with a ':' character to use as the * default value. - * @param string $exclude_id + * @param string $id * (optional) ID of a link plugin. This will exclude the link and its * children from being selected. * @param array $menus @@ -51,6 +51,6 @@ public function getParentSelectOptions($id = '', array $menus = NULL); * a single string containing the chosen menu name and parent ID separated * by a ':' character. */ - public function parentSelectElement($menu_parent, $exclude_id = '', array $menus = NULL); + public function parentSelectElement($menu_parent, $id = '', array $menus = NULL); } diff --git a/core/modules/menu_link/src/Plugin/Field/FieldType/MenuLinkItem.php b/core/modules/menu_link/src/Plugin/Field/FieldType/MenuLinkItem.php index bc8a4ab..5cc31a2 100644 --- a/core/modules/menu_link/src/Plugin/Field/FieldType/MenuLinkItem.php +++ b/core/modules/menu_link/src/Plugin/Field/FieldType/MenuLinkItem.php @@ -90,14 +90,8 @@ public static function propertyDefinitions(FieldStorageDefinitionInterface $fiel $definitions['menu_name'] = DataDefinition::create('string') ->setLabel(t('Menu')); - $definitions['url'] = DataDefinition::create('string') - ->setLabel(t('Menu link url')); $definitions['parent'] = DataDefinition::create('string') ->setLabel(t('Menu link parent')); - $definitions['title'] = DataDefinition::create('string') - ->setLabel(t('Menu link title')); - $definitions['description'] = DataDefinition::create('string') - ->setLabel(t('Menu link description')); $definitions['weight'] = DataDefinition::create('integer') ->setLabel(t('Menu link weight')); @@ -110,13 +104,6 @@ public static function propertyDefinitions(FieldStorageDefinitionInterface $fiel public static function schema(FieldStorageDefinitionInterface $field_definition) { $schema = []; - $schema['columns']['title'] = [ - 'description' => 'The menu link text.', - 'type' => 'varchar', - 'length' => 255, - 'not null' => FALSE, - ]; - $schema['columns']['menu_name'] = [ 'description' => 'The menu of the link', 'type' => 'varchar', @@ -135,13 +122,6 @@ public static function schema(FieldStorageDefinitionInterface $field_definition) 'type' => 'int', ]; - $schema['columns']['description'] = [ - 'description' => 'The description of the menu link.', - 'type' => 'blob', - 'size' => 'big', - 'not null' => FALSE, - ]; - return $schema; } @@ -209,18 +189,20 @@ public function getMenuPluginId() { */ protected function getMenuPluginDefinition() { $menu_definition = []; + $entity = $this->getEntity(); $menu_definition['id'] = $this->getPluginId(); - $menu_definition['title'] = $this->values['title']; + $menu_definition['title'] = $entity->label(); $menu_definition['menu_name'] = $this->values['menu_name']; $menu_definition['parent'] = $this->values['parent']; $menu_definition['weight'] = isset($this->values['weight']) ? $this->values['weight'] : 0; $menu_definition['class'] = '\Drupal\menu_link\Plugin\Menu\MenuLinkField'; $menu_definition['form_class'] = '\Drupal\menu_link\Plugin\Menu\Form\MenuLinkFieldForm'; - $menu_definition['metadata']['entity_id'] = $this->getEntity()->id(); - $menu_definition['metadata']['entity_type_id'] = $this->getEntity()->getEntityTypeId(); + $menu_definition['metadata']['entity_id'] = $entity->id(); + $menu_definition['metadata']['entity_type_id'] = $entity->getEntityTypeId(); $menu_definition['metadata']['field_name'] = $this->definition->getFieldDefinition()->getName(); + $menu_definition['metadata']['translateable'] = is_subclass_of($entity, '\Drupal\Core\TypedData\TranslatableInterface'); - $url = $this->getEntity()->urlInfo(); + $url = $entity->urlInfo(); $menu_definition['route_name'] = $url->getRouteName(); $menu_definition['route_parameters'] = $url->getRouteParameters(); diff --git a/core/modules/menu_link/src/Plugin/Field/FieldWidget/MenuLinkWidget.php b/core/modules/menu_link/src/Plugin/Field/FieldWidget/MenuLinkWidget.php index 4b1b583..1c0510a 100644 --- a/core/modules/menu_link/src/Plugin/Field/FieldWidget/MenuLinkWidget.php +++ b/core/modules/menu_link/src/Plugin/Field/FieldWidget/MenuLinkWidget.php @@ -73,10 +73,6 @@ public static function create(ContainerInterface $container, array $configuratio */ public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) { - $default_url_value = NULL; - - $default_title = isset($items[$delta]->title) ? $items[$delta]->title : NULL; - $default_description = isset($items[$delta]->description) ? $items[$delta]->description : NULL; $default_weight = isset($items[$delta]->weight) ? $items[$delta]->weight : 0; $available_menus = array_filter($items->getSetting('available_menus')); @@ -88,14 +84,6 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen if (!$this->account->hasPermission('administer menu')) { - $element['title'] = [ - '#type' => 'value', - '#value' => $default_title, - ]; - $element['description'] = [ - '#type' => 'value', - '#value' => $default_description, - ]; $element['weight'] = [ '#type' => 'value', '#value' => $default_weight, @@ -128,29 +116,6 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen ], ]; - $element['url'] = array( - '#type' => 'url', - '#title' => $this->t('URL'), - '#placeholder' => $this->getSetting('placeholder_url'), - '#default_value' => $default_url_value, - '#maxlength' => 2048, - '#required' => $element['#required'], - ); - - $element['title'] = [ - '#type' => 'textfield', - '#title' => $this->t('Menu link title'), - '#default_value' => $default_title, - ]; - - $element['description'] = [ - '#type' => 'textarea', - '#title' => $this->t('Description'), - '#default_value' => $default_description, - '#rows' => 1, - '#description' => $this->t('Shown when hovering over the menu link.'), - ]; - $plugin_id = $items[$delta]->getMenuPluginId(); $parent_element = $this->menuParentSelector->parentSelectElement($default_menu_parent, $plugin_id, $available_menus); @@ -180,13 +145,11 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen */ public function preRenderMenuDetails($element) { $element['menu']['enabled'] = $element['enabled']; - $element['menu']['title'] = $element['title']; - $element['menu']['description'] = $element['description']; $element['menu']['menu_parent'] = $element['menu_parent']; $element['menu']['weight'] = $element['weight']; // Hide the elements when enabled is disabled. - foreach (['title', 'description', 'menu_parent', 'weight'] as $form_element) { + foreach (['menu_parent', 'weight'] as $form_element) { $element['menu'][$form_element]['#states'] = [ 'invisible' => [ 'input[name="' . $element['menu']['enabled']['#name'] . '"' => ['checked' => FALSE], @@ -194,7 +157,7 @@ public function preRenderMenuDetails($element) { ]; } - unset($element['enabled'], $element['title'], $element['description'], $element['menu_parent'], $element['weight']); + unset($element['enabled'], $element['menu_parent'], $element['weight']); return $element; } diff --git a/core/modules/menu_link/src/Plugin/Menu/MenuLinkField.php b/core/modules/menu_link/src/Plugin/Menu/MenuLinkField.php index 7c42787..f05a6e3 100644 --- a/core/modules/menu_link/src/Plugin/Menu/MenuLinkField.php +++ b/core/modules/menu_link/src/Plugin/Menu/MenuLinkField.php @@ -8,6 +8,7 @@ namespace Drupal\menu_link\Plugin\Menu; use Drupal\Core\Entity\EntityManagerInterface; +use Drupal\Core\Language\LanguageManagerInterface; use Drupal\Core\Menu\MenuLinkBase; use Drupal\Core\Plugin\ContainerFactoryPluginInterface; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -18,6 +19,22 @@ class MenuLinkField extends MenuLinkBase implements ContainerFactoryPluginInterface { /** + * Entities IDs to load. + * + * It is an array of entity IDs keyed by entity IDs. + * + * @var array + */ + protected static $entityIdsToLoad = array(); + + /** + * The entity connected to this plugin instance. + * + * @var \Drupal\Core\Entity\EntityInterface + */ + protected $entity; + + /** * The entity manager. * * @var \Drupal\Core\Entity\EntityManagerInterface @@ -25,6 +42,13 @@ class MenuLinkField extends MenuLinkBase implements ContainerFactoryPluginInterf protected $entityManager; /** + * The language manager. + * + * @var \Drupal\Core\Language\LanguageManagerInterface + */ + protected $languageManager; + + /** * Constructs a new MenuLinkField object. * * @param array $configuration @@ -35,11 +59,20 @@ class MenuLinkField extends MenuLinkBase implements ContainerFactoryPluginInterf * The plugin implementation definition. * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager * The entity manager. + * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager + * The language manager. */ - public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityManagerInterface $entity_manager) { + public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityManagerInterface $entity_manager, LanguageManagerInterface $language_manager) { parent::__construct($configuration, $plugin_id, $plugin_definition); $this->entityManager = $entity_manager; + $this->languageManager = $language_manager; + + $entity_type_id = $this->pluginDefinition['metadata']['entity_type_id']; + $entity_id = $this->pluginDefinition['metadata']['entity_id']; + // Builds a list of entity IDs to take advantage of the more efficient + // EntityStorageInterface::loadMultiple() in getEntity() at render time. + static::$entityIdsToLoad[$entity_type_id][$entity_id] = $entity_id; } /** @@ -50,7 +83,8 @@ public static function create(ContainerInterface $container, array $configuratio $configuration, $plugin_id, $plugin_definition, - $container->get('entity.manager') + $container->get('entity.manager'), + $container->get('language_manager') ); } @@ -58,6 +92,12 @@ public static function create(ContainerInterface $container, array $configuratio * {@inheritdoc} */ public function getTitle() { + // We only need to get the title from the actual entity if it may be a + // translation based on the current language context. This can only happen + // if the site is configured to be multilingual. + if (!empty($this->pluginDefinition['metadata']['translateable']) && $this->languageManager->isMultilingual()) { + return $this->getEntity()->getTitle(); + } return $this->pluginDefinition['title']; } @@ -95,14 +135,28 @@ public function updateLink(array $new_definition_values, $persist) { /** * Loads the entity the field was attached to. * - * @return \Drupal\Core\Entity\EntityInterface|null + * @return \Drupal\Core\Entity\EntityInterface * Returns the entity, if exists. */ public function getEntity() { - $entity_type_id = $this->pluginDefinition['metadata']['entity_type_id']; - $entity_id = $this->pluginDefinition['metadata']['entity_id']; - $entity = $this->entityManager->getStorage($entity_type_id)->load($entity_id); - return $entity; + if (empty($this->entity)) { + $entity_type_id = $this->pluginDefinition['metadata']['entity_type_id']; + $entity_id = $this->pluginDefinition['metadata']['entity_id']; + // Make sure the current ID is in the list, since each plugin empties + // the list after calling loadMultple(). Note that the list may include + // multiple IDs added earlier in each plugin's constructor. + static::$entityIdsToLoad[$entity_type_id][$entity_id] = $entity_id; + $entities = $this->entityManager->getStorage($entity_type_id)->loadMultiple(array_values(static::$entityIdsToLoad[$entity_type_id])); + $entity = isset($entities[$entity_id]) ? $entities[$entity_id] : NULL; + static::$entityIdsToLoad[$entity_type_id] = array(); + // Clone the entity object to avoid tampering with the static cache. + $this->entity = clone $entity; + if (!empty($this->pluginDefinition['metadata']['translateable'])) { + $the_entity = $this->entityManager->getTranslationFromContext($this->entity); + $this->entity = $the_entity; + } + } + return $this->entity; } } diff --git a/core/modules/menu_ui/src/Tests/MenuNodeTest.php b/core/modules/menu_ui/src/Tests/MenuNodeTest.php index fe88faf..ed8ff07 100644 --- a/core/modules/menu_ui/src/Tests/MenuNodeTest.php +++ b/core/modules/menu_ui/src/Tests/MenuNodeTest.php @@ -134,7 +134,6 @@ function testMenuNodeFormWidget() { // Edit the node and create a menu link. $edit = array( 'menu[0][enabled]' => 1, - 'menu[0][title]' => $node_title, 'menu[0][weight]' => 17, ); $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save')); @@ -155,7 +154,6 @@ function testMenuNodeFormWidget() { $this->assertNoLink($node_title); // Add a menu link to the Administration menu. - $node->menu->title = $this->randomMachineName(16); $node->menu->menu_name = 'admin'; $node->save(); @@ -175,7 +173,6 @@ function testMenuNodeFormWidget() { // Create a second node. $child_node = $this->drupalCreateNode(array('type' => 'article')); // Assign a menu link to the second node, being a child of the first one. - $child_node->menu->title = $this->randomMachineName(16); $child_node->menu->parent = $node->menu->first()->getMenuPluginId(); $child_node->menu->menu_name = $node->menu->menu_name; $child_node->save();