How to Override Entity Access Handlers 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.
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.
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.
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
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.
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!
Solving complex Drupal development challenges for our clients is what we do best at Promet Source. What can we do for you?
Other Insights & Resources you may like
Get our newsletter
Alright, so, software ate the world. That happened. Technology is now at the heart of every modern company, and as far as we can tell that isn’t changing. That’s the sitch. Our job is to make it more human.