0

For example, there is a page on the site, created before.

I need to set custom permission for it.

Par example, if a user doesn't have a photo in his profile, he shouldn't have access to page "/forum".

On Drupal 7 it was possible via hook_menu_alter and set access control there.

Could you clarify me, how can I it on Drupal 8 ?

  • 1
    see the documentation drupal.org/docs/8/api/routing-system/access-checking-on-routes – 4k4 Oct 25 '17 at 8:00
  • I asked how to change access on existing route, not on route, creating by myself. That is, how to bind my custom access function to an existing route. – Yakimkin Roman Oct 25 '17 at 8:20
  • 1
    This is the next page in the doc drupal.org/docs/8/api/routing-system/… – 4k4 Oct 25 '17 at 8:34
  • Thank you, I've read it, but encounted with a problem. Namely, there is a class method $route->setRequirement('some_key', 'some_regex'); My services.yml file is services: yrv_page_access.forum_route_subscriber: class: Drupal\yrv_page_access\Routing\RouteSubscriber tags: - { name: event_subscriber } yrv_page_access.forum_access: class: Drupal\yrv_page_access\Access\CustomAccessCheck arguments: ['@current_user'] tags: - { name: forum_access_check, applies_to: _forum_access_check } How I should write setRequirement to assign my access ? – Yakimkin Roman Oct 25 '17 at 9:58
  • 1
    $route->setRequirement('_forum_access_check', 'TRUE'); – 4k4 Oct 25 '17 at 10:16
3

Here's an example which prevents anonymous users from resetting their password.

services.yml:

services:
  mymodule.route_subscriber:
    class: Drupal\mymodule\Routing\MymoduleRouteSubscriber
    tags: 
      - { name: event_subscriber }

src/Routing/MymoduleRouteSubscriber.php:

<?php

namespace Drupal\mymodule\Routing;

use Drupal\Core\Routing\RouteSubscriberBase;
use Symfony\Component\Routing\RouteCollection;

/**
 * Listens to the dynamic route events.
 */
class MymoduleRouteSubscriber extends RouteSubscriberBase {

  /**
   * {@inheritdoc}
   */
  protected function alterRoutes(RouteCollection $collection) {

    if ($route = $collection->get('user.pass')) {
      $route->setRequirement('_custom_access', '\Drupal\mymodule\Access\ResetPasswordAccessCheck::access');      
    }
  }

}

src/Access/ResetPasswordAccessCheck.php:

<?php
namespace Drupal\mymodule\Access;

use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Access\AccessResult;

class ResetPasswordAccessCheck {

  /**
   * A custom access check.
   *
   * @param \Drupal\Core\Session\AccountInterface $account
   *   Run access checks for this account.
   */
  public function access(AccountInterface $account) {

    return $account->isAnonymous() ? AccessResult::forbidden() : AccessResult::allowed();

  }

}

I've updated the documentation to clarify what return value is expected: https://www.drupal.org/docs/8/api/routing-system/access-checking-on-routes

Forum access example

You only need the route subscriber in services.yml:

services:
  yrv_page_access.forum_route_subscriber:
    class: Drupal\yrv_page_access\Routing\RouteSubscriber
    tags:
      - { name: event_subscriber }

RouteSubscriber:

<?php

namespace Drupal\yrv_page_access\Routing;

use Drupal\Core\Routing\RouteSubscriberBase;
use Symfony\Component\Routing\RouteCollection;

class RouteSubscriber extends RouteSubscriberBase {

  protected function alterRoutes(RouteCollection $collection){
    if ($route = $collection->get('forum.index')){
      $route->setRequirement('_custom_access', '\Drupal\yrv_page_access\Access\ForumAccessCheck::access');
    }
  }
}

Access check:

<?php

namespace Drupal\yrv_page_access\Access;

use Drupal\Core\Access\AccessResult;
use Drupal\Core\Session\AccountInterface;

/*
 * Custom access to the forum page
 */
class ForumAccessCheck {

  public function access(AccountInterface $account){
    return AccessResult::forbidden();
  }
}
  • How would I run a custom access check for all routes in Drupal? Just iterate the $collection in alterRoutes() or is there a simpler way? – TedMilker Nov 7 at 14:05
  • You could get all routes or use the iterator (see documentation: api.drupal.org/api/drupal/… ) but it's probably easiest to use the addRequirements() method: api.drupal.org/api/drupal/… – imclean Nov 10 at 22:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.