Jeśli chcesz sprawdzić poprawność obiekt z dowolnej logiki związanej z zewnętrznego uzależnienia (w przypadku usługi @security.context
uzyskać bieżącego użytkownika) ... należy:
- utworzyć niestandardową Potwierdzanie ograniczenie
- stworzyć niestandardowy walidator usługi wykorzystywane przez ograniczenie
- wstrzyknąć usługę
@security.context
do walidatora
- skorzystać z tej nowo utworzonej ograniczenia poprawności do sprawdzania poprawności podmiot,
Rozwiązaniem jest opisana w rozdziale dokumentacji Validators with Dependencies
This video pokazuje, dlaczego nie jest to absolutnie konieczne, aby mieć następującą Redbull walidator.
modelu/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"
Ograniczenie
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()
;
}
Nie można i nie powinno się używać Callback
ograniczenie do sprawdzania przed każdym uzależnienia zewnętrznego.
Nie należy próbować wstrzykiwać żadnych zależności sprawdzania poprawności do modelu domeny lub podmiotów bezpośrednio.
Logika walidacji powinna być przechowywana poza jednostkami w ogóle.
Adnotacje są już pewnego rodzaju miękkim sprzężeniem między jednostkami i walidatorem symfony. Z tego powodu zaleca się zwykle używanie konfiguracji xml do mapowania doktryn i walidacji.
Dziękuję. Ale to nie działa dla mnie. SecurityContextInterface wydaje się być przestarzałe od wersji 2.6 lub coś podobnego. Używam symfony3. – rvaliev
Zaktualizowano odpowiedź. W Symfony 2.6+ '@ security.token_storage' zapewnia metodę' getToken() 'zamiast' @ security.context' ... ale mógłbyś to sobie wyobrazić;) Jeśli moja odpowiedź dostarcza cennych informacji może rozważyć zaakceptowanie lub przynajmniej przejęcie go. – nifr
Jestem nowy w symfony, więc nie mogłem sam tego zrozumieć. W każdym razie teraz działa! Dziękuję Ci bardzo! :) – rvaliev