Loading src/Entity/Link.php +13 −3 Original line number Diff line number Diff line Loading @@ -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')) Loading Loading @@ -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')) Loading src/Form/LinkForm.php +113 −1 Original line number Diff line number Diff line Loading @@ -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. Loading @@ -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} */ Loading Loading @@ -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.')); } } } /** Loading Loading @@ -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)); } } } Loading
src/Entity/Link.php +13 −3 Original line number Diff line number Diff line Loading @@ -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')) Loading Loading @@ -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')) Loading
src/Form/LinkForm.php +113 −1 Original line number Diff line number Diff line Loading @@ -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. Loading @@ -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} */ Loading Loading @@ -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.')); } } } /** Loading Loading @@ -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)); } } }