1

When cloning a node using Entity Clone module, the menu link are not copied. As menu link item is created and managed on the node form level, there is no reference of the menu link item in the node entity level. See menu_ui_form_node_form_alter for more details.

1 Answer 1

1

Issue #2839833 has a proposal to add entity clone plugin to node entity to handle this special case.

Alternatively, we could use the event. Luckily Entity Clone module dispatches an event before & after clone for the other modules to act. Here is the code for menu copy:

  // mymodule.services.yml

 mymodule.entity_clone.subscriber:
    class: Drupal\mymodule\EventSubscriber\EntityCloneSubscriber
    tags:
      - { name: 'event_subscriber' }

Subscribe to the post clone event:

<?php

namespace Drupal\mymodule\EventSubscriber;

use Drupal\Core\Entity\EntityInterface;
use Drupal\entity_clone\Event\EntityCloneEvent;
use Drupal\entity_clone\Event\EntityCloneEvents;
use Drupal\menu_link_content\Entity\MenuLinkContent;
use Drupal\node\NodeInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

/**
 * Crates menu item after node clone.
 */
class EntityCloneSubscriber implements EventSubscriberInterface {

  /**
   * Entity post clone handler.
   *
   * @param \Drupal\entity_clone\Event\EntityCloneEvent $event
   *   An event object.
   *
   * @throws \Drupal\Core\Entity\EntityStorageException
   */
  public function onPostClone(EntityCloneEvent $event) {
    $entity = $event->getEntity();

    // Act only on node clone.
    if (!($entity instanceof  NodeInterface)) {
      return;
    }
    $cloned_entity = $event->getClonedEntity();
    $values = menu_ui_get_menu_link_defaults($entity);

    // Copy menu item, if available.
    if (!empty($values['entity_id'])) {
      $this->cloneNodeMenuLinkContent($cloned_entity, $values);
    }
  }

  /**
   * Clones menu link content associated with the node.
   *
   * @param \Drupal\Core\Entity\EntityInterface $cloned_entity
   *   Cloned node.
   * @param array $values
   *   An array of menu link content values.
   *
   * @throws \Drupal\Core\Entity\EntityStorageException
   */
  protected function cloneNodeMenuLinkContent(EntityInterface $cloned_entity, array $values) {
    $menu_item = MenuLinkContent::load($values['entity_id']);
    $menu_name = $values['menu_name'];

    // Create new menu link content with original value.
    $cloned_menu_item = MenuLinkContent::create([
      'link' => ['uri' => 'entity:node/' . $cloned_entity->id()],
      'langcode' => $cloned_entity->language()->getId(),
    ]);
    $cloned_menu_item->enabled->value = $menu_item->isEnabled() ? 1 : 0;
    $cloned_menu_item->title->value = trim($cloned_entity->getTitle());
    $cloned_menu_item->description->value = trim($values['description']);
    $cloned_menu_item->menu_name->value = $menu_name;
    $cloned_menu_item->parent->value = $values['parent'];
    $cloned_menu_item->weight->value = isset($values['weight']) ? $values['weight'] : 0;
    $cloned_menu_item->save();
  }

  /**
   * {@inheritdoc}
   */
  public static function getSubscribedEvents() {
    $events = [];
    $events[EntityCloneEvents::POST_CLONE][] = ['onPostClone', 200];
    return $events;
  }

}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.