core/includes/menu.inc | 4 +-
core/lib/Drupal/Core/Menu/MenuLinkTree.php | 18 ++++++---
core/modules/menu_ui/menu_ui.admin.inc | 2 +-
core/modules/menu_ui/menu_ui.info.yml | 2 +-
.../system/src/Controller/SystemController.php | 2 +-
core/modules/system/src/Form/ModulesListForm.php | 38 +++++++++++++----
core/modules/system/system.api.php | 2 +-
.../views/src/Plugin/Derivative/ViewsMenuLink.php | 8 ++--
.../src/Plugin/Menu/Form/ViewsMenuLinkForm.php | 47 +++++++++++++++-------
.../views/src/Plugin/Menu/ViewsMenuLink.php | 38 +++++------------
.../src/Plugin/views/display/DisplayPluginBase.php | 8 ++--
.../src/Plugin/views/display/PathPluginBase.php | 3 +-
core/modules/views/src/ViewExecutable.php | 6 +--
13 files changed, 103 insertions(+), 75 deletions(-)
diff --git a/core/includes/menu.inc b/core/includes/menu.inc
index 2e31ef3..405032e 100644
--- a/core/includes/menu.inc
+++ b/core/includes/menu.inc
@@ -285,12 +285,12 @@
* \Drupal\Core\Menu\DefaultMenuTreeManipulators for examples. This is only
* necessary if you want to do things like adding extra metadata to rendered
* links to display icons next to them.
- * - Pass the menu tree to \Drupal\menu_link\MenuTree::build(), this will build
+ * - Pass the menu tree to \Drupal\Core\Menu\MenuLinkTree::build(), this will build
* a renderable array.
*
* Combined, that would look like this:
* @code
- * $menu_tree = \Drupal::service('menu.link_tree');
+ * $menu_tree = \Drupal::menuTree();
* $menu_name = 'my_menu';
*
* // Build the typical default set of menu tree parameters.
diff --git a/core/lib/Drupal/Core/Menu/MenuLinkTree.php b/core/lib/Drupal/Core/Menu/MenuLinkTree.php
index aae6efd..943698c 100644
--- a/core/lib/Drupal/Core/Menu/MenuLinkTree.php
+++ b/core/lib/Drupal/Core/Menu/MenuLinkTree.php
@@ -61,6 +61,15 @@ class MenuLinkTree implements MenuLinkTreeInterface {
protected $routeMatch;
/**
+ * Stores the cached current route parameters by menu and current route match.
+ *
+ * @todo Remove this non-static caching in https://www.drupal.org/node/1805054.
+ *
+ * @var \Drupal\Core\Menu\MenuTreeParameters[]
+ */
+ protected $cachedCurrentRouteParameters;
+
+ /**
* Constructs a \Drupal\Core\Menu\MenuLinkTree object.
*
* @param \Drupal\Core\Menu\MenuTreeStorageInterface $tree_storage
@@ -93,14 +102,11 @@ public function __construct(MenuTreeStorageInterface $tree_storage, MenuLinkMana
* {@inheritdoc}
*/
public function getCurrentRouteMenuTreeParameters($menu_name) {
- static $cached_parameters = array();
-
- // @todo Remove this non-static caching in https://www.drupal.org/node/1805054.
$route_parameters = $this->routeMatch->getRawParameters()->all();
ksort($route_parameters);
$cid = 'current-route-parameters:' . $menu_name . ':route:' . $this->routeMatch->getRouteName() . ':route_parameters:' . serialize($route_parameters);
- if (!isset($cached_parameters[$menu_name])) {
+ if (!isset($this->cachedCurrentRouteParameters[$menu_name])) {
$cache = $this->cache->get($cid);
if ($cache && $cache->data) {
$parameters = $cache->data;
@@ -119,10 +125,10 @@ public function getCurrentRouteMenuTreeParameters($menu_name) {
$this->cache->set($cid, $parameters, CacheBackendInterface::CACHE_PERMANENT, array('menu' => $menu_name));
}
- $cached_parameters[$menu_name] = $parameters;
+ $this->cachedCurrentRouteParameters[$menu_name] = $parameters;
}
- return $cached_parameters[$menu_name];
+ return $this->cachedCurrentRouteParameters[$menu_name];
}
/**
diff --git a/core/modules/menu_ui/menu_ui.admin.inc b/core/modules/menu_ui/menu_ui.admin.inc
index cedc396..408272a 100644
--- a/core/modules/menu_ui/menu_ui.admin.inc
+++ b/core/modules/menu_ui/menu_ui.admin.inc
@@ -51,7 +51,7 @@ function theme_menu_overview_form($variables) {
);
$row = array();
- $row[] = drupal_render($indent) . drupal_render($element['title']);
+ $row[] = SafeMarkup::set(drupal_render($indent) . drupal_render($element['title']));
$row[] = array('data' => drupal_render($element['enabled']), 'class' => array('checkbox', 'menu-enabled'));
$row[] = SafeMarkup::set(drupal_render($element['weight']) . drupal_render($element['parent']) . drupal_render($element['id']));
$row[] = drupal_render($element['operations']);
diff --git a/core/modules/menu_ui/menu_ui.info.yml b/core/modules/menu_ui/menu_ui.info.yml
index 9dd90da..f3bf1be 100644
--- a/core/modules/menu_ui/menu_ui.info.yml
+++ b/core/modules/menu_ui/menu_ui.info.yml
@@ -6,4 +6,4 @@ version: VERSION
core: 8.x
configure: menu_ui.overview_page
dependencies:
- - menu_link_content
\ No newline at end of file
+ - menu_link_content
diff --git a/core/modules/system/src/Controller/SystemController.php b/core/modules/system/src/Controller/SystemController.php
index 8881e9f..c811e85 100644
--- a/core/modules/system/src/Controller/SystemController.php
+++ b/core/modules/system/src/Controller/SystemController.php
@@ -108,7 +108,7 @@ public static function create(ContainerInterface $container) {
* Provide the administration overview page.
*
* @param string $link_id
- * The ID of and administrative path link for which to display child links.
+ * The ID of the administrative path link for which to display child links.
*
* @return array
* A renderable array of the administration overview page.
diff --git a/core/modules/system/src/Form/ModulesListForm.php b/core/modules/system/src/Form/ModulesListForm.php
index 7dc500a..fe97c28 100644
--- a/core/modules/system/src/Form/ModulesListForm.php
+++ b/core/modules/system/src/Form/ModulesListForm.php
@@ -83,6 +83,13 @@ class ModulesListForm extends FormBase {
protected $routeMatch;
/**
+ * The menu link manager.
+ *
+ * @var \Drupal\Core\Menu\MenuLinkManagerInterface
+ */
+ protected $menuLinkManager;
+
+ /**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
@@ -94,7 +101,8 @@ public static function create(ContainerInterface $container) {
$container->get('current_user'),
$container->get('current_route_match'),
$container->get('title_resolver'),
- $container->get('router.route_provider')
+ $container->get('router.route_provider'),
+ $container->get('plugin.manager.menu.link')
);
}
@@ -117,8 +125,10 @@ public static function create(ContainerInterface $container) {
* The title resolver.
* @param \Drupal\Core\Routing\RouteProviderInterface $route_provider
* The route provider.
+ * @param \Drupal\Core\Menu\MenuLinkManagerInterface $menu_link_manager
+ * The menu link manager.
*/
- public function __construct(ModuleHandlerInterface $module_handler, KeyValueStoreExpirableInterface $key_value_expirable, AccessManager $access_manager, EntityManagerInterface $entity_manager, AccountInterface $current_user, RouteMatchInterface $route_match, TitleResolverInterface $title_resolver, RouteProviderInterface $route_provider) {
+ public function __construct(ModuleHandlerInterface $module_handler, KeyValueStoreExpirableInterface $key_value_expirable, AccessManager $access_manager, EntityManagerInterface $entity_manager, AccountInterface $current_user, RouteMatchInterface $route_match, TitleResolverInterface $title_resolver, RouteProviderInterface $route_provider, $menu_link_manager) {
$this->moduleHandler = $module_handler;
$this->keyValueExpirable = $key_value_expirable;
$this->accessManager = $access_manager;
@@ -127,6 +137,7 @@ public function __construct(ModuleHandlerInterface $module_handler, KeyValueStor
$this->routeMatch = $route_match;
$this->titleResolver = $title_resolver;
$this->routeProvider = $route_provider;
+ $this->menuLinkManager = $menu_link_manager;
}
/**
@@ -262,11 +273,22 @@ protected function buildRow(array $modules, Extension $module, $distribution) {
$route_parameters = isset($module->info['configure_parameters']) ? $module->info['configure_parameters'] : array();
if ($this->accessManager->checkNamedRoute($module->info['configure'], $route_parameters, $this->currentUser)) {
- $request = new Request();
- $request->attributes->set('_route_name', $module->info['configure']);
- $route_object = $this->routeProvider->getRouteByName($module->info['configure']);
- $request->attributes->set('_route', $route_object);
- $title = $this->titleResolver->getTitle($request, $route_object);
+ $links = $this->menuLinkManager->loadLinksByRoute($module->info['configure']);
+ /** @var \Drupal\Core\Menu\MenuLinkInterface $link */
+ $link = reset($links);
+ // Most configure links have a corresponding menu link, though some just
+ // have a route.
+ if ($link) {
+ $description = $link->getDescription();
+ }
+ else {
+ $request = new Request();
+ $request->attributes->set('_route_name', $module->info['configure']);
+ $route_object = $this->routeProvider->getRouteByName($module->info['configure']);
+ $request->attributes->set('_route', $route_object);
+ $description = $this->titleResolver->getTitle($request, $route_object);
+ }
+
$row['links']['configure'] = array(
'#type' => 'link',
@@ -276,7 +298,7 @@ protected function buildRow(array $modules, Extension $module, $distribution) {
'#options' => array(
'attributes' => array(
'class' => array('module-link', 'module-link-configure'),
- 'title' => $title,
+ 'title' => $description,
),
),
);
diff --git a/core/modules/system/system.api.php b/core/modules/system/system.api.php
index e1cf853..02ae231 100644
--- a/core/modules/system/system.api.php
+++ b/core/modules/system/system.api.php
@@ -397,7 +397,7 @@ function hook_page_build(&$page) {
}
/**
- * Alter all the menu links discovered by the menu link plugin manager.
+ * Alters all the menu links discovered by the menu link plugin manager.
*
* @param array $links
* The link definitions to be altered.
diff --git a/core/modules/views/src/Plugin/Derivative/ViewsMenuLink.php b/core/modules/views/src/Plugin/Derivative/ViewsMenuLink.php
index 66fbaa9..da5007a 100644
--- a/core/modules/views/src/Plugin/Derivative/ViewsMenuLink.php
+++ b/core/modules/views/src/Plugin/Derivative/ViewsMenuLink.php
@@ -11,7 +11,9 @@
use Drupal\views\Views;
/**
- * Provides menu links for views.
+ * Provides menu links for Views.
+ *
+ * @see \Drupal\views\Plugin\Menu\ViewsMenuLink
*/
class ViewsMenuLink implements DeriverInterface {
@@ -31,15 +33,13 @@ public function getDerivativeDefinition($derivative_id, $base_plugin_definition)
* {@inheritdoc}
*/
public function getDerivativeDefinitions($base_plugin_definition) {
- // @todo Decide what to do with all the crazy logic in views_menu_alter() in
- // https://drupal.org/node/2107533.
$links = array();
// @todo Replaces uses_hook_menu with a different annotation.
$views = Views::getApplicableViews('uses_hook_menu');
foreach ($views as $data) {
/** @var \Drupal\views\ViewExecutable $view */
list($view, $display_id) = $data;
- if ($result = $view->executeHookMenuLinks($display_id)) {
+ if ($result = $view->getMenuLinks($display_id)) {
foreach ($result as $link_id => $link) {
$links[$link_id] = $link + $base_plugin_definition;
}
diff --git a/core/modules/views/src/Plugin/Menu/Form/ViewsMenuLinkForm.php b/core/modules/views/src/Plugin/Menu/Form/ViewsMenuLinkForm.php
index cfb3d9e..db8b691 100644
--- a/core/modules/views/src/Plugin/Menu/Form/ViewsMenuLinkForm.php
+++ b/core/modules/views/src/Plugin/Menu/Form/ViewsMenuLinkForm.php
@@ -8,12 +8,11 @@
namespace Drupal\views\Plugin\Menu\Form;
use Drupal\Core\Menu\Form\MenuLinkDefaultForm;
-use Drupal\views\Plugin\Menu\ViewsMenuLink;
/**
- * Provides an edit form for the views.
+ * Provides a form to edit Views menu links.
*
- * This provides the feature to change the title, in contrast to the static
+ * This provides the feature to edit the title, in contrast to the static
* menu link form.
*
* @see \Drupal\views\Plugin\Menu\ViewsMenuLink
@@ -21,6 +20,13 @@
class ViewsMenuLinkForm extends MenuLinkDefaultForm {
/**
+ * The edited views menu link.
+ *
+ * @var \Drupal\views\Plugin\Menu\ViewsMenuLink
+ */
+ protected $menuLink;
+
+ /**
* {@inheritdoc}
*/
public function buildConfigurationForm(array $form, array &$form_state) {
@@ -31,22 +37,34 @@ public function buildConfigurationForm(array $form, array &$form_state) {
'#title' => $this->t('Title'),
// @todo how do we ensure that view is not loaded with a translation?
'#default_value' => $this->menuLink->getTitle(),
+ '#weight' => -10,
+ );
+
+ $form['description'] = array(
+ '#type' => 'textfield',
+ '#title' => $this->t('Description'),
+ '#description' => $this->t('Shown when hovering over the menu link.'),
+ // @todo how do we ensure that view is not loaded with a translation,
+ // see https://www.drupal.org/node/2309507
+ '#default_value' => $this->menuLink->getTitle(),
+ '#weight' => -5,
);
$form += parent::buildConfigurationForm($form, $form_state);
- if ($this->menuLink instanceof ViewsMenuLink) {
- $view = $this->menuLink->loadView();
- $id = $view->storage->id();
- $label = $view->storage->label();
- if ($this->moduleHandler->moduleExists('views_ui')) {
- $message = $this->t('This link is provided by the Views module. The path can be changed by editing the view @label', array('@url' => \Drupal::url('views_ui.edit', array('view' => $id)), '@label' => $label));
- }
- else {
- $message = $this->t('This link is provided by the Views module from view %label.', array('%label' => $label));
- }
- $form['info']['#title'] = $message;
+ $form['info']['#weight'] = -8;
+ $form['path']['#weight'] = -7;
+
+ $view = $this->menuLink->loadView();
+ $id = $view->storage->id();
+ $label = $view->storage->label();
+ if ($this->moduleHandler->moduleExists('views_ui')) {
+ $message = $this->t('This link is provided by the Views module. The path can be changed by editing the view @label', array('@url' => \Drupal::url('views_ui.edit', array('view' => $id)), '@label' => $label));
+ }
+ else {
+ $message = $this->t('This link is provided by the Views module from view %label.', array('%label' => $label));
}
+ $form['info']['#title'] = $message;
return $form;
}
@@ -56,6 +74,7 @@ public function buildConfigurationForm(array $form, array &$form_state) {
public function extractFormValues(array &$form, array &$form_state) {
$definition = parent::extractFormValues($form, $form_state);
$definition['title'] = $form_state['values']['title'];
+ $definition['description'] = $form_state['values']['description'];
return $definition;
}
diff --git a/core/modules/views/src/Plugin/Menu/ViewsMenuLink.php b/core/modules/views/src/Plugin/Menu/ViewsMenuLink.php
index a57fc9c..b7944a6 100644
--- a/core/modules/views/src/Plugin/Menu/ViewsMenuLink.php
+++ b/core/modules/views/src/Plugin/Menu/ViewsMenuLink.php
@@ -15,6 +15,8 @@
/**
* Defines menu links provided by views.
+ *
+ * @see \Drupal\views\Plugin\Derivative\ViewsMenuLink
*/
class ViewsMenuLink extends MenuLinkBase implements ContainerFactoryPluginInterface {
@@ -134,12 +136,16 @@ public function updateLink(array $new_definition_values, $persist) {
$view = $this->loadView();
$display = &$view->storage->getDisplay($view->current_display);
// Just save the title to the original view.
- // @todo What do we do about the other properties, like weight,
- // description and menu name.
- if ($display['display_options']['menu']['title'] != $new_definition_values['title']) {
- $display['display_options']['menu']['title'] = $new_definition_values['title'];
+ $changed = FALSE;
+ foreach (array('title' => 'title', 'weight' => 'weight', 'menu' => 'name', 'description' => 'description') as $definition_key => $views_key) {
+ if ($display['display_options']['menu'][$views_key] != $new_definition_values[$definition_key]) {
+ $display['display_options']['menu'][$views_key] = $new_definition_values[$definition_key];
+ $changed = TRUE;
+ }
+ }
+ if ($changed) {
// @todo Note: This triggers a full rebuild of everything, even we just
- // changed the title.
+ // changed some properties..
$view->storage->save();
}
}
@@ -148,26 +154,4 @@ public function updateLink(array $new_definition_values, $persist) {
return $this->pluginDefinition;
}
- /**
- * {@inheritdoc}
- */
- public function getBaseId() {
- $plugin_id = $this->getPluginId();
- if (strpos($plugin_id, 'views.') === 0) {
- $plugin_id = 'views';
- }
- return $plugin_id;
- }
-
- /**
- * {@inheritdoc}
- */
- public function getDerivativeId() {
- $plugin_id = $this->getPluginId();
- $derivative_id = NULL;
- if (strpos($plugin_id, 'views.') === 0) {
- list(, $derivative_id) = explode('views.', $plugin_id, 2);
- }
- return $derivative_id;
- }
}
diff --git a/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php b/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php
index 6139f5f..6ce6c07 100644
--- a/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php
+++ b/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php
@@ -2119,16 +2119,14 @@ public function renderMoreLink() {
}
/**
- * Creates menu links, if this display provides some.
- *
- * @internal param array $existing_links An array of already existing menu items provided by drupal.* An array of already existing menu items provided by drupal.
+ * Gets menu links, if this display provides some.
*
* @return array
* The menu links registers for this display.
*
- * @see hook_menu_link_defaults()
+ * @see \Drupal\views\Plugin\Derivative\ViewsMenuLink
*/
- public function executeHookMenuLinks() {
+ public function getMenuLinks() {
return array();
}
diff --git a/core/modules/views/src/Plugin/views/display/PathPluginBase.php b/core/modules/views/src/Plugin/views/display/PathPluginBase.php
index c3a3b97..a6e1759 100644
--- a/core/modules/views/src/Plugin/views/display/PathPluginBase.php
+++ b/core/modules/views/src/Plugin/views/display/PathPluginBase.php
@@ -278,9 +278,8 @@ public function alterRoutes(RouteCollection $collection) {
/**
* {@inheritdoc}
- * @return array
*/
- public function executeHookMenuLinks() {
+ public function getMenuLinks() {
$links = array();
// Replace % with the link to our standard views argument loader
diff --git a/core/modules/views/src/ViewExecutable.php b/core/modules/views/src/ViewExecutable.php
index 08e876b..c7e810b 100644
--- a/core/modules/views/src/ViewExecutable.php
+++ b/core/modules/views/src/ViewExecutable.php
@@ -1509,7 +1509,7 @@ public function attachDisplays() {
}
/**
- * Returns default menu links from the view and the named display handler.
+ * Returns menu links from the view and the named display handler.
*
* @param string $display_id
* A display ID.
@@ -1518,7 +1518,7 @@ public function attachDisplays() {
* The generated menu links for this view and display, FALSE if the call
* to ::setDisplay failed.
*/
- public function executeHookMenuLinks($display_id = NULL) {
+ public function getMenuLinks($display_id = NULL) {
// Prepare the view with the information we have. This was probably already
// called, but it's good to be safe.
if (!$this->setDisplay($display_id)) {
@@ -1527,7 +1527,7 @@ public function executeHookMenuLinks($display_id = NULL) {
// Execute the hook.
if (isset($this->display_handler)) {
- return $this->display_handler->executeHookMenuLinks();
+ return $this->display_handler->getMenuLinks();
}
}