Take the 2-minute tour ×
Drupal Answers is a question and answer site for Drupal developers and administrators. It's 100% free, no registration required.

I have an entity that has a field attached to it and the values that user types into the field has to be globally(website) unique(compared to other entities).

I have added validation to the entity form but what if I create this entity programmatically? How can I prevent the entity to be saved into the storage?

I've noticed there is a validate method in ContentEntityBase, though not in ConfigEntityBase. Is this the place for it? If so, I could use some examples.

share|improve this question

2 Answers 2

up vote 5 down vote accepted

Fields have constraints defined on them and as everything is a field on an entity, that's that. See Comment::baseFieldDefinitions does ->setConstraints(array('CommentName' => array()));. Then there's appropriate plugin in the Drupal\comment\Plugin\Validation\Constraint namespace in a class called CommentNameConstraint. The logic is in CommentNameConstraintValidator.

So the chain is

  1. setConstraints in basedFieldDefinitions setting a list of plugin ids (CommentName) and their arguments (empty array in the example
  2. A plugin in the Drupal\modulename\Plugin\Validation\Constraint namespace with the appropriate plugin id. The classname is not magic, the plugin id is what's important. Using the plugin id plus Constraint as classname seems to be best practice.
  3. Whatever classname you picked in the previous step, append Validator to it, make it extend Symfony\Component\Validator\ConstraintValidator and put your validation logic in validate.
share|improve this answer
    
What if the field is Field API field? –  Ivan Jaros Mar 20 at 14:40
    
Is it your field type? Then you can control it on the annotation of your class, see EmailItem for an example or by implementing the getConstraints() method if it is dynamic (like based on a setting), see StringItem for an example. When it's a config field from someone else, then I'm not sure.. maybe on the entity itself if controlled there, or you could alter it into the plugin definition if it applies to all fields of that type. –  Berdir Mar 20 at 15:40
    
No, it's not my field in this case. And even if it were, placing the constraint in it globally is not a good practice. –  Ivan Jaros Mar 21 at 11:30
    
It's perfectly good practice if the validation is required for that field type, like an email field must store a valid e-mail address. If you neither control the entity nor the field and it is a configurable field added through the UI then it's currently not possible to add a constraint I think. Feel free to open an issue to add a hook or something for that. –  Berdir Mar 21 at 16:45
    
Ok, but why it's not possible to add constraint to entity? That would solve my situation perfectly. –  Ivan Jaros Mar 21 at 19:41

Constraints for fields can be provided at two places: - on a per field-type level, i.e. in its annotation or getConstraints() method - on a per field basis by adding it to the field definitions. Right now, this is only possible for non-configurable fields - e.g. by implementing https://api.drupal.org/api/drupal/core!modules!system!entity.api.php/function/hook_entity_base_field_info_alter/8. It's not possible to add custom constraints to configurable fields right now (sounds like this could need improvement).

share|improve this answer
    
But why then, when we have now "services" that allow communicating with Drupal core via different paths than classic web UI, we don't have such validation in place? I mean what if I want to create some content entity via REST for, lets say a mobile application build on Drupal, and I provide some invalid data. How would by application knew that something is wrong? I don't think validation on form level is sufficient at all. –  Ivan Jaros Apr 12 at 18:04

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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