表单验证不适用于特定实体

时间:2019-06-21 09:02:11

标签: php symfony validation

使用 Symfony 4 ,我正在尝试在发送表单时对以下实体施加一些约束,但这些约束将不适用,我也不明白为什么。

结构如下:

  • 用户实体
  • 链接到用户的 BudgetLine 实体(1个用户->多个预算行)
  • 用于创建和修改预算行的 formType
  • CollectionType类的 formType ,可在单个表单中为每个用户预算行生成1个表单。

对BudgetLine实体的约束无效,我找不到原因...

用户实体


namespace App\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;


/**
 * @ORM\Entity(repositoryClass="App\Repository\UserRepository")
 * @UniqueEntity(fields={"email"},message="L'email est déjà utilisé")
 */
class User implements UserInterface 
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=255)
     * @Assert\Email()
     */
    private $email;

    /**
     * @ORM\Column(type="string", length=255)
     * 
     */
    private $username;

    /**
     * @ORM\Column(type="string", length=255)
     * @Assert\Length(min="8",minMessage="Votre mot de passe doit faire 8 caractères minimum")
     */
    private $password;

    /**
     * @Assert\Length(min="8",minMessage="Votre mot de passe doit faire 8 caractères minimum")
     * @Assert\EqualTo(propertyPath="confirm_password", message="Mots de passe différents",groups={"registration"})
     */
    public $confirm_password;

    /**
     * @ORM\Column(type="json_array", nullable=true)
     * @Assert\EqualTo(propertyPath="password", message="Mots de passe différents",groups={"registration"})
     */
    private $roles = array();

    /**
     * @ORM\OneToMany(targetEntity="App\Entity\BudgetLine", mappedBy="User", cascade={"persist"})
     */
    private $BudgetTable;

    public function __construct()
    {
        $this->BudgetTable = new ArrayCollection();
    }

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getEmail(): ?string
    {
        return $this->email;
    }

    public function setEmail(string $email): self
    {
        $this->email = $email;

        return $this;
    }

    public function getUsername(): ?string
    {
        return $this->username;
    }

    public function setUsername(string $username): self
    {
        $this->username = $username;

        return $this;
    }

    public function getPassword(): ?string
    {
        return $this->password;
    }

    public function setPassword(string $password): self
    {
        $this->password = $password;

        return $this;
    }

    public function eraseCredentials(){}

    public function getSalt(){}

    public function getRoles()
    {
        $roles = $this->roles;
        $roles[] = 'ROLE_USER';

        return array_unique($roles);
    }

    public function setRoles(array $roles)
    {
        $roles = array_values($roles); //on réinitialise les clefs de l'array
        $this->roles = $roles;

        // allows for chaining
        return $this;
    }

    public function unsetRoles(array $roles_unset)
    {
        $roles = $this->roles; //on charge les roles de l'objet user dans l'array $roles
        foreach($roles_unset as $role) //pour chaque role dans l'array $roles_unset qui nous est passé...
        {
            $key = array_search($role, $roles); //...on cherche sa clef dans $roles
            unset($roles[$key]); //et on delete le role correspondant de l'array
        }


        $roles = array_values($roles); //on réinitialise les clefs de l'array
        $this->roles = $roles; //on sauvegarde

        return $this;
    }

    public function hasRole(string $role)
    {
        $roles = $this->roles;
        if(($key = array_search($role, $roles)) !== false)
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    /**
     * @return Collection|BudgetLine[]
     */
    public function getBudgetTable(): Collection
    {
        return $this->BudgetTable;
    }

    public function addBudgetTable(BudgetLine $budgetTable): self
    {
        if (!$this->BudgetTable->contains($budgetTable)) {
            $this->BudgetTable[] = $budgetTable;
            $budgetTable->setUser($this);
        }

        return $this;
    }

    public function removeBudgetTable(BudgetLine $budgetTable): self
    {
        if ($this->BudgetTable->contains($budgetTable)) {
            $this->BudgetTable->removeElement($budgetTable);
            // set the owning side to null (unless already changed)
            if ($budgetTable->getUser() === $this) {
                $budgetTable->setUser(null);
            }
        }

        return $this;
    }
}

BudgetLine实体


namespace App\Entity;
use Symfony\Component\Validator\Constraints as Assert;


use Doctrine\ORM\Mapping as ORM;

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

    /**
     * @ORM\Column(type="string", length=255)
     */
    private $name;

    /**
     * @ORM\Column(type="float", nullable=true)
     * @Assert\Type(type="float",message="The value {{ value }} is not a valid {{ type }}.")
     */
    private $value_1;

    /**
     * @ORM\Column(type="string", length=255, nullable=true)
     */
    private $presta_1;

    /**
     * @ORM\Column(type="datetime", nullable=true)
     */
    private $date_1;

    /**
     * @ORM\Column(type="float", nullable=true)
     */
    private $value_2;

    /**
     * @ORM\Column(type="string", length=255, nullable=true)
     */
    private $presta_2;

    /**
     * @ORM\Column(type="datetime", nullable=true)
     */
    private $date_2;

    /**
     * @ORM\Column(type="float", nullable=true)
     */
    private $value_3;

    /**
     * @ORM\Column(type="string", length=255, nullable=true)
     */
    private $presta_3;

    /**
     * @ORM\Column(type="datetime", nullable=true)
     */
    private $date_3;

    /**
     * @ORM\Column(type="float", nullable=true)
     */
    private $value_4;

    /**
     * @ORM\Column(type="string", length=255, nullable=true)
     */
    private $presta_4;

    /**
     * @ORM\Column(type="datetime", nullable=true)
     */
    private $date_4;

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\User", inversedBy="BudgetTable")
     */
    private $User;

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\LineSubSubCategory", inversedBy="budgetLines")
     * @ORM\JoinColumn(nullable=false)
     */
    private $subSubCategory;

    public function getId(): ?int
    {
        return $this->id;
    }

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

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

        return $this;
    }

    public function getValue1(): ?float
    {
        return $this->value_1;
    }

    public function setValue1(float $value_1): self
    {
        $this->value_1 = $value_1;

        return $this;
    }

    public function getPresta1(): ?string
    {
        return $this->presta_1;
    }

    public function setPresta1(?string $presta_1): self
    {
        $this->presta_1 = $presta_1;

        return $this;
    }

    public function getDate1(): ?\DateTimeInterface
    {
        return $this->date_1;
    }

    public function setDate1(?\DateTimeInterface $date_1): self
    {
        $this->date_1 = $date_1;

        return $this;
    }

    public function getValue2(): ?float
    {
        return $this->value_2;
    }

    public function setValue2(float $value_2): self
    {
        $this->value_2 = $value_2;

        return $this;
    }

    public function getPresta2(): ?string
    {
        return $this->presta_2;
    }

    public function setPresta2(?string $presta_2): self
    {
        $this->presta_2 = $presta_2;

        return $this;
    }

    public function getDate2(): ?\DateTimeInterface
    {
        return $this->date_2;
    }

    public function setDate2(?\DateTimeInterface $date_2): self
    {
        $this->date_2 = $date_2;

        return $this;
    }

    public function getValue3(): ?float
    {
        return $this->value_3;
    }

    public function setValue3(float $value_3): self
    {
        $this->value_3 = $value_3;

        return $this;
    }

    public function getPresta3(): ?string
    {
        return $this->presta_3;
    }

    public function setPresta3(?string $presta_3): self
    {
        $this->presta_3 = $presta_3;

        return $this;
    }

    public function getDate3(): ?\DateTimeInterface
    {
        return $this->date_3;
    }

    public function setDate3(?\DateTimeInterface $date_3): self
    {
        $this->date_3 = $date_3;

        return $this;
    }

    public function getValue4(): ?float
    {
        return $this->value_4;
    }

    public function setValue4(float $value_4): self
    {
        $this->value_4 = $value_4;

        return $this;
    }

    public function getPresta4(): ?string
    {
        return $this->presta_4;
    }

    public function setPresta4(?string $presta_4): self
    {
        $this->presta_4 = $presta_4;

        return $this;
    }

    public function getDate4(): ?\DateTimeInterface
    {
        return $this->date_4;
    }

    public function setDate4(?\DateTimeInterface $date_4): self
    {
        $this->date_4 = $date_4;

        return $this;
    }

    public function getUser(): ?User
    {
        return $this->User;
    }

    public function setUser(?User $User): self
    {
        $this->User = $User;

        return $this;
    }

    public function getSubSubCategory(): ?LineSubSubCategory
    {
        return $this->subSubCategory;
    }

    public function setSubSubCategory(?LineSubSubCategory $subSubCategory): self
    {
        $this->subSubCategory = $subSubCategory;

        return $this;
    }
}

BudgetLineType表单


namespace App\Form;

use App\Entity\BudgetLine;
use Doctrine\DBAL\Types\FloatType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\DateType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;

class BudgetLineType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder

            ->add('value_1', TextType::class, array(
                'label' => false,
                'required' => false))
            ->add('presta_1', TextareaType::class, array(
                'label' => false,
                'required' => false))
            ->add('date_1', DateType::class, [
                'label' => false,
                'required' => false,
                'widget' => 'single_text'
            ])
            ->add('value_2', TextType::class, array(
                'label' => false,
                'required' => false))
            ->add('presta_2', TextareaType::class, array(
                'label' => false,
                'required' => false))
            ->add('date_2', DateType::class, [
                'label' => false,
                'required' => false,
                'widget' => 'single_text'
            ])
            ->add('value_3', TextType::class, array(
                'label' => false,
                'required' => false))
            ->add('presta_3', TextareaType::class, array(
                'label' => false,
                'required' => false))
            ->add('date_3', DateType::class, [
                'label' => false,
                'required' => false,
                'widget' => 'single_text'
            ])
            ->add('value_4', TextType::class, array(
                'label' => false,
                'required' => false))
            ->add('presta_4', TextareaType::class, array(
                'label' => false,
                'required' => false))
            ->add('date_4', DateType::class, [
                'label' => false,
                'required' => false,
                'widget' => 'single_text'
            ])
        ;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => BudgetLine::class,
        ]);
    }
}

收集BudgetLineType的表单

namespace App\Form;

use App\Entity\User;
use App\Entity\LineCategory;
use App\Form\BudgetLineType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;

class MakeUserTableType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {

        $builder->add('BudgetTable', CollectionType::class, [
            'entry_type' => BudgetLineType::class,
            'entry_options' => ['label' => false]]);

    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => User::class,
        ]);
    }
}

知道我在做什么错吗?

谢谢!

1 个答案:

答案 0 :(得分:0)

好吧,解决方案是将@Assert\Valid()放在用户的实体相关属性上,并在我的BudgetLineType字段上使用NumberType,以便类型验证将:

1)编辑用户时,从用户到预算行的级联

2)用类型约束封装数字验证