Issue #2301313 by pwolanin, dawehner, Wim Leers, effulgentsia, kgoel, YesCT, glide: MenuLinkNG part3 (no conversions): MenuLinkContent UI.
parent
49f4fddbf3
commit
ef4e932d71
|
@ -0,0 +1 @@
|
|||
definitions: []
|
|
@ -0,0 +1,27 @@
|
|||
|
||||
menu_link.static.overrides:
|
||||
type: mapping
|
||||
label: 'Menu link overrides'
|
||||
mapping:
|
||||
definitions:
|
||||
type: sequence
|
||||
label: Definitions
|
||||
sequence:
|
||||
- type: mapping
|
||||
label: Definition
|
||||
mapping:
|
||||
menu_name:
|
||||
type: string
|
||||
label: 'Menu name'
|
||||
parent:
|
||||
type: string
|
||||
label: 'Parent'
|
||||
weight:
|
||||
type: integer
|
||||
label: 'Weight'
|
||||
expanded:
|
||||
type: boolean
|
||||
label: 'Expanded'
|
||||
hidden:
|
||||
type: boolean
|
||||
label: 'Hidden'
|
|
@ -301,6 +301,11 @@ services:
|
|||
parent: default_plugin_manager
|
||||
plugin.cache_clearer:
|
||||
class: Drupal\Core\Plugin\CachedDiscoveryClearer
|
||||
paramconverter.menu_link:
|
||||
class: Drupal\Core\ParamConverter\MenuLinkPluginConverter
|
||||
tags:
|
||||
- { name: paramconverter }
|
||||
arguments: ['@plugin.manager.menu.link']
|
||||
menu.tree_storage:
|
||||
class: Drupal\Core\Menu\MenuTreeStorage
|
||||
arguments: ['@database', '@cache.menu', 'menu_tree']
|
||||
|
|
|
@ -0,0 +1,215 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Core\Menu\Form\MenuLinkDefaultForm.
|
||||
*/
|
||||
|
||||
namespace Drupal\Core\Menu\Form;
|
||||
|
||||
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
|
||||
use Drupal\Core\Menu\MenuLinkInterface;
|
||||
use Drupal\Core\Menu\MenuLinkManagerInterface;
|
||||
use Drupal\Core\Menu\MenuParentFormSelectorInterface;
|
||||
use Drupal\Core\Extension\ModuleHandlerInterface;
|
||||
use Drupal\Core\StringTranslation\StringTranslationTrait;
|
||||
use Drupal\Core\StringTranslation\TranslationInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Provides an edit form for static menu links.
|
||||
*
|
||||
* @see \Drupal\Core\Menu\MenuLinkDefault
|
||||
*/
|
||||
class MenuLinkDefaultForm implements MenuLinkFormInterface, ContainerInjectionInterface {
|
||||
|
||||
use StringTranslationTrait;
|
||||
|
||||
/**
|
||||
* The edited menu link.
|
||||
*
|
||||
* @var \Drupal\Core\Menu\MenuLinkInterface
|
||||
*/
|
||||
protected $menuLink;
|
||||
|
||||
/**
|
||||
* The menu link manager.
|
||||
*
|
||||
* @var \Drupal\Core\Menu\MenuLinkManagerInterface
|
||||
*/
|
||||
protected $menuLinkManager;
|
||||
|
||||
/**
|
||||
* The parent form selector service.
|
||||
*
|
||||
* @var \Drupal\Core\Menu\MenuParentFormSelectorInterface
|
||||
*/
|
||||
protected $menuParentSelector;
|
||||
|
||||
/**
|
||||
* The module handler service.
|
||||
*
|
||||
* @var \Drupal\Core\Extension\ModuleHandlerInterface
|
||||
*/
|
||||
protected $moduleHandler;
|
||||
|
||||
/**
|
||||
* The module data from system_get_info().
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $moduleData;
|
||||
|
||||
/**
|
||||
* Constructs a new \Drupal\Core\Menu\Form\MenuLinkDefaultForm.
|
||||
*
|
||||
* @param \Drupal\Core\Menu\MenuLinkManagerInterface $menu_link_manager
|
||||
* The menu link manager.
|
||||
* @param \Drupal\Core\Menu\MenuParentFormSelectorInterface $menu_parent_selector
|
||||
* The menu parent form selector service.
|
||||
* @param \Drupal\Core\StringTranslation\TranslationInterface $string_translation
|
||||
* The string translation.
|
||||
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
|
||||
* The module handler;
|
||||
*/
|
||||
public function __construct(MenuLinkManagerInterface $menu_link_manager, MenuParentFormSelectorInterface $menu_parent_selector, TranslationInterface $string_translation, ModuleHandlerInterface $module_handler) {
|
||||
$this->menuLinkManager = $menu_link_manager;
|
||||
$this->menuParentSelector = $menu_parent_selector;
|
||||
$this->stringTranslation = $string_translation;
|
||||
$this->moduleHandler = $module_handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
return new static(
|
||||
$container->get('plugin.manager.menu.link'),
|
||||
$container->get('menu.parent_form_selector'),
|
||||
$container->get('string_translation'),
|
||||
$container->get('module_handler')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setMenuLinkInstance(MenuLinkInterface $menu_link) {
|
||||
$this->menuLink = $menu_link;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildConfigurationForm(array $form, array &$form_state) {
|
||||
$form['#title'] = $this->t('Edit menu link %title', array('%title' => $this->menuLink->getTitle()));
|
||||
|
||||
$provider = $this->menuLink->getProvider();
|
||||
$form['info'] = array(
|
||||
'#type' => 'item',
|
||||
'#title' => $this->t('This link is provided by the @name module. The title and path cannot be edited.', array('@name' => $this->getModuleName($provider))),
|
||||
);
|
||||
$link = array(
|
||||
'#type' => 'link',
|
||||
'#title' => $this->menuLink->getTitle(),
|
||||
) + $this->menuLink->getUrlObject()->toRenderArray();
|
||||
$form['path'] = array(
|
||||
'link' => $link,
|
||||
'#type' => 'item',
|
||||
'#title' => $this->t('Link'),
|
||||
);
|
||||
|
||||
$form['enabled'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => $this->t('Enable menu link'),
|
||||
'#description' => $this->t('Menu links that are not enabled will not be listed in any menu.'),
|
||||
'#default_value' => !$this->menuLink->isHidden(),
|
||||
);
|
||||
|
||||
$form['expanded'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Show as expanded'),
|
||||
'#description' => $this->t('If selected and this menu link has children, the menu will always appear expanded.'),
|
||||
'#default_value' => $this->menuLink->isExpanded(),
|
||||
);
|
||||
|
||||
$menu_parent = $this->menuLink->getMenuName() . ':' . $this->menuLink->getParent();
|
||||
$form['menu_parent'] = $this->menuParentSelector->parentSelectElement($menu_parent, $this->menuLink->getPluginId());
|
||||
$form['menu_parent']['#title'] = $this->t('Parent link');
|
||||
$form['menu_parent']['#description'] = $this->t('The maximum depth for a link and all its children is fixed. Some menu links may not be available as parents if selecting them would exceed this limit.');
|
||||
$form['menu_parent']['#attributes']['class'][] = 'menu-title-select';
|
||||
|
||||
$delta = max(abs($this->menuLink->getWeight()), 50);
|
||||
$form['weight'] = array(
|
||||
'#type' => 'number',
|
||||
'#min' => -$delta,
|
||||
'#max' => $delta,
|
||||
'#default_value' => $this->menuLink->getWeight(),
|
||||
'#title' => $this->t('Weight'),
|
||||
'#description' => $this->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.'),
|
||||
);
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function extractFormValues(array &$form, array &$form_state) {
|
||||
$new_definition = array();
|
||||
$new_definition['hidden'] = $form_state['values']['enabled'] ? 0 : 1;
|
||||
$new_definition['weight'] = (int) $form_state['values']['weight'];
|
||||
$new_definition['expanded'] = $form_state['values']['expanded'] ? 1 : 0;
|
||||
list($menu_name, $parent) = explode(':', $form_state['values']['menu_parent'], 2);
|
||||
if (!empty($menu_name)) {
|
||||
$new_definition['menu_name'] = $menu_name;
|
||||
}
|
||||
if (isset($parent)) {
|
||||
$new_definition['parent'] = $parent;
|
||||
}
|
||||
return $new_definition;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function validateConfigurationForm(array &$form, array &$form_state) {
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function submitConfigurationForm(array &$form, array &$form_state) {
|
||||
$new_definition = $this->extractFormValues($form, $form_state);
|
||||
|
||||
return $this->menuLinkManager->updateDefinition($this->menuLink->getPluginId(), $new_definition);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of the module.
|
||||
*
|
||||
* @param string $module
|
||||
* The machine name of a module.
|
||||
*
|
||||
* @todo This function is horrible, but core has nothing better until we add a
|
||||
* a method to the ModuleHandler that handles this nicely.
|
||||
* https://drupal.org/node/2281989
|
||||
*
|
||||
* @return string
|
||||
* The human-readable, localized module name, or the machine name passed in
|
||||
* if no matching module is found.
|
||||
*/
|
||||
protected function getModuleName($module) {
|
||||
// Gather module data.
|
||||
if (!isset($this->moduleData)) {
|
||||
$this->moduleData = system_get_info('module');
|
||||
}
|
||||
// If the module exists, return its human-readable name.
|
||||
if (isset($this->moduleData[$module])) {
|
||||
return $this->t($this->moduleData[$module]['name']);
|
||||
}
|
||||
// Otherwise, return the machine name.
|
||||
return $module;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Core\Menu\Form\MenuLinkFormInterface.
|
||||
*/
|
||||
|
||||
namespace Drupal\Core\Menu\Form;
|
||||
|
||||
use Drupal\Core\Menu\MenuLinkInterface;
|
||||
use Drupal\Core\Plugin\PluginFormInterface;
|
||||
|
||||
/**
|
||||
* Defines an interface for edit forms of menu links.
|
||||
*
|
||||
* All menu link plugins use the same interface for their configuration or
|
||||
* editing form, but the implementations may differ.
|
||||
*
|
||||
* @see \Drupal\Core\Menu\MenuLinkInterface::getFormClass()
|
||||
*/
|
||||
interface MenuLinkFormInterface extends PluginFormInterface {
|
||||
|
||||
/**
|
||||
* Injects the menu link plugin instance.
|
||||
*
|
||||
* @param \Drupal\Core\Menu\MenuLinkInterface $menu_link
|
||||
* A menu link plugin instance.
|
||||
*/
|
||||
public function setMenuLinkInstance(MenuLinkInterface $menu_link);
|
||||
|
||||
/**
|
||||
* Extracts a plugin definition from form values.
|
||||
*
|
||||
* @param array $form
|
||||
* An associative array containing the structure of the form.
|
||||
* @param array $form_state
|
||||
* An associative array containing the current state of the form.
|
||||
*
|
||||
* @return array
|
||||
* The new plugin definition values taken from the form values.
|
||||
*/
|
||||
public function extractFormValues(array &$form, array &$form_state);
|
||||
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Core\ParamConverter\MenuLinkPluginConverter.
|
||||
*/
|
||||
|
||||
namespace Drupal\Core\ParamConverter;
|
||||
|
||||
use Drupal\Core\Menu\MenuLinkManagerInterface;
|
||||
use Drupal\Component\Plugin\Exception\PluginException;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\Routing\Route;
|
||||
|
||||
/**
|
||||
* Parameter converter for upcasting entity ids to full objects.
|
||||
*/
|
||||
class MenuLinkPluginConverter implements ParamConverterInterface {
|
||||
|
||||
/**
|
||||
* Plugin manager which creates the instance from the value.
|
||||
*
|
||||
* @var \Drupal\Core\Menu\MenuLinkManagerInterface
|
||||
*/
|
||||
protected $menuLinkManager;
|
||||
|
||||
/**
|
||||
* Constructs a new MenuLinkPluginConverter.
|
||||
*
|
||||
* @param \Drupal\Core\Menu\MenuLinkManagerInterface $menu_link_manager
|
||||
* The menu link plugin manager.
|
||||
*/
|
||||
public function __construct(MenuLinkManagerInterface $menu_link_manager) {
|
||||
$this->menuLinkManager = $menu_link_manager;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function convert($value, $definition, $name, array $defaults, Request $request) {
|
||||
if ($value) {
|
||||
try {
|
||||
return $this->menuLinkManager->createInstance($value);
|
||||
}
|
||||
catch (PluginException $e) {
|
||||
// Suppress the error.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function applies($definition, $name, Route $route) {
|
||||
return (!empty($definition['type']) && $definition['type'] === 'menu_link_plugin');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
menu_link_content.link_edit:
|
||||
route_name: menu_link_content.link_edit
|
||||
base_route: menu_link_content.link_edit
|
||||
title: Edit
|
|
@ -0,0 +1,23 @@
|
|||
menu_link_content.link_add:
|
||||
path: '/admin/structure/menu/manage/{menu}/add'
|
||||
defaults:
|
||||
_content: '\Drupal\menu_link_content\Controller\MenuController::addLink'
|
||||
_title: 'Add menu link'
|
||||
requirements:
|
||||
_entity_create_access: 'menu_link_content'
|
||||
|
||||
menu_link_content.link_edit:
|
||||
path: '/admin/structure/menu/item/{menu_link_content}/edit'
|
||||
defaults:
|
||||
_entity_form: 'menu_link_content.default'
|
||||
_title: 'Edit menu link'
|
||||
requirements:
|
||||
_entity_access: 'menu_link_content.update'
|
||||
|
||||
menu_link_content.link_delete:
|
||||
path: '/admin/structure/menu/item/{menu_link_content}/delete'
|
||||
defaults:
|
||||
_entity_form: 'menu_link_content.delete'
|
||||
_title: 'Delete menu link'
|
||||
requirements:
|
||||
_entity_access: 'menu_link_content.delete'
|
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\menu_link_content\Controller\MenuController.
|
||||
*/
|
||||
|
||||
namespace Drupal\menu_link_content\Controller;
|
||||
|
||||
use Drupal\Core\Controller\ControllerBase;
|
||||
use Drupal\system\MenuInterface;
|
||||
|
||||
/**
|
||||
* Defines a route controller for a form for menu link content entity creation.
|
||||
*/
|
||||
class MenuController extends ControllerBase {
|
||||
|
||||
/**
|
||||
* Provides the menu link creation form.
|
||||
*
|
||||
* @param \Drupal\system\MenuInterface $menu
|
||||
* An entity representing a custom menu.
|
||||
*
|
||||
* @return array
|
||||
* Returns the menu link creation form.
|
||||
*/
|
||||
public function addLink(MenuInterface $menu) {
|
||||
$menu_link = $this->entityManager()->getStorage('menu_link_content')->create(array(
|
||||
'id' => '',
|
||||
'parent' => '',
|
||||
'menu_name' => $menu->id(),
|
||||
'bundle' => 'menu_link_content',
|
||||
));
|
||||
return $this->entityFormBuilder()->getForm($menu_link);
|
||||
}
|
||||
|
||||
}
|
|
@ -41,6 +41,7 @@ use Drupal\Core\Url;
|
|||
* links = {
|
||||
* "canonical" = "menu_link_content.link_edit",
|
||||
* "edit-form" = "menu_link_content.link_edit",
|
||||
* "delete-form" = "menu_link_content.link_delete",
|
||||
* }
|
||||
* )
|
||||
*/
|
||||
|
@ -336,30 +337,9 @@ class MenuLinkContent extends ContentEntityBase implements MenuLinkContentInterf
|
|||
->setDescription(t('A flag to indicate if the link points to a full URL starting with a protocol, like http:// (1 = external, 0 = internal).'))
|
||||
->setSetting('default_value', FALSE);
|
||||
|
||||
// The form widget doesn't work yet for core fields, so we skip the
|
||||
// for display and manually create form elements for the boolean fields.
|
||||
// @see https://drupal.org/node/2226493
|
||||
// @see https://drupal.org/node/2150511
|
||||
$fields['expanded'] = FieldDefinition::create('boolean')
|
||||
->setLabel(t('Expanded'))
|
||||
->setDescription(t('Flag for whether this link should be rendered as expanded in menus - expanded links always have their child links displayed, instead of only when the link is in the active trail (1 = expanded, 0 = not expanded).'))
|
||||
->setSetting('default_value', FALSE)
|
||||
->setDisplayOptions('view', array(
|
||||
'label' => 'hidden',
|
||||
'type' => 'boolean',
|
||||
'weight' => 0,
|
||||
));
|
||||
|
||||
// We manually create a form element for this, since the form logic is
|
||||
// is inverted to show enabled.
|
||||
$fields['hidden'] = FieldDefinition::create('boolean')
|
||||
->setLabel(t('Hidden'))
|
||||
->setDescription(t('A flag for whether the link should be hidden in menus or rendered normally.'))
|
||||
->setSetting('default_value', FALSE);
|
||||
|
||||
$fields['weight'] = FieldDefinition::create('integer')
|
||||
->setLabel(t('Weight'))
|
||||
->setDescription(t('Link weight among links in the same menu at the same depth.'))
|
||||
->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.'))
|
||||
->setSetting('default_value', 0)
|
||||
->setDisplayOptions('view', array(
|
||||
'label' => 'hidden',
|
||||
|
@ -368,9 +348,31 @@ class MenuLinkContent extends ContentEntityBase implements MenuLinkContentInterf
|
|||
))
|
||||
->setDisplayOptions('form', array(
|
||||
'type' => 'integer',
|
||||
'weight' => 20,
|
||||
));
|
||||
|
||||
$fields['expanded'] = FieldDefinition::create('boolean')
|
||||
->setLabel(t('Show as expanded'))
|
||||
->setDescription(t('If selected and this menu link has children, the menu will always appear expanded.'))
|
||||
->setSetting('default_value', FALSE)
|
||||
->setDisplayOptions('view', array(
|
||||
'label' => 'hidden',
|
||||
'type' => 'boolean',
|
||||
'weight' => 0,
|
||||
))
|
||||
->setDisplayOptions('form', array(
|
||||
'settings' => array('display_label' => TRUE),
|
||||
'weight' => 0,
|
||||
));
|
||||
|
||||
// @todo We manually create a form element for this, since the form logic is
|
||||
// is inverted to show enabled. Flip this to a status field and use the
|
||||
// normal entity Boolean widget. https://www.drupal.org/node/2305707
|
||||
$fields['hidden'] = FieldDefinition::create('boolean')
|
||||
->setLabel(t('Hidden'))
|
||||
->setDescription(t('A flag for whether the link should be hidden in menus or rendered normally.'))
|
||||
->setSetting('default_value', FALSE);
|
||||
|
||||
$fields['langcode'] = FieldDefinition::create('language')
|
||||
->setLabel(t('Language code'))
|
||||
->setDescription(t('The node language code.'));
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\menu_link_content\Form\MenuLinkContentDeleteForm.
|
||||
*/
|
||||
|
||||
namespace Drupal\menu_link_content\Form;
|
||||
|
||||
use Drupal\Core\Entity\ContentEntityConfirmFormBase;
|
||||
use Drupal\Core\Entity\EntityManagerInterface;
|
||||
use Drupal\Core\Logger\LoggerChannelFactoryInterface;
|
||||
use Drupal\Core\Url;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Provides a delete form for content menu links.
|
||||
*/
|
||||
class MenuLinkContentDeleteForm extends ContentEntityConfirmFormBase {
|
||||
|
||||
/**
|
||||
* Logger channel.
|
||||
*
|
||||
* @var \Drupal\Core\Logger\LoggerChannelInterface
|
||||
*/
|
||||
protected $logger;
|
||||
|
||||
/**
|
||||
* Constructs a MenuLinkContentDeleteForm object.
|
||||
*
|
||||
* @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
|
||||
* The entity manager.
|
||||
* @param \Drupal\Core\Logger\LoggerChannelFactoryInterface $logger_factory
|
||||
* The logger channel factory.
|
||||
*/
|
||||
public function __construct(EntityManagerInterface $entity_manager, LoggerChannelFactoryInterface $logger_factory) {
|
||||
parent::__construct($entity_manager);
|
||||
$this->logger = $logger_factory->get('menu');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
return new static(
|
||||
$container->get('entity.manager'),
|
||||
$container->get('logger.factory')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getQuestion() {
|
||||
return $this->t('Are you sure you want to delete the custom menu link %item?', array('%item' => $this->entity->getTitle()));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCancelRoute() {
|
||||
return new Url('menu_ui.menu_edit', array('menu' => $this->entity->getMenuName()));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function submit(array $form, array &$form_state) {
|
||||
$t_args = array('%title' => $this->entity->getTitle());
|
||||
$this->entity->delete();
|
||||
drupal_set_message($this->t('The menu link %title has been deleted.', $t_args));
|
||||
$this->logger->notice('Deleted menu link %title.', $t_args);
|
||||
$form_state['redirect_route'] = array(
|
||||
'route_name' => '<front>',
|
||||
);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,440 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\menu_link_content\Form\MenuLinkContentForm.
|
||||
*/
|
||||
|
||||
namespace Drupal\menu_link_content\Form;
|
||||
|
||||
use Drupal\Component\Utility\UrlHelper;
|
||||
use Drupal\Core\Access\AccessManager;
|
||||
use Drupal\Core\Entity\ContentEntityForm;
|
||||
use Drupal\Core\Entity\EntityManagerInterface;
|
||||
use Drupal\Core\Extension\ModuleHandlerInterface;
|
||||
use Drupal\Core\Language\Language;
|
||||
use Drupal\Core\Language\LanguageManagerInterface;
|
||||
use Drupal\Core\Menu\Form\MenuLinkFormInterface;
|
||||
use Drupal\Core\Menu\MenuLinkInterface;
|
||||
use Drupal\Core\Menu\MenuParentFormSelectorInterface;
|
||||
use Drupal\Core\ParamConverter\ParamNotConvertedException;
|
||||
use Drupal\Core\Path\AliasManagerInterface;
|
||||
use Drupal\Core\Routing\MatchingRouteNotFoundException;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
use Drupal\Core\Url;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\Routing\RequestContext;
|
||||
|
||||
/**
|
||||
* Provides a form to add/update content menu links.
|
||||
*
|
||||
* Note: This is not only a content entity form, but also implements the
|
||||
* MenuLinkFormInterface, so the same class can be used in places expecting a
|
||||
* generic menu link plugin configuration form.
|
||||
*/
|
||||
class MenuLinkContentForm extends ContentEntityForm implements MenuLinkFormInterface {
|
||||
|
||||
/**
|
||||
* The content menu link.
|
||||
*
|
||||
* @var \Drupal\menu_link_content\Entity\MenuLinkContentInterface
|
||||
*/
|
||||
protected $entity;
|
||||
|
||||
/**
|
||||
* The parent form selector service.
|
||||
*
|
||||
* @var \Drupal\Core\Menu\MenuParentFormSelectorInterface
|
||||
*/
|
||||
protected $menuParentSelector;
|
||||
|
||||
/**
|
||||
* The request context.
|
||||
*
|
||||
* @var \Symfony\Component\Routing\RequestContext
|
||||
*/
|
||||
protected $requestContext;
|
||||
|
||||
/**
|
||||
* The language manager.
|
||||
*
|
||||
* @var \Drupal\Core\Language\LanguageManagerInterface
|
||||
*/
|
||||
protected $languageManager;
|
||||
|
||||
/**
|
||||
* The access manager.
|
||||
*
|
||||
* @var \Drupal\Core\Access\AccessManager
|
||||
*/
|
||||
protected $accessManager;
|
||||
|
||||
/**
|
||||
* The current user.
|
||||
*
|
||||
* @var \Drupal\Core\Session\AccountInterface
|
||||
*/
|
||||
protected $account;
|
||||
|
||||
/**
|
||||
* Constructs a MenuLinkContentForm object.
|
||||
*
|
||||
* @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
|
||||
* The entity manager.
|
||||
* @param \Drupal\Core\Menu\MenuParentFormSelectorInterface $menu_parent_selector
|
||||
* The menu parent form selector service.
|
||||
* @param \Drupal\Core\Path\AliasManagerInterface $alias_manager
|
||||
* The alias manager.
|
||||
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
|
||||
* The module handler;
|
||||
* @param \Symfony\Component\Routing\RequestContext $request_context
|
||||
* The request context.
|
||||
* @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
|
||||
* The language manager.
|
||||
* @param \Drupal\Core\Access\AccessManager $access_manager
|
||||
* The access manager.
|
||||
* @param \Drupal\Core\Session\AccountInterface $account
|
||||
* The current user.
|
||||
*/
|
||||
public function __construct(EntityManagerInterface $entity_manager, MenuParentFormSelectorInterface $menu_parent_selector, AliasManagerInterface $alias_manager, ModuleHandlerInterface $module_handler, RequestContext $request_context, LanguageManagerInterface $language_manager, AccessManager $access_manager, AccountInterface $account) {
|
||||
parent::__construct($entity_manager, $language_manager);
|
||||
$this->menuParentSelector = $menu_parent_selector;
|
||||
$this->pathAliasManager = $alias_manager;
|
||||
$this->moduleHandler = $module_handler;
|
||||
$this->requestContext = $request_context;
|
||||
$this->languageManager = $language_manager;
|
||||
$this->accessManager = $access_manager;
|
||||
$this->account = $account;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
return new static(
|
||||
$container->get('entity.manager'),
|
||||
$container->get('menu.parent_form_selector'),
|
||||
$container->get('path.alias_manager'),
|
||||
$container->get('module_handler'),
|
||||
$container->get('router.request_context'),
|
||||
$container->get('language_manager'),
|
||||
$container->get('access_manager'),
|
||||
$container->get('current_user')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setMenuLinkInstance(MenuLinkInterface $menu_link) {
|
||||
// Load the entity for the entity form. Loading by entity ID is much faster
|
||||
// than loading by UUID, so use that ID if we have it.
|
||||
$metadata = $menu_link->getMetaData();
|
||||
if (!empty($metadata['entity_id'])) {
|
||||
$this->entity = $this->entityManager->getStorage('menu_link_content')->load($metadata['entity_id']);
|
||||
}
|
||||
else {
|
||||
// Fallback to the loading by UUID.
|
||||
$links = $this->entityManager->getStorage('menu_link_content')->loadByProperties(array('uuid' => $menu_link->getDerivativeId()));
|
||||
$this->entity = reset($links);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildConfigurationForm(array $form, array &$form_state) {
|
||||
return $this->buildEditForm($form, $form_state);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildEditForm(array &$form, array &$form_state) {
|
||||
$this->setOperation('default');
|
||||
$this->init($form_state);
|
||||
|
||||
return $this->form($form, $form_state);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function validateConfigurationForm(array &$form, array &$form_state) {
|
||||
$this->doValidate($form, $form_state);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function validateEditForm(array &$form, array &$form_state) {
|
||||
$this->doValidate($form, $form_state);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function submitConfigurationForm(array &$form, array &$form_state) {
|
||||
return $this->submitEditForm($form, $form_state);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function submitEditForm(array &$form, array &$form_state) {
|
||||
// Remove button and internal Form API values from submitted values.
|
||||
form_state_values_clean($form_state);
|
||||
$this->entity = $this->buildEntity($form, $form_state);
|
||||
$this->entity->save();
|
||||
return $form_state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Breaks up a user-entered URL or path into all the relevant parts.
|
||||
*
|
||||
* @param string $url
|
||||
* The user-entered URL or path.
|
||||
*
|
||||
* @return array
|
||||
* The extracted parts.
|
||||
*/
|
||||
protected function extractUrl($url) {
|
||||
$extracted = UrlHelper::parse($url);
|
||||
$external = UrlHelper::isExternal($url);
|
||||
if ($external) {
|
||||
$extracted['url'] = $extracted['path'];
|
||||
$extracted['route_name'] = NULL;
|
||||
$extracted['route_parameters'] = array();
|
||||
}
|
||||
else {
|
||||
$extracted['url'] = '';
|
||||
// If the path doesn't match a Drupal path, the route should end up empty.
|
||||
$extracted['route_name'] = NULL;
|
||||
$extracted['route_parameters'] = array();
|
||||
try {
|
||||
// Find the route_name.
|
||||
$normal_path = $this->pathAliasManager->getPathByAlias($extracted['path']);
|
||||
$url_obj = Url::createFromPath($normal_path);
|
||||
$extracted['route_name'] = $url_obj->getRouteName();
|
||||
$extracted['route_parameters'] = $url_obj->getRouteParameters();
|
||||
}
|
||||
catch (MatchingRouteNotFoundException $e) {
|
||||
// The path doesn't match a Drupal path.
|
||||
}
|
||||
catch (ParamNotConvertedException $e) {
|
||||
// A path like node/99 matched a route, but the route parameter was
|
||||
// invalid (e.g. node with ID 99 does not exist).
|
||||
}
|
||||
}
|
||||
return $extracted;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function extractFormValues(array &$form, array &$form_state) {
|
||||
$new_definition = array();
|
||||
$new_definition['expanded'] = !empty($form_state['values']['expanded']) ? 1 : 0;
|
||||
$new_definition['hidden'] = empty($form_state['values']['enabled']) ? 1 : 0;
|
||||
list($menu_name, $parent) = explode(':', $form_state['values']['menu_parent'], 2);
|
||||
if (!empty($menu_name)) {
|
||||
$new_definition['menu_name'] = $menu_name;
|
||||
}
|
||||
$new_definition['parent'] = isset($parent) ? $parent : '';
|
||||
|
||||
$extracted = $this->extractUrl($form_state['values']['url']);
|
||||
$new_definition['url'] = $extracted['url'];
|
||||
$new_definition['route_name'] = $extracted['route_name'];
|
||||
$new_definition['route_parameters'] = $extracted['route_parameters'];
|
||||
$new_definition['options'] = array();
|
||||
if ($extracted['query']) {
|
||||
$new_definition['options']['query'] = $extracted['query'];
|
||||
}
|
||||
if ($extracted['fragment']) {
|
||||
$new_definition['options']['fragment'] = $extracted['fragment'];
|
||||
}
|
||||
$new_definition['title'] = $form_state['values']['title'][0]['value'];
|
||||
$new_definition['description'] = $form_state['values']['description'][0]['value'];
|
||||
$new_definition['weight'] = (int) $form_state['values']['weight'][0]['value'];
|
||||
|
||||
return $new_definition;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function form(array $form, array &$form_state) {
|
||||
$form = parent::form($form, $form_state);
|
||||
|
||||
// We always show the internal path here.
|
||||
/** @var \Drupal\Core\Url $url */
|
||||
$url = $this->getEntity()->getUrlObject();
|
||||
if ($url->isExternal()) {
|
||||
$default_value = $url->toString();
|
||||
}
|
||||
elseif ($url->getRouteName() == '<front>') {
|
||||
// The default route for new entities is <front>, but we just want an
|
||||
// empty form field.
|
||||
$default_value = $this->getEntity()->isNew() ? '' : '<front>';
|
||||
}
|
||||
else {
|
||||
// @todo Url::getInternalPath() calls UrlGenerator::getPathFromRoute()
|
||||
// which need a replacement since it is deprecated.
|
||||
// https://www.drupal.org/node/2307061
|
||||
$default_value = $url->getInternalPath();
|
||||
// @todo Add a helper method to Url to render just the query string and
|
||||
// fragment. https://www.drupal.org/node/2305013
|
||||
$options = $url->getOptions();
|
||||
if (isset($options['query'])) {
|
||||
$default_value .= $options['query'] ? ('?' . UrlHelper::buildQuery($options['query'])) : '';
|
||||
}
|
||||
if (isset($options['fragment']) && $options['fragment'] !== '') {
|
||||
$default_value .= '#' . $options['fragment'];
|
||||
}
|
||||
}
|
||||
$form['url'] = array(
|
||||
'#title' => $this->t('Link path'),
|
||||
'#type' => 'textfield',
|
||||
'#description' => $this->t('The path for this menu link. This can be an internal Drupal path such as %add-node or an external URL such as %drupal. Enter %front to link to the front page.', array('%front' => '<front>', '%add-node' => 'node/add', '%drupal' => 'http://drupal.org')),
|
||||
'#default_value' => $default_value,
|
||||
'#required' => TRUE,
|
||||
'#weight' => -2,
|
||||
);
|
||||
|
||||
$language_configuration = $this->moduleHandler->invoke('language', 'get_default_configuration', array('menu_link_content', 'menu_link_content'));
|
||||
if ($this->entity->isNew()) {
|
||||
$default_language = isset($language_configuration['langcode']) ? $language_configuration['langcode'] : $this->languageManager->getDefaultLanguage()->getId();
|
||||
}
|
||||
else {
|
||||
$default_language = $this->entity->getUntranslated()->language()->getId();
|
||||
}
|
||||
$form['langcode'] = array(
|
||||
'#title' => t('Language'),
|
||||
'#type' => 'language_select',
|
||||
'#default_value' => $default_language,
|
||||
'#languages' => Language::STATE_ALL,
|
||||
'#access' => !empty($language_configuration['language_show']),
|
||||
);
|
||||
|
||||
$form['enabled'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => $this->t('Enable menu link'),
|
||||
'#description' => $this->t('Menu links that are not enabled will not be listed in any menu.'),
|
||||
'#default_value' => !$this->entity->isHidden(),
|
||||
'#weight' => 0,
|
||||
);
|
||||
|
||||
$default = $this->entity->getMenuName() . ':' . $this->entity->getParentId();
|
||||
$form['menu_parent'] = $this->menuParentSelector->parentSelectElement($default, $this->entity->getPluginId());
|
||||
$form['menu_parent']['#weight'] = 10;
|
||||
$form['menu_parent']['#title'] = $this->t('Parent link');
|
||||
$form['menu_parent']['#description'] = $this->t('The maximum depth for a link and all its children is fixed. Some menu links may not be available as parents if selecting them would exceed this limit.');
|
||||
$form['menu_parent']['#attributes']['class'][] = 'menu-title-select';
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function actions(array $form, array &$form_state) {
|
||||
$element = parent::actions($form, $form_state);
|
||||
$element['submit']['#button_type'] = 'primary';
|
||||
$element['delete']['#access'] = $this->entity->access('delete');
|
||||
|
||||
return $element;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function validate(array $form, array &$form_state) {
|
||||
$this->doValidate($form, $form_state);
|
||||
|
||||
parent::validate($form, $form_state);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildEntity(array $form, array &$form_state) {
|
||||
/** @var \Drupal\menu_link_content\Entity\MenuLinkContentInterface $entity */
|
||||
$entity = parent::buildEntity($form, $form_state);
|
||||
$new_definition = $this->extractFormValues($form, $form_state);
|
||||
|
||||
$entity->parent->value = $new_definition['parent'];
|
||||
$entity->menu_name->value = $new_definition['menu_name'];
|
||||
$entity->hidden->value = (bool) $new_definition['hidden'];
|
||||
$entity->expanded->value = $new_definition['expanded'];
|
||||
|
||||
$entity->url->value = $new_definition['url'];
|
||||
$entity->route_name->value = $new_definition['route_name'];
|
||||
$entity->setRouteParameters($new_definition['route_parameters']);
|
||||
$entity->setOptions($new_definition['options']);
|
||||
|
||||
return $entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function save(array $form, array &$form_state) {
|
||||
// The entity is rebuilt in parent::submit().
|
||||
$menu_link = $this->entity;
|
||||
$saved = $menu_link->save();
|
||||
|
||||
if ($saved) {
|
||||
drupal_set_message($this->t('The menu link has been saved.'));
|
||||
$form_state['redirect_route'] = array(
|
||||
'route_name' => 'menu_link_content.link_edit',
|
||||
'route_parameters' => array(
|
||||
'menu_link_content' => $menu_link->id(),
|
||||
),
|
||||
);
|
||||
}
|
||||
else {
|
||||
drupal_set_message($this->t('There was an error saving the menu link.'), 'error');
|
||||
$form_state['rebuild'] = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the form, both on the menu link edit and content menu link form.
|
||||
*
|
||||
* $form is not currently used, but passed here to match the normal form
|
||||
* validation method signature.
|
||||
*
|
||||
* @param array $form
|
||||
* A nested array form elements comprising the form.
|
||||
* @param array $form_state
|
||||
* An associative array containing the current state of the form.
|
||||
*/
|
||||
protected function doValidate(array $form, array &$form_state) {
|
||||
$extracted = $this->extractUrl($form_state['values']['url']);
|
||||
|
||||
// If both URL and route_name are empty, the entered value is not valid.
|
||||
$valid = FALSE;
|
||||
if ($extracted['url']) {
|
||||
// This is an external link.
|
||||
$valid = TRUE;
|
||||
}
|
||||
elseif ($extracted['route_name']) {
|
||||
// Users are not allowed to add a link to a page they cannot access.
|
||||
$valid = $this->accessManager->checkNamedRoute($extracted['route_name'], $extracted['route_parameters'], $this->account);
|
||||
}
|
||||
if (!$valid) {
|
||||
$this->setFormError('url', $form_state, $this->t("The path '@link_path' is either invalid or you do not have access to it.", array('@link_path' => $form_state['values']['url'])));
|
||||
}
|
||||
elseif ($extracted['route_name']) {
|
||||
// The user entered a Drupal path.
|
||||
$normal_path = $this->pathAliasManager->getPathByAlias($extracted['path']);
|
||||
if ($extracted['path'] != $normal_path) {
|
||||
drupal_set_message($this->t('The menu system stores system paths only, but will use the URL alias for display. %link_path has been stored as %normal_path', array(
|
||||
'%link_path' => $extracted['path'],
|
||||
'%normal_path' => $normal_path,
|
||||
)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\menu_link_content\Tests\MenuLinkContentUITest.
|
||||
*/
|
||||
|
||||
namespace Drupal\menu_link_content\Tests;
|
||||
|
||||
use Drupal\content_translation\Tests\ContentTranslationUITest;
|
||||
|
||||
/**
|
||||
* Tests the menu link content UI.
|
||||
*
|
||||
* @group Menu
|
||||
*/
|
||||
class MenuLinkContentUITest extends ContentTranslationUITest {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array(
|
||||
'language',
|
||||
'content_translation',
|
||||
'menu_link_content',
|
||||
'menu_ui',
|
||||
);
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setUp() {
|
||||
$this->entityTypeId = 'menu_link_content';
|
||||
$this->bundle = 'menu_link_content';
|
||||
$this->fieldName = 'title';
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getTranslatorPermissions() {
|
||||
return array_merge(parent::getTranslatorPermissions(), array('administer menu'));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function createEntity($values, $langcode, $bundle_name = NULL) {
|
||||
$values['menu_name'] = 'tools';
|
||||
$values['route_name'] = 'menu_ui.overview_page';
|
||||
$values['title'] = 'Test title';
|
||||
|
||||
return parent::createEntity($values, $langcode, $bundle_name);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,105 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\menu_ui\Form\MenuLinkEditForm.
|
||||
*/
|
||||
|
||||
namespace Drupal\menu_ui\Form;
|
||||
|
||||
use Drupal\Core\DependencyInjection\ClassResolverInterface;
|
||||
use Drupal\Core\Form\FormBase;
|
||||
use Drupal\Core\Menu\MenuLinkInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Defines a generic edit form for all menu link plugin types.
|
||||
*
|
||||
* The menu link plugin defines which class defines the corresponding form.
|
||||
*
|
||||
* @see \Drupal\Core\Menu\MenuLinkInterface::getFormClass()
|
||||
*/
|
||||
class MenuLinkEditForm extends FormBase {
|
||||
|
||||
/**
|
||||
* The class resolver
|
||||
*
|
||||
* @var \Drupal\Core\DependencyInjection\ClassResolverInterface
|
||||
*/
|
||||
protected $classResolver;
|
||||
|
||||
/**
|
||||
* Constructs a MenuLinkEditForm object.
|
||||
*
|
||||
* @param \Drupal\Core\DependencyInjection\ClassResolverInterface $class_resolver
|
||||
* The class resolver.
|
||||
*/
|
||||
public function __construct(ClassResolverInterface $class_resolver) {
|
||||
$this->classResolver = $class_resolver;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
return new static(
|
||||
$container->get('class_resolver')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFormId() {
|
||||
return 'menu_link_edit';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @param \Drupal\Core\Menu\MenuLinkInterface $menu_link_plugin
|
||||
* The plugin instance to use for this form.
|
||||
*/
|
||||
public function buildForm(array $form, array &$form_state, MenuLinkInterface $menu_link_plugin = NULL) {
|
||||
$form['menu_link_id'] = array(
|
||||
'#type' => 'value',
|
||||
'#value' => $menu_link_plugin->getPluginId(),
|
||||
);
|
||||
$class_name = $menu_link_plugin->getFormClass();
|
||||
$form['#plugin_form'] = $this->classResolver->getInstanceFromDefinition($class_name);
|
||||
$form['#plugin_form']->setMenuLinkInstance($menu_link_plugin);
|
||||
|
||||
$form += $form['#plugin_form']->buildConfigurationForm($form, $form_state);
|
||||
|
||||
$form['actions'] = array('#type' => 'actions');
|
||||
$form['actions']['submit'] = array(
|
||||
'#type' => 'submit',
|
||||
'#value' => $this->t('Save'),
|
||||
'#button_type' => 'primary',
|
||||
);
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function validateForm(array &$form, array &$form_state) {
|
||||
$form['#plugin_form']->validateConfigurationForm($form, $form_state);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function submitForm(array &$form, array &$form_state) {
|
||||
$link = $form['#plugin_form']->submitConfigurationForm($form, $form_state);
|
||||
|
||||
drupal_set_message($this->t('The menu link has been saved.'));
|
||||
$form_state['redirect_route'] = array(
|
||||
'route_name' => 'menu_ui.menu_edit',
|
||||
'route_parameters' => array(
|
||||
'menu' => $link->getMenuName(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue