Skip to main content

How to Override Entity Access Handlers in Drupal

15 min read
Aug 26, 2020
Jan 8, 2024
How to Override Entity Access Handler in Drupal

Level up your understanding of entity access in this second part of Promet's series on mastering entity access.

In this second part of our series on Mastering Entity Access, we present a scenario in which overriding the entity access handler proved to be the optimal solution for a client requirement that we override the menu set on Block Layout settings at the node level. In the process we gained valuable information information on entity access challenges. 

Read Part I here.

By default depending on the market (country-language pair), we set a certain menu in the Block Layout settings.  For example, on gb-en, we set menu A, but on ph-en we place menu B.  A challenge arises when the client wants to be able to override those settings on a per node basis as needed.

 

Screen showing node edit form with menu type option
Screen showing node edit form with menu type option

 

Our initial thought is to use,hook_block_access, however on its own, this would not work because once a deny is issued on the Block Layout settings (see Caveat item 1 on Part 1: How to Master Entity Access in Drupal), any allow on hook_block_access would not matter anymore. 

Our solution is to override the access handler for the Block entity.

 

Overriding the access handler for the Block entity

 

1. Check the default access handler and the implementing class.

 

Screen showing block entity annotation
Screen showing block entity annotation

 

The image above shows Drupal\block\Entity\Block.php entity annotation.  We can override the access handler defined here to customize to our own use case.

 

2. Extend and implement your custom access handler

 

Screen showing implementation override on BlockAccessControlHandler
Screen showing implementation override on BlockAccessControlHandler

 

Extend the Drupal\block\BlockAccessControlHandler and override checkAccess() method. You can inject your custom access control logic inside this method. 

In our use case, we check first if we are looking at a node page and check if field_masthead_type was set to override anything.  If it does, then we provide access to certain blocks.  Otherwise, we delegate the decision back to BlockAccessControlHandler via parent::checkAccess() which respects the default Block Layout settings.

 

3. Replace the handler in your custom module.

Once we created the implementing class, we need to inform Drupal about this change by using hook_entity_type_build as shown.

With these 3 steps, we are able to implement the client requirement.  Don’t forget flush caches.

 

Screen showing how to override the access handler for the block entity
Screen showing how to override the access handler for the block entity

 

Diving deeper on Entity Access

 

Drupal\Core\Entity\EntityAccessControlHandler

Almost all entity access handlers, including Blocks and Nodes, extend EntityAccessControlHandler.  BlockAccessControlHandler is the handler for blocks and NodeAccessControlHandler for nodes, both extend EntityAccessControlHandler.  

As you can see from the image below, EntityAccessControlHandler access() method will first invoke hook_entity_access and hook_ENTITY_TYPE_access and then call on checkAccess(). The checkAccess method is where most entity access control handlers implement their custom logic and is overridden.  For blocks, this is where the Block Layout settings access are calculated.  

By extending EntityAccessControlHandler and only overriding checkAccess, most entity access control handlers will still respect hook_entity_access checks.

Dependency injection and Object Oriented Programming rocks!

 

Screen showing the EntityAccessControlHandler Implementation
Screen showing the EntityAccessControlHandler Implementation

 

Solving complex Drupal development challenges for our clients is what we do best at Promet Source. What can we do for you?

 

subscribe informantion

 

How may I assist you?