If you want to check an object with any logic related to an external dependency (in your case, the @security.context service to get the current user) ... you should:
- create custom validation constraint
- create a custom validator service that will be used by the constraint
- embed the
@security.context service in the validator - use this newly created validation constraint to validate your entity
The solution is described in the Validators with Dependencies documentation chapter.
This video shows why it is absolutely necessary to have the next RedBull validator.
Model / Entity
use FamilyGuy\Validator\Constraints\Peter as PeterIsNotAllowedToOrder; class Order { public $drink;
Config
# app/config/services.yml services: validator.red_bull: class: FamilyGuy\Validator\Constraints\Peter\RedBullValidator # for symfony < 2.6 use @security.context arguments: ["@security.token_storage"] tags: - name: "validator.constraint_validator" alias: "peter_red_bull_constraint_validator"
Constraint
use Symfony\Component\Validator\Constraint; namespace FamilyGuy\Validator\Constraints\Peter; class RedBull extends Constraint { public $message = 'Peter... You are not allowed to order %drink%.'; public function validatedBy() {
Validator:
// For symfony < 2.6 use SecurityContextInterface // use Symfony\Component\Security\Core\SecurityContextInterface; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\ConstraintValidator; namespace FamilyGuy\Validator\Constraints\Peter; class RedBullValidator extends ConstraintValidator { /** @var TokenStorageInterface|SecurityContextInterface */ protected $tokenStorage; /** @param TokenStorageInterface|SecurityContextInterface $token_storage */ public function __construct(TokenStorageInterface $token_storage) { $this->tokenStorage = $token_storage; } public function validate($drink, Constraint $constraint) { $currentUser = $this->tokenStorage->getToken()->getUser()->getName(); if ($currentUser !== "Peter") { return; } if ( $drink !== "RedBull" ) { return } $this->context->buildViolation($constraint->message) ->setParameter('%drink%', $drink) ->addViolation() ; }
You cannot and should not use the Callback restriction to check for any external dependency.
Do not try to embed any validation dependency in your model or entities directly.
Validation logic must be stored outside of entities as a whole.
Annotations are already a kind of soft link between objects and the symfony authenticator. Therefore, it is recommended that you usually use the xml configuration for doctrine and validation comparisons.
nifr
source share