3 namespace Drupal\Core\Access;
5 use Drupal\Core\Controller\ControllerResolverInterface;
6 use Drupal\Core\Routing\Access\AccessInterface as RoutingAccessInterface;
7 use Drupal\Core\Routing\RouteMatchInterface;
8 use Drupal\Core\Session\AccountInterface;
9 use Symfony\Component\Routing\Route;
12 * Defines an access checker that allows specifying a custom method for access.
14 * You should only use it when you are sure that the access callback will not be
15 * reused. Good examples in core are Edit or Toolbar module.
17 * The method is called on another instance of the controller class, so you
18 * cannot reuse any stored property of your actual controller instance used
19 * to generate the output.
21 class CustomAccessCheck implements RoutingAccessInterface {
24 * The controller resolver.
26 * @var \Drupal\Core\Controller\ControllerResolverInterface
28 protected $controllerResolver;
31 * The arguments resolver.
33 * @var \Drupal\Core\Access\AccessArgumentsResolverFactoryInterface
35 protected $argumentsResolverFactory;
38 * Constructs a CustomAccessCheck instance.
40 * @param \Drupal\Core\Controller\ControllerResolverInterface $controller_resolver
41 * The controller resolver.
42 * @param \Drupal\Core\Access\AccessArgumentsResolverFactoryInterface $arguments_resolver_factory
43 * The arguments resolver factory.
45 public function __construct(ControllerResolverInterface $controller_resolver, AccessArgumentsResolverFactoryInterface $arguments_resolver_factory) {
46 $this->controllerResolver = $controller_resolver;
47 $this->argumentsResolverFactory = $arguments_resolver_factory;
51 * Checks access for the account and route using the custom access checker.
53 * @param \Symfony\Component\Routing\Route $route
55 * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
56 * The route match object to be checked.
57 * @param \Drupal\Core\Session\AccountInterface $account
58 * The account being checked.
60 * @return \Drupal\Core\Access\AccessResultInterface
63 public function access(Route $route, RouteMatchInterface $route_match, AccountInterface $account) {
65 $callable = $this->controllerResolver->getControllerFromDefinition($route->getRequirement('_custom_access'));
67 catch (\InvalidArgumentException $e) {
68 // The custom access controller method was not found.
69 throw new \BadMethodCallException(sprintf('The "%s" method is not callable as a _custom_access callback in route "%s"', $route->getRequirement('_custom_access'), $route->getPath()));
72 $arguments_resolver = $this->argumentsResolverFactory->getArgumentsResolver($route_match, $account);
73 $arguments = $arguments_resolver->getArguments($callable);
75 return call_user_func_array($callable, $arguments);