Flag Module >>> https://www.drupal.org/project/flag

How to disable/prevent some Users (NOT Roles) from adding (for example a Node) to bookmarks? Maybe showing a message after clicking on the Boomark button (You are not authorized to make this choice or something like that).

  • is this D7 or D8 ? – berramou Dec 8 '19 at 11:23

I assume you use Drupal 8:

Flag action handled by \Drupal\flag\Controller\ActionLinkController::flag so i think you should override this to check on your user and prevent to flag bookmarks nodes:

  1. Override ActionLinkController controller using RouteSubscriber like the following:
    Add the following to YOUR_MODULE_NAME.services.yml

    class: Drupal\YOUR_MODULE_NAME\Routing\RouteSubscriber
      - { name: event_subscriber }

Create YOUR_MODULE_NAME/src/Routing/RouteSubscriber.php

namespace Drupal\YOUR_MODULE_NAME\Routing;

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

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

   * {@inheritdoc}
  protected function alterRoutes(RouteCollection $collection) {
    // Change the route associated with /flag/flag/{flag}/{entity_id}.
    if ($route = $collection->get('flag.action_link_flag')) {
      $route->setDefault('_controller', '\Drupal\YOUR_MODULE_NAME\Controller\MyCustomActionLinkController::flag');

  1. Create your new Controller YOUR_MODULE_NAME/src/Controller/MyCustomActionLinkController.php like the following:

namespace Drupal\YOUR_MODULE_NAME\Controller;

use Drupal\Component\Utility\Html;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\ReplaceCommand;
use Drupal\Core\Entity\EntityInterface;
use Drupal\flag\Ajax\ActionLinkFlashCommand;
use Drupal\flag\Controller\ActionLinkController;
use Drupal\flag\FlagInterface;

class MyCustomActionLinkController extends ActionLinkController {

   * Performs a flagging when called via a route.
   * @param \Drupal\flag\FlagInterface $flag
   *   The flag entity.
   * @param int $entity_id
   *   The flaggable entity ID.
   * @return \Drupal\Core\Ajax\AjaxResponse|null
   *   The response object, only if successful.
   * @see \Drupal\flag\Plugin\Reload
  public function flag(FlagInterface $flag, $entity_id) {
    /* @var \Drupal\Core\Entity\EntityInterface $entity */
    $entity = $this->flagService->getFlaggableById($flag, $entity_id);
    $uid = \Drupal::currentUser()->id();
    // Do your check here i just test with the user admin.
    if ($uid == 1) {
      // Change the message you want to show 
      $flag->setFlagMessage("Sorry you don't have right to bookmark this");
      return $this->generateResponse($flag, $entity, $flag->getMessage('flag'));
    else {
      try {
        $this->flagService->flag($flag, $entity);
      } catch (\LogicException $e) {
        // Fail silently so we return to the entity, which will show an updated
        // link for the existing state of the flag.
      return $this->generateResponse($flag, $entity, $flag->getMessage('flag'));

   * Generates a response after the flag has been updated.
   * @param \Drupal\flag\FlagInterface $flag
   *   The flag entity.
   * @param \Drupal\Core\Entity\EntityInterface $entity
   *   The entity object.
   * @param string $message
   *   (optional) The message to flash.
   * @return \Drupal\Core\Ajax\AjaxResponse
   *   The response object.
  private function generateResponse(FlagInterface $flag, EntityInterface $entity, $message) {
    // Create a new AJAX response.
    $response = new AjaxResponse();

    // Get the link type plugin.
    $link_type = $flag->getLinkTypePlugin();

    // Generate the link render array.
    $link = $link_type->getAsFlagLink($flag, $entity);

    // Generate a CSS selector to use in a JQuery Replace command.
    $selector = '.js-flag-' . Html::cleanCssIdentifier($flag->id()) . '-' . $entity->id();

    // Create a new JQuery Replace command to update the link display.
    $replace = new ReplaceCommand($selector, $this->renderer->renderPlain($link));

    // Push a message pulsing command onto the stack.
    $pulse = new ActionLinkFlashCommand($selector, $message);

    return $response;


  1. You may need to do the same the route flag.action_link_flag_nojs.
  2. I reimplement the method generateResponse because it has a private visibility.

Here is a possible implementation:

  • Create some role, say Bookmarks allowed, which by default you assign to all your users. And make sure to limit access to your Bookmarks (button) to only those users who have been authorized for this Bookmarks allowed role.

  • Use the Flag module, to implement a flag to flag users, with a label like, say, Deny bookmarks.

  • Implement some logic, eg using the Rules module (or some custom module if you prefer), so that when a user gets flagged with the Deny bookmarks flag, authorization for this Bookmarks allowed role is removed.

  • Finally, flag all those "some users" with this flag.

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.