View source
<?php
namespace Drupal\bigmenu;
use Drupal\Core\Link;
use Drupal\Core\Url;
use Drupal\menu_ui\MenuForm;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Menu\MenuLinkTreeElement;
use Drupal\Core\Menu\MenuTreeParameters;
use Drupal\Core\Render\Element;
use Symfony\Component\DependencyInjection\ContainerInterface;
class BigMenuForm extends MenuForm {
protected $tree = [];
protected $config;
public static function create(ContainerInterface $container) {
$instance = parent::create($container);
$instance->config = $container
->get('config.factory')
->get('bigmenu.settings');
return $instance;
}
protected function buildOverviewForm(array &$form, FormStateInterface $form_state) {
$menu_link = $this
->getRequest()->query
->get('menu_link');
$form['#cache']['contexts'][] = 'url.query_args:menu_link';
$max_depth = $this->config
->get('max_depth') ?: 1;
return $this
->buildOverviewFormWithDepth($form, $form_state, $max_depth, $menu_link);
}
protected function buildOverviewFormWithDepth(array &$form, FormStateInterface $form_state, $depth = 1, $menu_link = NULL) {
if (!$form_state
->has('menu_overview_form_parents')) {
$form_state
->set('menu_overview_form_parents', []);
}
$form['#attached']['library'][] = 'menu_ui/drupal.menu_ui.adminforms';
if ($menu_link && $this->menuLinkManager
->hasDefinition($menu_link)) {
$breadcrumbs = [];
$parent = $this->menuLinkManager
->createInstance($menu_link);
while ($parent_id = $parent
->getParent()) {
$parent = $this->menuLinkManager
->createInstance($parent_id);
$breadcrumbs[] = new Link($parent
->getTitle(), $this->entity
->toUrl('edit-form')
->setOption('query', [
'menu_link' => $parent_id,
]));
}
$breadcrumbs[] = $this->entity
->toLink($this
->t('Back to @label top level', [
'@label' => $this->entity
->label(),
]), 'edit-form');
$form['breadcrumb'] = [
'#theme' => 'breadcrumb',
'#links' => array_reverse($breadcrumbs),
];
}
$form['links'] = [
'#type' => 'table',
'#theme' => 'table__menu_overview',
'#header' => [
$this
->t('Menu link'),
$this
->t('Edit children'),
[
'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' => $this->entity
->toUrl('add-link-form', [
'query' => [
'destination' => $this->entity
->toUrl('edit-form')
->toString(),
],
])
->toString(),
]);
if (empty($this->tree)) {
$this->tree = $this
->getTree($depth, $menu_link);
}
$count = function (array $tree) {
$sum = function ($carry, MenuLinkTreeElement $item) {
return $carry + $item
->count();
};
return array_reduce($tree, $sum);
};
$delta = max($count($this->tree), 50);
$links = $this
->buildOverviewTreeForm($this->tree, $delta);
$this
->processLinks($form, $links, $menu_link);
return $form;
}
public function processLinks(array &$form, array &$links, $menu_link) {
foreach (Element::children($links) as $id) {
if (isset($links[$id]['#item'])) {
$element = $links[$id];
$form['links'][$id]['#item'] = $element['#item'];
$form['links'][$id]['#attributes'] = $element['#attributes'];
$form['links'][$id]['#attributes']['class'][] = 'draggable';
$form['links'][$id]['#weight'] = $element['#item']->link
->getWeight();
$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]['root'][] = [];
if ($form['links'][$id]['#item']->hasChildren || $this
->hasAnyChildren($links[$id]['#item'])) {
if (is_null($menu_link) || isset($menu_link) && $menu_link != $element['#item']->link
->getPluginId()) {
$uri = $this->entity
->toUrl('edit-form', [
'query' => [
'menu_link' => $element['#item']->link
->getPluginId(),
],
]);
$form['links'][$id]['root'][] = [
'#type' => 'link',
'#title' => $this
->t('Edit child items'),
'#url' => $uri,
];
}
}
$form['links'][$id]['enabled'] = $element['enabled'];
$form['links'][$id]['enabled']['#wrapper_attributes']['class'] = [
'checkbox',
'menu-enabled',
];
$form['links'][$id]['weight'] = $element['weight'];
$form['links'][$id]['operations'] = $element['operations'];
$form['links'][$id]['id'] = $element['id'];
$form['links'][$id]['parent'] = $element['parent'];
}
}
}
protected function getTree($depth, $root = NULL) {
$tree_params = new MenuTreeParameters();
$tree_params
->setMaxDepth($depth);
if ($root) {
$tree_params
->setRoot($root);
}
$tree = $this->menuTree
->load($this->entity
->id(), $tree_params);
$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);
return $tree;
}
public function save(array $form, FormStateInterface $form_state) {
parent::save($form, $form_state);
$form_state
->setRedirectUrl(Url::fromUserInput($this
->getRedirectDestination()
->get()));
}
protected function hasAnyChildren(MenuLinkTreeElement $element) {
$depth = $element->depth + 1;
$tree_params = new MenuTreeParameters();
$tree_params
->setMinDepth($depth);
$tree_params
->setMaxDepth($depth);
$tree_params
->addExpandedParents([
$element->link
->getPluginId(),
]);
$tree = $this->menuTree
->load($this->entity
->id(), $tree_params);
return !empty($tree);
}
}