Entity Validation API overview

Last updated on
7 July 2023

In Drupal 8 Entity validation is moved to a separate Entity validation API and decoupled from form validation. Decoupling entity validation from forms allows validation entities to be independent of form submissions, such as when changed via the RESTful web service. This new validation API has been implemented based on the Symfony validator.

Overview

Validation is controlled by a set of constraints, such as the maximum length of some text or restriction to a set of allowed values. Symfony comes with many useful constraints, which Drupal extends with more Drupal-specific constraints. Drupal Symfony validator has been integrated with the Typed Data API, such that validation constraints can be used and specified as part of Entity field definitions and, generally, any typed data definition.

Using the API

Validation can be invoked by calling the validate() method on any typed data object as in the following example:

    $definition = DataDefinition::create('integer')
      ->addConstraint('Range', ['min' => 5]);
    $typed_data = \Drupal::typedDataManager()->create($definition, 10);
    $violations = $typed_data->validate();

This returns a list of violations if passed an empty validation:

  if ($violations->count() > 0) {
    // Validation failed.
  }

Violations are objects, which provide a translated violation message to the caller:

  print $violations[0]->getMessage();

In this example, a Range constraint has been specified as part of the data definition. However, some additional constraints might be auto-generated by the class, or added in as default based on the data type. For example, an e-mail type would add the constraints to ensure the value is a string and a valid e-mail address. All applied constraints can be retrieved by calling $typed_data->getConstraints().

Calling validate() on a typed data object is a shortcut to obtain a Symfony validator and validate the data, whereas this Symfony validator object has been configured as necessary for validating typed data. $typed_data->validate() is equivalent to:

    return \Drupal::typedDataManager()->getValidator()->validate($typed_data);

Validating entities

Entity fields and field items are typed data objects, and can be validated as in this example:

$violations = $entity->field_text->validate();

Here is an example of validating an entity as a whole:

$violations = $entity->validate();

Violations contain the property path to the property that failed validation, relative to the object where validation began. For example, if the example field's text (which resides in $field[0]->value) fails validation $violation->getPropertyPath() the property path would be "0.value" in the first example and "field_text.0.value" in the second.

Putting constraints on field item properties

Entity field definitions ease putting constraints on individual field item properties via the setPropertyConstraints() method. In the following example, the field definition puts a maximum length constraint on the field item's value property ($field[0]->value):

    $fields['name'] = BaseFieldDefinition::create('string')
      ->setLabel(t('Name'))
      ->setPropertyConstraints('value', ['Length' => ['max' => 32]]);

Relationship to Symfony validator

Drupal makes use of Symfony constraint classes and their validation logic (ConstraintValidator classes) but integrates them via the Drupal 8 plugin system so that they are discovered via the usual annotation-based plugin discovery. As a result, references to constraints in typed data definitions are plugin IDs. For example, Range in the example above refers to the Range constraint plugin (class).

Symfony validator is configured to use a Drupal translator class, such that violation messages correctly run through t(). While Symfony constraint messages use a {{ key }} syntax for message placeholders, those messages are converted to use regular Drupal placeholders in the form of %key. For consistency, this approach should be followed if further Symfony constraints are exposed to Drupal.

Documentation

For further details, read about Symfony validator

Help improve this page

Page status: No known problems

You can: