2016-03-28 7 views

Antwort

8

Wenn Sie ein Objekt mit jeder Logik zu einer externen Abhängigkeit (in Ihrem Fall die @security.context Dienst den aktuellen Benutzer zu bekommen) mit Bezug validieren möchten ... sollten Sie:

  • eine benutzerdefinierte Validierungs- erstellen constraint
  • erstellen benutzerdefinierten Validator Dienst durch die
  • die @security.context Dienst in den Prüfer einzuspritzen Constraint verwendet werden
  • verwenden diese neu Einschränkung erstellt Validierung Ihr Unternehmen zu validieren

Die Lösung wird beschrieben in der Dokumentation Kapitel Validators with Dependencies


This video zeigt, warum es unbedingt notwendig, die folgende RedBull Validator zu haben.

Modell/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's 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() 
     ; 
    } 

Sie können nicht und Sie sollten nicht die Callback Einschränkung verwenden gegen jede externe Abhängigkeit zu validieren.

Versuchen Sie nicht, eine beliebige Validierungsabhängigkeit in Ihr Domänenmodell oder Entitäten direkt zu injizieren.

Die Validierungslogik sollte im Allgemeinen aus Entitäten herausgehalten werden.

Anmerkungen sind bereits eine Art von Soft-Kopplung zwischen Entitäten und dem Symfony-Validator. Aus diesem Grund wird empfohlen, in der Regel die XML-Konfiguration für Doku- ment- und Validierungszuordnungen zu verwenden.

+0

Vielen Dank. Aber es funktioniert nicht für mich. SecurityContextInterface scheint seit 2.6 oder so veraltet zu sein. Ich benutze symfony3. – rvaliev

+1

Die Antwort wurde aktualisiert. Mit Symfony 2.6+ bietet das '@ security.token_storage' die' getToken() 'Methode anstelle von' @ security.context' ... aber das hättest du selbst herausfinden können;) Wenn meine Antwort dir wertvolle Einblicke liefert könnte in Erwägung ziehen, es zu akzeptieren oder zumindest zu verbessern. – nifr

+1

Ich bin neu in symfony, also konnte ich es nicht selbst herausfinden. Wie auch immer, es funktioniert jetzt !! Vielen Dank! :) – rvaliev

Verwandte Themen