Commit 9d5aefb7 authored by catch's avatar catch

Issue #2048223 by dawehner, ParisLiakos, herom, fubhy, damiankloip, vijaycs85,...

Issue #2048223 by dawehner, ParisLiakos, herom, fubhy, damiankloip, vijaycs85, joelpittet, tim.plunkett: Add $account argument to AccessCheckInterface::access() method and use the current_user() service.
parent 9b5afa85
......@@ -192,10 +192,11 @@ services:
arguments: ['@container.namespaces']
plugin.manager.menu.local_action:
class: Drupal\Core\Menu\LocalActionManager
arguments: ['@controller_resolver', '@request', '@router.route_provider', '@module_handler', '@cache.cache', '@language_manager', '@access_manager']
arguments: ['@controller_resolver', '@request', '@router.route_provider', '@module_handler', '@cache.cache', '@language_manager', '@access_manager', '@current_user']
plugin.manager.menu.local_task:
class: Drupal\Core\Menu\LocalTaskManager
arguments: ['@controller_resolver', '@request', '@router.route_provider', '@module_handler', '@cache.cache', '@language_manager', '@access_manager']
arguments: ['@controller_resolver', '@request', '@router.route_provider', '@module_handler', '@cache.cache', '@language_manager', '@access_manager', '@current_user']
scope: request
request:
class: Symfony\Component\HttpFoundation\Request
# @TODO the synthetic setting must be uncommented whenever drupal_session_initialize()
......@@ -348,6 +349,8 @@ services:
arguments: ['@settings']
route_enhancer.authentication:
class: Drupal\Core\Routing\Enhancer\AuthenticationEnhancer
calls:
- [setContainer, ['@service_container']]
tags:
- { name: route_enhancer, priority: 1000 }
arguments: ['@authentication']
......@@ -410,6 +413,14 @@ services:
- [setRequest, ['@?request']]
access_subscriber:
class: Drupal\Core\EventSubscriber\AccessSubscriber
arguments: ['@access_manager', '@current_user']
calls:
- [setCurrentUser, ['@?current_user']]
tags:
- { name: event_subscriber }
scope: request
access_route_subscriber:
class: Drupal\Core\EventSubscriber\AccessRouteSubscriber
tags:
- { name: event_subscriber }
arguments: ['@access_manager']
......@@ -631,6 +642,7 @@ services:
factory_method: authenticate
factory_service: authentication
arguments: ['@request']
synchronized: true
asset.css.collection_renderer:
class: Drupal\Core\Asset\CssCollectionRenderer
arguments: [ '@state' ]
......
......@@ -2176,7 +2176,7 @@ function form_process_autocomplete($element, &$form_state) {
$parameters = isset($element['#autocomplete_route_parameters']) ? $element['#autocomplete_route_parameters'] : array();
$path = \Drupal::urlGenerator()->generate($element['#autocomplete_route_name'], $parameters);
$access = \Drupal::service('access_manager')->checkNamedRoute($element['#autocomplete_route_name'], $parameters);
$access = \Drupal::service('access_manager')->checkNamedRoute($element['#autocomplete_route_name'], $parameters, \Drupal::currentUser());
}
if ($access) {
$element['#attributes']['class'][] = 'form-autocomplete';
......
......@@ -1018,7 +1018,7 @@ function menu_item_route_access(Route $route, $href, &$map) {
}
}
return \Drupal::service('access_manager')->check($route, $request);
return \Drupal::service('access_manager')->check($route, $request, \Drupal::currentUser());
}
/**
......
......@@ -10,6 +10,7 @@
use Drupal\Core\ParamConverter\ParamConverterManager;
use Drupal\Core\Routing\RequestHelper;
use Drupal\Core\Routing\RouteProviderInterface;
use Drupal\Core\Session\AccountInterface;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;
......@@ -180,6 +181,8 @@ protected function applies(Route $route) {
* The route to check access to.
* @param array $parameters
* Optional array of values to substitute into the route path patern.
* @param \Drupal\Core\Session\AccountInterface $account
* 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.
......@@ -187,18 +190,17 @@ protected function applies(Route $route) {
* @return bool
* Returns TRUE if the user has access to the route, otherwise FALSE.
*/
public function checkNamedRoute($route_name, array $parameters = array(), Request $route_request = NULL) {
public function checkNamedRoute($route_name, array $parameters = array(), AccountInterface $account, Request $route_request = NULL) {
try {
$route = $this->routeProvider->getRouteByName($route_name, $parameters);
if (empty($route_request)) {
// Create a request and copy the account from the current request.
$route_request = RequestHelper::duplicate($this->request, $this->urlGenerator->generate($route_name, $parameters));
$defaults = $parameters;
$defaults['_account'] = $this->request->attributes->get('_account');
$defaults[RouteObjectInterface::ROUTE_OBJECT] = $route;
$route_request->attributes->add($this->paramConverterManager->enhance($defaults, $route_request));
}
return $this->check($route, $route_request);
return $this->check($route, $route_request, $account);
}
catch (RouteNotFoundException $e) {
return FALSE;
......@@ -217,23 +219,21 @@ public function checkNamedRoute($route_name, array $parameters = array(), Reques
* The route to check access to.
* @param \Symfony\Component\HttpFoundation\Request $request
* The incoming request object.
* @param \Drupal\Core\Session\AccountInterface $account
* The current account.
*
* @return bool
* Returns TRUE if the user has access to the route, otherwise FALSE.
*
* @throws \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException
* If any access check denies access or none explicitly approve.
*/
public function check(Route $route, Request $request) {
public function check(Route $route, Request $request, AccountInterface $account) {
$checks = $route->getOption('_access_checks') ?: array();
$conjunction = $route->getOption('_access_mode') ?: 'ALL';
if ($conjunction == 'ALL') {
return $this->checkAll($checks, $route, $request);
return $this->checkAll($checks, $route, $request, $account);
}
else {
return $this->checkAny($checks, $route, $request);
return $this->checkAny($checks, $route, $request, $account);
}
}
......@@ -246,11 +246,13 @@ public function check(Route $route, Request $request) {
* The route to check access to.
* @param \Symfony\Component\HttpFoundation\Request $request
* The incoming request object.
* @param \Drupal\Core\Session\AccountInterface $account
* The current user.
*
* @return bool
* Returns TRUE if the user has access to the route, else FALSE.
*/
protected function checkAll(array $checks, Route $route, Request $request) {
protected function checkAll(array $checks, Route $route, Request $request, AccountInterface $account) {
$access = FALSE;
foreach ($checks as $service_id) {
......@@ -258,7 +260,7 @@ protected function checkAll(array $checks, Route $route, Request $request) {
$this->loadCheck($service_id);
}
$service_access = $this->checks[$service_id]->access($route, $request);
$service_access = $this->checks[$service_id]->access($route, $request, $account);
if ($service_access === AccessInterface::ALLOW) {
$access = TRUE;
}
......@@ -281,11 +283,13 @@ protected function checkAll(array $checks, Route $route, Request $request) {
* The route to check access to.
* @param \Symfony\Component\HttpFoundation\Request $request
* The incoming request object.
* @param \Drupal\Core\Session\AccountInterface $account
* The current user.
*
* @return bool
* Returns TRUE if the user has access to the route, else FALSE.
*/
protected function checkAny(array $checks, $route, $request) {
protected function checkAny(array $checks, $route, $request, AccountInterface $account) {
// No checks == deny by default.
$access = FALSE;
......@@ -294,7 +298,7 @@ protected function checkAny(array $checks, $route, $request) {
$this->loadCheck($service_id);
}
$service_access = $this->checks[$service_id]->access($route, $request);
$service_access = $this->checks[$service_id]->access($route, $request, $account);
if ($service_access === AccessInterface::ALLOW) {
$access = TRUE;
}
......
......@@ -8,6 +8,7 @@
namespace Drupal\Core\Access;
use Drupal\Core\Controller\ControllerResolverInterface;
use Drupal\Core\Session\AccountInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Route;
......@@ -50,7 +51,7 @@ public function appliesTo() {
/**
* {@inheritdoc}
*/
public function access(Route $route, Request $request) {
public function access(Route $route, Request $request, AccountInterface $account) {
$access_controller = $route->getRequirement('_custom_access');
$controller = $this->controllerResolver->getControllerFromDefinition($access_controller);
......
......@@ -7,6 +7,7 @@
namespace Drupal\Core\Access;
use Drupal\Core\Session\AccountInterface;
use Symfony\Component\Routing\Route;
use Symfony\Component\HttpFoundation\Request;
......@@ -25,7 +26,7 @@ public function appliesTo() {
/**
* {@inheritdoc}
*/
public function access(Route $route, Request $request) {
public function access(Route $route, Request $request, AccountInterface $account) {
if ($route->getRequirement('_access') === 'TRUE') {
return static::ALLOW;
}
......
......@@ -107,6 +107,10 @@ protected function parseDefinition($id, $service, $filename) {
$definition->setSynthetic($service['synthetic']);
}
if (isset($service['synchronized'])) {
$definition->setSynchronized($service['synchronized']);
}
if (isset($service['public'])) {
$definition->setPublic($service['public']);
}
......
......@@ -8,6 +8,7 @@
namespace Drupal\Core\Entity;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Session\AccountInterface;
use Symfony\Component\Routing\Route;
use Symfony\Component\HttpFoundation\Request;
use Drupal\Core\Access\StaticAccessCheckInterface;
......@@ -37,7 +38,7 @@ public function appliesTo() {
* @endcode
* Available operations are 'view', 'update', 'create', and 'delete'.
*/
public function access(Route $route, Request $request) {
public function access(Route $route, Request $request, AccountInterface $account) {
// Split the entity type and the operation.
$requirement = $route->getRequirement('_entity_access');
list($entity_type, $operation) = explode('.', $requirement);
......@@ -45,7 +46,7 @@ public function access(Route $route, Request $request) {
if ($request->attributes->has($entity_type)) {
$entity = $request->attributes->get($entity_type);
if ($entity instanceof EntityInterface) {
return $entity->access($operation) ? static::ALLOW : static::DENY;
return $entity->access($operation, $account) ? static::ALLOW : static::DENY;
}
}
// No opinion, so other access checks should decide if access should be
......
......@@ -8,6 +8,7 @@
namespace Drupal\Core\Entity;
use Drupal\Core\Access\StaticAccessCheckInterface;
use Drupal\Core\Session\AccountInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Route;
......@@ -50,7 +51,7 @@ public function appliesTo() {
/**
* {@inheritdoc}
*/
public function access(Route $route, Request $request) {
public function access(Route $route, Request $request, AccountInterface $account) {
list($entity_type, $bundle) = explode(':', $route->getRequirement($this->requirementsKey) . ':');
// The bundle argument can contain request argument placeholders like
......@@ -65,7 +66,7 @@ public function access(Route $route, Request $request) {
return static::DENY;
}
}
return $this->entityManager->getAccessController($entity_type)->createAccess($bundle) ? static::ALLOW : static::DENY;
return $this->entityManager->getAccessController($entity_type)->createAccess($bundle, $account) ? static::ALLOW : static::DENY;
}
}
<?php
/**
* @file
* Contains \Drupal\Core\EventSubscriber\AccessRouteSubscriber.
*/
namespace Drupal\Core\EventSubscriber;
use Drupal\Core\Access\AccessManager;
use Drupal\Core\Routing\RouteBuildEvent;
use Drupal\Core\Routing\RoutingEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
/**
* Provides a subscriber to set access checkers on route building.
*/
class AccessRouteSubscriber implements EventSubscriberInterface {
/**
* The access manager.
*
* @var \Drupal\Core\Access\AccessManager
*/
protected $accessManager;
/**
* Constructs a new AccessSubscriber.
*
* @param \Drupal\Core\Access\AccessManager $access_manager
* The access check manager that will be responsible for applying
* AccessCheckers against routes.
*/
public function __construct(AccessManager $access_manager) {
$this->accessManager = $access_manager;
}
/**
* Apply access checks to routes.
*
* @param \Drupal\Core\Routing\RouteBuildEvent $event
* The event to process.
*/
public function onRoutingRouteAlterSetAccessCheck(RouteBuildEvent $event) {
$this->accessManager->setChecks($event->getRouteCollection());
}
/**
* Registers the methods in this class that should be listeners.
*
* @return array
* An array of event listener definitions.
*/
static function getSubscribedEvents() {
// Setting very low priority to ensure access checks are run after alters.
$events[RoutingEvents::ALTER][] = array('onRoutingRouteAlterSetAccessCheck', -50);
return $events;
}
}
......@@ -7,29 +7,45 @@
namespace Drupal\Core\EventSubscriber;
use Drupal\Core\Access\AccessManager;
use Drupal\Core\Session\AccountInterface;
use Symfony\Cmf\Component\Routing\RouteObjectInterface;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Drupal\Core\Routing\RoutingEvents;
use Drupal\Core\Access\AccessManager;
use Drupal\Core\Routing\RouteBuildEvent;
/**
* Access subscriber for controller requests.
*/
class AccessSubscriber implements EventSubscriberInterface {
/**
* The current user.
*
* @var \Drupal\Core\Session\AccountInterface
*/
protected $currentUser;
/**
* The access manager.
*
* @var \Drupal\Core\Access\AccessManager
*/
protected $accessManager;
/**
* Constructs a new AccessSubscriber.
*
* @param \Drupal\Core\Access\AccessManager $access_manager
* The access check manager that will be responsible for applying
* AccessCheckers against routes.
* @param \Drupal\Core\Session\AccountInterface $current_user
* The current user.
*/
public function __construct(AccessManager $access_manager) {
public function __construct(AccessManager $access_manager, AccountInterface $current_user) {
$this->accessManager = $access_manager;
$this->currentUser = $current_user;
}
/**
......@@ -37,6 +53,9 @@ public function __construct(AccessManager $access_manager) {
*
* @param \Symfony\Component\HttpKernel\Event\GetResponseEvent $event
* The Event to process.
*
* @throws \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException
* Thrown when the access got denied.
*/
public function onKernelRequestAccessCheck(GetResponseEvent $event) {
$request = $event->getRequest();
......@@ -46,20 +65,20 @@ public function onKernelRequestAccessCheck(GetResponseEvent $event) {
return;
}
$access = $this->accessManager->check($request->attributes->get(RouteObjectInterface::ROUTE_OBJECT), $request);
$access = $this->accessManager->check($request->attributes->get(RouteObjectInterface::ROUTE_OBJECT), $request, $this->currentUser);
if (!$access) {
throw new AccessDeniedHttpException();
}
}
/**
* Apply access checks to routes.
* Sets the current user.
*
* @param \Drupal\Core\Routing\RouteBuildEvent $event
* The event to process.
* @param \Drupal\Core\Session\AccountInterface|null $current_user
* The current user service.
*/
public function onRoutingRouteAlterSetAccessCheck(RouteBuildEvent $event) {
$this->accessManager->setChecks($event->getRouteCollection());
public function setCurrentUser(AccountInterface $current_user = NULL) {
$this->currentUser = $current_user;
}
/**
......@@ -70,9 +89,8 @@ public function onRoutingRouteAlterSetAccessCheck(RouteBuildEvent $event) {
*/
static function getSubscribedEvents() {
$events[KernelEvents::REQUEST][] = array('onKernelRequestAccessCheck', 30);
// Setting very low priority to ensure access checks are run after alters.
$events[RoutingEvents::ALTER][] = array('onRoutingRouteAlterSetAccessCheck', -50);
return $events;
}
}
......@@ -20,6 +20,7 @@
use Drupal\Core\Routing\RouteProviderInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface;
use Drupal\Core\Session\AccountInterface;
/**
* Manages discovery and instantiation of menu local action plugins.
......@@ -83,6 +84,13 @@ class LocalActionManager extends DefaultPluginManager {
*/
protected $accessManager;
/**
* The current user.
*
* @var \Drupal\Core\Session\AccountInterface
*/
protected $account;
/**
* The plugin instances.
*
......@@ -109,7 +117,7 @@ class LocalActionManager extends DefaultPluginManager {
* @param \Drupal\Core\Access\AccessManager $access_manager
* The access manager.
*/
public function __construct(ControllerResolverInterface $controller_resolver, Request $request, RouteProviderInterface $route_provider, ModuleHandlerInterface $module_handler, CacheBackendInterface $cache_backend, LanguageManager $language_manager, AccessManager $access_manager) {
public function __construct(ControllerResolverInterface $controller_resolver, Request $request, RouteProviderInterface $route_provider, ModuleHandlerInterface $module_handler, CacheBackendInterface $cache_backend, LanguageManager $language_manager, AccessManager $access_manager, AccountInterface $account) {
// Skip calling the parent constructor, since that assumes annotation-based
// discovery.
$this->discovery = new YamlDiscovery('local_actions', $module_handler->getModuleDirectories());
......@@ -117,6 +125,7 @@ public function __construct(ControllerResolverInterface $controller_resolver, Re
$this->factory = new ContainerFactory($this);
$this->routeProvider = $route_provider;
$this->accessManager = $access_manager;
$this->account = $account;
$this->controllerResolver = $controller_resolver;
$this->request = $request;
$this->alterInfo($module_handler, 'menu_local_actions');
......@@ -181,7 +190,7 @@ public function getActionsForRoute($route_appears) {
'route_parameters' => $route_parameters,
'localized_options' => $plugin->getOptions($this->request),
),
'#access' => $this->accessManager->checkNamedRoute($route_name, $route_parameters),
'#access' => $this->accessManager->checkNamedRoute($route_name, $route_parameters, $this->account),
'#weight' => $plugin->getWeight(),
);
}
......
......@@ -18,6 +18,7 @@
use Drupal\Core\Plugin\Discovery\YamlDiscovery;
use Drupal\Core\Plugin\Factory\ContainerFactory;
use Drupal\Core\Routing\RouteProviderInterface;
use Drupal\Core\Session\AccountInterface;
use Symfony\Component\HttpFoundation\Request;
/**
......@@ -88,6 +89,13 @@ class LocalTaskManager extends DefaultPluginManager {
*/
protected $accessManager;
/**
* The current user.
*
* @var \Drupal\Core\Session\AccountInterface
*/
protected $account;
/**
* Constructs a \Drupal\Core\Menu\LocalTaskManager object.
*
......@@ -105,8 +113,10 @@ class LocalTaskManager extends DefaultPluginManager {
* The language manager.
* @param \Drupal\Core\Access\AccessManager $access_manager
* The access manager.
* @param \Drupal\Core\Session\AccountInterface $account
* The current user.
*/
public function __construct(ControllerResolverInterface $controller_resolver, Request $request, RouteProviderInterface $route_provider, ModuleHandlerInterface $module_handler, CacheBackendInterface $cache, LanguageManager $language_manager, AccessManager $access_manager) {
public function __construct(ControllerResolverInterface $controller_resolver, Request $request, RouteProviderInterface $route_provider, ModuleHandlerInterface $module_handler, CacheBackendInterface $cache, LanguageManager $language_manager, AccessManager $access_manager, AccountInterface $account) {
$this->discovery = new YamlDiscovery('local_tasks', $module_handler->getModuleDirectories());
$this->discovery = new ContainerDerivativeDiscoveryDecorator($this->discovery);
$this->factory = new ContainerFactory($this);
......@@ -114,6 +124,7 @@ public function __construct(ControllerResolverInterface $controller_resolver, Re
$this->request = $request;
$this->routeProvider = $route_provider;
$this->accessManager = $access_manager;
$this->account = $account;
$this->alterInfo($module_handler, 'local_tasks');
$this->setCacheBackend($cache, $language_manager, 'local_task_plugins', array('local_task' => 1));
}
......@@ -265,7 +276,7 @@ public function getTasksBuild($current_route_name) {
$route_parameters = $child->getRouteParameters($this->request);
// Find out whether the user has access to the task.
$access = $this->accessManager->checkNamedRoute($route_name, $route_parameters);
$access = $this->accessManager->checkNamedRoute($route_name, $route_parameters, $this->account);
if ($access) {
$active = $this->isRouteActive($current_route_name, $route_name, $route_parameters);
......
......@@ -8,6 +8,7 @@
namespace Drupal\Core\Routing\Access;
use Drupal\Core\Access\AccessInterface as GenericAccessInterface;
use Drupal\Core\Session\AccountInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Route;
......@@ -23,10 +24,12 @@ interface AccessInterface extends GenericAccessInterface {
* The route to check against.
* @param \Symfony\Component\HttpFoundation\Request $request
* The request object.
* @param \Drupal\Core\Session\AccountInterface $account
* The currently logged in account.
*
* @return bool|null
* self::ALLOW, self::DENY, or self::KILL.
*/
public function access(Route $route, Request $request);
public function access(Route $route, Request $request, AccountInterface $account);
}
......@@ -9,6 +9,7 @@
use Drupal\Core\Authentication\AuthenticationManagerInterface;
use Symfony\Cmf\Component\Routing\Enhancer\RouteEnhancerInterface;
use Symfony\Component\DependencyInjection\ContainerAware;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Cmf\Component\Routing\RouteObjectInterface;
......@@ -20,7 +21,7 @@
* all authentication mechanisms. Instead, we check if the used provider is
* valid for the matched route and if not, force the user to anonymous.
*/
class AuthenticationEnhancer implements RouteEnhancerInterface {
class AuthenticationEnhancer extends ContainerAware implements RouteEnhancerInterface {
/**
* The authentication manager.
......@@ -52,6 +53,9 @@ public function enhance(array $defaults, Request $request) {
// force the user back to anonymous.
if (!in_array($auth_provider_triggered, $auth_providers)) {
$anonymous_user = drupal_anonymous_user();
$this->container->set('current_user', $anonymous_user, 'request');
// @todo Remove this in https://drupal.org/node/2073531
$request->attributes->set('_account', $anonymous_user);
// The global $user object is included for backward compatibility only
......
......@@ -8,6 +8,7 @@
namespace Drupal\Core\Theme;
use Drupal\Core\Access\StaticAccessCheckInterface;
use Drupal\Core\Session\AccountInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Route;
......@@ -26,7 +27,7 @@ public function appliesTo() {
/**
* {@inheritdoc}
*/
public function access(Route $route, Request $request) {
public function access(Route $route, Request $request, AccountInterface $account) {
return $this->checkAccess($request->attributes->get('theme')) ? static::ALLOW : static::DENY;
}
......
......@@ -9,6 +9,7 @@
use Drupal\Core\Access\StaticAccessCheckInterface;
use Drupal\Core\Database\Connection;
use Drupal\Core\Session\AccountInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Route;
......@@ -44,10 +45,8 @@ public function appliesTo() {
/**
* {@inheritdoc}
*/
public function access(Route $route, Request $request) {
// @todo Replace user_access() with a correctly injected and session-using
// alternative.
return user_access('access news feeds') && (bool) $this->database->queryRange('SELECT 1 FROM {aggregator_category}', 0, 1)->fetchField() ? static::ALLOW : static::DENY;
public function access(Route $route, Request $request, AccountInterface $account) {
return $account->hasPermission('access news feeds') && (bool) $this->database->queryRange('SELECT 1 FROM {aggregator_category}', 0, 1)->fetchField() ? static::ALLOW : static::DENY;
}
}
services:
book.breadcrumb:
class: Drupal\book\BookBreadcrumbBuilder
arguments: ['@entity.manager', '@access_manager']
arguments: ['@entity.manager', '@access_manager', '@current_user']
tags:
- { name: breadcrumb_builder, priority: 701 }
book.manager:
......
......@@ -9,6 +9,7 @@
use Drupal\book\BookManager;
use Drupal\Core\Access\StaticAccessCheckInterface;
use Drupal\Core\Session\AccountInterface;
use Symfony\Component\Routing\Route;
use Symfony\Component\HttpFoundation\Request;
......@@ -44,7 +45,7 @@ public function appliesTo() {
/**
* {@inheritdoc}
*/
public function access(Route $route, Request $request) {
public function access(Route $route, Request $request, AccountInterface $account) {
$node = $request->attributes->get('node');
if (!empty($node)) {
return $this->bookManager->checkNodeIsRemovable($node) ? static::ALLOW : static::DENY;
......
......@@ -10,6 +10,7 @@
use Drupal\Core\Access\AccessManager;
use Drupal\Core\Breadcrumb\BreadcrumbBuilderBase;
use Drupal\Core\Entity\EntityManager;
use Drupal\Core\Session\AccountInterface;
use Drupal\node\NodeInterface;
/**
......@@ -31,6 +32,13 @@ class BookBreadcrumbBuilder extends BreadcrumbBuilderBase {
*/
protected $accessManager;
/**
* The current user account.
*
* @var \Drupal\Core\Session\AccountInterface
*/
protected $account;
/**
* Constructs the BookBreadcrumbBuilder.
*
......@@ -38,10 +46,13 @@ class BookBreadcrumbBuilder extends BreadcrumbBuilderBase {
* The entity manager service.
* @param \Drupal\Core\Access\AccessManager $access_manager
* The access manager.
* @param \Drupal\Core\Session\AccountInterface $account
* The current user account.
*/
public function __construct(EntityManager $entity_manager, AccessManager $access_manager) {
public function __construct(EntityManager $entity_manager, AccessManager $access_manager, AccountInterface $account) {
$this->menuLinkStorage = $entity_manager->getStorageController('menu_link');
$this->accessManager = $access_manager;
$this->account = $account;
}
/**
......@@ -63,7 +74,7 @@ public function build(array $attributes) {
$depth = 1;
while (!empty($book['p' . ($depth + 1)])) {
if (!empty($menu_links[$book['p' . $depth]]) && ($menu_link = $menu_links[$book['p' . $depth]])) {
if ($this->accessManager->checkNamedRoute($menu_link->route_name, $menu_link->route_parameters)) {
if ($this->accessManager->checkNamedRoute($menu_link->route_name, $menu_link->route_parameters, $this->account)) {
$links[] = $this->l($menu_link->label(), $menu_link->route_name, $menu_link->route_parameters, $menu_link->options);
}
}
......