1

I am testing how to add a custom constraint to a Drupal 8 (node) entity. I have a fresh D8 site with a content type "Product" and a field "field_stock_level" of type Number (integer).

I created a module with the following code: entity_validation.module:

/**
 * Implements hook_entity_bundle_field_info_alter().
 */
function entity_validation_entity_bundle_field_info_alter(&$fields,\Drupal\Core\Entity\EntityTypeInterface $entity_type, $bundle) {
  if ($entity_type->id() == 'node') {
    switch ($bundle) {
      case 'product':
        $fields['field_stock_level']->addConstraint('EvenNumber', []);
        break;
    }
  }
}

EvenNumberConstraint.php:

<?php
// Note: file is saved in location: modules/custom/entity_validation/src/Plugin/Validation/Constraint/EvenNumberConstraint.php
/**
 * @file
 * Contains \Drupal\entity_validation\Plugin\Validation\Constraint\EvenNumberConstraint.
 */
namespace Drupal\entity_validation\Plugin\Validation\Constraint;
use Symfony\Component\Validator\Constraint;
/**
 * Checks that a given number is even.
 *
 * @Constraint(
 *   id = "EvenNumber",
 *   label = @Translation("Even Number", context = "Validation"),
 * )
 */
class EvenNumberConstraint extends Constraint {

  public $noEvenNumberMessage = 'The entered number must be even.';
}

EvenNumberConstraintValidator.php:

<?php
// Note: file is saved in location: modules/custom/entity_validation/src/Plugin/Validation/Constraint/EvenNumberConstraintValidator.php
/**
 * @file
 * Contains \Drupal\entity_validation\Plugin\Validation\Constraint\EvenNumberConstraintValidator.
 */
namespace Drupal\entity_validation\Plugin\Validation\Constraint;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
/**
 * Validates the EvenNumber constraint.
 */
class EvenNumberConstraintValidator extends ConstraintValidator {
  /**
   * {@inheritdoc}
   */
  public function validate($field, Constraint $constraint) {
    $value = $field->value;
    if (!isset($value)) {
      return NULL;
    }
    // Verify that given value is even.
    if ($value % 2 != 0) {
      $this->context->addViolation($constraint->noEvenNumberMessage);
    }
  }
}

The validation runs, and the code adds the violation. However on saving the node, I get the following error:

Recoverable fatal error: Argument 1 passed to Drupal\Core\Form\FormState::setError() must be of the type array, null given, called in core/lib/Drupal/Core/Field/WidgetBase.php on line 448 and defined in Drupal\Core\Form\FormState->setError() (line 1157 of core/lib/Drupal/Core/Form/FormState.php).

Anyone knows what's going on? I can't seem to figure it out...

  • Looks good. Though I think the "field will be FieldList not the field item. Also this is a long shot but maybe remove return NULL and just return; – user21641 Oct 14 '15 at 19:44
  • Maybe this recent watchdog article will help? drupalwatchdog.com/volume-5/issue-2/… – benjy Oct 17 '15 at 0:55
  • Thanks, I was actually experimenting based on that article, but then got stuck :) – Sven Decabooter Oct 25 '15 at 16:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.