association-1.0.0-alpha2/modules/association_menu/src/Form/AssociationMenuForm.php
modules/association_menu/src/Form/AssociationMenuForm.php
<?php namespace Drupal\association_menu\Form; use Drupal\association\Entity\AssociationInterface; use Drupal\association\Entity\AssociationLink; use Drupal\association_menu\AssociatedEntityMenuItem; use Drupal\association_menu\AssociationMenuStorageInterface; use Drupal\association_menu\MenuItemInterface; use Drupal\association_menu\Utility\MenuTreeHelper; use Drupal\association_page\Entity\AssociationPage; use Drupal\Core\DependencyInjection\ContainerInjectionInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Form\FormBase; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Url; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; /** * Form for managing the menu built for association content. */ class AssociationMenuForm extends FormBase implements ContainerInjectionInterface { /** * The entity type manager. * * @var \Drupal\Core\Entity\EntityTypeManagerInterface */ protected $entityTypeManager; /** * Association menu item storage manager. * * @var \Drupal\association_menu\AssociationMenuStorageInterface */ protected $menuStorage; /** * Create a new instance of the entity association menu management form. * * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager * The entity type manager. * @param \Drupal\association_menu\AssociationMenuStorageInterface $association_menu_storage * Association navigation storage manager. */ public function __construct(EntityTypeManagerInterface $entity_type_manager, AssociationMenuStorageInterface $association_menu_storage) { $this->entityTypeManager = $entity_type_manager; $this->menuStorage = $association_menu_storage; } /** * {@inheritdoc} */ public static function create(ContainerInterface $container) { return new static( $container->get('entity_type.manager'), $container->get('association_menu.storage') ); } /** * {@inheritdoc} */ public function getFormId() { return 'association_menu_management_form'; } /** * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state, AssociationInterface $association = NULL) { if (!$association) { throw new NotFoundHttpException(); } $form_state->set('association_id', $association->id()); $assocType = $association->getType(); $menuOpts = $assocType->getThirdPartySettings('association_menu'); $form['#title'] = $this->t('Menu for @bundle_label: %label', [ '@bundle_label' => $assocType->label(), '%label' => $association->label(), ]); $form['menu_tree'] = [ '#type' => 'table', '#attributes' => ['id' => 'draggable-nav-items-overview'], '#empty' => $this->t('No content associated to this relationship.'), '#header' => [ 'label' => $this->t('Title'), 'type' => $this->t('Type'), 'enabled' => $this->t('Enabled'), 'expanded' => $this->t('Expanded'), 'parent' => $this->t('Parent'), 'weight' => $this->t('Sort order'), 'actions' => $this->t('Operations'), ], '#tabledrag' => [ 'sort' => [ 'action' => 'order', 'relationship' => 'sibling', 'group' => 'association__nav-weight', ], ], ]; // Menu nesting has been enabled for this association type, add the // table drag settings to set menu item parents. if (!empty($menuOpts['menu_nesting'])) { $form['menu_tree']['#tabledrag']['parent'] = [ 'action' => 'match', 'relationship' => 'parent', 'group' => 'association__nav-parent', 'source' => 'association__nav-id', 'hidden' => TRUE, ]; } else { unset($form['menu_tree']['#header']['parent']); } $menu = $this->menuStorage->getMenuItems($association); foreach ($menu as $item) { $this->addRows($association, $item, $form['menu_tree'], $menuOpts); } $form['actions'] = [ '#type' => 'actions', 'save' => [ '#type' => 'submit', '#value' => $this->t('Save'), ], ]; return $form; } /** * {@inheritdoc} */ public function submitForm(array &$form, FormStateInterface $form_state) { $items = $form_state->getValue('menu_tree'); $assocId = $form_state->get('association_id'); /** @var \Drupal\association\Entity\AssociationInterface */ $association = $this->entityTypeManager ->getStorage('association') ->load($assocId); $assocType = $association->getType(); $menuOptions = $assocType->getThirdPartySettings('association_menu'); if ($association && $items) { foreach ($items as $id => &$data) { $data['id'] = $id; unset($data['label']); if (empty($data['parent']) || empty($menuOptions['menu_nesting'])) { $data['parent'] = 0; $data['depth'] = 0; } else { MenuTreeHelper::setItemDepth($items, $data); } } unset($data); // Update just the menu tree related fields of the menu links. $this->menuStorage->updateMenuTree($association, $items); $this ->messenger() ->addStatus($this->t('Successfully updated menu configurations')); } else { $this ->messenger() ->addError($this->t('Unable to save menu changes.')); } } /** * Build the table row, and subtree rows for the navigation tree. * * @param \Drupal\association\Entity\AssociationInterface $association * The association this menu item belongs to. * @param \Drupal\association_menu\MenuItemInterface $item * Menu item to build into the data row. * @param array $table * Reference to the table form element. * @param array $options * Configured menu options. * @param int $depth * The current depth to build the rows at (controls the indents). */ protected function addRows(AssociationInterface $association, MenuItemInterface $item, array &$table, array $options = [], $depth = 0) { $itemId = $item->id(); $title = $item->getTitle() ?: $this->t('<missing title>'); $behavior = $association->getBehavior(); $operations = []; $operations['edit'] = [ 'title' => $this->t('Edit'), 'url' => Url::fromRoute('association_menu.edit_item_form', [ 'association' => $association->id(), 'menu_item_id' => $itemId, ]), ]; if ($item instanceof AssociatedEntityMenuItem) { $entity = $item->getEntity(); // The menu item type is determined by the menu item's entity type. if ($entity instanceof AssociationPage) { $linkType = $this->t('@bundle_label main page', [ '@bundle_label' => $association->getType()->label(), ]); } elseif ($behavior && $entity instanceof AssociationLink) { $target = $entity->getTarget(); $linkType = $behavior->getTagLabel($entity->getTag(), $target->getEntityTypeId(), $target->bundle()); } else { $linkType = $this->t('@bundle_label content', [ '@bundle_label' => $association->getType()->label(), ]); } } else { $operations['delete'] = [ 'title' => $this->t('Delete'), 'url' => Url::fromRoute('association_menu.delete_item_confirm', [ 'association' => $association->id(), 'menu_item_id' => $itemId, ]), ]; $linkType = $this->t('Custom menu link'); } $table[$itemId] = [ '#attributes' => [ 'id' => $itemId, 'class' => ['draggable'], ], 'label' => [ 'indent' => [ '#theme' => 'indentation', '#size' => $depth, ], 'display_name' => [ '#type' => 'link', '#title' => $title, '#url' => $item->getUrl(), ], 'id' => [ '#type' => 'hidden', '#value' => $itemId, '#attributes' => [ 'class' => ['association__nav-id'], ], ], ], 'type' => [ '#markup' => $linkType, ], 'enabled' => [ '#type' => 'checkbox', '#default_value' => $item->isEnabled(), ], 'expanded' => [ '#type' => 'checkbox', '#default_value' => $item->isExpanded(), ], 'parent' => [ '#type' => 'textfield', '#default_value' => $item->getParentId(), '#attributes' => [ 'class' => ['association__nav-parent'], ], ], 'weight' => [ '#type' => 'number', '#default_value' => $item->getWeight() ?? 0, '#attributes' => [ 'class' => ['association__nav-weight'], ], ], 'actions' => [ '#type' => 'operations', '#links' => $operations, ], ]; // If menu nesting isn't available, remove the "parent" form elements // and any row indents. if (empty($options['menu_nesting'])) { unset($table[$itemId]['parent']); unset($table[$itemId]['label']['indent']); } if (!empty($item->children)) { foreach ($item->children as $child) { $this->addRows($association, $child, $table, $options, $depth + 1); } } } }