Issue #1800998 by dawehner, swentel: Use route system instead of hook_menu() in Views.
parent
3cdae0550c
commit
7002e6baaa
|
@ -774,7 +774,7 @@ function _menu_translate(&$router_item, $map, $to_arg = FALSE) {
|
||||||
// Attempt to match this path to provide a fully built request to the
|
// Attempt to match this path to provide a fully built request to the
|
||||||
// acccess checker.
|
// acccess checker.
|
||||||
try {
|
try {
|
||||||
$request->attributes->add(Drupal::service('router')->matchRequest($request));
|
$request->attributes->add(Drupal::service('router.dynamic')->matchRequest($request));
|
||||||
$router_item['access'] = Drupal::service('access_manager')->check($route, $request);
|
$router_item['access'] = Drupal::service('access_manager')->check($route, $request);
|
||||||
}
|
}
|
||||||
catch (NotFoundHttpException $e) {
|
catch (NotFoundHttpException $e) {
|
||||||
|
|
|
@ -10,6 +10,7 @@ namespace Drupal\menu_link;
|
||||||
use Drupal\Core\Entity\DatabaseStorageController;
|
use Drupal\Core\Entity\DatabaseStorageController;
|
||||||
use Drupal\Core\Entity\EntityInterface;
|
use Drupal\Core\Entity\EntityInterface;
|
||||||
use Drupal\Core\Entity\EntityStorageException;
|
use Drupal\Core\Entity\EntityStorageException;
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Controller class for menu links.
|
* Controller class for menu links.
|
||||||
|
@ -216,6 +217,36 @@ class MenuLinkStorageController extends DatabaseStorageController {
|
||||||
$entity->router_path = _menu_find_router_path($entity->link_path);
|
$entity->router_path = _menu_find_router_path($entity->link_path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Find the route_name.
|
||||||
|
if (!isset($entity->route_name)) {
|
||||||
|
$entity->route_name = $this->findRouteName($entity->link_path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the route_name matching a URL.
|
||||||
|
*
|
||||||
|
* @param string $link_path
|
||||||
|
* The link path to find a route name for.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* The route name.
|
||||||
|
*/
|
||||||
|
protected function findRouteName($link_path) {
|
||||||
|
// Look up the route_name used for the given path.
|
||||||
|
$request = Request::create('/' . $link_path);
|
||||||
|
$request->attributes->set('system_path', $link_path);
|
||||||
|
try {
|
||||||
|
// Use router.dynamic instead of router, because router will call the
|
||||||
|
// legacy router which will call hook_menu() and you will get back to
|
||||||
|
// this method.
|
||||||
|
$result = \Drupal::service('router.dynamic')->matchRequest($request);
|
||||||
|
return isset($result['_route']) ? $result['_route'] : '';
|
||||||
|
}
|
||||||
|
catch (\Exception $e) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -72,10 +72,6 @@ class NodeRSSContentTest extends NodeTestBase {
|
||||||
// viewing node.
|
// viewing node.
|
||||||
$this->drupalGet("node/$node->nid");
|
$this->drupalGet("node/$node->nid");
|
||||||
$this->assertNoText($rss_only_content, 'Node content designed for RSS does not appear when viewing node.');
|
$this->assertNoText($rss_only_content, 'Node content designed for RSS does not appear when viewing node.');
|
||||||
|
|
||||||
// Check that the node feed page does not try to interpret additional path
|
|
||||||
// components as arguments for node_feed() and returns default content.
|
|
||||||
$this->drupalGet('rss.xml/' . $this->randomName() . '/' . $this->randomName());
|
|
||||||
$this->assertText($rss_only_content, 'Ignore page arguments when delivering rss.xml.');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,74 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Contains \Drupal\node\Tests\Views\NodeIntegrationTest.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Drupal\node\Tests\Views;
|
||||||
|
|
||||||
|
class NodeIntegrationTest extends NodeTestBase {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Views used by this test.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
public static $testViews = array('test_node_view');
|
||||||
|
|
||||||
|
public static function getInfo() {
|
||||||
|
return array(
|
||||||
|
'name' => 'Node: Views data',
|
||||||
|
'description' => 'Tests the node integration into views.',
|
||||||
|
'group' => 'Views module integration',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests basic node view with a node type argument.
|
||||||
|
*/
|
||||||
|
public function testNodeViewTypeArgument() {
|
||||||
|
// Create two content types with three nodes each.
|
||||||
|
$types = array();
|
||||||
|
$all_nids = array();
|
||||||
|
for ($i = 0; $i < 2; $i++) {
|
||||||
|
$type = $this->drupalCreateContentType();
|
||||||
|
$types[] = $type;
|
||||||
|
|
||||||
|
for ($j = 0; $j < 5; $j++) {
|
||||||
|
// Ensure the right order of the nodes.
|
||||||
|
$node = $this->drupalCreateNode(array('type' => $type->type, 'created' => REQUEST_TIME - ($i * 5 + $j)));
|
||||||
|
$nodes[$type->type][$node->id()] = $node;
|
||||||
|
$all_nids[] = $node->id();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->drupalGet('test-node-view');
|
||||||
|
$this->assertResponse(404);
|
||||||
|
|
||||||
|
$this->drupalGet('test-node-view/all');
|
||||||
|
$this->assertResponse(200);
|
||||||
|
$this->assertNids($all_nids);
|
||||||
|
|
||||||
|
foreach ($types as $type) {
|
||||||
|
$this->drupalGet("test-node-view/{$type->type}");
|
||||||
|
$this->assertNids(array_keys($nodes[$type->type]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensures that a list of nodes appear on the page.
|
||||||
|
*
|
||||||
|
* @param array $expected_nids
|
||||||
|
* An array of node IDs.
|
||||||
|
*/
|
||||||
|
protected function assertNids(array $expected_nids = array()) {
|
||||||
|
$result = $this->xpath('//span[@class="field-content"]');
|
||||||
|
$nids = array();
|
||||||
|
foreach ($result as $element) {
|
||||||
|
$nids[] = (int) $element;
|
||||||
|
}
|
||||||
|
$this->assertEqual($nids, $expected_nids);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,195 @@
|
||||||
|
base_field: nid
|
||||||
|
base_table: node
|
||||||
|
core: 8.x
|
||||||
|
description: ''
|
||||||
|
status: '1'
|
||||||
|
display:
|
||||||
|
page_1:
|
||||||
|
display_plugin: page
|
||||||
|
id: page_1
|
||||||
|
display_title: Page
|
||||||
|
position: ''
|
||||||
|
display_options:
|
||||||
|
path: test-node-view
|
||||||
|
default:
|
||||||
|
display_plugin: default
|
||||||
|
id: default
|
||||||
|
display_title: Master
|
||||||
|
position: ''
|
||||||
|
display_options:
|
||||||
|
access:
|
||||||
|
type: perm
|
||||||
|
options:
|
||||||
|
perm: 'access content'
|
||||||
|
cache:
|
||||||
|
type: none
|
||||||
|
options: { }
|
||||||
|
query:
|
||||||
|
type: views_query
|
||||||
|
options:
|
||||||
|
disable_sql_rewrite: '0'
|
||||||
|
distinct: '0'
|
||||||
|
slave: '0'
|
||||||
|
query_comment: ''
|
||||||
|
query_tags: { }
|
||||||
|
exposed_form:
|
||||||
|
type: basic
|
||||||
|
options:
|
||||||
|
submit_button: Apply
|
||||||
|
reset_button: '0'
|
||||||
|
reset_button_label: Reset
|
||||||
|
exposed_sorts_label: 'Sort by'
|
||||||
|
expose_sort_order: '1'
|
||||||
|
sort_asc_label: Asc
|
||||||
|
sort_desc_label: Desc
|
||||||
|
pager:
|
||||||
|
type: full
|
||||||
|
options:
|
||||||
|
items_per_page: '10'
|
||||||
|
offset: '0'
|
||||||
|
id: '0'
|
||||||
|
total_pages: ''
|
||||||
|
expose:
|
||||||
|
items_per_page: '0'
|
||||||
|
items_per_page_label: 'Items per page'
|
||||||
|
items_per_page_options: '5, 10, 20, 40, 60'
|
||||||
|
items_per_page_options_all: '0'
|
||||||
|
items_per_page_options_all_label: '- All -'
|
||||||
|
offset: '0'
|
||||||
|
offset_label: Offset
|
||||||
|
tags:
|
||||||
|
previous: '‹ previous'
|
||||||
|
next: 'next ›'
|
||||||
|
first: '« first'
|
||||||
|
last: 'last »'
|
||||||
|
quantity: '9'
|
||||||
|
style:
|
||||||
|
type: default
|
||||||
|
row:
|
||||||
|
type: fields
|
||||||
|
fields:
|
||||||
|
nid:
|
||||||
|
id: nid
|
||||||
|
table: node
|
||||||
|
field: nid
|
||||||
|
relationship: none
|
||||||
|
group_type: group
|
||||||
|
admin_label: ''
|
||||||
|
label: Nid
|
||||||
|
exclude: '0'
|
||||||
|
alter:
|
||||||
|
alter_text: '0'
|
||||||
|
text: ''
|
||||||
|
make_link: '0'
|
||||||
|
path: ''
|
||||||
|
absolute: '0'
|
||||||
|
external: '0'
|
||||||
|
replace_spaces: '0'
|
||||||
|
path_case: none
|
||||||
|
trim_whitespace: '0'
|
||||||
|
alt: ''
|
||||||
|
rel: ''
|
||||||
|
link_class: ''
|
||||||
|
prefix: ''
|
||||||
|
suffix: ''
|
||||||
|
target: ''
|
||||||
|
nl2br: '0'
|
||||||
|
max_length: ''
|
||||||
|
word_boundary: '1'
|
||||||
|
ellipsis: '1'
|
||||||
|
more_link: '0'
|
||||||
|
more_link_text: ''
|
||||||
|
more_link_path: ''
|
||||||
|
strip_tags: '0'
|
||||||
|
trim: '0'
|
||||||
|
preserve_tags: ''
|
||||||
|
html: '0'
|
||||||
|
element_type: ''
|
||||||
|
element_class: ''
|
||||||
|
element_label_type: ''
|
||||||
|
element_label_class: ''
|
||||||
|
element_label_colon: '1'
|
||||||
|
element_wrapper_type: ''
|
||||||
|
element_wrapper_class: ''
|
||||||
|
element_default_classes: '1'
|
||||||
|
empty: ''
|
||||||
|
hide_empty: '0'
|
||||||
|
empty_zero: '0'
|
||||||
|
hide_alter_empty: '1'
|
||||||
|
link_to_node: '0'
|
||||||
|
plugin_id: node
|
||||||
|
filters:
|
||||||
|
status:
|
||||||
|
value: '1'
|
||||||
|
table: node
|
||||||
|
field: status
|
||||||
|
id: status
|
||||||
|
expose:
|
||||||
|
operator: '0'
|
||||||
|
group: '1'
|
||||||
|
sorts:
|
||||||
|
created:
|
||||||
|
id: created
|
||||||
|
table: node
|
||||||
|
field: created
|
||||||
|
order: DESC
|
||||||
|
relationship: none
|
||||||
|
group_type: group
|
||||||
|
admin_label: ''
|
||||||
|
exposed: '0'
|
||||||
|
expose:
|
||||||
|
label: ''
|
||||||
|
granularity: second
|
||||||
|
title: test_node_view
|
||||||
|
header: { }
|
||||||
|
footer: { }
|
||||||
|
empty: { }
|
||||||
|
relationships: { }
|
||||||
|
arguments:
|
||||||
|
type:
|
||||||
|
id: type
|
||||||
|
table: node
|
||||||
|
field: type
|
||||||
|
relationship: none
|
||||||
|
group_type: group
|
||||||
|
admin_label: ''
|
||||||
|
default_action: 'not found'
|
||||||
|
exception:
|
||||||
|
value: all
|
||||||
|
title_enable: '0'
|
||||||
|
title: All
|
||||||
|
title_enable: '0'
|
||||||
|
title: ''
|
||||||
|
breadcrumb_enable: '0'
|
||||||
|
breadcrumb: ''
|
||||||
|
default_argument_type: fixed
|
||||||
|
default_argument_options:
|
||||||
|
argument: ''
|
||||||
|
default_argument_skip_url: '0'
|
||||||
|
summary_options:
|
||||||
|
base_path: ''
|
||||||
|
count: '1'
|
||||||
|
items_per_page: '25'
|
||||||
|
override: '0'
|
||||||
|
summary:
|
||||||
|
sort_order: asc
|
||||||
|
number_of_records: '0'
|
||||||
|
format: default_summary
|
||||||
|
specify_validation: '0'
|
||||||
|
validate:
|
||||||
|
type: none
|
||||||
|
fail: 'not found'
|
||||||
|
validate_options: { }
|
||||||
|
glossary: '0'
|
||||||
|
limit: '0'
|
||||||
|
case: none
|
||||||
|
path_case: none
|
||||||
|
transform_dash: '0'
|
||||||
|
break_phrase: '0'
|
||||||
|
plugin_id: node_type
|
||||||
|
label: test_node_view
|
||||||
|
module: views
|
||||||
|
id: test_node_view
|
||||||
|
tag: ''
|
||||||
|
uuid: 377e9d79-57ea-4836-a100-a255c58e40ca
|
||||||
|
langcode: en
|
|
@ -23,7 +23,7 @@ use Drupal\views\Plugin\views\display\PathPluginBase;
|
||||||
* module = "rest",
|
* module = "rest",
|
||||||
* title = @Translation("REST export"),
|
* title = @Translation("REST export"),
|
||||||
* help = @Translation("Create a REST export resource."),
|
* help = @Translation("Create a REST export resource."),
|
||||||
* uses_hook_menu = TRUE,
|
* uses_route = TRUE,
|
||||||
* admin = @Translation("REST export")
|
* admin = @Translation("REST export")
|
||||||
* )
|
* )
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -14,6 +14,10 @@ use Symfony\Component\HttpFoundation\Response;
|
||||||
*/
|
*/
|
||||||
class TestControllers {
|
class TestControllers {
|
||||||
|
|
||||||
|
public function test() {
|
||||||
|
return new Response('test');
|
||||||
|
}
|
||||||
|
|
||||||
public function test1() {
|
public function test1() {
|
||||||
return new Response('test1');
|
return new Response('test1');
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ namespace Drupal\user\Plugin\views\access;
|
||||||
use Drupal\Component\Annotation\Plugin;
|
use Drupal\Component\Annotation\Plugin;
|
||||||
use Drupal\views\Plugin\views\access\AccessPluginBase;
|
use Drupal\views\Plugin\views\access\AccessPluginBase;
|
||||||
use Drupal\Core\Annotation\Translation;
|
use Drupal\Core\Annotation\Translation;
|
||||||
|
use Symfony\Component\Routing\Route;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Access plugin that provides permission-based access control.
|
* Access plugin that provides permission-based access control.
|
||||||
|
@ -30,11 +31,14 @@ class Permission extends AccessPluginBase {
|
||||||
protected $usesOptions = TRUE;
|
protected $usesOptions = TRUE;
|
||||||
|
|
||||||
public function access($account) {
|
public function access($account) {
|
||||||
return views_check_perm($this->options['perm'], $account);
|
return user_access($this->options['perm'], $account) || user_access('access all views', $account);
|
||||||
}
|
}
|
||||||
|
|
||||||
function get_access_callback() {
|
/**
|
||||||
return array('views_check_perm', array($this->options['perm']));
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function alterRouteDefinition(Route $route) {
|
||||||
|
$route->setRequirement('_permission', $this->options['perm']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function summaryTitle() {
|
public function summaryTitle() {
|
||||||
|
|
|
@ -10,6 +10,7 @@ namespace Drupal\user\Plugin\views\access;
|
||||||
use Drupal\Component\Annotation\Plugin;
|
use Drupal\Component\Annotation\Plugin;
|
||||||
use Drupal\views\Plugin\views\access\AccessPluginBase;
|
use Drupal\views\Plugin\views\access\AccessPluginBase;
|
||||||
use Drupal\Core\Annotation\Translation;
|
use Drupal\Core\Annotation\Translation;
|
||||||
|
use Symfony\Component\Routing\Route;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Access plugin that provides role-based access control.
|
* Access plugin that provides role-based access control.
|
||||||
|
@ -29,12 +30,18 @@ class Role extends AccessPluginBase {
|
||||||
*/
|
*/
|
||||||
protected $usesOptions = TRUE;
|
protected $usesOptions = TRUE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
public function access($account) {
|
public function access($account) {
|
||||||
return views_check_roles(array_filter($this->options['role']), $account);
|
return user_access('access all views', $account) || array_intersect(array_filter($this->options['role']), $account->roles);
|
||||||
}
|
}
|
||||||
|
|
||||||
function get_access_callback() {
|
/**
|
||||||
return array('views_check_roles', array(array_filter($this->options['role'])));
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function alterRouteDefinition(Route $route) {
|
||||||
|
$route->setRequirement('_role_id', $this->options['role']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function summaryTitle() {
|
public function summaryTitle() {
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Contains \Drupal\views\EventSubscriber\RouteSubscriber.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Drupal\views\EventSubscriber;
|
||||||
|
|
||||||
|
use Drupal\Core\Routing\RouteBuildEvent;
|
||||||
|
use Drupal\Core\Routing\RoutingEvents;
|
||||||
|
use Drupal\views\Plugin\views\display\DisplayRouterInterface;
|
||||||
|
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds up the routes of all views.
|
||||||
|
*/
|
||||||
|
class RouteSubscriber implements EventSubscriberInterface {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public static function getSubscribedEvents() {
|
||||||
|
$events[RoutingEvents::DYNAMIC] = 'dynamicRoutes';
|
||||||
|
return $events;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds routes defined by all views.
|
||||||
|
*
|
||||||
|
* @param \Drupal\Core\Routing\RouteBuildEvent $event
|
||||||
|
* The route building event.
|
||||||
|
*/
|
||||||
|
public function dynamicRoutes(RouteBuildEvent $event) {
|
||||||
|
$collection = $event->getRouteCollection();
|
||||||
|
|
||||||
|
$views = views_get_applicable_views('uses_route');
|
||||||
|
foreach ($views as $data) {
|
||||||
|
list($view, $display_id) = $data;
|
||||||
|
if ($view->setDisplay($display_id) && $display = $view->displayHandlers->get($display_id)) {
|
||||||
|
if ($display instanceof DisplayRouterInterface) {
|
||||||
|
$display->collectRoutes($collection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$view->destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -9,13 +9,14 @@ namespace Drupal\views\Plugin\views\access;
|
||||||
|
|
||||||
use Drupal\views\Plugin\views\PluginBase;
|
use Drupal\views\Plugin\views\PluginBase;
|
||||||
use Drupal\views\ViewExecutable;
|
use Drupal\views\ViewExecutable;
|
||||||
|
use Symfony\Component\Routing\Route;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @defgroup views_access_plugins Views access plugins
|
* @defgroup views_access_plugins Views access plugins
|
||||||
* @{
|
* @{
|
||||||
* The base plugin to handle access to a view.
|
* The base plugin to handle access to a view.
|
||||||
*
|
*
|
||||||
* Therefore it primarily has to implement the access and the get_access_callback
|
* Therefore it primarily has to implement the access and the alterRouteDefinition
|
||||||
* method.
|
* method.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -65,18 +66,15 @@ abstract class AccessPluginBase extends PluginBase {
|
||||||
abstract public function access($account);
|
abstract public function access($account);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine the access callback and arguments.
|
* Allows access plugins to alter the route definition of a view.
|
||||||
*
|
*
|
||||||
* This information will be embedded in the menu in order to reduce
|
* Likely the access plugin will add new requirements, so its custom access
|
||||||
* performance hits during menu item access testing, which happens
|
* checker can be applied.
|
||||||
* a lot.
|
|
||||||
*
|
*
|
||||||
* @return array
|
* @param \Symfony\Component\Routing\Route $route
|
||||||
* The first item of the array should be the function to call,and the
|
* The route to change.
|
||||||
* second item should be an array of arguments. The first item may also be
|
|
||||||
* TRUE (bool only) which will indicate no access control.
|
|
||||||
*/
|
*/
|
||||||
abstract function get_access_callback();
|
abstract public function alterRouteDefinition(Route $route);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,8 @@ namespace Drupal\views\Plugin\views\access;
|
||||||
use Drupal\Core\Annotation\Translation;
|
use Drupal\Core\Annotation\Translation;
|
||||||
use Drupal\Component\Annotation\Plugin;
|
use Drupal\Component\Annotation\Plugin;
|
||||||
|
|
||||||
|
use Symfony\Component\Routing\Route;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Access plugin that provides no access control at all.
|
* Access plugin that provides no access control at all.
|
||||||
*
|
*
|
||||||
|
@ -36,11 +38,10 @@ class None extends AccessPluginBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements Drupal\views\Plugin\views\access\AccessPluginBase::get_access_callback().
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function get_access_callback() {
|
public function alterRouteDefinition(Route $route) {
|
||||||
// No access control.
|
$route->setRequirement('_access', 'TRUE');
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Contains \Drupal\views\Plugin\views\display\DisplayRouterInterface.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Drupal\views\Plugin\views\display;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines an interface for displays that can collect routes.
|
||||||
|
*
|
||||||
|
* In addition to implementing the interface, specify 'uses_routes' in the
|
||||||
|
* plugin definition.
|
||||||
|
*/
|
||||||
|
use Symfony\Component\Routing\RouteCollection;
|
||||||
|
|
||||||
|
interface DisplayRouterInterface {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds the route entry of a view to the collection.
|
||||||
|
*
|
||||||
|
* @param \Symfony\Component\Routing\RouteCollection $collection
|
||||||
|
* A collection of routes that should be registered for this resource.
|
||||||
|
*/
|
||||||
|
public function collectRoutes(RouteCollection $collection);
|
||||||
|
|
||||||
|
}
|
|
@ -22,7 +22,7 @@ use Drupal\Core\Annotation\Translation;
|
||||||
* id = "feed",
|
* id = "feed",
|
||||||
* title = @Translation("Feed"),
|
* title = @Translation("Feed"),
|
||||||
* help = @Translation("Display the view as a feed, such as an RSS feed."),
|
* help = @Translation("Display the view as a feed, such as an RSS feed."),
|
||||||
* uses_hook_menu = TRUE,
|
* uses_route = TRUE,
|
||||||
* admin = @Translation("Feed")
|
* admin = @Translation("Feed")
|
||||||
* )
|
* )
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -22,6 +22,7 @@ use Drupal\Core\Annotation\Translation;
|
||||||
* title = @Translation("Page"),
|
* title = @Translation("Page"),
|
||||||
* help = @Translation("Display the view as a page, with a URL and menu links."),
|
* help = @Translation("Display the view as a page, with a URL and menu links."),
|
||||||
* uses_hook_menu = TRUE,
|
* uses_hook_menu = TRUE,
|
||||||
|
* uses_route = TRUE,
|
||||||
* contextual_links_locations = {"page"},
|
* contextual_links_locations = {"page"},
|
||||||
* theme = "views_view",
|
* theme = "views_view",
|
||||||
* admin = @Translation("Page")
|
* admin = @Translation("Page")
|
||||||
|
@ -92,7 +93,10 @@ class Page extends PathPluginBase {
|
||||||
// And the title, which is much easier.
|
// And the title, which is much easier.
|
||||||
drupal_set_title(filter_xss_admin($this->view->getTitle()), PASS_THROUGH);
|
drupal_set_title(filter_xss_admin($this->view->getTitle()), PASS_THROUGH);
|
||||||
|
|
||||||
return $render;
|
$response = $this->view->getResponse();
|
||||||
|
$response->setContent(drupal_render_page($render));
|
||||||
|
|
||||||
|
return $response;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -8,13 +8,16 @@
|
||||||
namespace Drupal\views\Plugin\views\display;
|
namespace Drupal\views\Plugin\views\display;
|
||||||
|
|
||||||
use Drupal\views\Views;
|
use Drupal\views\Views;
|
||||||
|
|
||||||
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
|
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
|
||||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||||
|
use Symfony\Component\Routing\Route;
|
||||||
|
use Symfony\Component\Routing\RouteCollection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The base display plugin for path/callbacks. This is used for pages and feeds.
|
* The base display plugin for path/callbacks. This is used for pages and feeds.
|
||||||
*/
|
*/
|
||||||
abstract class PathPluginBase extends DisplayPluginBase {
|
abstract class PathPluginBase extends DisplayPluginBase implements DisplayRouterInterface {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Overrides \Drupal\views\Plugin\views\display\DisplayPluginBase::hasPath().
|
* Overrides \Drupal\views\Plugin\views\display\DisplayPluginBase::hasPath().
|
||||||
|
@ -33,6 +36,69 @@ abstract class PathPluginBase extends DisplayPluginBase {
|
||||||
return $options;
|
return $options;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function collectRoutes(RouteCollection $collection) {
|
||||||
|
$view_id = $this->view->storage->id();
|
||||||
|
$display_id = $this->display['id'];
|
||||||
|
|
||||||
|
$defaults = array(
|
||||||
|
'_controller' => 'Drupal\views\Routing\ViewPageController::handle',
|
||||||
|
'view_id' => $view_id,
|
||||||
|
'display_id' => $display_id,
|
||||||
|
);
|
||||||
|
|
||||||
|
// @todo How do we apply argument validation?
|
||||||
|
$bits = explode('/', $this->getOption('path'));
|
||||||
|
// @todo Figure out validation/argument loading.
|
||||||
|
// Replace % with %views_arg for menu autoloading and add to the
|
||||||
|
// page arguments so the argument actually comes through.
|
||||||
|
$arg_counter = 0;
|
||||||
|
|
||||||
|
$this->view->initHandlers();
|
||||||
|
$view_arguments = $this->view->argument;
|
||||||
|
|
||||||
|
$argument_ids = array_keys($view_arguments);
|
||||||
|
$total_arguments = count($argument_ids);
|
||||||
|
|
||||||
|
// Replace arguments in the views UI (defined via %) with parameters in
|
||||||
|
// routes (defined via {}). As a name for the parameter use arg_$key, so
|
||||||
|
// it can be pulled in the views controller from the request.
|
||||||
|
foreach ($bits as $pos => $bit) {
|
||||||
|
if ($bit == '%') {
|
||||||
|
// Generate the name of the parameter using the key of the argument
|
||||||
|
// handler.
|
||||||
|
$arg_id = 'arg_' . $argument_ids[$arg_counter++];
|
||||||
|
$bits[$pos] = '{' . $arg_id . '}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add missing arguments not defined in the path, but added as handler.
|
||||||
|
while (($total_arguments - $arg_counter) > 0) {
|
||||||
|
$arg_id = 'arg_' . $argument_ids[$arg_counter++];
|
||||||
|
$bit = '{' . $arg_id . '}';
|
||||||
|
// In contrast to the previous loop add the defaults here, as % was not
|
||||||
|
// specified, which means the argument is optional.
|
||||||
|
$defaults[$arg_id] = NULL;
|
||||||
|
$bits[] = $bit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$route_path = '/' . implode('/', $bits);
|
||||||
|
|
||||||
|
$route = new Route($route_path, $defaults);
|
||||||
|
|
||||||
|
// Add access check parameters to the route.
|
||||||
|
$access_plugin = $this->getPlugin('access');
|
||||||
|
if (!isset($access_plugin)) {
|
||||||
|
// @todo Do we want to support a default plugin in getPlugin itself?
|
||||||
|
$access_plugin = Views::pluginManager('access')->createInstance('none');
|
||||||
|
}
|
||||||
|
$access_plugin->alterRouteDefinition($route);
|
||||||
|
|
||||||
|
$collection->add("view.$view_id.$display_id", $route);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Overrides \Drupal\views\Plugin\views\display\DisplayPluginBase::executeHookMenu().
|
* Overrides \Drupal\views\Plugin\views\display\DisplayPluginBase::executeHookMenu().
|
||||||
*/
|
*/
|
||||||
|
@ -60,49 +126,9 @@ abstract class PathPluginBase extends DisplayPluginBase {
|
||||||
|
|
||||||
$path = implode('/', $bits);
|
$path = implode('/', $bits);
|
||||||
|
|
||||||
$access_plugin = $this->getPlugin('access');
|
|
||||||
if (!isset($access_plugin)) {
|
|
||||||
$access_plugin = Views::pluginManager('access')->createInstance('none');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get access callback might return an array of the callback + the dynamic
|
|
||||||
// arguments.
|
|
||||||
$access_plugin_callback = $access_plugin->get_access_callback();
|
|
||||||
|
|
||||||
if (is_array($access_plugin_callback)) {
|
|
||||||
$access_arguments = array();
|
|
||||||
|
|
||||||
// Find the plugin arguments.
|
|
||||||
$access_plugin_method = array_shift($access_plugin_callback);
|
|
||||||
$access_plugin_arguments = array_shift($access_plugin_callback);
|
|
||||||
if (!is_array($access_plugin_arguments)) {
|
|
||||||
$access_plugin_arguments = array();
|
|
||||||
}
|
|
||||||
|
|
||||||
$access_arguments[0] = array($access_plugin_method, &$access_plugin_arguments);
|
|
||||||
|
|
||||||
// Move the plugin arguments to the access arguments array.
|
|
||||||
$i = 1;
|
|
||||||
foreach ($access_plugin_arguments as $key => $value) {
|
|
||||||
if (is_int($value)) {
|
|
||||||
$access_arguments[$i] = $value;
|
|
||||||
$access_plugin_arguments[$key] = $i;
|
|
||||||
$i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$access_arguments = array($access_plugin_callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($path) {
|
if ($path) {
|
||||||
$items[$path] = array(
|
$items[$path] = array(
|
||||||
// Default views page entry.
|
'route_name' => "view.{$this->view->storage->id()}.{$this->display['id']}",
|
||||||
'page callback' => 'views_page',
|
|
||||||
'page arguments' => $page_arguments,
|
|
||||||
// Default access check (per display).
|
|
||||||
'access callback' => 'views_access',
|
|
||||||
'access arguments' => $access_arguments,
|
|
||||||
// Identify URL embedded arguments and correlate them to a handler.
|
// Identify URL embedded arguments and correlate them to a handler.
|
||||||
'load arguments' => array($this->view->storage->id(), $this->display['id'], '%index'),
|
'load arguments' => array($this->view->storage->id(), $this->display['id'], '%index'),
|
||||||
);
|
);
|
||||||
|
@ -159,11 +185,6 @@ abstract class PathPluginBase extends DisplayPluginBase {
|
||||||
$default_path = implode('/', $bits);
|
$default_path = implode('/', $bits);
|
||||||
$items[$default_path] = array(
|
$items[$default_path] = array(
|
||||||
// Default views page entry.
|
// Default views page entry.
|
||||||
'page callback' => 'views_page',
|
|
||||||
'page arguments' => $page_arguments,
|
|
||||||
// Default access check (per display).
|
|
||||||
'access callback' => 'views_access',
|
|
||||||
'access arguments' => $access_arguments,
|
|
||||||
// Identify URL embedded arguments and correlate them to a
|
// Identify URL embedded arguments and correlate them to a
|
||||||
// handler.
|
// handler.
|
||||||
'load arguments' => array($this->view->storage->id(), $this->display['id'], '%index'),
|
'load arguments' => array($this->view->storage->id(), $this->display['id'], '%index'),
|
||||||
|
|
|
@ -0,0 +1,86 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Contains \Drupal\views\Routing\ViewPageController.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Drupal\views\Routing;
|
||||||
|
|
||||||
|
use Drupal\Core\ControllerInterface;
|
||||||
|
use Drupal\Core\Entity\EntityStorageControllerInterface;
|
||||||
|
use Drupal\views\ViewExecutableFactory;
|
||||||
|
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines a page controller to execute and render a view.
|
||||||
|
*/
|
||||||
|
class ViewPageController implements ControllerInterface {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The entity storage controller.
|
||||||
|
*
|
||||||
|
* @var \Drupal\Core\Entity\EntityStorageControllerInterface
|
||||||
|
*/
|
||||||
|
protected $storageController;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The view executable factory.
|
||||||
|
*
|
||||||
|
* @var \Drupal\views\ViewExecutableFactory
|
||||||
|
*/
|
||||||
|
protected $executableFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a ViewPageController object.
|
||||||
|
*
|
||||||
|
* @param \Drupal\Core\Entity\EntityStorageControllerInterface $storage_controller
|
||||||
|
* The entity storage controller.
|
||||||
|
* @param \Drupal\views\ViewExecutableFactory $executable_factory
|
||||||
|
* The view executable factory
|
||||||
|
*/
|
||||||
|
public function __construct(EntityStorageControllerInterface $storage_controller, ViewExecutableFactory $executable_factory) {
|
||||||
|
$this->storageController = $storage_controller;
|
||||||
|
$this->executableFactory = $executable_factory;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public static function create(ContainerInterface $container) {
|
||||||
|
return new static(
|
||||||
|
$container->get('plugin.manager.entity')->getStorageController('view'),
|
||||||
|
$container->get('views.executable')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles a response for a view.
|
||||||
|
*/
|
||||||
|
public function handle(Request $request) {
|
||||||
|
$view_id = $request->attributes->get('view_id');
|
||||||
|
$display_id = $request->attributes->get('display_id');
|
||||||
|
|
||||||
|
$entities = $this->storageController->load(array($view_id));
|
||||||
|
$entity = reset($entities);
|
||||||
|
if (empty($entity)) {
|
||||||
|
throw new NotFoundHttpException(format_string('Page controller for view %id requested, but view was not found.', array('%id' => $view_id)));
|
||||||
|
}
|
||||||
|
$view = $this->executableFactory->get($entity);
|
||||||
|
$view->setDisplay($display_id);
|
||||||
|
$view->initHandlers();
|
||||||
|
|
||||||
|
$args = array();
|
||||||
|
foreach (array_keys((array) $view->argument) as $argument_id) {
|
||||||
|
$arg = $request->attributes->get('arg_' . $argument_id);
|
||||||
|
if (isset($arg)) {
|
||||||
|
$args[] = $arg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $view->executeDisplay($display_id, $args);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -7,6 +7,8 @@
|
||||||
|
|
||||||
namespace Drupal\views\Tests\Plugin;
|
namespace Drupal\views\Tests\Plugin;
|
||||||
|
|
||||||
|
use Drupal\views\Tests\ViewTestData;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Basic test for pluggable access.
|
* Basic test for pluggable access.
|
||||||
*
|
*
|
||||||
|
@ -35,6 +37,8 @@ class AccessTest extends PluginTestBase {
|
||||||
|
|
||||||
$this->enableViewsTestModule();
|
$this->enableViewsTestModule();
|
||||||
|
|
||||||
|
ViewTestData::importTestViews(get_class($this), array('views_test_data'));
|
||||||
|
|
||||||
$this->admin_user = $this->drupalCreateUser(array('access all views'));
|
$this->admin_user = $this->drupalCreateUser(array('access all views'));
|
||||||
$this->web_user = $this->drupalCreateUser();
|
$this->web_user = $this->drupalCreateUser();
|
||||||
$this->web_role = current($this->web_user->roles);
|
$this->web_role = current($this->web_user->roles);
|
||||||
|
@ -42,6 +46,7 @@ class AccessTest extends PluginTestBase {
|
||||||
$this->normal_role = $this->drupalCreateRole(array());
|
$this->normal_role = $this->drupalCreateRole(array());
|
||||||
$this->normal_user = $this->drupalCreateUser(array('views_test_data test permission'));
|
$this->normal_user = $this->drupalCreateUser(array('views_test_data test permission'));
|
||||||
$this->normal_user->roles[$this->normal_role] = $this->normal_role;
|
$this->normal_user->roles[$this->normal_role] = $this->normal_role;
|
||||||
|
|
||||||
// @todo when all the plugin information is cached make a reset function and
|
// @todo when all the plugin information is cached make a reset function and
|
||||||
// call it here.
|
// call it here.
|
||||||
}
|
}
|
||||||
|
@ -74,57 +79,19 @@ class AccessTest extends PluginTestBase {
|
||||||
$access_plugin = $view->display_handler->getPlugin('access');
|
$access_plugin = $view->display_handler->getPlugin('access');
|
||||||
|
|
||||||
$this->assertFalse($access_plugin->access($this->normal_user));
|
$this->assertFalse($access_plugin->access($this->normal_user));
|
||||||
|
$this->drupalGet('test_access_static');
|
||||||
|
$this->assertResponse(403);
|
||||||
|
|
||||||
|
$display = &$view->storage->getDisplay('default');
|
||||||
|
$display['display_options']['access']['options']['access'] = TRUE;
|
||||||
$access_plugin->options['access'] = TRUE;
|
$access_plugin->options['access'] = TRUE;
|
||||||
|
$view->save();
|
||||||
|
$this->container->get('router.builder')->rebuild();
|
||||||
|
|
||||||
$this->assertTrue($access_plugin->access($this->normal_user));
|
$this->assertTrue($access_plugin->access($this->normal_user));
|
||||||
|
|
||||||
// FALSE comes from hook_menu caching.
|
$this->drupalGet('test_access_static');
|
||||||
$expected_hook_menu = array(
|
$this->assertResponse(200);
|
||||||
'views_test_data_test_static_access_callback', array(FALSE)
|
|
||||||
);
|
|
||||||
$hook_menu = $view->executeHookMenu('page_1');
|
|
||||||
$this->assertEqual($expected_hook_menu, $hook_menu['test_access_static']['access arguments'][0]);
|
|
||||||
|
|
||||||
$expected_hook_menu = array(
|
|
||||||
'views_test_data_test_static_access_callback', array(TRUE)
|
|
||||||
);
|
|
||||||
$this->assertTrue(views_access($expected_hook_menu));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests dynamic access plugin.
|
|
||||||
*
|
|
||||||
* @see Drupal\views_test\Plugin\views\access\DyamicTest
|
|
||||||
*/
|
|
||||||
function testDynamicAccessPlugin() {
|
|
||||||
$view = views_get_view('test_access_dynamic');
|
|
||||||
$view->setDisplay();
|
|
||||||
$argument1 = $this->randomName();
|
|
||||||
$argument2 = $this->randomName();
|
|
||||||
state()->set('test_dynamic_access_argument1', $argument1);
|
|
||||||
state()->set('test_dynamic_access_argument2', $argument2);
|
|
||||||
|
|
||||||
$access_plugin = $view->display_handler->getPlugin('access');
|
|
||||||
|
|
||||||
$this->assertFalse($access_plugin->access($this->normal_user));
|
|
||||||
|
|
||||||
$access_plugin->options['access'] = TRUE;
|
|
||||||
$this->assertFalse($access_plugin->access($this->normal_user));
|
|
||||||
|
|
||||||
$view->setArguments(array($argument1, $argument2));
|
|
||||||
$this->assertTrue($access_plugin->access($this->normal_user));
|
|
||||||
|
|
||||||
// FALSE comes from hook_menu caching.
|
|
||||||
$expected_hook_menu = array(
|
|
||||||
'views_test_data_test_dynamic_access_callback', array(FALSE, 1, 2)
|
|
||||||
);
|
|
||||||
$hook_menu = $view->executeHookMenu('page_1');
|
|
||||||
$this->assertEqual($expected_hook_menu, $hook_menu['test_access_dynamic']['access arguments'][0]);
|
|
||||||
|
|
||||||
$expected_hook_menu = array(
|
|
||||||
'views_test_data_test_dynamic_access_callback', array(TRUE, 1, 2)
|
|
||||||
);
|
|
||||||
$this->assertTrue(views_access($expected_hook_menu, $argument1, $argument2));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,26 +2,45 @@
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file
|
* @file
|
||||||
* Definition of Drupal\views\Tests\Plugin\DisplayPageTest.
|
* Contains \Drupal\views\Tests\Plugin\DisplayPageTest.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Drupal\views\Tests\Plugin;
|
namespace Drupal\views\Tests\Plugin;
|
||||||
|
|
||||||
use Drupal\views\Tests\Plugin\PluginTestBase;
|
use Drupal\Core\Routing\RouteBuildEvent;
|
||||||
|
use Drupal\views\EventSubscriber\RouteSubscriber;
|
||||||
|
use Drupal\views\Tests\ViewUnitTestBase;
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
use Symfony\Component\HttpKernel\HttpKernelInterface;
|
||||||
|
use Symfony\Component\Routing\RouteCollection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests the page display plugin.
|
* Tests the page display plugin.
|
||||||
*
|
*
|
||||||
* @see Drupal\views\Plugin\display\Page
|
* @see Drupal\views\Plugin\display\Page
|
||||||
*/
|
*/
|
||||||
class DisplayPageTest extends PluginTestBase {
|
class DisplayPageTest extends ViewUnitTestBase {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Views used by this test.
|
* Views used by this test.
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
public static $testViews = array('test_page_display');
|
public static $testViews = array('test_page_display', 'test_page_display_route');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Modules to enable.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
public static $modules = array('system', 'user');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The router dumper to get all routes.
|
||||||
|
*
|
||||||
|
* @var \Drupal\Core\Routing\MatcherDumper
|
||||||
|
*/
|
||||||
|
protected $routerDumper;
|
||||||
|
|
||||||
public static function getInfo() {
|
public static function getInfo() {
|
||||||
return array(
|
return array(
|
||||||
|
@ -31,21 +50,82 @@ class DisplayPageTest extends PluginTestBase {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
protected function setUp() {
|
protected function setUp() {
|
||||||
parent::setUp();
|
parent::setUp();
|
||||||
|
|
||||||
$this->enableViewsTestModule();
|
// Setup the needed tables in order to make the drupal router working.
|
||||||
|
$this->installSchema('system', 'router');
|
||||||
|
$this->installSchema('system', 'url_alias');
|
||||||
|
$this->installSchema('system', 'menu_router');
|
||||||
|
$this->installSchema('user', 'role_permission');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks the behavior of the page for access denied/not found behaviours.
|
* Checks the behavior of the page for access denied/not found behaviours.
|
||||||
*/
|
*/
|
||||||
public function testPageResponses() {
|
public function testPageResponses() {
|
||||||
$view = views_get_view('test_page_display');
|
// @todo Importing a route should fire a container rebuild.
|
||||||
$this->drupalGet('test_page_display_403');
|
$this->container->get('router.builder')->rebuild();
|
||||||
$this->assertResponse(403);
|
|
||||||
$this->drupalGet('test_page_display_404');
|
$subrequest = Request::create('/test_page_display_403', 'GET');
|
||||||
$this->assertResponse(404);
|
$response = $this->container->get('http_kernel')->handle($subrequest, HttpKernelInterface::SUB_REQUEST);
|
||||||
|
$this->assertEqual($response->getStatusCode(), 403);
|
||||||
|
|
||||||
|
$subrequest = Request::create('/test_page_display_404', 'GET');
|
||||||
|
$response = $this->container->get('http_kernel')->handle($subrequest, HttpKernelInterface::SUB_REQUEST);
|
||||||
|
$this->assertEqual($response->getStatusCode(), 404);
|
||||||
|
|
||||||
|
$subrequest = Request::create('/test_page_display_200', 'GET');
|
||||||
|
$response = $this->container->get('http_kernel')->handle($subrequest, HttpKernelInterface::SUB_REQUEST);
|
||||||
|
$this->assertEqual($response->getStatusCode(), 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks that the router items are properly registered
|
||||||
|
*/
|
||||||
|
public function testPageRouterItems() {
|
||||||
|
$subscriber = new RouteSubscriber();
|
||||||
|
$collection = new RouteCollection();
|
||||||
|
$subscriber->dynamicRoutes(new RouteBuildEvent($collection, 'dynamic_routes'));
|
||||||
|
|
||||||
|
// Check the controller defaults.
|
||||||
|
foreach ($collection as $id => $route) {
|
||||||
|
if (strpos($id, 'test_page_display_route') === 0) {
|
||||||
|
$this->assertEqual($route->getDefault('_controller'), 'Drupal\views\Routing\ViewPageController::handle');
|
||||||
|
$this->assertEqual($route->getDefault('view_id'), 'test_page_display_route');
|
||||||
|
$this->assertEqual($route->getDefault('display_id'), str_replace('test_page_display_route.', '', $id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check the generated patterns and default values.
|
||||||
|
$route = $collection->get('view.test_page_display_route.page_1');
|
||||||
|
$this->assertEqual($route->getPath(), '/test_route_without_arguments');
|
||||||
|
|
||||||
|
$route = $collection->get('view.test_page_display_route.page_2');
|
||||||
|
$this->assertEqual($route->getPath(), '/test_route_with_argument/{arg_id}');
|
||||||
|
$this->assertTrue($route->hasDefault('arg_id'), 'A default value is set for the optional argument id.');
|
||||||
|
|
||||||
|
$route = $collection->get('view.test_page_display_route.page_3');
|
||||||
|
$this->assertEqual($route->getPath(), '/test_route_with_argument/{arg_id}/suffix');
|
||||||
|
$this->assertFalse($route->hasDefault('arg_id'), 'No default value is set for the required argument id.');
|
||||||
|
|
||||||
|
$route = $collection->get('view.test_page_display_route.page_4');
|
||||||
|
$this->assertEqual($route->getPath(), '/test_route_with_argument/{arg_id}/suffix/{arg_id_2}');
|
||||||
|
$this->assertFalse($route->hasDefault('arg_id'), 'No default value is set for the required argument id.');
|
||||||
|
$this->assertTrue($route->hasDefault('arg_id_2'), 'A default value is set for the optional argument id_2.');
|
||||||
|
|
||||||
|
$route = $collection->get('view.test_page_display_route.page_5');
|
||||||
|
$this->assertEqual($route->getPath(), '/test_route_with_argument/{arg_id}/{arg_id_2}');
|
||||||
|
$this->assertTrue($route->hasDefault('arg_id'), 'A default value is set for the optional argument id.');
|
||||||
|
$this->assertTrue($route->hasDefault('arg_id_2'), 'A default value is set for the optional argument id_2.');
|
||||||
|
|
||||||
|
$route = $collection->get('view.test_page_display_route.page_6');
|
||||||
|
$this->assertEqual($route->getPath(), '/test_route_with_argument/{arg_id}/{arg_id_2}');
|
||||||
|
$this->assertFalse($route->hasDefault('arg_id'), 'No default value is set for the required argument id.');
|
||||||
|
$this->assertFalse($route->hasDefault('arg_id_2'), 'No default value is set for the required argument id_2.');
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Contains \Drupal\views\Tests\Plugin\DisplayPageWebTest.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Drupal\views\Tests\Plugin;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests the views page display plugin as webtest.
|
||||||
|
*/
|
||||||
|
class DisplayPageWebTest extends PluginTestBase {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Views used by this test.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
public static $testViews = array('test_page_display_arguments');
|
||||||
|
|
||||||
|
public static function getInfo() {
|
||||||
|
return array(
|
||||||
|
'name' => 'Display: Page plugin (web)',
|
||||||
|
'description' => 'Tests the page display plugin (web).',
|
||||||
|
'group' => 'Views Plugins',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function setUp() {
|
||||||
|
parent::setUp();
|
||||||
|
|
||||||
|
$this->enableViewsTestModule();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests arguments.
|
||||||
|
*/
|
||||||
|
public function testArguments() {
|
||||||
|
$this->drupalGet('test_route_without_arguments');
|
||||||
|
$this->assertResponse(200);
|
||||||
|
$result = $this->xpath('//span[@class="field-content"]');
|
||||||
|
$this->assertEqual(count($result), 5, 'All entries was returned');
|
||||||
|
|
||||||
|
$this->drupalGet('test_route_without_arguments/1');
|
||||||
|
$this->assertResponse(404);
|
||||||
|
|
||||||
|
$this->drupalGet('test_route_with_argument/1');
|
||||||
|
$this->assertResponse(200);
|
||||||
|
$result = $this->xpath('//span[@class="field-content"]');
|
||||||
|
$this->assertEqual(count($result), 1, 'Ensure that just the filtered entry was returned.');
|
||||||
|
$this->assertEqual((string) $result[0], 1, 'The passed ID was returned.');
|
||||||
|
|
||||||
|
$this->drupalGet('test_route_with_suffix/1/suffix');
|
||||||
|
$this->assertResponse(200);
|
||||||
|
$result = $this->xpath('//span[@class="field-content"]');
|
||||||
|
$this->assertEqual(count($result), 1, 'Ensure that just the filtered entry was returned.');
|
||||||
|
$this->assertEqual((string) $result[0], 1, 'The passed ID was returned.');
|
||||||
|
|
||||||
|
$this->drupalGet('test_route_with_suffix_and_argument/1/suffix/2');
|
||||||
|
$this->assertResponse(200);
|
||||||
|
$result = $this->xpath('//span[@class="field-content"]');
|
||||||
|
$this->assertEqual(count($result), 0, 'No result was returned.');
|
||||||
|
|
||||||
|
$this->drupalGet('test_route_with_suffix_and_argument/1/suffix/1');
|
||||||
|
$this->assertResponse(200);
|
||||||
|
$result = $this->xpath('//span[@class="field-content"]');
|
||||||
|
$this->assertEqual(count($result), 1, 'Ensure that just the filtered entry was returned.');
|
||||||
|
$this->assertEqual((string) $result[0], 1, 'The passed ID was returned.');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,95 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Contains \Drupal\views\Tests\ViewPageControllerTest.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Drupal\views\Tests;
|
||||||
|
|
||||||
|
use Drupal\views\Routing\ViewPageController;
|
||||||
|
use Drupal\views\ViewExecutableFactory;
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests the page controller but not the actualy execution/rendering of a view.
|
||||||
|
*
|
||||||
|
* @see \Drupal\views\Routing\ViewPageController
|
||||||
|
*/
|
||||||
|
class ViewPageControllerTest extends ViewUnitTestBase {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Modules to enable.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
public static $modules = array('user');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Views used by this test.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
public static $testViews = array('test_page_view');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The page controller of views.
|
||||||
|
*
|
||||||
|
* @var \Drupal\views\Routing\ViewPageController
|
||||||
|
*/
|
||||||
|
public $pageController;
|
||||||
|
|
||||||
|
public static function getInfo() {
|
||||||
|
return array(
|
||||||
|
'name' => 'View page controller test',
|
||||||
|
'description' => 'Tests views page controller.',
|
||||||
|
'group' => 'Views'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
protected function setUp() {
|
||||||
|
parent::setUp();
|
||||||
|
|
||||||
|
$this->installSchema('system', 'menu_router');
|
||||||
|
$this->installSchema('user', 'role_permission');
|
||||||
|
|
||||||
|
$this->pageController = new ViewPageController($this->container->get('plugin.manager.entity')->getStorageController('view'), new ViewExecutableFactory());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests the page controller.
|
||||||
|
*/
|
||||||
|
public function testPageController() {
|
||||||
|
$this->assertTrue($this->pageController instanceof ViewPageController, 'Ensure the right class is stored in the container');
|
||||||
|
|
||||||
|
// Pass in a non existent view.
|
||||||
|
$random_view_id = $this->randomName();
|
||||||
|
|
||||||
|
$request = new Request();
|
||||||
|
$request->attributes->set('view_id', $random_view_id);
|
||||||
|
$request->attributes->set('display_id', 'default');
|
||||||
|
try {
|
||||||
|
$this->pageController->handle($request);
|
||||||
|
$this->fail('No exception thrown on non-existing view.');
|
||||||
|
}
|
||||||
|
|
||||||
|
catch (NotFoundHttpException $e) {
|
||||||
|
$this->pass('Exception thrown when view was not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
$request->attributes->set('view_id', 'test_page_view');
|
||||||
|
$output = $this->pageController->handle($request);
|
||||||
|
$this->assertTrue(is_array($output));
|
||||||
|
$this->assertEqual($output['#view']->storage->id, 'test_page_view', 'The right view was executed.');
|
||||||
|
|
||||||
|
$request->attributes->set('display_id', 'page_1');
|
||||||
|
$output = $this->pageController->handle($request);
|
||||||
|
$this->assertTrue($output instanceof Response, 'Ensure the page display returns a response object.');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -8,6 +8,7 @@
|
||||||
namespace Drupal\views\Tests;
|
namespace Drupal\views\Tests;
|
||||||
|
|
||||||
use Drupal\simpletest\WebTestBase;
|
use Drupal\simpletest\WebTestBase;
|
||||||
|
use Drupal\views\ViewExecutable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines a base class for Views testing in the full web test environment.
|
* Defines a base class for Views testing in the full web test environment.
|
||||||
|
@ -31,6 +32,10 @@ abstract class ViewTestBase extends WebTestBase {
|
||||||
protected function setUp() {
|
protected function setUp() {
|
||||||
parent::setUp();
|
parent::setUp();
|
||||||
|
|
||||||
|
// Ensure that the plugin definitions are cleared.
|
||||||
|
foreach (ViewExecutable::getPluginTypes() as $plugin_type) {
|
||||||
|
$this->container->get("plugin.manager.views.$plugin_type")->clearCachedDefinitions();
|
||||||
|
}
|
||||||
ViewTestData::importTestViews(get_class($this), array('views_test_config'));
|
ViewTestData::importTestViews(get_class($this), array('views_test_config'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,6 +52,8 @@ abstract class ViewTestBase extends WebTestBase {
|
||||||
|
|
||||||
module_enable(array('views_test_data'));
|
module_enable(array('views_test_data'));
|
||||||
$this->resetAll();
|
$this->resetAll();
|
||||||
|
$this->rebuildContainer();
|
||||||
|
$this->container->get('module_handler')->reload();
|
||||||
|
|
||||||
// Load the test dataset.
|
// Load the test dataset.
|
||||||
$data_set = $this->dataSet();
|
$data_set = $this->dataSet();
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Contains \Drupal\views\ViewsAccessCheck.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Drupal\views;
|
||||||
|
|
||||||
|
use Drupal\Core\Access\AccessCheckInterface;
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
use Symfony\Component\Routing\Route;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines a route access checker for the _access_all_views permission.
|
||||||
|
*
|
||||||
|
* @todo We could leverage the permission one as well?
|
||||||
|
*/
|
||||||
|
class ViewsAccessCheck implements AccessCheckInterface {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements AccessCheckInterface::applies().
|
||||||
|
*/
|
||||||
|
public function applies(Route $route) {
|
||||||
|
return array_key_exists('view_id', $route->getDefaults());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements AccessCheckInterface::applies().
|
||||||
|
*/
|
||||||
|
public function access(Route $route, Request $request) {
|
||||||
|
$access = user_access('access all views');
|
||||||
|
|
||||||
|
return $access ?: NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,33 +0,0 @@
|
||||||
base_table: node
|
|
||||||
core: '8'
|
|
||||||
description: ''
|
|
||||||
status: '1'
|
|
||||||
display:
|
|
||||||
default:
|
|
||||||
display_options:
|
|
||||||
access:
|
|
||||||
type: test_dynamic
|
|
||||||
cache:
|
|
||||||
type: none
|
|
||||||
exposed_form:
|
|
||||||
type: basic
|
|
||||||
pager:
|
|
||||||
type: full
|
|
||||||
style:
|
|
||||||
type: default
|
|
||||||
row:
|
|
||||||
type: fields
|
|
||||||
display_plugin: default
|
|
||||||
display_title: Master
|
|
||||||
id: default
|
|
||||||
position: '0'
|
|
||||||
page_1:
|
|
||||||
display_options:
|
|
||||||
path: test_access_dynamic
|
|
||||||
display_plugin: page
|
|
||||||
display_title: Page
|
|
||||||
id: page_1
|
|
||||||
position: '0'
|
|
||||||
label: ''
|
|
||||||
id: test_access_dynamic
|
|
||||||
tag: ''
|
|
|
@ -1,14 +1,22 @@
|
||||||
base_table: node
|
base_table: views_test_data
|
||||||
core: '8'
|
core: '8'
|
||||||
description: ''
|
description: ''
|
||||||
status: '1'
|
status: '1'
|
||||||
display:
|
display:
|
||||||
default:
|
default:
|
||||||
display_options:
|
display_options:
|
||||||
access:
|
defaults:
|
||||||
type: none
|
fields: '0'
|
||||||
cache:
|
pager: '0'
|
||||||
type: none
|
pager_options: '0'
|
||||||
|
sorts: '0'
|
||||||
|
fields:
|
||||||
|
age:
|
||||||
|
field: age
|
||||||
|
id: age
|
||||||
|
relationship: none
|
||||||
|
table: views_test_data
|
||||||
|
plugin_id: numeric
|
||||||
display_plugin: default
|
display_plugin: default
|
||||||
display_title: Master
|
display_title: Master
|
||||||
id: default
|
id: default
|
||||||
|
@ -19,14 +27,21 @@ display:
|
||||||
display_plugin: page
|
display_plugin: page
|
||||||
display_title: Page
|
display_title: Page
|
||||||
id: page_1
|
id: page_1
|
||||||
position: '0'
|
position: '1'
|
||||||
page_2:
|
page_2:
|
||||||
display_options:
|
display_options:
|
||||||
path: test_page_display_404
|
path: test_page_display_404
|
||||||
display_plugin: page
|
display_plugin: page
|
||||||
display_title: Page
|
display_title: Page
|
||||||
id: page_2
|
id: page_2
|
||||||
position: '0'
|
position: '2'
|
||||||
|
page_3:
|
||||||
|
display_options:
|
||||||
|
path: test_page_display_200
|
||||||
|
display_plugin: page
|
||||||
|
display_title: Page
|
||||||
|
id: page_3
|
||||||
|
position: '3'
|
||||||
label: ''
|
label: ''
|
||||||
id: test_page_display
|
id: test_page_display
|
||||||
tag: ''
|
tag: ''
|
||||||
|
|
|
@ -0,0 +1,87 @@
|
||||||
|
base_table: views_test_data
|
||||||
|
base_field: id
|
||||||
|
core: '8'
|
||||||
|
description: ''
|
||||||
|
status: '1'
|
||||||
|
display:
|
||||||
|
default:
|
||||||
|
display_options:
|
||||||
|
defaults:
|
||||||
|
fields: '0'
|
||||||
|
pager: '0'
|
||||||
|
pager_options: '0'
|
||||||
|
sorts: '0'
|
||||||
|
fields:
|
||||||
|
id:
|
||||||
|
id: id
|
||||||
|
field: id
|
||||||
|
table: views_test_data
|
||||||
|
plugin_id: numeric
|
||||||
|
display_plugin: default
|
||||||
|
display_title: Master
|
||||||
|
id: default
|
||||||
|
position: '0'
|
||||||
|
page_1:
|
||||||
|
display_options:
|
||||||
|
path: test_route_without_arguments
|
||||||
|
display_plugin: page
|
||||||
|
display_title: Page
|
||||||
|
id: page_1
|
||||||
|
position: '0'
|
||||||
|
page_2:
|
||||||
|
display_options:
|
||||||
|
defaults:
|
||||||
|
arguments: '0'
|
||||||
|
arguments:
|
||||||
|
id:
|
||||||
|
field: id
|
||||||
|
id: id
|
||||||
|
relationship: none
|
||||||
|
table: views_test_data
|
||||||
|
plugin_id: numeric
|
||||||
|
path: test_route_with_argument
|
||||||
|
display_plugin: page
|
||||||
|
display_title: Page
|
||||||
|
id: page_2
|
||||||
|
position: '0'
|
||||||
|
page_3:
|
||||||
|
display_options:
|
||||||
|
defaults:
|
||||||
|
arguments: '0'
|
||||||
|
arguments:
|
||||||
|
id:
|
||||||
|
field: id
|
||||||
|
id: id
|
||||||
|
relationship: none
|
||||||
|
table: views_test_data
|
||||||
|
plugin_id: numeric
|
||||||
|
path: test_route_with_suffix/%/suffix
|
||||||
|
display_plugin: page
|
||||||
|
display_title: Page
|
||||||
|
id: page_3
|
||||||
|
position: '0'
|
||||||
|
page_4:
|
||||||
|
display_options:
|
||||||
|
defaults:
|
||||||
|
arguments: '0'
|
||||||
|
arguments:
|
||||||
|
id:
|
||||||
|
field: id
|
||||||
|
id: id
|
||||||
|
relationship: none
|
||||||
|
table: views_test_data
|
||||||
|
plugin_id: numeric
|
||||||
|
id_2:
|
||||||
|
field: id
|
||||||
|
id: id_2
|
||||||
|
relationship: none
|
||||||
|
table: views_test_data
|
||||||
|
plugin_id: numeric
|
||||||
|
path: test_route_with_suffix_and_argument/%/suffix
|
||||||
|
display_plugin: page
|
||||||
|
display_title: Page
|
||||||
|
id: page_4
|
||||||
|
position: '0'
|
||||||
|
human_name: ''
|
||||||
|
id: test_page_display_arguments
|
||||||
|
tag: ''
|
|
@ -0,0 +1,142 @@
|
||||||
|
base_table: views_test_data
|
||||||
|
base_field: id
|
||||||
|
core: '8'
|
||||||
|
description: ''
|
||||||
|
status: '1'
|
||||||
|
display:
|
||||||
|
default:
|
||||||
|
display_options:
|
||||||
|
defaults:
|
||||||
|
fields: '0'
|
||||||
|
pager: '0'
|
||||||
|
pager_options: '0'
|
||||||
|
sorts: '0'
|
||||||
|
fields:
|
||||||
|
id:
|
||||||
|
id: id
|
||||||
|
table: views_test_data
|
||||||
|
field: id
|
||||||
|
plugin_id: numeric
|
||||||
|
display_plugin: default
|
||||||
|
display_title: Master
|
||||||
|
id: default
|
||||||
|
position: '0'
|
||||||
|
page_1:
|
||||||
|
display_options:
|
||||||
|
path: test_route_without_arguments
|
||||||
|
display_plugin: page
|
||||||
|
display_title: Page
|
||||||
|
id: page_1
|
||||||
|
position: '0'
|
||||||
|
page_2:
|
||||||
|
display_options:
|
||||||
|
defaults:
|
||||||
|
arguments: '0'
|
||||||
|
arguments:
|
||||||
|
id:
|
||||||
|
field: id
|
||||||
|
id: id
|
||||||
|
relationship: none
|
||||||
|
table: views_test_data
|
||||||
|
plugin_id: numeric
|
||||||
|
path: test_route_with_argument
|
||||||
|
display_plugin: page
|
||||||
|
display_title: Page
|
||||||
|
id: page_2
|
||||||
|
position: '0'
|
||||||
|
page_3:
|
||||||
|
display_options:
|
||||||
|
defaults:
|
||||||
|
arguments: '0'
|
||||||
|
arguments:
|
||||||
|
id:
|
||||||
|
field: id
|
||||||
|
id: id
|
||||||
|
relationship: none
|
||||||
|
table: views_test_data
|
||||||
|
plugin_id: numeric
|
||||||
|
path: test_route_with_argument/%/suffix
|
||||||
|
display_plugin: page
|
||||||
|
display_title: Page
|
||||||
|
id: page_3
|
||||||
|
position: '0'
|
||||||
|
page_4:
|
||||||
|
display_options:
|
||||||
|
defaults:
|
||||||
|
arguments: '0'
|
||||||
|
arguments:
|
||||||
|
id:
|
||||||
|
field: id
|
||||||
|
id: id
|
||||||
|
relationship: none
|
||||||
|
table: views_test_data
|
||||||
|
plugin_id: numeric
|
||||||
|
id_2:
|
||||||
|
field: id
|
||||||
|
id: id_2
|
||||||
|
relationship: none
|
||||||
|
table: views_test_data
|
||||||
|
plugin_id: numeric
|
||||||
|
path: test_route_with_argument/%/suffix
|
||||||
|
display_plugin: page
|
||||||
|
display_title: Page
|
||||||
|
id: page_4
|
||||||
|
position: '0'
|
||||||
|
page_5:
|
||||||
|
display_options:
|
||||||
|
defaults:
|
||||||
|
arguments: '0'
|
||||||
|
arguments:
|
||||||
|
id:
|
||||||
|
field: id
|
||||||
|
id: id
|
||||||
|
relationship: none
|
||||||
|
table: views_test_data
|
||||||
|
plugin_id: numeric
|
||||||
|
id_2:
|
||||||
|
field: id
|
||||||
|
id: id_2
|
||||||
|
relationship: none
|
||||||
|
table: views_test_data
|
||||||
|
plugin_id: numeric
|
||||||
|
path: test_route_with_argument
|
||||||
|
display_plugin: page
|
||||||
|
display_title: Page
|
||||||
|
id: page_5
|
||||||
|
position: '0'
|
||||||
|
page_6:
|
||||||
|
display_options:
|
||||||
|
defaults:
|
||||||
|
arguments: '0'
|
||||||
|
arguments:
|
||||||
|
id:
|
||||||
|
field: id
|
||||||
|
id: id
|
||||||
|
relationship: none
|
||||||
|
table: views_test_data
|
||||||
|
plugin_id: numeric
|
||||||
|
id_2:
|
||||||
|
field: id
|
||||||
|
id: id_2
|
||||||
|
relationship: none
|
||||||
|
table: views_test_data
|
||||||
|
plugin_id: numeric
|
||||||
|
path: test_route_with_argument/%/%
|
||||||
|
display_plugin: page
|
||||||
|
display_title: Page
|
||||||
|
id: page_6
|
||||||
|
position: '0'
|
||||||
|
page_7:
|
||||||
|
display_options:
|
||||||
|
defaults:
|
||||||
|
access: '0'
|
||||||
|
access:
|
||||||
|
type: test_static
|
||||||
|
path: test_route_arguments_access
|
||||||
|
display_plugin: page
|
||||||
|
display_title: Page
|
||||||
|
id: page_7
|
||||||
|
position: '0'
|
||||||
|
human_name: ''
|
||||||
|
id: test_page_display_route
|
||||||
|
tag: ''
|
|
@ -0,0 +1,30 @@
|
||||||
|
base_table: views_test_data
|
||||||
|
core: '8'
|
||||||
|
description: ''
|
||||||
|
disabled: '0'
|
||||||
|
display:
|
||||||
|
default:
|
||||||
|
display_options:
|
||||||
|
defaults:
|
||||||
|
fields: '0'
|
||||||
|
pager: '0'
|
||||||
|
pager_options: '0'
|
||||||
|
sorts: '0'
|
||||||
|
fields:
|
||||||
|
age:
|
||||||
|
field: age
|
||||||
|
id: age
|
||||||
|
relationship: none
|
||||||
|
table: views_test_data
|
||||||
|
plugin_id: numeric
|
||||||
|
display_plugin: default
|
||||||
|
display_title: Master
|
||||||
|
id: default
|
||||||
|
position: '0'
|
||||||
|
page_1:
|
||||||
|
display_plugin: page
|
||||||
|
display_title: Test page view
|
||||||
|
id: page_1
|
||||||
|
human_name: ''
|
||||||
|
id: test_page_view
|
||||||
|
tag: ''
|
|
@ -1,40 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file
|
|
||||||
* Definition of Drupal\views_test_data\Plugin\views\access\DynamicTest.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Drupal\views_test_data\Plugin\views\access;
|
|
||||||
|
|
||||||
use Drupal\Component\Annotation\Plugin;
|
|
||||||
use Drupal\Core\Annotation\Translation;
|
|
||||||
use Drupal\views\Plugin\views\access\AccessPluginBase;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests a dynamic access plugin.
|
|
||||||
*
|
|
||||||
* @Plugin(
|
|
||||||
* id = "test_dynamic",
|
|
||||||
* title = @Translation("Dynamic test access plugin."),
|
|
||||||
* help = @Translation("Provides a dynamic test access plugin.")
|
|
||||||
* )
|
|
||||||
*/
|
|
||||||
class DynamicTest extends AccessPluginBase {
|
|
||||||
|
|
||||||
protected function defineOptions() {
|
|
||||||
$options = parent::defineOptions();
|
|
||||||
$options['access'] = array('default' => FALSE, 'bool' => TRUE);
|
|
||||||
|
|
||||||
return $options;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function access($account) {
|
|
||||||
return !empty($this->options['access']) && isset($this->view->args[0]) && $this->view->args[0] == state()->get('test_dynamic_access_argument1') && isset($this->view->args[1]) && $this->view->args[1] == state()->get('test_dynamic_access_argument2');
|
|
||||||
}
|
|
||||||
|
|
||||||
function get_access_callback() {
|
|
||||||
return array('views_test_data_test_dynamic_access_callback', array(!empty($options['access']), 1, 2));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -10,6 +10,7 @@ namespace Drupal\views_test_data\Plugin\views\access;
|
||||||
use Drupal\Component\Annotation\Plugin;
|
use Drupal\Component\Annotation\Plugin;
|
||||||
use Drupal\Core\Annotation\Translation;
|
use Drupal\Core\Annotation\Translation;
|
||||||
use Drupal\views\Plugin\views\access\AccessPluginBase;
|
use Drupal\views\Plugin\views\access\AccessPluginBase;
|
||||||
|
use Symfony\Component\Routing\Route;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests a static access plugin.
|
* Tests a static access plugin.
|
||||||
|
@ -33,8 +34,13 @@ class StaticTest extends AccessPluginBase {
|
||||||
return !empty($this->options['access']);
|
return !empty($this->options['access']);
|
||||||
}
|
}
|
||||||
|
|
||||||
function get_access_callback() {
|
/**
|
||||||
return array('views_test_data_test_static_access_callback', array(!empty($options['access'])));
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function alterRouteDefinition(Route $route) {
|
||||||
|
if (!empty($this->options['access'])) {
|
||||||
|
$route->setRequirement('_access', 'TRUE');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,14 +19,6 @@ function views_test_data_permission() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function views_test_data_test_static_access_callback($access) {
|
|
||||||
return $access;
|
|
||||||
}
|
|
||||||
|
|
||||||
function views_test_data_test_dynamic_access_callback($access, $argument1, $argument2) {
|
|
||||||
return $access && $argument1 == state()->get('test_dynamic_access_argument1') && $argument2 == state()->get('test_dynamic_access_argument2');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Access callback for the generic handler test.
|
* Access callback for the generic handler test.
|
||||||
*
|
*
|
||||||
|
|
|
@ -354,16 +354,6 @@ function views_menu_alter(&$callbacks) {
|
||||||
// overriding) one that we removed above.
|
// overriding) one that we removed above.
|
||||||
$callbacks[$path] = $item;
|
$callbacks[$path] = $item;
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
// This item already exists, so it must be one that we added.
|
|
||||||
// We change the various callback arguments to pass an array
|
|
||||||
// of possible display IDs instead of a single ID.
|
|
||||||
$callbacks[$path]['page arguments'][1] = (array)$callbacks[$path]['page arguments'][1];
|
|
||||||
$callbacks[$path]['page arguments'][1][] = $display_id;
|
|
||||||
$callbacks[$path]['access arguments'][] = $item['access arguments'][0];
|
|
||||||
$callbacks[$path]['load arguments'][1] = (array)$callbacks[$path]['load arguments'][1];
|
|
||||||
$callbacks[$path]['load arguments'][1][] = $display_id;
|
|
||||||
}
|
|
||||||
$our_paths[$path] = TRUE;
|
$our_paths[$path] = TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -654,7 +644,6 @@ function views_field_create_instance($instance) {
|
||||||
cache('views_info')->deleteAll();
|
cache('views_info')->deleteAll();
|
||||||
cache('views_results')->deleteAll();
|
cache('views_results')->deleteAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements hook_field_update_instance.
|
* Implements hook_field_update_instance.
|
||||||
*/
|
*/
|
||||||
|
@ -686,6 +675,13 @@ function views_invalidate_cache() {
|
||||||
|
|
||||||
$module_handler = Drupal::moduleHandler();
|
$module_handler = Drupal::moduleHandler();
|
||||||
|
|
||||||
|
// Set the router to be rebuild.
|
||||||
|
// @todo Figure out why the cache rebuild is trigged but the route table
|
||||||
|
// does not exist yet.
|
||||||
|
if (db_table_exists('router')) {
|
||||||
|
Drupal::service('router.builder')->rebuild();
|
||||||
|
}
|
||||||
|
|
||||||
// Invalidate the block cache to update views block derivatives.
|
// Invalidate the block cache to update views block derivatives.
|
||||||
if ($module_handler->moduleExists('block')) {
|
if ($module_handler->moduleExists('block')) {
|
||||||
Drupal::service('plugin.manager.block')->clearCachedDefinitions();
|
Drupal::service('plugin.manager.block')->clearCachedDefinitions();
|
||||||
|
@ -695,68 +691,6 @@ function views_invalidate_cache() {
|
||||||
$module_handler->invokeAll('views_invalidate_cache');
|
$module_handler->invokeAll('views_invalidate_cache');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine if the logged in user has access to a view.
|
|
||||||
*
|
|
||||||
* This function should only be called from a menu hook or some other
|
|
||||||
* embedded source. Each argument is the result of a call to
|
|
||||||
* views_plugin_access::get_access_callback() which is then used
|
|
||||||
* to determine if that display is accessible. If *any* argument
|
|
||||||
* is accessible, then the view is accessible.
|
|
||||||
*/
|
|
||||||
function views_access() {
|
|
||||||
$args = func_get_args();
|
|
||||||
foreach ($args as $arg) {
|
|
||||||
if ($arg === TRUE) {
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!is_array($arg)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
list($callback, $arguments) = $arg;
|
|
||||||
$arguments = $arguments ? $arguments : array();
|
|
||||||
// Bring dynamic arguments to the access callback.
|
|
||||||
foreach ($arguments as $key => $value) {
|
|
||||||
if (is_int($value) && isset($args[$value])) {
|
|
||||||
$arguments[$key] = $args[$value];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (function_exists($callback) && call_user_func_array($callback, $arguments)) {
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Access callback for the views_plugin_access_perm access plugin.
|
|
||||||
*
|
|
||||||
* Determine if the specified user has access to a view on the basis of
|
|
||||||
* permissions. If the $account argument is omitted, the current user
|
|
||||||
* is used.
|
|
||||||
*/
|
|
||||||
function views_check_perm($perm, $account = NULL) {
|
|
||||||
return user_access($perm, $account) || user_access('access all views', $account);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Access callback for the views_plugin_access_role access plugin.
|
|
||||||
|
|
||||||
* Determine if the specified user has access to a view on the basis of any of
|
|
||||||
* the requested roles. If the $account argument is omitted, the current user
|
|
||||||
* is used.
|
|
||||||
*/
|
|
||||||
function views_check_roles($rids, $account = NULL) {
|
|
||||||
global $user;
|
|
||||||
$account = isset($account) ? $account : $user;
|
|
||||||
$roles = array_keys($account->roles);
|
|
||||||
$roles[] = $account->uid ? DRUPAL_AUTHENTICATED_RID : DRUPAL_ANONYMOUS_RID;
|
|
||||||
return user_access('access all views', $account) || array_intersect(array_filter($rids), $roles);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the current 'page view' that is being displayed so that it is easy
|
* Set the current 'page view' that is being displayed so that it is easy
|
||||||
* for other modules or the theme to identify.
|
* for other modules or the theme to identify.
|
||||||
|
|
|
@ -78,3 +78,12 @@ services:
|
||||||
factory_method: get
|
factory_method: get
|
||||||
factory_service: cache_factory
|
factory_service: cache_factory
|
||||||
arguments: [views_results]
|
arguments: [views_results]
|
||||||
|
views.route_subscriber:
|
||||||
|
class: Drupal\views\EventSubscriber\RouteSubscriber
|
||||||
|
arguments: ['@config.factory']
|
||||||
|
tags:
|
||||||
|
- { name: 'event_subscriber' }
|
||||||
|
views.route_access_check:
|
||||||
|
class: Drupal\views\ViewsAccessCheck
|
||||||
|
tags:
|
||||||
|
- { name: 'access_check' }
|
||||||
|
|
Loading…
Reference in New Issue