Overriding the default handlers for any entity in Drupal 8
Drupal 8 has a lot of things in core which makes a developer life easier, and Annotations are one of them. Annotation is a discovery mechanism similar to info hooks in Drupal 7.
Entities declare handlers which takes care of different functions like Access, Storage , List building etc. in annotations.
Let’s take an example of User Entity.
Below are the handlers declared in User Entity annotation.
handlers = {
"storage" = "Drupal\user\UserStorage",
"storage_schema" = "Drupal\user\UserStorageSchema",
"access" = "Drupal\user\UserAccessControlHandler",
"list_builder" = "Drupal\user\UserListBuilder",
"views_data" = "Drupal\user\UserViewsData",
"route_provider" = {
"html" = "Drupal\user\Entity\UserRouteProvider",
},
"form" = {
"default" = "Drupal\user\ProfileForm",
"cancel" = "Drupal\user\Form\UserCancelForm",
"register" = "Drupal\user\RegisterForm"
},
"translation" = "Drupal\user\ProfileTranslationHandler"
}
Now say we want to override access handler for User entity. We can use hook_entity_type_alter to alter the class for handler.
/**
* Implements hook_entity_type_alter().
*/
function MY_MODULE_entity_type_alter(array &$entity_types) {
$entity_types['user']->setHandlerClass('access', CustomAccessHandler::class);
}
Now you can create your own Access handler at MY_MODULE/src/CustomAccessHandler.
You can either extend the EntityAccessControlHandler class or extend the default handler ie., UserAccessControlHandler in our case and just override your required function.
<?php
namespace Drupal\MY_MODULE;
use Drupal\user\UserAccessControlHandler;
/**
* Defines the custom access control handler for the user entity type.
*/
class CustomAccessHandler extends UserAccessControlHandler {
/**
* {@inheritdoc}
*/
protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) {
// Custom override code.
}
}
Remember to rebuild your caches after this.