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.