diff --git a/core/core.services.yml b/core/core.services.yml
index c43da8c..1c926c2 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -664,7 +664,7 @@ services:
class: Drupal\Core\Access\AccessArgumentsResolver
access_manager:
class: Drupal\Core\Access\AccessManager
- arguments: ['@router.route_provider', '@url_generator', '@paramconverter_manager', '@access_arguments_resolver', '@request_stack']
+ arguments: ['@router.route_provider', '@url_generator', '@paramconverter_manager', '@access_arguments_resolver', '@request_stack', '@current_user']
calls:
- [setContainer, ['@service_container']]
access_route_subscriber:
diff --git a/core/includes/common.inc b/core/includes/common.inc
index 618c23b..eeee7cb 100644
--- a/core/includes/common.inc
+++ b/core/includes/common.inc
@@ -2809,6 +2809,14 @@ function drupal_render(&$elements, $is_recursive_call = FALSE) {
$current->postRenderCache = NestedArray::mergeDeep($current->postRenderCache, $parent->postRenderCache);
$stack->push($current);
};
+ /** @var \Drupal\Core\Controller\ControllerResolverInterface $controller_resolver */
+ $controller_resolver = \Drupal::service('controller_resolver');
+ if (!isset($elements['#access']) && isset($elements['#access_callback'])) {
+ if (is_string($elements['#access_callback']) && strpos($elements['#access_callback'], '::') === FALSE) {
+ $elements['#access_callback'] = $controller_resolver->getControllerFromDefinition($elements['#access_callback']);
+ }
+ $elements['#access'] = call_user_func($elements['#access_callback'], $elements);
+ }
// Early-return nothing if user does not have access.
if (empty($elements) || (isset($elements['#access']) && !$elements['#access'])) {
@@ -2856,8 +2864,6 @@ function drupal_render(&$elements, $is_recursive_call = FALSE) {
// Make any final changes to the element before it is rendered. This means
// that the $element or the children can be altered or corrected before the
// element is rendered into the final text.
- /** @var \Drupal\Core\Controller\ControllerResolverInterface $controller_resolver */
- $controller_resolver = \Drupal::service('controller_resolver');
if (isset($elements['#pre_render'])) {
foreach ($elements['#pre_render'] as $callable) {
if (is_string($callable) && strpos($callable, '::') === FALSE) {
diff --git a/core/lib/Drupal/Core/Access/AccessManager.php b/core/lib/Drupal/Core/Access/AccessManager.php
index 54d13de..8a8af77 100644
--- a/core/lib/Drupal/Core/Access/AccessManager.php
+++ b/core/lib/Drupal/Core/Access/AccessManager.php
@@ -103,6 +103,13 @@ class AccessManager implements ContainerAwareInterface, AccessManagerInterface {
protected $requestStack;
/**
+ * The current user.
+ *
+ * @var \Drupal\Core\Session\AccountInterface
+ */
+ protected $currentUser;
+
+ /**
* Constructs a AccessManager instance.
*
* @param \Drupal\Core\Routing\RouteProviderInterface $route_provider
@@ -115,13 +122,16 @@ class AccessManager implements ContainerAwareInterface, AccessManagerInterface {
* The access arguments resolver.
* @param \Symfony\Component\HttpFoundation\RequestStack $requestStack
* The request stack object.
+ * @param \Drupal\Core\Session\AccountInterface $current_user
+ * The current user.
*/
- public function __construct(RouteProviderInterface $route_provider, UrlGeneratorInterface $url_generator, ParamConverterManagerInterface $paramconverter_manager, AccessArgumentsResolverInterface $arguments_resolver, RequestStack $requestStack) {
+ public function __construct(RouteProviderInterface $route_provider, UrlGeneratorInterface $url_generator, ParamConverterManagerInterface $paramconverter_manager, AccessArgumentsResolverInterface $arguments_resolver, RequestStack $requestStack, AccountInterface $current_user) {
$this->routeProvider = $route_provider;
$this->urlGenerator = $url_generator;
$this->paramConverterManager = $paramconverter_manager;
$this->argumentsResolver = $arguments_resolver;
$this->requestStack = $requestStack;
+ $this->currentUser = $current_user;
}
/**
@@ -182,7 +192,7 @@ protected function applies(Route $route) {
/**
* {@inheritdoc}
*/
- public function checkNamedRoute($route_name, array $parameters = array(), AccountInterface $account, Request $route_request = NULL) {
+ public function checkNamedRoute($route_name, array $parameters = array(), AccountInterface $account = NULL, Request $route_request = NULL) {
try {
$route = $this->routeProvider->getRouteByName($route_name, $parameters);
if (empty($route_request)) {
@@ -210,7 +220,10 @@ public function checkNamedRoute($route_name, array $parameters = array(), Accoun
/**
* {@inheritdoc}
*/
- public function check(Route $route, Request $request, AccountInterface $account) {
+ public function check(Route $route, Request $request, AccountInterface $account = NULL) {
+ if (!isset($account)) {
+ $account = $this->currentUser;
+ }
$checks = $route->getOption('_access_checks') ?: array();
$conjunction = $route->getOption('_access_mode') ?: static::ACCESS_MODE_ALL;
diff --git a/core/lib/Drupal/Core/Access/AccessManagerInterface.php b/core/lib/Drupal/Core/Access/AccessManagerInterface.php
index df88ba6..db6cfa3 100644
--- a/core/lib/Drupal/Core/Access/AccessManagerInterface.php
+++ b/core/lib/Drupal/Core/Access/AccessManagerInterface.php
@@ -45,7 +45,8 @@
* @param array $parameters
* Optional array of values to substitute into the route path patern.
* @param \Drupal\Core\Session\AccountInterface $account
- * The current user.
+ * (optional) Run access checks for this account. Defaults to the current
+ * user.
* @param \Symfony\Component\HttpFoundation\Request $route_request
* Optional incoming request object. If not provided, one will be built
* using the route information and the current request from the container.
@@ -53,7 +54,7 @@
* @return bool
* Returns TRUE if the user has access to the route, otherwise FALSE.
*/
- public function checkNamedRoute($route_name, array $parameters = array(), AccountInterface $account, Request $route_request = NULL);
+ public function checkNamedRoute($route_name, array $parameters = array(), AccountInterface $account = NULL, Request $route_request = NULL);
/**
* For each route, saves a list of applicable access checks to the route.
@@ -86,11 +87,12 @@ public function addCheckService($service_id, $service_method, array $applies_che
* @param \Symfony\Component\HttpFoundation\Request $request
* The incoming request object.
* @param \Drupal\Core\Session\AccountInterface $account
- * The current account.
+ * (optional) Run access checks for this account. Defaults to the current
+ * user.
*
* @return bool
* Returns TRUE if the user has access to the route, otherwise FALSE.
*/
- public function check(Route $route, Request $request, AccountInterface $account);
+ public function check(Route $route, Request $request, AccountInterface $account = NULL);
}
diff --git a/core/lib/Drupal/Core/Url.php b/core/lib/Drupal/Core/Url.php
index ea407cc..d97f017 100644
--- a/core/lib/Drupal/Core/Url.php
+++ b/core/lib/Drupal/Core/Url.php
@@ -10,6 +10,7 @@
use Drupal\Component\Utility\UrlHelper;
use Drupal\Core\DependencyInjection\DependencySerializationTrait;
use Drupal\Core\Routing\UrlGeneratorInterface;
+use Drupal\Core\Session\AccountInterface;
use Symfony\Cmf\Component\Routing\RouteObjectInterface;
use Symfony\Component\HttpFoundation\Request;
@@ -27,6 +28,13 @@ class Url {
protected $urlGenerator;
/**
+ * The access manager
+ *
+ * @var \Drupal\Core\Access\AccessManagerInterface
+ */
+ protected $accessManager;
+
+ /**
* The route name.
*
* @var string
@@ -386,6 +394,7 @@ public function toRenderArray() {
'#route_name' => $this->getRouteName(),
'#route_parameters' => $this->getRouteParameters(),
'#options' => $this->getOptions(),
+ '#access_callback' => array(get_class(), 'renderAccess'),
);
}
}
@@ -412,6 +421,45 @@ public function getInternalPath() {
}
/**
+ * Checks this Url object against applicable access check services.
+ *
+ * Determines whether the route is accessible or not.
+ *
+ * @param \Drupal\Core\Session\AccountInterface $account
+ * (optional) Run access checks for this account. Defaults to the current
+ * user.
+ *
+ * @return bool
+ * Returns TRUE if the user has access to the url, otherwise FALSE.
+ */
+ public function access(AccountInterface $account = NULL) {
+ return $this->accessManager()->checkNamedRoute($this->getRouteName(), $this->getRouteParameters(), $account);
+ }
+
+ /**
+ * Checks a Url render element against applicable access check services.
+ *
+ * @param array $element
+ * A render element as returned from \Drupal\Core\Url::toRenderArray().
+ *
+ * @return bool
+ * Returns TRUE if the current user has access to the url, otherwise FALSE.
+ */
+ public static function renderAccess(array $element) {
+ return (new static($element['#route_name'], $element['#route_parameters'], $element['#options']))->access();
+ }
+
+ /**
+ * @return \Drupal\Core\Access\AccessManagerInterface
+ */
+ protected function accessManager() {
+ if (!isset($this->accessManager)) {
+ $this->accessManager = \Drupal::service('access_manager');
+ }
+ return $this->accessManager;
+ }
+
+ /**
* Gets the URL generator.
*
* @return \Drupal\Core\Routing\UrlGeneratorInterface
diff --git a/core/modules/rdf/src/Tests/Field/TaxonomyTermReferenceRdfaTest.php b/core/modules/rdf/src/Tests/Field/TaxonomyTermReferenceRdfaTest.php
index ed4bbf5..b3610d3 100644
--- a/core/modules/rdf/src/Tests/Field/TaxonomyTermReferenceRdfaTest.php
+++ b/core/modules/rdf/src/Tests/Field/TaxonomyTermReferenceRdfaTest.php
@@ -7,9 +7,8 @@
namespace Drupal\rdf\Tests\Field;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
-use Drupal\rdf\Tests\Field\FieldRdfaTestBase;
-use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Language\LanguageInterface;
+use Drupal\user\Entity\Role;
/**
* Tests the RDFa output of the taxonomy term reference field formatter.
@@ -100,6 +99,10 @@ protected function setUp() {
public function testAllFormatters() {
// Tests the plain formatter.
$this->assertFormatterRdfa(array('type' => 'taxonomy_term_reference_plain'), 'http://schema.org/about', array('value' => $this->term->getName(), 'type' => 'literal'));
+ // Grant the access content permission to the anonymous user.
+ Role::create(array('id' => DRUPAL_ANONYMOUS_RID))
+ ->grantPermission('access content')
+ ->save();
// Tests the link formatter.
$term_uri = $this->getAbsoluteUri($this->term);
$this->assertFormatterRdfa(array('type'=>'taxonomy_term_reference_link'), 'http://schema.org/about', array('value' => $term_uri, 'type' => 'uri'));
diff --git a/core/modules/system/src/Plugin/Block/SystemBrandingBlock.php b/core/modules/system/src/Plugin/Block/SystemBrandingBlock.php
index 77e63e1..7740c79 100644
--- a/core/modules/system/src/Plugin/Block/SystemBrandingBlock.php
+++ b/core/modules/system/src/Plugin/Block/SystemBrandingBlock.php
@@ -12,9 +12,8 @@
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
-use Drupal\Core\Routing\UrlGeneratorInterface;
-use Drupal\Core\Session\AccountInterface;
use Drupal\Component\Utility\Xss;
+use Drupal\Core\Url;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
@@ -28,13 +27,6 @@
class SystemBrandingBlock extends BlockBase implements ContainerFactoryPluginInterface {
/**
- * The URL generator.
- *
- * @var \Drupal\Core\Routing\UrlGeneratorInterface
- */
- protected $urlGenerator;
-
- /**
* Stores the configuration factory.
*
* @var \Drupal\Core\Config\ConfigFactoryInterface
@@ -42,13 +34,6 @@ class SystemBrandingBlock extends BlockBase implements ContainerFactoryPluginInt
protected $configFactory;
/**
- * The current user.
- *
- * @var \Drupal\Core\Session\AccountInterface
- */
- protected $currentUser;
-
- /**
* Creates a SystemBrandingBlock instance.
*
* @param array $configuration
@@ -59,16 +44,10 @@ class SystemBrandingBlock extends BlockBase implements ContainerFactoryPluginInt
* The plugin implementation definition.
* @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
* The factory for configuration objects.
- * @param \Drupal\Core\Routing\UrlGeneratorInterface $url_generator
- * The url generator service.
- * @param \Drupal\Core\Session\AccountInterface $current_user
- * The current user.
*/
- public function __construct(array $configuration, $plugin_id, $plugin_definition, ConfigFactoryInterface $config_factory, UrlGeneratorInterface $url_generator, AccountInterface $current_user) {
+ public function __construct(array $configuration, $plugin_id, $plugin_definition, ConfigFactoryInterface $config_factory) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->configFactory = $config_factory;
- $this->urlGenerator = $url_generator;
- $this->currentUser = $current_user;
}
/**
@@ -79,9 +58,7 @@ public static function create(ContainerInterface $container, array $configuratio
$configuration,
$plugin_id,
$plugin_definition,
- $container->get('config.factory'),
- $container->get('url_generator'),
- $container->get('current_user')
+ $container->get('config.factory')
);
}
@@ -111,26 +88,26 @@ public function blockForm($form, FormStateInterface $form_state) {
$theme = $form_state['block_theme'];
// Get permissions.
- $administer_themes_access = $this->currentUser->hasPermission('administer themes');
- $administer_site_configuration_access = $this->currentUser->hasPermission('administer site configuration');
-
- if ($administer_themes_access) {
- // Get paths to theme settings pages.
- $appearance_settings_url = $this->urlGenerator->generateFromRoute('system.theme_settings');
- $theme_settings_url = $this->urlGenerator->generateFromRoute('system.theme_settings_theme', array('theme' => $theme));
+ $url_system_theme_settings = new Url('system.theme_settings');
+ $url_system_theme_settings_theme = new Url('system.theme_settings_theme', array('theme' => $theme));
+ if ($url_system_theme_settings->access() && $url_system_theme_settings_theme->access()) {
// Provide links to the Appearance Settings and Theme Settings pages
// if the user has access to administer themes.
- $site_logo_description = $this->t('Defined on the Appearance Settings or Theme Settings page.', array('@appearance' => $appearance_settings_url, '@theme' => $theme_settings_url));
+ $site_logo_description = $this->t('Defined on the Appearance Settings or Theme Settings page.', array(
+ '@appearance' => $url_system_theme_settings->toString(),
+ '@theme' => $url_system_theme_settings_theme->toString(),
+ ));
}
else {
// Explain that the user does not have access to the Appearance and Theme
// Settings pages.
$site_logo_description = $this->t('Defined on the Appearance or Theme Settings page. You do not have the appropriate permissions to change the site logo.');
}
- if ($administer_site_configuration_access) {
+ $url_system_site_information_settings = new Url('system.site_information_settings');
+ if ($url_system_site_information_settings->access()) {
// Get paths to settings pages.
- $site_information_url = $this->urlGenerator->generateFromRoute('system.site_information_settings');
+ $site_information_url = $url_system_site_information_settings->toString();
// Provide link to Site Information page if the user has access to
// administer site configuration.
diff --git a/core/modules/system/src/Tests/Common/RenderTest.php b/core/modules/system/src/Tests/Common/RenderTest.php
index 0789052..57f8c08 100644
--- a/core/modules/system/src/Tests/Common/RenderTest.php
+++ b/core/modules/system/src/Tests/Common/RenderTest.php
@@ -54,6 +54,31 @@ function testDrupalRenderBasics() {
'expected' => '',
),
array(
+ 'name' => 'access denied via callback',
+ 'value' => array(
+ '#markup' => 'foo',
+ '#access_callback' => 'is_bool',
+ ),
+ 'expected' => '',
+ ),
+ array(
+ 'name' => 'access granted via callback',
+ 'value' => array(
+ '#markup' => 'foo',
+ '#access_callback' => 'is_array',
+ ),
+ 'expected' => 'foo',
+ ),
+ array(
+ 'name' => 'access FALSE is honored',
+ 'value' => array(
+ '#markup' => 'foo',
+ '#access' => FALSE,
+ '#access_callback' => 'is_array',
+ ),
+ 'expected' => '',
+ ),
+ array(
'name' => 'previously printed',
'value' => array(
'#markup' => 'foo',
diff --git a/core/modules/system/src/Tests/Form/ConfirmFormTest.php b/core/modules/system/src/Tests/Form/ConfirmFormTest.php
index 3ea2820..fcb4e61 100644
--- a/core/modules/system/src/Tests/Form/ConfirmFormTest.php
+++ b/core/modules/system/src/Tests/Form/ConfirmFormTest.php
@@ -33,7 +33,7 @@ function testConfirmForm() {
// Test canelling the form.
$this->clickLink(t('ConfirmFormTestForm::getCancelText().'));
- $this->assertUrl('admin', array(), "The form's cancel link was followed.");
+ $this->assertUrl('form-test/autocomplete', array(), "The form's cancel link was followed.");
// Test submitting the form.
$this->drupalPostForm('form-test/confirm-form', NULL, t('ConfirmFormTestForm::getConfirmText().'));
@@ -47,7 +47,7 @@ function testConfirmForm() {
// Test cancelling the form with a complex destination.
$this->drupalGet('form-test/confirm-form-array-path');
$this->clickLink(t('ConfirmFormArrayPathTestForm::getCancelText().'));
- $this->assertUrl('admin', array('query' => array('destination' => 'admin/config')), "The form's complex cancel link was followed.");
+ $this->assertUrl('form-test/confirm-form', array('query' => array('destination' => 'admin/config')), "The form's complex cancel link was followed.");
}
}
diff --git a/core/modules/system/src/Tests/Routing/UrlIntegrationTest.php b/core/modules/system/src/Tests/Routing/UrlIntegrationTest.php
new file mode 100644
index 0000000..66239c9
--- /dev/null
+++ b/core/modules/system/src/Tests/Routing/UrlIntegrationTest.php
@@ -0,0 +1,68 @@
+installSchema('system', ['router']);
+ }
+
+ /**
+ * Ensures that the access() method on \Drupal\Core\Url objects works.
+ */
+ public function testAccess() {
+ \Drupal::service('router.builder')->rebuild();
+ /** @var \Drupal\user\RoleInterface $role_with_access */
+ $role_with_access = Role::create(['id' => 'role_with_access']);
+ $role_with_access->grantPermission('administer users');
+ $role_with_access->save();
+
+ /** @var \Drupal\user\RoleInterface $role_without_access */
+ $role_without_access = Role::create(['id' => 'role_without_access']);
+ $role_without_access->save();
+
+ $user_with_access = User::create(['roles' => ['role_with_access']]);
+ $user_without_access = User::create(['roles' => ['role_without_access']]);
+
+ $url_always_access = new Url('router_test.1');
+ $this->assertTrue($url_always_access->access($user_with_access));
+ $this->assertTrue($url_always_access->access($user_without_access));
+
+ $url_none_access = new Url('router_test.15');
+ $this->assertFalse($url_none_access->access($user_with_access));
+ $this->assertFalse($url_none_access->access($user_without_access));
+
+ $url_access = new Url('router_test.16');
+ $this->assertTrue($url_access->access($user_with_access));
+ $this->assertFalse($url_access->access($user_without_access));
+ }
+
+}
diff --git a/core/modules/system/tests/modules/form_test/src/ConfirmFormArrayPathTestForm.php b/core/modules/system/tests/modules/form_test/src/ConfirmFormArrayPathTestForm.php
index c089a26..6cd8c2f 100644
--- a/core/modules/system/tests/modules/form_test/src/ConfirmFormArrayPathTestForm.php
+++ b/core/modules/system/tests/modules/form_test/src/ConfirmFormArrayPathTestForm.php
@@ -25,7 +25,7 @@ public function getFormId() {
* {@inheritdoc}
*/
public function getCancelUrl() {
- return new Url('system.admin', array(), array(
+ return new Url('form_test.route6', array(), array(
'query' => array(
'destination' => 'admin/config',
),
diff --git a/core/modules/system/tests/modules/form_test/src/ConfirmFormTestForm.php b/core/modules/system/tests/modules/form_test/src/ConfirmFormTestForm.php
index a031747..fd74f3b 100644
--- a/core/modules/system/tests/modules/form_test/src/ConfirmFormTestForm.php
+++ b/core/modules/system/tests/modules/form_test/src/ConfirmFormTestForm.php
@@ -34,7 +34,7 @@ public function getQuestion() {
* {@inheritdoc}
*/
public function getCancelUrl() {
- return new Url('system.admin');
+ return new Url('form_test.route8');
}
/**
diff --git a/core/modules/system/tests/modules/router_test_directory/router_test.routing.yml b/core/modules/system/tests/modules/router_test_directory/router_test.routing.yml
index 7405d88..5b02a3b 100644
--- a/core/modules/system/tests/modules/router_test_directory/router_test.routing.yml
+++ b/core/modules/system/tests/modules/router_test_directory/router_test.routing.yml
@@ -93,6 +93,20 @@ router_test.14:
defaults:
_controller: '\Drupal\router_test\TestControllers::test9'
+router_test.15:
+ path: '/router_test/test15'
+ defaults:
+ _controller: '\Drupal\router_test\TestControllers::test1'
+ requirements:
+ _access: 'FALSE'
+
+router_test.16:
+ path: '/router_test/test16'
+ defaults:
+ _controller: '\Drupal\router_test\TestControllers::test1'
+ requirements:
+ _permission: 'administer users'
+
router_test.hierarchy_parent:
path: '/menu-test/parent'
defaults:
diff --git a/core/tests/Drupal/Tests/Core/Access/AccessManagerTest.php b/core/tests/Drupal/Tests/Core/Access/AccessManagerTest.php
index 3aa8046..0f45b83 100644
--- a/core/tests/Drupal/Tests/Core/Access/AccessManagerTest.php
+++ b/core/tests/Drupal/Tests/Core/Access/AccessManagerTest.php
@@ -92,6 +92,11 @@ class AccessManagerTest extends UnitTestCase {
protected $requestStack;
/**
+ * @var \Drupal\Core\Session\AccountInterface|\PHPUnit_Framework_MockObject_MockObject
+ */
+ protected $currentUser;
+
+ /**
* {@inheritdoc}
*/
protected function setUp() {
@@ -129,11 +134,12 @@ protected function setUp() {
$this->paramConverter = $this->getMock('Drupal\Core\ParamConverter\ParamConverterManagerInterface');
$this->account = $this->getMock('Drupal\Core\Session\AccountInterface');
+ $this->currentUser = $this->getMock('Drupal\Core\Session\AccountInterface');
$this->argumentsResolver = $this->getMock('Drupal\Core\Access\AccessArgumentsResolverInterface');
$this->requestStack = new RequestStack();
- $this->accessManager = new AccessManager($this->routeProvider, $this->urlGenerator, $this->paramConverter, $this->argumentsResolver, $this->requestStack);
+ $this->accessManager = new AccessManager($this->routeProvider, $this->urlGenerator, $this->paramConverter, $this->argumentsResolver, $this->requestStack, $this->currentUser);
$this->accessManager->setContainer($this->container);
}
@@ -162,7 +168,7 @@ public function testSetChecks() {
*/
public function testSetChecksWithDynamicAccessChecker() {
// Setup the access manager.
- $this->accessManager = new AccessManager($this->routeProvider, $this->urlGenerator, $this->paramConverter, $this->argumentsResolver, $this->requestStack);
+ $this->accessManager = new AccessManager($this->routeProvider, $this->urlGenerator, $this->paramConverter, $this->argumentsResolver, $this->requestStack, $this->currentUser);
$this->accessManager->setContainer($this->container);
// Setup the dynamic access checker.
@@ -220,6 +226,25 @@ public function testCheck() {
}
/**
+ * Tests \Drupal\Core\Access\AccessManager::check() with no account specified.
+ *
+ * @covers ::check
+ */
+ public function testCheckWithNullAccount() {
+ $this->setupAccessChecker();
+ $this->accessManager->setChecks($this->routeCollection);
+ $request = new Request;
+ $route = $this->routeCollection->get('test_route_2');
+ $this->argumentsResolver->expects($this->once())
+ ->method('getArguments')
+ ->with(array($this->container->get('test_access_default'), 'access'), $route, $request, $this->currentUser)
+ ->will($this->returnCallback(function ($callable, $route, $request, $account) {
+ return array($route);
+ }));
+ $this->accessManager->check($route, $request);
+ }
+
+ /**
* Provides data for the conjunction test.
*
* @return array
@@ -472,7 +497,7 @@ public function testCheckNamedRouteWithUpcastedValues() {
$subrequest = Request::create('/test-route-1/example');
- $this->accessManager = new AccessManager($this->routeProvider, $this->urlGenerator, $this->paramConverter, $this->argumentsResolver, $this->requestStack);
+ $this->accessManager = new AccessManager($this->routeProvider, $this->urlGenerator, $this->paramConverter, $this->argumentsResolver, $this->requestStack, $this->currentUser);
$this->accessManager->setContainer($this->container);
$this->requestStack->push(new Request());
@@ -532,7 +557,7 @@ public function testCheckNamedRouteWithDefaultValue() {
$subrequest = Request::create('/test-route-1/example');
- $this->accessManager = new AccessManager($this->routeProvider, $this->urlGenerator, $this->paramConverter, $this->argumentsResolver, $this->requestStack);
+ $this->accessManager = new AccessManager($this->routeProvider, $this->urlGenerator, $this->paramConverter, $this->argumentsResolver, $this->requestStack, $this->currentUser);
$this->accessManager->setContainer($this->container);
$this->requestStack->push(new Request());
@@ -610,7 +635,7 @@ public function testCheckException($return_value, $access_mode) {
->will($this->returnValue($return_value));
$container->set('test_incorrect_value', $access_check);
- $access_manager = new AccessManager($route_provider, $this->urlGenerator, $this->paramConverter, $this->argumentsResolver, $this->requestStack);
+ $access_manager = new AccessManager($route_provider, $this->urlGenerator, $this->paramConverter, $this->argumentsResolver, $this->requestStack, $this->currentUser);
$access_manager->setContainer($container);
$access_manager->addCheckService('test_incorrect_value', 'access');
@@ -665,7 +690,7 @@ protected static function convertAccessCheckInterfaceToString($constant) {
* Adds a default access check service to the container and the access manager.
*/
protected function setupAccessChecker() {
- $this->accessManager = new AccessManager($this->routeProvider, $this->urlGenerator, $this->paramConverter, $this->argumentsResolver, $this->requestStack);
+ $this->accessManager = new AccessManager($this->routeProvider, $this->urlGenerator, $this->paramConverter, $this->argumentsResolver, $this->requestStack, $this->currentUser);
$this->accessManager->setContainer($this->container);
$access_check = new DefaultAccessCheck();
$this->container->register('test_access_default', $access_check);
diff --git a/core/tests/Drupal/Tests/Core/UrlTest.php b/core/tests/Drupal/Tests/Core/UrlTest.php
index 92f429d..32a75c0 100644
--- a/core/tests/Drupal/Tests/Core/UrlTest.php
+++ b/core/tests/Drupal/Tests/Core/UrlTest.php
@@ -7,6 +7,7 @@
namespace Drupal\Tests\Core;
+use Drupal\Core\Access\AccessManagerInterface;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\Url;
use Drupal\Tests\UnitTestCase;
@@ -22,6 +23,11 @@
class UrlTest extends UnitTestCase {
/**
+ * @var \Symfony\Component\DependencyInjection\ContainerInterface
+ */
+ protected $container;
+
+ /**
* The URL generator
*
* @var \Drupal\Core\Routing\UrlGeneratorInterface|\PHPUnit_Framework_MockObject_MockObject
@@ -60,10 +66,10 @@ protected function setUp() {
->will($this->returnValueMap($this->map));
$this->router = $this->getMock('Drupal\Tests\Core\Routing\TestRouterInterface');
- $container = new ContainerBuilder();
- $container->set('router.no_access_checks', $this->router);
- $container->set('url_generator', $this->urlGenerator);
- \Drupal::setContainer($container);
+ $this->container = new ContainerBuilder();
+ $this->container->set('router.no_access_checks', $this->router);
+ $this->container->set('url_generator', $this->urlGenerator);
+ \Drupal::setContainer($this->container);
}
/**
@@ -318,4 +324,81 @@ public function testGetOptions($urls) {
}
}
+ /**
+ * Tests the access() method.
+ *
+ * @param bool $access
+ *
+ * @covers ::access
+ * @covers ::getAccessManager
+ * @covers ::setAccessManager
+ * @dataProvider accessProvider
+ */
+ public function testAccess($access) {
+ $account = $this->getMock('Drupal\Core\Session\AccountInterface');
+ $url = new TestUrl('entity.node.canonical', ['node' => 3]);
+ $url->setAccessManager($this->getMockAccessManager($access, $account));
+ $this->assertEquals($access, $url->access($account));
+ }
+
+ /**
+ * Tests the renderAccess() method.
+ *
+ * @param bool $access
+ *
+ * @covers ::renderAccess
+ * @dataProvider accessProvider
+ */
+ public function testRenderAccess($access) {
+ $element = array(
+ '#route_name' => 'entity.node.canonical',
+ '#route_parameters' => ['node' => 3],
+ '#options' => [],
+ );
+ $this->container->set('current_user', $this->getMock('Drupal\Core\Session\AccountInterface'));
+ $this->container->set('access_manager', $this->getMockAccessManager($access));
+ $this->assertEquals($access, TestUrl::renderAccess($element));
+ }
+
+ /**
+ * Creates a mock access manager for the access tests.
+ *
+ * @param bool $access
+ * @param \Drupal\Core\Session\AccountInterface|NULL $account
+ *
+ * @return \Drupal\Core\Access\AccessManagerInterface|\PHPUnit_Framework_MockObject_MockObject
+ */
+ protected function getMockAccessManager($access, $account = NULL) {
+ $access_manager = $this->getMock('Drupal\Core\Access\AccessManagerInterface');
+ $access_manager->expects($this->once())
+ ->method('checkNamedRoute')
+ ->with('entity.node.canonical', ['node' => 3], $account)
+ ->willReturn($access);
+ return $access_manager;
+ }
+
+ /**
+ * Data provider for the access test methods.
+ */
+ public function accessProvider() {
+ return array(
+ array(TRUE),
+ array(FALSE),
+ );
+ }
+
+}
+
+class TestUrl extends Url {
+
+ /**
+ * Sets the access manager.
+ *
+ * @param \Drupal\Core\Access\AccessManagerInterface $access_manager
+ */
+ public function setAccessManager(AccessManagerInterface $access_manager) {
+ $this->accessManager = $access_manager;
+ }
+
+
}