Commit cd74c624 authored by webchick's avatar webchick

Issue #2091691 by tim.plunkett: Convert test non-form page callbacks to routes and controllers.

parent 2867e5ba
......@@ -1942,10 +1942,10 @@ function menu_navigation_links($menu_name, $level = 0) {
/**
* Collects the local tasks (tabs), action links, and the root path.
*
* @param $level
* @param int $level
* The level of tasks you ask for. Primary tasks are 0, secondary are 1.
*
* @return
* @return array
* An array containing
* - tabs: Local tasks for the requested level.
* - actions: Action links for the requested level.
......@@ -1965,11 +1965,6 @@ function menu_local_tasks($level = 0) {
);
if (!isset($data)) {
$data = array();
// Set defaults in case there are no actions or tabs.
$actions = $empty['actions'];
$tabs = array();
// Look for route-based tabs.
$data['tabs'] = array();
$data['actions'] = array();
......@@ -1983,25 +1978,57 @@ function menu_local_tasks($level = 0) {
}
}
// @todo Remove the code below once the old menu router system got removed.
// @todo Remove when all local tasks/actions are converted to plugins.
$router_item = menu_get_item();
// If this router item points to its parent, start from the parents to
// compute tabs and actions.
if ($router_item && ($router_item['type'] & MENU_LINKS_TO_PARENT)) {
$router_item = menu_get_item($router_item['tab_parent_href']);
}
// If we failed to fetch a router item or the current user doesn't have
// access to it, don't bother computing the tabs.
if (!$router_item || !$router_item['access']) {
if ((!$route_name && !$router_item) || ($router_item && !$router_item['access'])) {
return $empty;
}
// @todo remove all code using {menu_router} and anything using MENU_*
// constants when all local actions and local tasks are converted to
// plugins. The remaining code should just invoke those managers plus do the
// invocations of hook_menu_local_tasks() and hook_menu_local_tasks_alter().
if ($router_item) {
_menu_get_legacy_tasks($router_item, $data, $root_path);
}
// Allow modules to dynamically add further tasks.
$module_handler = \Drupal::moduleHandler();
foreach ($module_handler->getImplementations('menu_local_tasks') as $module) {
$function = $module . '_menu_local_tasks';
$function($data, $route_name);
}
// Allow modules to alter local tasks.
$module_handler->alter('menu_local_tasks', $data, $route_name);
}
if (isset($data['tabs'][$level])) {
return array(
'tabs' => $data['tabs'][$level],
'actions' => $data['actions'],
'root_path' => $root_path,
);
}
elseif (!empty($data['actions'])) {
return array('actions' => $data['actions']) + $empty;
}
return $empty;
}
/**
* Finds legacy local tasks/actions.
*
* @param array $router_item
* The current router item.
* @param array $data
* An associative array of local tasks/actions.
* @param string $root_path
*
* @deprecated Remove once all local tasks/actions are converted to plugins.
*/
function _menu_get_legacy_tasks($router_item, &$data, &$root_path) {
// Get all tabs (also known as local tasks) and the root page.
$result = db_select('menu_router', NULL, array('fetch' => PDO::FETCH_ASSOC))
->fields('menu_router')
......@@ -2030,6 +2057,7 @@ function menu_local_tasks($level = 0) {
// Tab parenting may skip levels, so the number of parts in the path may not
// equal the depth. Thus we use the $depth counter (offset by 1000 for ksort).
$depth = 1001;
$tabs = array();
$actions = array();
while (isset($children[$path])) {
$tabs_current = array();
......@@ -2170,28 +2198,6 @@ function menu_local_tasks($level = 0) {
// Remove the depth, we are interested only in their relative placement.
$tabs = array_values($tabs);
$data['tabs'] += $tabs;
// Allow modules to dynamically add further tasks.
$module_handler = \Drupal::moduleHandler();
foreach ($module_handler->getImplementations('menu_local_tasks') as $module) {
$function = $module . '_menu_local_tasks';
$function($data, $router_item, $root_path);
}
// Allow modules to alter local tasks.
$module_handler->alter('menu_local_tasks', $data, $router_item, $root_path);
}
if (isset($data['tabs'][$level])) {
return array(
'tabs' => $data['tabs'][$level],
'actions' => $data['actions'],
'root_path' => $root_path,
);
}
elseif (!empty($data['actions'])) {
return array('actions' => $data['actions']) + $empty;
}
return $empty;
}
/**
......
......@@ -84,7 +84,9 @@ public function content(Request $request, $_content) {
}
if (!is_array($page_content)) {
$page_content = array(
'main' => array(
'#markup' => $page_content,
),
);
}
if (!isset($page_content['#title'])) {
......
......@@ -30,8 +30,8 @@ function custom_block_help($path, $arg) {
/**
* Implements hook_menu_local_tasks().
*/
function custom_block_menu_local_tasks(&$data, $router_item, $root_path) {
if ($router_item['route_name'] == 'custom_block.list') {
function custom_block_menu_local_tasks(&$data, $route_name) {
if ($route_name == 'custom_block.list') {
// @todo Move to a LocalAction plugin when https://drupal.org/node/2045267
// allows local actions to work with query strings.
$item = menu_get_item('block/add');
......@@ -48,13 +48,13 @@ function custom_block_menu_local_tasks(&$data, $router_item, $root_path) {
$routes = array_map(function ($theme) {
return "block.admin_display_$theme";
}, array_keys(list_themes()));
if (in_array($router_item['route_name'], $routes)) {
if (in_array($route_name, $routes)) {
// @todo Move to a LocalAction plugin when https://drupal.org/node/2045267
// allows local actions to work with query strings.
$item = menu_get_item('block/add');
if ($item['access']) {
// Add a destination parameter.
$item['localized_options']['query']['theme'] = end($router_item['map']);
$item['localized_options']['query']['theme'] = \Drupal::request()->attributes->get('theme');
$data['actions']['block/add'] = array(
'#theme' => 'menu_local_action',
'#link' => $item,
......
......@@ -92,10 +92,7 @@ function custom_block_test_menu() {
$items['custom-block/%custom_block'] = array(
'title callback' => 'entity_page_label',
'title arguments' => array(1),
'page callback' => 'entity_view',
'page arguments' => array(1, 'default'),
'access callback' => 'entity_page_access',
'access arguments' => array(1, 'view'),
'route_name' => 'custom_block_test.custom_block_view',
);
return $items;
}
custom_block_test.custom_block_view:
path: '/custom-block/{custom_block}'
defaults:
_entity_view: 'custom_block'
requirements:
_entity_access: 'custom_block.view'
......@@ -372,7 +372,7 @@ function testCommentFunctionality() {
$data = array('bundle' => 'entity_test_render', 'name' => $random_label);
$new_entity = entity_create('entity_test_render', $data);
$new_entity->save();
$this->drupalGet('entity_test_render/manage/' . $new_entity->id() . '/edit');
$this->drupalGet('entity_test_render/manage/' . $new_entity->id());
$this->assertNoFieldChecked('edit-field-foobar-0-status-1');
$this->assertFieldChecked('edit-field-foobar-0-status-2');
$this->assertNoField('edit-field-foobar-0-status-0');
......
content_translation.local_tasks:
derivative: 'Drupal\content_translation\Plugin\Derivative\ContentTranslationLocalTasks'
class: 'Drupal\content_translation\Plugin\ContentTranslationLocalTasks'
weight: 100
<?php
/**
* @file
* Contains \Drupal\content_translation\Plugin\ContentTranslationLocalTasks.
*/
namespace Drupal\content_translation\Plugin;
use Drupal\Core\Menu\LocalTaskDefault;
use Symfony\Component\HttpFoundation\Request;
/**
* Provides route parameter manipulation for content translation local tasks.
*/
class ContentTranslationLocalTasks extends LocalTaskDefault {
/**
* {@inheritdoc}
*/
public function getRouteParameters(Request $request) {
$parameters = parent::getRouteParameters($request);
$entity_type = $this->pluginDefinition['entity_type'];
if ($raw_variables = $request->attributes->get('_raw_variables')) {
// When the entity type is in the path, populate 'entity' for any dynamic
// local tasks.
if ($raw_variables->has($entity_type)) {
$entity = $raw_variables->get($entity_type);
$parameters['entity'] = $entity;
}
// When 'entity' is in the path, populate the parameters with the value
// for the actual entity type.
elseif ($raw_variables->has('entity')) {
$entity = $raw_variables->get('entity');
$parameters[$entity_type] = $entity;
}
}
return $parameters;
}
}
<?php
/**
* @file
* Contains \Drupal\content_translation\Plugin\Derivative\ContentTranslationLocalTasks.
*/
namespace Drupal\content_translation\Plugin\Derivative;
use Drupal\Component\Plugin\Derivative\DerivativeBase;
use Drupal\Core\Entity\EntityManager;
use Drupal\Core\Plugin\Discovery\ContainerDerivativeInterface;
use Drupal\Core\Routing\RouteProviderInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Provides dynamic local tasks for content translation.
*/
class ContentTranslationLocalTasks extends DerivativeBase implements ContainerDerivativeInterface {
/**
* The entity manager.
*
* @var \Drupal\Core\Entity\EntityManager
*/
protected $entityManager;
/**
* The route provider.
*
* @var \Drupal\Core\Routing\RouteProviderInterface
*/
protected $routeProvider;
/**
* Constructs a new ContentTranslationLocalTasks.
*
* @param \Drupal\Core\Entity\EntityManager $entity_manager
* The entity manager.
* @param \Drupal\Core\Routing\RouteProviderInterface $route_provider
* The route provider.
*/
public function __construct(EntityManager $entity_manager, RouteProviderInterface $route_provider) {
$this->entityManager = $entity_manager;
$this->routeProvider = $route_provider;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, $base_plugin_id) {
return new static(
$container->get('entity.manager'),
$container->get('router.route_provider')
);
}
/**
* {@inheritdoc}
*/
public function getDerivativeDefinitions(array $base_plugin_definition) {
// Create tabs for all possible entity types.
foreach ($this->entityManager->getDefinitions() as $entity_type => $entity_info) {
if ($entity_info['translatable'] && isset($entity_info['translation'])) {
$path = '/' . preg_replace('/%(.*)/', '{$1}', $entity_info['menu_base_path']);
if ($routes = $this->routeProvider->getRoutesByPattern($path)->all()) {
// Find the route name for the entity page.
$entity_route_name = key($routes);
$entity_tab = $entity_route_name . '_tab';
// Find the route name for the translation overview.
$translation_route_name = "content_translation.translation_overview_$entity_type";
$translation_tab = $translation_route_name . '_tab';
// Both tabs will have the same root and entity type.
$common_tab_settings = array(
'tab_root_id' => $entity_tab,
'entity_type' => $entity_type,
);
$this->derivatives[$entity_tab] = $base_plugin_definition + $common_tab_settings;
$this->derivatives[$entity_tab]['title'] = t('Edit');
$this->derivatives[$entity_tab]['route_name'] = $entity_route_name;
$this->derivatives[$translation_tab] = $base_plugin_definition + $common_tab_settings;
$this->derivatives[$translation_tab]['title'] = t('Translate');
$this->derivatives[$translation_tab]['route_name'] = $translation_route_name;
}
}
}
return parent::getDerivativeDefinitions($base_plugin_definition);
}
}
......@@ -112,7 +112,7 @@ function testDateField() {
"{$field_name}[0][value][date]" => $date->format($date_format),
);
$this->drupalPostForm(NULL, $edit, t('Save'));
preg_match('|entity_test/manage/(\d+)/edit|', $this->url, $match);
preg_match('|entity_test/manage/(\d+)|', $this->url, $match);
$id = $match[1];
$this->assertText(t('entity_test @id has been created.', array('@id' => $id)));
$this->assertRaw($date->format($date_format));
......@@ -183,7 +183,7 @@ function testDatetimeField() {
"{$field_name}[0][value][time]" => $date->format($time_format),
);
$this->drupalPostForm(NULL, $edit, t('Save'));
preg_match('|entity_test/manage/(\d+)/edit|', $this->url, $match);
preg_match('|entity_test/manage/(\d+)|', $this->url, $match);
$id = $match[1];
$this->assertText(t('entity_test @id has been created.', array('@id' => $id)));
$this->assertRaw($date->format($date_format));
......@@ -276,7 +276,7 @@ function testDatelistWidget() {
}
$this->drupalPostForm(NULL, $edit, t('Save'));
preg_match('|entity_test/manage/(\d+)/edit|', $this->url, $match);
preg_match('|entity_test/manage/(\d+)|', $this->url, $match);
$id = $match[1];
$this->assertText(t('entity_test @id has been created.', array('@id' => $id)));
......
......@@ -103,7 +103,7 @@ function testEmailField() {
"{$field_name}[0][value]" => $value,
);
$this->drupalPostForm(NULL, $edit, t('Save'));
preg_match('|entity_test/manage/(\d+)/edit|', $this->url, $match);
preg_match('|entity_test/manage/(\d+)|', $this->url, $match);
$id = $match[1];
$this->assertText(t('entity_test @id has been created.', array('@id' => $id)));
$this->assertRaw($value);
......
......@@ -129,14 +129,14 @@ function testFieldFormSingle() {
"{$field_name}[0][value]" => $value,
);
$this->drupalPostForm(NULL, $edit, t('Save'));
preg_match('|entity_test/manage/(\d+)/edit|', $this->url, $match);
preg_match('|entity_test/manage/(\d+)|', $this->url, $match);
$id = $match[1];
$this->assertText(t('entity_test @id has been created.', array('@id' => $id)), 'Entity was created');
$entity = entity_load('entity_test', $id);
$this->assertEqual($entity->{$field_name}->value, $value, 'Field value was saved');
// Display edit form.
$this->drupalGet('entity_test/manage/' . $id . '/edit');
$this->drupalGet('entity_test/manage/' . $id);
$this->assertFieldByName("{$field_name}[0][value]", $value, 'Widget is displayed with the correct default value');
$this->assertNoField("{$field_name}[1][value]", 'No extraneous widget is displayed');
......@@ -160,7 +160,7 @@ function testFieldFormSingle() {
'name' => $this->randomName(),
"{$field_name}[0][value]" => $value
);
$this->drupalPostForm('entity_test/manage/' . $id . '/edit', $edit, t('Save'));
$this->drupalPostForm('entity_test/manage/' . $id, $edit, t('Save'));
$this->assertText(t('entity_test @id has been updated.', array('@id' => $id)), 'Entity was updated');
$this->container->get('entity.manager')->getStorageController('entity_test')->resetCache(array($id));
$entity = entity_load('entity_test', $id);
......@@ -194,7 +194,7 @@ function testFieldFormDefaultValue() {
"{$field_name}[0][value]" => '',
);
$this->drupalPostForm(NULL, $edit, t('Save'));
preg_match('|entity_test/manage/(\d+)/edit|', $this->url, $match);
preg_match('|entity_test/manage/(\d+)|', $this->url, $match);
$id = $match[1];
$this->assertText(t('entity_test @id has been created.', array('@id' => $id)), 'Entity was created.');
$entity = entity_load('entity_test', $id);
......@@ -225,7 +225,7 @@ function testFieldFormSingleRequired() {
"{$field_name}[0][value]" => $value,
);
$this->drupalPostForm(NULL, $edit, t('Save'));
preg_match('|entity_test/manage/(\d+)/edit|', $this->url, $match);
preg_match('|entity_test/manage/(\d+)|', $this->url, $match);
$id = $match[1];
$this->assertText(t('entity_test @id has been created.', array('@id' => $id)), 'Entity was created');
$entity = entity_load('entity_test', $id);
......@@ -238,7 +238,7 @@ function testFieldFormSingleRequired() {
'name' => $this->randomName(),
"{$field_name}[0][value]" => $value,
);
$this->drupalPostForm('entity_test/manage/' . $id . '/edit', $edit, t('Save'));
$this->drupalPostForm('entity_test/manage/' . $id, $edit, t('Save'));
$this->assertRaw(t('!name field is required.', array('!name' => $this->instance['label'])), 'Required field with no value fails validation');
}
......@@ -315,7 +315,7 @@ function testFieldFormUnlimited() {
// Submit the form and create the entity.
$this->drupalPostForm(NULL, $edit, t('Save'));
preg_match('|entity_test/manage/(\d+)/edit|', $this->url, $match);
preg_match('|entity_test/manage/(\d+)|', $this->url, $match);
$id = $match[1];
$this->assertText(t('entity_test @id has been created.', array('@id' => $id)), 'Entity was created');
$entity = entity_load('entity_test', $id);
......@@ -467,7 +467,7 @@ function testFieldFormMultipleWidget() {
$field_name => '1, 2, 3',
);
$this->drupalPostForm(NULL, $edit, t('Save'));
preg_match('|entity_test/manage/(\d+)/edit|', $this->url, $match);
preg_match('|entity_test/manage/(\d+)|', $this->url, $match);
$id = $match[1];
// Check that the values were saved.
......@@ -475,7 +475,7 @@ function testFieldFormMultipleWidget() {
$this->assertFieldValues($entity_init, $field_name, array(1, 2, 3));
// Display the form, check that the values are correctly filled in.
$this->drupalGet('entity_test/manage/' . $id . '/edit');
$this->drupalGet('entity_test/manage/' . $id);
$this->assertFieldByName($field_name, '1, 2, 3', 'Widget is displayed.');
// Submit the form with more values than the field accepts.
......@@ -548,7 +548,7 @@ function testFieldFormAccess() {
"{$field_name}[0][value]" => 1,
);
$this->drupalPostForm(NULL, $edit, t('Save'));
preg_match("|$entity_type/manage/(\d+)/edit|", $this->url, $match);
preg_match("|$entity_type/manage/(\d+)|", $this->url, $match);
$id = $match[1];
// Check that the default value was saved.
......@@ -563,7 +563,7 @@ function testFieldFormAccess() {
"{$field_name}[0][value]" => 2,
'revision' => TRUE,
);
$this->drupalPostForm($entity_type . '/manage/' . $id . '/edit', $edit, t('Save'));
$this->drupalPostForm($entity_type . '/manage/' . $id, $edit, t('Save'));
// Check that the new revision has the expected values.
$this->container->get('entity.manager')->getStorageController($entity_type)->resetCache(array($id));
......@@ -605,7 +605,7 @@ function testFieldFormHiddenWidget() {
// the field that uses the hidden widget.
$this->assertNoField("{$field_name}[0][value]", 'The hidden widget is not displayed');
$this->drupalPostForm(NULL, array('user_id' => 1, 'name' => $this->randomName()), t('Save'));
preg_match('|' . $entity_type . '/manage/(\d+)/edit|', $this->url, $match);
preg_match('|' . $entity_type . '/manage/(\d+)|', $this->url, $match);
$id = $match[1];
$this->assertText(t('entity_test_rev @id has been created.', array('@id' => $id)), 'Entity was created');
$entity = entity_load($entity_type, $id);
......@@ -622,7 +622,7 @@ function testFieldFormHiddenWidget() {
->save();
// Display edit form.
$this->drupalGet($entity_type . '/manage/' . $id . '/edit');
$this->drupalGet($entity_type . '/manage/' . $id);
$this->assertFieldByName("{$field_name}[0][value]", 99, 'Widget is displayed with the correct default value');
// Update the entity.
......@@ -643,7 +643,7 @@ function testFieldFormHiddenWidget() {
// Create a new revision.
$edit = array('revision' => TRUE);
$this->drupalPostForm($entity_type . '/manage/' . $id . '/edit', $edit, t('Save'));
$this->drupalPostForm($entity_type . '/manage/' . $id, $edit, t('Save'));
// Check that the expected value has been carried over to the new revision.
entity_get_controller($entity_type)->resetCache(array($id));
......
......@@ -122,7 +122,7 @@ function testFieldFormTranslationRevisions() {
"{$field_name}[0][value]" => $entity->{$field_name}->value,
'revision' => TRUE,
);
$this->drupalPostForm($this->entity_type . '/manage/' . $entity->id() . '/edit', $edit, t('Save'));
$this->drupalPostForm($this->entity_type . '/manage/' . $entity->id(), $edit, t('Save'));
// Check translation revisions.
$this->checkTranslationRevisions($entity->id(), $entity->getRevisionId(), $available_langcodes);
......
......@@ -148,11 +148,11 @@ function forum_menu() {
/**
* Implements hook_menu_local_tasks().
*/
function forum_menu_local_tasks(&$data, $router_item, $root_path) {
function forum_menu_local_tasks(&$data, $route_name) {
global $user;
// Add action link to 'node/add/forum' on 'forum' sub-pages.
if ($root_path == 'forum' || $root_path == 'forum/%') {
if (in_array($route_name, array('forum.index', 'forum.page'))) {
$request = \Drupal::request();
$forum_term = $request->attributes->get('taxonomy_term');
$vid = \Drupal::config('forum.settings')->get('vocabulary');
......
......@@ -107,7 +107,7 @@ function testURLValidation() {
"{$field_name}[0][url]" => $value,
);
$this->drupalPostForm(NULL, $edit, t('Save'));
preg_match('|entity_test/manage/(\d+)/edit|', $this->url, $match);
preg_match('|entity_test/manage/(\d+)|', $this->url, $match);
$id = $match[1];
$this->assertText(t('entity_test @id has been created.', array('@id' => $id)));
$this->assertRaw($value);
......@@ -228,7 +228,7 @@ function testLinkTitle() {
"{$field_name}[0][title]" => '',
);
$this->drupalPostForm(NULL, $edit, t('Save'));
preg_match('|entity_test/manage/(\d+)/edit|', $this->url, $match);
preg_match('|entity_test/manage/(\d+)|', $this->url, $match);
$id = $match[1];
$this->assertText(t('entity_test @id has been created.', array('@id' => $id)));
......@@ -243,7 +243,7 @@ function testLinkTitle() {
'name' => $this->randomName(),
"{$field_name}[0][title]" => $title,
);
$this->drupalPostForm("entity_test/manage/$id/edit", $edit, t('Save'));
$this->drupalPostForm("entity_test/manage/$id", $edit, t('Save'));
$this->assertText(t('entity_test @id has been updated.', array('@id' => $id)));
$this->renderTestEntity($id);
......@@ -309,7 +309,7 @@ function testLinkFormatter() {
// Assert label is shown.
$this->assertText('Read more about this entity');
$this->drupalPostForm(NULL, $edit, t('Save'));
preg_match('|entity_test/manage/(\d+)/edit|', $this->url, $match);
preg_match('|entity_test/manage/(\d+)|', $this->url, $match);
$id = $match[1];
$this->assertText(t('entity_test @id has been created.', array('@id' => $id)));
......@@ -445,7 +445,7 @@ function testLinkSeparateFormatter() {
"{$field_name}[1][title]" => $title2,
);
$this->drupalPostForm(NULL, $edit, t('Save'));
preg_match('|entity_test/manage/(\d+)/edit|', $this->url, $match);
preg_match('|entity_test/manage/(\d+)|', $this->url, $match);
$id = $match[1];