Пользовательский валидатор symfony4 не может получить доступ к частной собственности - PullRequest
0 голосов
/ 10 июля 2019

Я использую symfony4 для веб-приложения. Я успешно использую компонент проверки для проверки IP-адреса. Но у меня есть ошибка Не удается получить доступ к частному свойству App \ Entity \ Terminal :: $ name при попытке использовать мое собственное пользовательское ограничение, следуя этому руководству: https://symfony.com/doc/current/validation/custom_constraint.html

Моя сущность для проверки: src / Entity / Terminal.php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use App\Validator\Constraints as AcmeAssert;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * @ORM\Entity(repositoryClass="App\Repository\TerminalRepository")
 */
class Terminal
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=255, nullable=true)
     * @AcmeAssert\IsAHostname // error cannot access private property when this constraint is used
     */
    private $name;

    /**
     * @ORM\Column(type="string", length=255, nullable=true)
     * @Assert\Ip //this constraint works
     */
    private $ip;

    ...

    public function getName(): ?string          
{                                           
    return $this->name;                     
}                                           

public function setName(?string $name): self
{                                           
    $this->name = $name;                    

    return $this;                           
}

...

public function getIp(): ?string        
{                                       
    return $this->ip;                   
}                                       

public function setIp(?string $ip): self
{                                       
    $this->ip = $ip;                    

    return $this;                       
}    

...                                  
}

Мое пользовательское ограничение: src / Validator / Constraints / IsAHostname.php

namespace App\Validator\Constraints;

use Symfony\Component\Validator\Constraint;

/**
 * @Annotation
 */
class IsAHostname extends Constraint
{
    public $message = 'The string "{{ string }}" contains illegal character.';
}

Мой пользовательский валидатор ограничений: src / Validator / Constraints / IsAHostnameValidator.php

namespace App\Validator\Constraints;

use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
use Symfony\Component\Validator\Exception\UnexpectedValueException;

class IsAHostnameValidator extends ConstraintValidator
{
    public function validate($value, Constraint $constraint)
    {
        if (!$constraint instanceof IsAHostname) {
            throw new UnexpectedTypeException($constraint, IsAHostname::class);
        }
        // custom constraints should ignore null and empty values to allow
        // other constraints (NotBlank, NotNull, etc.) take care of that

        if (null === $value || '' === $value) {
            return;
        }

        if (!is_string($value)) {
                // throw this exception if your validator cannot handle the passed type so that it can be marked as invalid
                throw new UnexpectedValueException($value, 'string');

                // separate multiple types using pipes
                // throw new UnexpectedValueException($value, 'string|int');
        }

        if (!preg_match('/^[a-zA-Z0-9-]+$/', $value, $matches)) {
            $this->context->buildViolation($constraint->message)
                ->setParameter('{{ string }}', $value)
                ->addViolation();
        }
    }
}

Как я это называю, мой Контроллер:

 /**
     * @IsGranted("ROLE_OPERATOR")
     * @Route("/terminal/{id}", name="terminal_operation", methods={"POST"})
     **/
public function operateTerminalController(Terminal $terminal, Request $request, OperateTerminal $operateTerminal, ValidatorInterface $validator)
{
// paramConverter use {id} in the address to find the corresponding terminal in the db and build $terminal object
$terminalInfoErrors= $validator->validate($terminal);
...
}

Ограничение Ip работает отлично, я пробовал с разными значениями и выдает ошибки только тогда, когда ожидается. Но когда я добавляю свое пользовательское ограничение @AcmeAssert \ IsAHostname, оно выдает мне следующую ошибку:

Невозможно получить доступ к частной собственности App \ Entity \ Terminal :: $ name

выброшено из-за $ TerminalInfoErrors = $ validator-> validate ($ терминал);

Если возможно, я хотел бы, чтобы некоторые идеи отладили это. Я полагаю, что метод доступа к свойству отличается между этими двумя ограничениями.

  • Как валидатор может получить доступ к частному свойству сущности с помощью этого предварительно созданного ограничения Ip?
  • Что я могу сделать, чтобы мои пользовательские ограничения обращались к свойству объекта таким же образом?
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...