Commit b9a978d2 authored by catch's avatar catch

Issue #2177041 by dawehner, Berdir, jibran: Remove all implementations of hook_menu.

parent d1bbfa74
......@@ -302,6 +302,11 @@ services:
calls:
- [setContext, ['@router.request_context']]
- [add, ['@router.dynamic']]
router.path_roots_subscriber:
class: Drupal\Core\EventSubscriber\PathRootsSubscriber
arguments: ['@state']
tags:
- { name: event_subscriber }
entity.query:
class: Drupal\Core\Entity\Query\QueryFactory
arguments: ['@entity.manager']
......
......@@ -13,6 +13,7 @@
use Drupal\Core\Routing\RequestHelper;
use Drupal\Core\Template\Attribute;
use Drupal\menu_link\Entity\MenuLink;
use Drupal\menu_link\MenuLinkInterface;
use Drupal\menu_link\MenuLinkStorageController;
use Symfony\Cmf\Component\Routing\RouteObjectInterface;
use Symfony\Component\HttpFoundation\Request;
......@@ -561,7 +562,10 @@ function _menu_check_access(&$item, $map) {
* (link title attribute) matches the description, it is translated as well.
*/
function _menu_item_localize(&$item, $map, $link_translate = FALSE) {
$title_callback = $item['title_callback'];
// Allow default menu links to be translated.
// @todo Figure out a proper way to support translations of menu links, see
// https://drupal.org/node/2193777.
$title_callback = $item instanceof MenuLinkInterface && !$item->customized ? 't' : $item['title_callback'];
$item['localized_options'] = $item['options'];
// All 'class' attributes are assumed to be an array during rendering, but
// links stored in the database may use an old string value.
......@@ -580,6 +584,8 @@ function _menu_item_localize(&$item, $map, $link_translate = FALSE) {
if (!$link_translate || !isset($item['link_title']) || ($item['title'] == $item['link_title'])) {
// t() is a special case. Since it is used very close to all the time,
// we handle it directly instead of using indirect, slower methods.
// @todo Recheck this line once https://drupal.org/node/2084421 is in.
$item['title'] = isset($item['link_title']) ? $item['link_title'] : $item['title'];
if ($title_callback == 't') {
if (empty($item['title_arguments'])) {
$item['title'] = t($item['title']);
......@@ -2395,7 +2401,7 @@ function menu_link_rebuild_defaults() {
if ($all_links) {
$query = \Drupal::entityQuery('menu_link')
->condition('machine_name', array_keys($all_links), 'NOT IN')
->condition('machine_name', NULL, '<>')
->exists('machine_name')
->condition('external', 0)
->condition('updated', 0)
->condition('customized', 0)
......
<?php
/**
* @file
* Contains \Drupal\Core\EventSubscriber\PathRootsSubscriber.
*/
namespace Drupal\Core\EventSubscriber;
use Drupal\Core\KeyValueStore\StateInterface;
use Drupal\Core\Routing\RouteBuildEvent;
use Drupal\Core\Routing\RoutingEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Routing\RouteCollection;
/**
* Provides all available first bits of all route paths.
*/
class PathRootsSubscriber implements EventSubscriberInterface {
/**
* Stores the path roots available in the router.
*
* A path root is the first virtual directory of a path, like 'admin', 'node'
* or 'user'.
*
* @var array
*/
protected $pathRoots;
/**
* The state key value store.
*
* @var \Drupal\Core\KeyValueStore\StateInterface
*/
protected $state;
/**
* Constructs a new PathRootsSubscriber instance.
*
* @param \Drupal\Core\KeyValueStore\StateInterface $state
* The state key value store.
*/
public function __construct(StateInterface $state) {
$this->state = $state;
}
/**
* Collects all path roots.
*
* @param \Drupal\Core\Routing\RouteBuildEvent $event
* The route build event.
*/
public function onRouteAlter(RouteBuildEvent $event) {
$collection = $event->getRouteCollection();
foreach ($collection->all() as $route) {
$bits = explode('/', ltrim($route->getPath(), '/'));
$this->pathRoots[$bits[0]] = $bits[0];
}
}
/**
* {@inheritdoc}
*/
public function onRouteFinished() {
$this->state->set('router.path_roots', array_keys($this->pathRoots));
unset($this->pathRoots);
}
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents() {
$events = array();
// Try to set a low priority to ensure that all routes are already added.
$events[RoutingEvents::ALTER][] = array('onRouteAlter', -1024);
$events[RoutingEvents::FINISHED][] = array('onRouteFinished');
return $events;
}
}
......@@ -60,7 +60,7 @@ protected function lazyLoadCache() {
// On a cold start $this->storage will be empty and the whitelist will
// need to be rebuilt from scratch. The whitelist is initialized from the
// list of all valid path roots stored in the 'menu_path_roots' state,
// list of all valid path roots stored in the 'router.path_roots' state,
// with values initialized to NULL. During the request, each path requested
// that matches one of these keys will be looked up and the array value set
// to either TRUE or FALSE. This ensures that paths which do not exist in
......@@ -75,7 +75,7 @@ protected function lazyLoadCache() {
* Loads menu path roots to prepopulate cache.
*/
protected function loadMenuPathRoots() {
if ($roots = $this->state->get('menu_path_roots')) {
if ($roots = $this->state->get('router.path_roots')) {
foreach ($roots as $root) {
$this->storage[$root] = NULL;
$this->persist($root);
......
......@@ -44,18 +44,6 @@ function action_permission() {
);
}
/**
* Implements hook_menu().
*/
function action_menu() {
$items['admin/config/system/actions'] = array(
'title' => 'Actions',
'description' => 'Manage the actions defined for your site.',
'route_name' => 'action.admin',
);
return $items;
}
/**
* Implements hook_menu_link_defaults().
*/
......
......@@ -87,48 +87,6 @@ function aggregator_theme() {
);
}
/**
* Implements hook_menu().
*/
function aggregator_menu() {
$items['admin/config/services/aggregator'] = array(
'title' => 'Feed aggregator',
'description' => "Configure which content your site aggregates from other sites, and how often it polls them.",
'route_name' => 'aggregator.admin_overview',
'weight' => 10,
);
$items['admin/config/services/aggregator/remove/%aggregator_feed'] = array(
'title' => 'Remove items',
'route_name' => 'aggregator.feed_items_delete',
);
$items['admin/config/services/aggregator/update/%aggregator_feed'] = array(
'title' => 'Update items',
'route_name' => 'aggregator.feed_refresh',
);
$items['aggregator'] = array(
'title' => 'Feed aggregator',
'weight' => 5,
'route_name' => 'aggregator.page_last',
);
$items['aggregator/sources'] = array(
'title' => 'Sources',
'route_name' => 'aggregator.sources',
);
$items['aggregator/sources/%aggregator_feed'] = array(
'route_name' => 'aggregator.feed_view',
);
$items['admin/config/services/aggregator/edit/feed/%aggregator_feed'] = array(
'title' => 'Edit feed',
'route_name' => 'aggregator.feed_edit',
);
$items['admin/config/services/aggregator/delete/feed/%aggregator_feed'] = array(
'title' => 'Delete feed',
'route_name' => 'aggregator.feed_delete',
);
return $items;
}
/**
* Implements hook_menu_link_defaults().
*/
......
......@@ -37,23 +37,6 @@ function ban_permission() {
);
}
/**
* Implements hook_menu().
*/
function ban_menu() {
$items['admin/config/people/ban'] = array(
'title' => 'IP address bans',
'description' => 'Manage banned IP addresses.',
'route_name' => 'ban.admin_page',
'weight' => 10,
);
$items['admin/config/people/ban/delete/%'] = array(
'title' => 'Delete IP address',
'route_name' => 'ban.delete',
);
return $items;
}
/**
* Implements hook_menu_link_defaults().
*/
......
......@@ -92,29 +92,6 @@ function block_permission() {
);
}
/**
* Implements hook_menu().
*
* @todo Clarify the documentation for the per-plugin block admin links.
*/
function block_menu() {
$items['admin/structure/block'] = array(
'title' => 'Block layout',
'description' => 'Configure what block content appears in your site\'s sidebars and other regions.',
'route_name' => 'block.admin_display',
);
$items['admin/structure/block/manage/%block'] = array(
'title' => 'Configure block',
'route_name' => 'block.admin_edit',
);
$items['admin/structure/block/add/%/%'] = array(
'title' => 'Place block',
'type' => MENU_VISIBLE_IN_BREADCRUMB,
'route_name' => 'block.admin_add',
);
return $items;
}
/**
* Implements hook_menu_link_defaults().
*/
......
......@@ -37,33 +37,6 @@ function custom_block_help($path, $arg) {
}
}
/**
* Implements hook_menu().
*/
function custom_block_menu() {
$items['admin/structure/block/custom-blocks'] = array(
'title' => 'Custom block library',
'description' => 'Manage custom blocks.',
'route_name' => 'custom_block.list',
'type' => MENU_NORMAL_ITEM,
);
$items['admin/structure/block/custom-blocks/manage/%custom_block_type'] = array(
'title' => 'Edit custom block type',
'title callback' => 'entity_page_label',
'title arguments' => array(5),
'route_name' => 'custom_block.type_edit',
);
$items['block/add'] = array(
'title' => 'Add custom block',
'description' => 'Add custom block',
'route_name' => 'custom_block.add_page',
);
return $items;
}
/**
* Implements hook_menu_link_defaults().
*/
......@@ -73,6 +46,11 @@ function custom_block_menu_link_defaults() {
'description' => 'Add custom block',
'route_name' => 'custom_block.add_page',
);
$items['custom_block.list'] = array(
'link_title' => 'Custom block library',
'parent' => 'block.admin.structure',
'description' => 'Manage custom blocks.',
);
return $links;
}
......
......@@ -29,6 +29,10 @@ public function getOptions(Request $request) {
if ($request->attributes->get(RouteObjectInterface::ROUTE_NAME) == 'custom_block.list') {
$options['query']['destination'] = 'admin/structure/block/custom-blocks';
}
// Adds a destination on custom block listing.
if ($request->attributes->get(RouteObjectInterface::ROUTE_NAME) == 'custom_block.list') {
$options['query']['destination'] = 'admin/structure/block/custom-blocks';
}
return $options;
}
......
......@@ -66,17 +66,3 @@ function custom_block_test_custom_block_insert(CustomBlock $custom_block) {
throw new Exception('Test exception for rollback.');
}
}
/**
* Implements hook_menu().
*/
function custom_block_test_menu() {
$items = array();
// Add a block-view callback.
$items['custom-block/%custom_block'] = array(
'title callback' => 'entity_page_label',
'title arguments' => array(1),
'route_name' => 'custom_block_test.custom_block_view',
);
return $items;
}
......@@ -162,28 +162,6 @@ function book_node_links_alter(array &$node_links, NodeInterface $node, array &$
}
}
/**
* Implements hook_menu().
*/
function book_menu() {
$items['admin/structure/book'] = array(
'title' => 'Books',
'description' => "Manage your site's book outlines.",
'route_name' => 'book.admin',
);
$items['book'] = array(
'title' => 'Books',
'route_name' => 'book.render',
'type' => MENU_SUGGESTED_ITEM,
);
$items['node/%node/outline/remove'] = array(
'title' => 'Remove from outline',
'route_name' => 'book.remove',
);
return $items;
}
/**
* Implements hook_menu_link_defaults().
*/
......
......@@ -177,28 +177,6 @@ function comment_theme() {
);
}
/**
* Implements hook_menu().
*/
function comment_menu() {
$items['admin/structure/comments'] = array(
'title' => 'Comment forms',
'description' => 'Manage fields and displays settings for comment forms.',
'route_name' => 'comment.bundle_list',
);
$items['admin/structure/comments/manage/%'] = array(
'title' => 'Comment form',
'route_name' => 'comment.bundle',
);
$items['admin/content/comment'] = array(
'title' => 'Comments',
'description' => 'List and edit site comments and the comment approval queue.',
'route_name' => 'comment.admin',
);
return $items;
}
/**
* Implements hook_menu_link_defaults().
*/
......@@ -220,12 +198,12 @@ function comment_menu_link_defaults() {
}
/**
* Implements hook_menu_alter().
* Implements hook_menu_link_defaults_alter()
*/
function comment_menu_alter(&$items) {
if (isset($items['admin/content'])) {
function comment_menu_links_defaults_alter(&$links) {
if (isset($links['node.admin.content'])) {
// Add comments to the description for admin/content if any.
$items['admin/content']['description'] = 'Administer content and comments.';
$links['node.admin.content']['description'] = 'Administer content and comments.';
}
}
......
......@@ -57,19 +57,6 @@ function config_file_download($uri) {
}
}
/**
* Implements hook_menu().
*/
function config_menu() {
$items['admin/config/development/configuration'] = array(
'title' => 'Configuration management',
'description' => 'Import, export, or synchronize your site configuration.',
'route_name' => 'config.sync',
);
return $items;
}
/**
* Implements hook_menu_link_defaults().
*/
......
......@@ -10,32 +10,6 @@
require_once dirname(__FILE__) . '/config_test.hooks.inc';
/**
* Implements hook_menu().
*/
function config_test_menu() {
$items['admin/structure/config_test'] = array(
'title' => 'Test configuration',
'route_name' => 'config_test.list_page',
);
$items['admin/structure/config_test/manage/%config_test'] = array(
'route_name' => 'config_test.entity',
);
$items['admin/structure/config_test/manage/%config_test/delete'] = array(
'title' => 'Delete',
'route_name' => 'config_test.entity_delete',
);
$items['admin/structure/config_test/manage/%config_test/enable'] = array(
'title' => 'Enable',
'route_name' => 'config_test.entity_enable',
);
$items['admin/structure/config_test/manage/%config_test/disable'] = array(
'title' => 'Disable',
'route_name' => 'config_test.entity_disable',
);
return $items;
}
/**
* Loads a ConfigTest object.
*
......
......@@ -31,20 +31,6 @@ function config_translation_help($path) {
}
}
/**
* Implements hook_menu().
*/
function config_translation_menu() {
$items = array();
$items['admin/config/regional/config-translation'] = array(
'title' => 'Configuration translation',
'description' => 'Translate the configuration.',
'route_name' => 'config_translation.mapper_list',
'weight' => 30,
);
return $items;
}
/**
* Implements hook_menu_link_defaults().
*/
......
......@@ -51,34 +51,6 @@ function contact_permission() {
);
}
/**
* Implements hook_menu().
*/
function contact_menu() {
$items['admin/structure/contact'] = array(
'title' => 'Contact form categories',
'description' => 'Create a system contact form and set up categories for the form to use.',
'route_name' => 'contact.category_list',
);
$items['admin/structure/contact/manage/%contact_category'] = array(
'title' => 'Edit contact category',
'route_name' => 'contact.category_edit',
);
$items['contact'] = array(
'title' => 'Contact',
'route_name' => 'contact.site_page',
'menu_name' => 'footer',
'type' => MENU_SUGGESTED_ITEM,
);
$items['contact/%contact_category'] = array(
'title' => 'Contact category form',
'route_name' => 'contact.site_page_category',
'type' => MENU_VISIBLE_IN_BREADCRUMB,
);
return $items;
}
/**
* Implements hook_menu_link_defaults().
*/
......
......@@ -244,10 +244,6 @@ function content_translation_menu() {
* https://drupal.org/node/1987882 and https://drupal.org/node/2047633.
*/
function content_translation_menu_alter(array &$items) {
// Clarify where translation settings are located.
$items['admin/config/regional/content-language']['title'] = 'Content language and translation';
$items['admin/config/regional/content-language']['description'] = 'Configure language and translation support for content.';
// Check that the declared menu base paths are actually valid.
foreach (\Drupal::entityManager()->getDefinitions() as $entity_type_id => $entity_type) {
if (content_translation_enabled($entity_type_id)) {
......
......@@ -36,42 +36,6 @@ function dblog_help($path, $arg) {
}
}
/**
* Implements hook_menu().
*/
function dblog_menu() {
$items['admin/reports/dblog'] = array(
'title' => 'Recent log messages',
'description' => 'View events that have recently been logged.',
'route_name' => 'dblog.overview',
'weight' => -1,
);
$items['admin/reports/page-not-found'] = array(
'title' => "Top 'page not found' errors",
'description' => "View 'page not found' errors (404s).",
'route_name' => 'dblog.page_not_found',
);
$items['admin/reports/access-denied'] = array(
'title' => "Top 'access denied' errors",
'description' => "View 'access denied' errors (403s).",
'route_name' => 'dblog.access_denied',
);
$items['admin/reports/event/%'] = array(
'title' => 'Details',
'route_name' => 'dblog.event',
);
if (\Drupal::moduleHandler()->moduleExists('search')) {
$items['admin/reports/search'] = array(
'title' => 'Top search phrases',
'description' => 'View most popular search phrases.',
'route_name' => 'dblog.search',
);
}
return $items;
}
/**
* Implements hook_menu_link_defaults().
*/
......
......@@ -39,19 +39,11 @@ function editor_help($path, $arg) {
}
/**
* Implements hook_menu_alter().
* Implements hook_menu_link_defaults_alter().
*
* Rewrites the menu entries for filter module that relate to the configuration
* of text editors.
*/
function editor_menu_alter(&$items) {
$items['admin/config/content/formats']['title'] = 'Text formats and editors';
$items['admin/config/content/formats']['description'] = 'Configure how user-contributed content is filtered and formatted, as well as the text editor user interface (WYSIWYGs or toolbars).';
}
/**
* Implements hook_menu_link_defaults_alter().
*/
function editor_menu_link_defaults_alter(array &$links) {
$links['filter.admin.formats']['link_title'] = 'Text formats and editors';
$links['filter.admin.formats']['description'] = 'Configure how user-contributed content is filtered and formatted, as well as the text editor user interface (WYSIWYGs or toolbars).';
......
......@@ -44,57 +44,6 @@ function entity_permission() {
);
}
/**
* Implements hook_menu().
*/
function entity_menu() {
$items = array();
$items['admin/structure/display-modes'] = array(
'title' => 'Display modes',
'description' => 'Configure what displays are available for your content and forms.',
'route_name' => 'entity.display_mode',
);
// View modes.
$items['admin/structure/display-modes/view'] = array(
'title' => 'View modes',
'description' => 'Manage custom view modes.',
'route_name' => 'entity.view_mode_list',
);
$items['admin/structure/display-modes/view/add'] = array(
'title' => 'Add view mode',
'route_name' => 'entity.view_mode_add',
'type' => MENU_SIBLING_LOCAL_TASK,
);
$items['admin/structure/display-modes/view/add/%'] = array(
'route_name' => 'entity.view_mode_add_type',
);
$items['admin/structure/display-modes/view/manage/%/delete'] = array(
'route_name' => 'entity.view_mode_delete',
);
// Form modes.
$items['admin/structure/display-modes/form'] = array(
'title' => 'Form modes',
'description' => 'Manage custom form modes.',
'route_name' => 'entity.form_mode_list',
);
$items['admin/structure/display-modes/form/add'] = array(
'title' => 'Add form mode',
'route_name' => 'entity.form_mode_add',
'type' => MENU_SIBLING_LOCAL_TASK,
);
$items['admin/structure/display-modes/form/add/%'] = array(
'route_name' => 'entity.form_mode_add_type',
);
$items['admin/structure/display-modes/form/manage/%/delete'] = array(
'route_name' => 'entity.form_mode_delete',
);
return $items;
}
/**
* Implements hook_menu_link_defaults().
*/
......
......@@ -36,19 +36,6 @@ function field_test_permission() {
return $perms;
}
/**
* Implements hook_menu().
*/
function field_test_menu() {
$items = array();
$items['test-entity/nested/%entity_test/%entity_test'] = array(
'title' => 'Nested entity form',
'route_name' => 'field_test.entity_nested_form',
);
return $items;
}
/**
* Store and retrieve keyed data for later verification by unit tests.
*
......
......@@ -52,20 +52,6 @@ function field_ui_help($path, $arg) {
}
}
/**
* Implements hook_menu().
*/
function field_ui_menu() {
$items['admin/reports/fields'] = array(
'title' => 'Field list',
'description' => 'Overview of fields on all entity types.',
'route_name' => 'field_ui.list',
'type' => MENU_NORMAL_ITEM,
);