Commit bef44dfd authored by Philippe Guillard's avatar Philippe Guillard Committed by Christopher C. Wells
Browse files

Issue #2839670 by mstef, pguillard, RajeevK: Add ability to select parent and...

Issue #2839670 by mstef, pguillard, RajeevK: Add ability to select parent and weight when adding a link
parent 5d960836
Loading
Loading
Loading
Loading
+13 −3
Original line number Diff line number Diff line
@@ -208,9 +208,14 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {

    $fields['parent'] = BaseFieldDefinition::create('entity_reference')
      ->setLabel(t('Parent'))
      ->setDescription(t('The parent item'))
      ->setDescription(t('The parent menu item.'))
      ->setSetting('target_type', 'colossal_menu_link')
      ->setSetting('handler', 'default');
      ->setSetting('handler', 'default')
      ->setDisplayOptions('form', array(
        'type' => 'options_select',
        'weight' => 5,
      ))
      ->setDisplayConfigurable('form', TRUE);

    $fields['title'] = BaseFieldDefinition::create('string')
      ->setLabel(t('Title'))
@@ -258,7 +263,12 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
    $fields['weight'] = BaseFieldDefinition::create('integer')
      ->setLabel(t('Weight'))
      ->setDescription(t('Link weight among links in the same menu at the same depth. In the menu, the links with high weight will sink and links with a low weight will be positioned nearer the top.'))
      ->setDefaultValue(0);
      ->setDefaultValue(0)
      ->setDisplayOptions('form', array(
        'type' => 'number',
        'weight' => 20,
      ))
      ->setDisplayConfigurable('form', TRUE);

    $fields['langcode'] = BaseFieldDefinition::create('language')
      ->setLabel(t('Language code'))
+113 −1
Original line number Diff line number Diff line
@@ -2,10 +2,19 @@

namespace Drupal\colossal_menu\Form;

use Drupal\colossal_menu\Menu\MenuLinkTree;
use Drupal\Core\Entity\ContentEntityForm;
use Drupal\Core\Entity\EntityRepositoryInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Menu\Form\MenuLinkFormInterface;
use Drupal\Core\Menu\MenuLinkInterface;
use Drupal\Core\Entity\Display\EntityFormDisplayInterface;
use Drupal\Core\Entity\Entity\EntityFormDisplay;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Component\Datetime\TimeInterface;
use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
use Drupal\Core\Menu\MenuTreeParameters;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Form controller for Link edit forms.
@@ -14,6 +23,46 @@
 */
class LinkForm extends ContentEntityForm implements MenuLinkFormInterface {

  /**
   * The link tree.
   *
   * @var \Drupal\colossal_menu\Menu\MenuLinkTree
   */
  protected $linkTree;

  /**
   * Constructs a LinkForm object.
   *
   * @param \Drupal\Core\Entity\EntityRepositoryInterface $entity_repository
   *   The entity repository service.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entity manager.
   * @param \Drupal\colossal_menu\Menu\MenuLinkTree $link_tree
   *   The colossal menu link tree.
   * @param \Drupal\Core\Entity\EntityTypeBundleInfoInterface $entity_type_bundle_info
   *   The entity type bundle service.
   * @param \Drupal\Component\Datetime\TimeInterface $time
   *   The time service.
   */
   public function __construct(EntityRepositoryInterface $entity_repository, EntityTypeManagerInterface $entity_type_manager, MenuLinkTree $link_tree, EntityTypeBundleInfoInterface $entity_type_bundle_info = NULL, TimeInterface $time = NULL) {
     parent::__construct($entity_repository, $entity_type_bundle_info, $time);
     $this->entityTypeManager = $entity_type_manager;
     $this->linkTree = $link_tree;
   }

   /**
    * {@inheritdoc}
    */
   public static function create(ContainerInterface $container) {
     return new static(
       $container->get('entity.repository'),
       $container->get('entity_type.manager'),
       $container->get('colossal_menu.link_tree'),
       $container->get('entity_type.bundle.info'),
       $container->get('datetime.time')
     );
   }

  /**
   * {@inheritdoc}
   */
@@ -59,7 +108,29 @@ public function form(array $form, FormStateInterface $form_state) {
      $form['#title'] = $this->t('Edit %label', ['%label' => $link->label()]);
    }

    return parent::form($form, $form_state, $link);
    $form = parent::form($form, $form_state, $link);

    // Override the parent select options to limit them to links of the
    // given menu and display the link hierarchy.
    $form['parent']['widget']['#options'] = $this->parentSelectOptions();

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function validateForm(array &$form, FormStateInterface $form_state) {
    $entity = parent::validateForm($form, $form_state);

    // Check if a parent is present.
    if ($parent = $entity->get('parent')->entity) {
      // Check if the link ID and the parent ID are the same.
      if ($parent->id() == $entity->id()) {
        // Set an error.
        $form_state->setErrorByName('parent', $this->t('The parent cannot be set to the link being edited.'));
      }
    }
  }

  /**
@@ -87,4 +158,45 @@ public function save(array $form, FormStateInterface $form_state) {
    ]);
  }

  /**
   * Provide the select list options for the parent field.
   *
   * @return array
   *   An array of select list options, keyed by link ID.
   */
  public function parentSelectOptions() {
    // Start the options.
    $options = ['_none' => '- ' . $this->t('None') . ' -'];

    // Load the menu tree for the menu that the link is part of.
    $tree = $this->linkTree->load($this->entity->getMenuName(), new MenuTreeParameters);

    // Recursively add the parent options as a tree.
    $this->parentSelectOptionsRecursive($options, $tree);

    return $options;
  }

  /**
   * Recursive callback to generate the select list options for the link parent
   * as a tree with depth.
   *
   * @param array &$options
   *   The select list options array.
   * @param array $tree
   *   The menu link tree.
   * @param int $depth
   *   The depth of the menu tree.
   */
  protected function parentSelectOptionsRecursive(array &$options, array $tree, int $depth = 0) {
    // Iterate the tree.
    foreach ($tree as $id => $level) {
      // Add the parent link.
      $options[$id] = str_repeat('-', ($depth * 2)) . ' ' . $level->link->label();

      // Recursively add the children.
      $this->parentSelectOptionsRecursive($options, $level->subtree, ($depth + 1));
    }
  }

}