wse-1.0.x-dev/modules/wse_menu/src/Form/WseMenuForm.php

modules/wse_menu/src/Form/WseMenuForm.php
<?php

namespace Drupal\wse_menu\Form;

use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Menu\MenuLinkTreeElement;
use Drupal\Core\Menu\MenuTreeParameters;
use Drupal\Core\Render\Element;
use Drupal\Core\Url;
use Drupal\Core\Utility\Error;
use Drupal\menu_ui\MenuForm;
use Drupal\workspaces\WorkspaceManagerInterface;
use Drupal\wse_menu\WseMenuTreeStorageInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Extends MenuForm for workspace-specific changes.
 *
 * @internal
 */
class WseMenuForm extends MenuForm {

  use TrackedLinkValidationTrait;

  /**
   * The workspace manager.
   *
   * @var \Drupal\workspaces\WorkspaceManagerInterface
   */
  protected WorkspaceManagerInterface $workspaceManager;

  /**
   * The WSE menu tree storage.
   *
   * @var \Drupal\wse_menu\WseMenuTreeStorageInterface
   */
  protected WseMenuTreeStorageInterface $menuTreeStorage;

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container): self {
    $instance = parent::create($container);
    $instance->workspaceManager = $container->get('workspaces.manager');
    $instance->menuTreeStorage = $container->get('wse_menu.tree_storage');
    return $instance;
  }

  /**
   * {@inheritdoc}
   */
  public function form(array $form, FormStateInterface $form_state): array {
    $form = parent::form($form, $form_state);
    $form_state->set('workspace_safe', TRUE);
    return $form;
  }

  /**
   * {@inheritdoc}
   */
  protected function actions(array $form, FormStateInterface $form_state): array {
    $actions = parent::actions($form, $form_state);

    if ($this->workspaceManager->hasActiveWorkspace()) {
      $actions['rebuild_tree'] = [
        '#type' => 'submit',
        '#value' => $this->t('Rebuild menu tree'),
        '#submit' => ['::rebuildMenuTree'],
      ];
    }

    return $actions;
  }

  /**
   * Form submission handler for the 'rebuild_tree' action.
   *
   * @param array $form
   *   An associative array containing the structure of the form.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The current state of the form.
   */
  public function rebuildMenuTree(array $form, FormStateInterface $form_state): void {
    if (!$this->workspaceManager->hasActiveWorkspace()) {
      return;
    }

    try {
      $this->menuTreeStorage->rebuildWorkspaceMenuTree($this->workspaceManager->getActiveWorkspace());
      $this->messenger()->addStatus($this->t('The workspace menu tree has been rebuilt.'));
    }
    catch (\Exception $e) {
      Error::logException($this->logger('wse_menu'), $e);
      $this->messenger()->addError($this->t('The workspace menu tree could not be rebuilt. All errors have been logged.'));
    }
  }

  /**
   * {@inheritdoc}
   */
  protected function buildOverviewForm(array &$form, FormStateInterface $form_state): array {
    // Ensure that menu_overview_form_submit() knows the parents of this form
    // section.
    if (!$form_state->has('menu_overview_form_parents')) {
      $form_state->set('menu_overview_form_parents', []);
    }

    $form['#attached']['library'][] = 'menu_ui/drupal.menu_ui.adminforms';

    $tree = $this->menuTree->load($this->entity->id(), new MenuTreeParameters());

    // We indicate that a menu administrator is running the menu access check.
    $this->getRequest()->attributes->set('_menu_admin', TRUE);
    $manipulators = [
      ['callable' => 'menu.default_tree_manipulators:checkAccess'],
      ['callable' => 'menu.default_tree_manipulators:generateIndexAndSort'],
    ];
    $tree = $this->menuTree->transform($tree, $manipulators);
    $this->getRequest()->attributes->set('_menu_admin', FALSE);

    // Determine the delta; the number of weights to be made available.
    $count = function (array $tree) {
      $sum = function ($carry, MenuLinkTreeElement $item) {
        return $carry + $item->count();
      };
      return array_reduce($tree, $sum);
    };
    $delta = max($count($tree), 50);

    $form['links'] = [
      '#type' => 'table',
      '#theme' => 'table__menu_overview',
      '#header' => [
        $this->t('Menu link'),
        [
          'data' => $this->t('Enabled'),
          'class' => ['checkbox'],
        ],
        $this->t('Weight'),
        [
          'data' => $this->t('Operations'),
          'colspan' => 3,
        ],
      ],
      '#attributes' => [
        'id' => 'menu-overview',
      ],
      '#tabledrag' => [
        [
          'action' => 'match',
          'relationship' => 'parent',
          'group' => 'menu-parent',
          'subgroup' => 'menu-parent',
          'source' => 'menu-id',
          'hidden' => TRUE,
          'limit' => $this->menuTree->maxDepth() - 1,
        ],
        [
          'action' => 'order',
          'relationship' => 'sibling',
          'group' => 'menu-weight',
        ],
      ],
    ];

    $form['links']['#empty'] = $this->t('There are no menu links yet. <a href=":url">Add link</a>.', [
      ':url' => Url::fromRoute('entity.menu.add_link_form', ['menu' => $this->entity->id()], [
        'query' => ['destination' => $this->entity->toUrl('edit-form')->toString()],
      ])->toString(),
    ]);
    $links = $this->buildOverviewTreeForm($tree, $delta);

    foreach (Element::children($links) as $id) {
      if (isset($links[$id]['#item'])) {
        $element = $links[$id];

        $form['links'][$id]['#item'] = $element['#item'];

        // TableDrag: Mark the table row as draggable.
        $form['links'][$id]['#attributes'] = $element['#attributes'];
        $form['links'][$id]['#attributes']['class'][] = 'draggable';

        // TableDrag: Sort the table row according to its existing/configured
        // weight.
        $form['links'][$id]['#weight'] = $element['#item']->link->getWeight();

        // Add special classes to be used for tabledrag.js.
        $element['parent']['#attributes']['class'] = ['menu-parent'];
        $element['weight']['#attributes']['class'] = ['menu-weight'];
        $element['id']['#attributes']['class'] = ['menu-id'];

        $form['links'][$id]['title'] = [
          [
            '#theme' => 'indentation',
            '#size' => $element['#item']->depth - 1,
          ],
          $element['title'],
        ];
        $form['links'][$id]['enabled'] = $element['enabled'];
        $form['links'][$id]['enabled']['#wrapper_attributes']['class'] = ['checkbox', 'menu-enabled'];

        $form['links'][$id]['weight'] = $element['weight'];

        // Operations (dropbutton) column.
        $form['links'][$id]['operations'] = $element['operations'];

        $form['links'][$id]['id'] = $element['id'];
        $form['links'][$id]['parent'] = $element['parent'];
      }
    }

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function validateForm(array &$form, FormStateInterface $form_state): void {
    parent::validateForm($form, $form_state);
    $this->validateLinks($form_state);
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc