问题
I have an entity ArticlePattern, which has a property pattern (string). I need to access the database to check if pattern is correct. So I would like to define a method ArticlePattern::isPatternValid() and add a constraint (using Doctrine's annotation) which would check if isPatternValid is true during validation by Validator object.
From what I have read here and there it is not a good idea, to make an entity depended on service container, which mean I cannot access the doctrine service from inside ArticlePattern::isPatternValid().
So how can I make a custom validation constraint which need an access to the database? How do you deal with such situations which I think is very common seeing so many questions about accessing a service container from an entity class.
EDIT:
Ok, thanks guys, so the answer is a Custom Validation Constraint
回答1:
A validator object can be:
- A simple object, that has no connection to the framework environment at all.
- A service (in the context of dependency injection container) which could do absolutley anything as long as it impements
Symfony\Component\Validator\ConstraintValidatorInterface
So what do you have to do?
- Define a simple constraint
- Override
validatedBy()method to return validator "name" (return 'my_validator';) Define a simple service in DIC:
<service id="project.validator.my" class="Project\Constraints\MyValidator"> <!-- service definition here --> <!-- the service has to be tagged --> <tag name="validator.constraint_validator" alias="my_validator" /> </service>
EDIT
You've asked about multiple properties validation. In such a case you could create a validator that is related to the object rather to the property of the object.
In your constraint class define the target of that constraint (property / class):
class MyConstraint ... { ... public function targets() { return self::CLASS_CONSTRAINT; } }Annotate validated class instead of property:
@Assert/MyConstraint(...) class MyClass { private $firstName; private $lastName; @Assert/Email private $email; ... }The validator itself looks pretty much the same as in case of validating a property:
class MyValidator extends ConstraintValidator { public function isValid($value, Constraint $constraint) { // $value is an object rather a property } }
回答2:
Your constraint should override the base validatedBy() method and return the id of the constraint validator service in your container.
public function validatedBy()
{
return 'my_pattern_validator';
}
来源:https://stackoverflow.com/questions/8934607/symfony2-doctrine-validation-constraint-which-requires-access-to-a-database