Issue #2027183 by tim.plunkett, YesCT: hook_menu() title callback is ignored on routes.
parent
a2c2367bf8
commit
0cb8f162e8
|
@ -777,9 +777,13 @@ function _menu_translate(&$router_item, $map, $to_arg = FALSE) {
|
|||
$router_item['tab_parent_href'] = implode('/', $tab_parent_map);
|
||||
$router_item['options'] = array();
|
||||
if (!empty($router_item['route_name'])) {
|
||||
// Route-provided menu items do not have menu loaders, so replace the map
|
||||
// with the link map.
|
||||
$map = $link_map;
|
||||
|
||||
$route_provider = Drupal::getContainer()->get('router.route_provider');
|
||||
$route = $route_provider->getRouteByName($router_item['route_name']);
|
||||
$router_item['access'] = menu_item_route_access($route, $router_item['href']);
|
||||
$router_item['access'] = menu_item_route_access($route, $router_item['href'], $map);
|
||||
}
|
||||
else {
|
||||
// @todo: Remove once all routes are converted.
|
||||
|
@ -917,7 +921,7 @@ function _menu_link_translate(&$item, $translate = FALSE) {
|
|||
// menu_tree_check_access() may set this ahead of time for links to nodes.
|
||||
if (!isset($item['access'])) {
|
||||
if ($route = $item->getRoute()) {
|
||||
$item['access'] = menu_item_route_access($route, $item['href']);
|
||||
$item['access'] = menu_item_route_access($route, $item['href'], $map);
|
||||
}
|
||||
elseif (!empty($item['load_functions']) && !_menu_load_objects($item, $map)) {
|
||||
// An error occurred loading an object.
|
||||
|
@ -953,23 +957,41 @@ function _menu_link_translate(&$item, $translate = FALSE) {
|
|||
* Router for the given menu item.
|
||||
* @param string $href
|
||||
* Menu path as returned by $item['href'] of menu_get_item().
|
||||
* @param array $map
|
||||
* An array of path arguments, for example, array('node', '5').
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if the user has access or FALSE if the user should be presented
|
||||
* with access denied.
|
||||
*/
|
||||
function menu_item_route_access(Route $route, $href) {
|
||||
function menu_item_route_access(Route $route, $href, &$map) {
|
||||
$request = Request::create('/' . $href);
|
||||
$request->attributes->set('system_path', $href);
|
||||
// Attempt to match this path to provide a fully built request to the
|
||||
// access checker.
|
||||
try {
|
||||
$request->attributes->add(Drupal::service('router.dynamic')->matchRequest($request));
|
||||
return Drupal::service('access_manager')->check($route, $request);
|
||||
}
|
||||
catch (NotFoundHttpException $e) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Populate the map with any matching values from the request.
|
||||
$path_bits = explode('/', trim($route->getPath(), '/'));
|
||||
foreach ($map as $index => $map_item) {
|
||||
$matches = array();
|
||||
// Search for placeholders wrapped by curly braces. For example, a path
|
||||
// 'foo/{bar}/baz' would return 'bar'.
|
||||
if (isset($path_bits[$index]) && preg_match('/{(?<placeholder>.*)}/', $path_bits[$index], $matches)) {
|
||||
// If that placeholder is present on the request attributes, replace the
|
||||
// placeholder in the map with the value.
|
||||
if ($request->attributes->has($matches['placeholder'])) {
|
||||
$map[$index] = $request->attributes->get($matches['placeholder']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Drupal::service('access_manager')->check($route, $request);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -83,7 +83,7 @@ function field_ui_menu() {
|
|||
'weight' => 1,
|
||||
);
|
||||
$items["$path/fields/%"] = array(
|
||||
'title callback' => 'field_ui_instance_title',
|
||||
'title callback' => 'entity_page_label',
|
||||
'title arguments' => array($field_position),
|
||||
'route_name' => "field_ui.instance_edit.$entity_type",
|
||||
);
|
||||
|
@ -209,16 +209,6 @@ function field_ui_instance_load($field_name, $entity_type, $bundle_name, $bundle
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Title callback: Returns the name of a given instance.
|
||||
*
|
||||
* @see field_ui_menu()
|
||||
*/
|
||||
function field_ui_instance_title($instance) {
|
||||
$entity = entity_load('field_instance', $instance);
|
||||
return $entity->label();
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_theme().
|
||||
*/
|
||||
|
|
|
@ -37,6 +37,7 @@ class LocalActionTest extends WebTestBase {
|
|||
$this->drupalGet('menu-test-local-action');
|
||||
// Ensure that both menu and route based actions are shown.
|
||||
$this->assertLocalAction(array(
|
||||
'menu-test-local-action/dynamic-title' => 'My dynamic-title action',
|
||||
'menu-test-local-action/hook_menu' => 'My hook_menu action',
|
||||
'menu-test-local-action/routing' => 'My routing action',
|
||||
));
|
||||
|
|
|
@ -432,9 +432,25 @@ function menu_test_menu() {
|
|||
'type' => MENU_LOCAL_ACTION,
|
||||
);
|
||||
|
||||
$items['menu-test-local-action/dynamic-title'] = array(
|
||||
'title' => 'My dynamic title action',
|
||||
'title callback' => 'menu_test_local_action_dynamic_title',
|
||||
'title arguments' => array(1),
|
||||
'route_name' => 'menu_test_local_action4',
|
||||
'weight' => -10,
|
||||
'type' => MENU_LOCAL_ACTION,
|
||||
);
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Title callback: Set a dynamic title for a local action.
|
||||
*/
|
||||
function menu_test_local_action_dynamic_title($arg) {
|
||||
return t('My @arg action', array('@arg' => $arg));
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_local_actions().
|
||||
*/
|
||||
|
|
|
@ -37,3 +37,10 @@ menu_test_local_action3:
|
|||
_content: '\Drupal\menu_test\TestControllers::test2'
|
||||
requirements:
|
||||
_access: 'TRUE'
|
||||
|
||||
menu_test_local_action4:
|
||||
pattern: '/menu-test-local-action/dynamic-title'
|
||||
defaults:
|
||||
_content: '\Drupal\menu_test\TestControllers::test2'
|
||||
requirements:
|
||||
_access: 'TRUE'
|
||||
|
|
Loading…
Reference in New Issue