Adding storage, access, and form handlers for entitiesfor Drupal 8 , 9 , 10 , and 11

Last updated :  

Introduction

In the last lesson, we defined a custom entity using annotations, establishing a structural foundation. To turn this theoretical framework into a fully functioning part of your Drupal site, we must introduce storage solutions, access controls, and form handlers. These elements complete the infrastructure needed for robust custom entity management.

Storage Handlers

Storage handlers manage how and where entities store their data. For our Contact Message entity, we'll ensure it properly interacts with the database to handle CRUD (Create, Read, Update, Delete) operations.

Defining a DefaultStorage

Drupal provides a default SqlContentEntityStorage class, which is commonly used for storage. To use this storage handler, ensure your entity's annotation specifies this handler:


 *   handlers = {
 *     "storage" = "Drupal\Core\Entity\Sql\SqlContentEntityStorage",
}

By doing this, your entity inherits standard storage capabilities, leveraging Drupal’s built-in database abstraction tools.

Access Control Handlers

Access control handlers determine who can view or modify your entities. It's crucial for securing sensitive data and managing permissions across user roles.

Setting AccessControlHandler

Implement an EntityAccessControlHandler to govern interactions. In your module, add an access handler like so:


 *   handlers = {
 *     "access" = "Drupal\custom_module\ContactMessageAccessControlHandler",
}

Creating the Access Control Class

Create a file, src/ContactMessageAccessControlHandler.php and implement:

namespace Drupal\custom_module;

use Drupal\Core\Entity\EntityAccessControlHandler;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Session\AccountInterface;

class ContactMessageAccessControlHandler extends EntityAccessControlHandler {
  
  protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) {
    switch ($operation) {
      case 'view':
        return AccessResult::allowedIfHasPermission($account, 'view contact message entity');
      case 'update':
        return AccessResult::allowedIfHasPermission($account, 'edit contact message entity');
      case 'delete':
        return AccessResult::allowedIfHasPermission($account, 'delete contact message entity');
    }
    return AccessResult::neutral();
  }

  protected function checkCreateAccess(AccountInterface $account, array $context, $entity_bundle = NULL) {
    return AccessResult::allowedIfHasPermission($account, 'add contact message entity');
  }
}

This setup checks permissions for viewing, updating, and deleting the entity based on user roles.

Form Handlers

Form handlers define how users interact with entities through forms. They handle the processes of gathering user inputs, validating, and saving data.

Creating Form Handlers

Design form handlers using Drupal's Form API by creating ContactMessageForm and ContactMessageDeleteForm.

Example Add/Edit Form

Create src/Form/ContactMessageForm.php:

namespace Drupal\custom_module\Form;

use Drupal\Core\Entity\ContentEntityForm;
use Drupal\Core\Form\FormStateInterface;

class ContactMessageForm extends ContentEntityForm {

  public function buildForm(array $form, FormStateInterface $form_state) {
    $form = parent::buildForm($form, $form_state);

    // Custom additions to the form can follow here.

    return $form;
  }

  public function save(array $form, FormStateInterface $form_state) {
    $entity = $this->getEntity();
    $status = $entity->save();

    switch ($status) {
      case SAVED_NEW:
        drupal_set_message($this->t('Created the %label Contact Message.', [
          '%label' => $entity->label(),
        ]));
        break;

      default:
        drupal_set_message($this->t('Saved the %label Contact Message.', [
          '%label' => $entity->label(),
        ]));
    }

    $form_state->setRedirect('entity.contact_message.canonical', ['contact_message' => $entity->id()]);
  }
}

Handling Form Deletion

Similarly, create ContactMessageDeleteForm to manage deletions efficiently:

namespace Drupal\custom_module\Form;

use Drupal\Core\Entity\ContentEntityDeleteForm;

class ContactMessageDeleteForm extends ContentEntityDeleteForm {
  // Inherits delete handling from ContentEntityDeleteForm.
}

Conclusion

Incorporating storage, access, and form handlers into your custom entity ensures that it integrates seamlessly with Drupal's core functionalities. These handlers are vital for proper data storage, access management, and user interaction with your entity.

Teaser for the Next Lesson

Building on this solid foundation, our next lesson will cover how to add fields to custom entities programmatically. This will enable further customization and data handling for your Drupal entities. Stay tuned!