3

I'm defining a base field for my custom content entity:

$fields['machine_name'] = BaseFieldDefinition::create('string')
  ->setLabel(t('Machine name'))
  ->addConstraint('UniqueField')
  ->addConstraint('Regex', ['pattern' => '[^a-z0-9_]+'])
  ->setTranslatable(false)
  ->setRequired(true);

However RegexValidator throws UnexpectedTypeException complaining that passed value is of type FieldItemList. This is obvious since in Drupal 8 even single value fields are lists (with one item).

So how can I use Regex validator with entity fields? Or do I have to write my own regex validator that will handle FieldItemLists?

5

You do not need to create your own Validator. Instead, use setPropertyConstraints instead of addConstraint to attach the Regex validator to the individual property of the field rather than the FieldItemList. For a string field, add the constraint to "value." For a link field, you may want to add it to "URI," etc. Here is an example:

->setPropertyConstraints(
  'value', ['Regex' => [
    'pattern' => '/^[0-9]+$/',
    'message' => t('Please use numbers only in the blah field.'),
  ]]
);
0
2

I ended up writing my own Validator and Constraint classes.

FieldRegexValidator class:

class FieldRegexValidator extends RegexValidator {

  /**
   * @inheritDoc
   */
  public function validate($value, Constraint $constraint) {
    // When dealing with FieldItemLists we have to check all of it's items.
    if ($value instanceof FieldItemList) {
      foreach ($value as $item) {
        parent::validate(reset($item->getValue()), $constraint);
      }
    } else {
      // This is the default behavior of parent class.
      parent::validate($value, $constraint);
    }
  }

}

FieldRegexConstraint class:

/**
 * Regex constraint for fields.
 *
 * Extends the core Drupal validation to handle FieldItemList correctly.
 *
 * @Constraint(
 *   id = "FieldRegex",
 *   label = @Translation("Field regex", context = "Validation")
 * )
 */
class FieldRegexConstraint extends RegexConstraint {

  public $message = 'This value does not match requested pattern.';

  /**
   * {@inheritdoc}
   */
  public function validatedBy() {
    return 'Drupal\gaps\Plugin\Validation\Constraint\FieldRegexValidator';
  }
}

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.