Symfony2: How to check an object, taking into account the current user?

I am doing a custom check using a callback inside a User object.

Therefore, I need to get the User object of the current user.

In the controller, I can do it like this:

$user= $this->get('security.context')->getToken()->getUser(); 

But how do I do this inside a User object?

+7
validation symfony
source share
1 answer

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 { /** @PeterIsNotAllowedToOrder/RedBull */ 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; /** * @Annotation */ class RedBull extends Constraint { /** @var string */ public $message = 'Peter... You are not allowed to order %drink%.'; /** @return string */ public function validatedBy() { // has to match the validator service alias ! return 'peter_red_bull_constraint_validator'; } } 

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.

+8
source share

All Articles