具有组的Valid约束的Symfony条件验证

如何解决具有组的Valid约束的Symfony条件验证

至少对于我来说,我遇到了非常奇怪的Symfony行为。 我有嵌套表格的表格类型。我仅在某些情况下需要验证此嵌套表单。

这就是为什么我将验证组添加到Valid()约束的原因。 如果我使用相同的组例如。 TextType,它按预期工作。如果我从Valid()中删除组,它也可以工作。因此,这意味着Valid()约束本身会起作用,而在使用验证组时它就不会起作用。

      $builder
               ->add('test',TextType::class,[
                    'mapped' => false,'constraints' => [new NotBlank(['groups' => 'SenderAddress'])],])
                ->add('senderAddress',AddressType::class,[
                    'label' => false,'constraints' => [new Valid(['groups' => 'SenderAddress'])],])
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'validation_groups' => function (FormInterface $form) {
                if (!$form->get('senderAddresses')->getData()) {
                    return ['Default','SenderAddress'];
                }
                return ['Default'];
            },]);
    }

因此,如果senderAddresses中没有任何内容,并且

  1. test 字段为空, test 字段已正确验证,并且使用NotBlank()暴力
  2. senderAddress不会显示任何暴力,即使字段为空?!

但是,当我尝试删除senderAddress的组验证时,它可以按预期工作。 我在做什么错了?

->add('senderAddress',[
   'label' => false,'constraints' => [new Valid()],//but this is not how I want it!
])

编辑: 这些是我处理的对象

CalculationType的实体订单

<?php

namespace App\Entity;

use App\Repository\OrderRepository;
use App\Traits\IdentifierTrait;
use DateTime;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * @ORM\Entity(repositoryClass=OrderRepository::class)
 * @ORM\Table(name="`order`")
 */
class Order
{
    use IdentifierTrait;

    public const STATUSES = [
        'order.statuses.calculation' => self::STATUS_CALCULATION,'order.statuses.created' => self::STATUS_CREATED,];

    public const STATUS_CALCULATION = 1;
    public const STATUS_CREATED = 2;

    /**
     * @ORM\ManyToOne(targetEntity="Address",cascade={"persist"})
     *
     * @var Address
     */
    private Address $senderAddress;

    /**
     * @ORM\ManyToOne(targetEntity="Address",cascade={"persist"})
     *
     * @var Address
     */
    private Address $recipientAddress;

    /**
     * @ORM\ManyToOne(targetEntity="Package",cascade={"persist"})
     * @Assert\Valid()
     *
     * @var Package
     */
    private Package $package;

    /**
     * @ORM\Column(type="datetime")
     *
     * @var DateTime
     */
    private DateTime $createdAt;

    /**
     * @ORM\Column(type="integer",length=1,options={"unsigned": true})
     *
     * @var int
     */
    protected int $status = self::STATUS_CALCULATION;

    /**
     * @ORM\Column(type="text",length=255,nullable=TRUE)
     *
     * @var null|string
     */
    private ?string $serviceType = null;

    /**
     * @ORM\ManyToOne(targetEntity=User::class)
     *
     * @var User
     */
    private User $user;

    /**
     * Order constructor.
     */
    public function __construct()
    {
        $this->createdAt = new DateTime('now');
    }

    /**
     * @return Address
     */
    public function getSenderAddress(): Address
    {
        return $this->senderAddress;
    }

    /**
     * @param Address $senderAddress
     */
    public function setSenderAddress(Address $senderAddress): void
    {
        $this->senderAddress = $senderAddress;
    }

    /**
     * @return Address
     */
    public function getRecipientAddress(): Address
    {
        return $this->recipientAddress;
    }

    /**
     * @param Address $recipientAddress
     */
    public function setRecipientAddress(Address $recipientAddress): void
    {
        $this->recipientAddress = $recipientAddress;
    }

    /**
     * @return Package
     */
    public function getPackage(): Package
    {
        return $this->package;
    }

    /**
     * @param Package $package
     */
    public function setPackage(Package $package): void
    {
        $this->package = $package;
    }

    /**
     * @return string|null
     */
    public function getServiceType(): ?string
    {
        return $this->serviceType;
    }

    /**
     * @param string|null $serviceType
     */
    public function setServiceType(?string $serviceType): void
    {
        $this->serviceType = $serviceType;
    }

    /**
     * @return DateTime
     */
    public function getCreatedAt(): DateTime
    {
        return $this->createdAt;
    }

    /**
     * @param DateTime $createdAt
     */
    public function setCreatedAt(DateTime $createdAt): void
    {
        $this->createdAt = $createdAt;
    }

    /**
     * @return int
     */
    public function getStatus(): int
    {
        return $this->status;
    }

    /**
     * @param int $status
     */
    public function setStatus(int $status): void
    {
        $this->status = $status;
    }

    /**
     * @return User
     */
    public function getUser(): User
    {
        return $this->user;
    }

    /**
     * @param User $user
     */
    public function setUser(User $user): void
    {
        $this->user = $user;
    }
}

AddressType的实体地址

<?php

namespace App\Entity;

use App\Repository\AddressRepository;
use App\Traits\IdentifierTrait;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Intl\Countries;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * @ORM\Entity(repositoryClass=AddressRepository::class)
 */
class Address
{
    use IdentifierTrait;

    public const TYPES = [
        'address.types.sender' => self::TYPE_SENDER,'address.types.recipient' => self::TYPE_RECIPIENT,];

    public const TYPE_SENDER = 1;
    public const TYPE_RECIPIENT = 2;

    /**
     * @ORM\ManyToOne(targetEntity=User::class,inversedBy="addresses")
     *
     * @var User|null
     */
    private ?User $user;

    /**
     * @ORM\Column(type="string",length=100,nullable=true)
     * @Assert\Length(
     *     max="100"
     * )
     *
     * @var string|null
     */
    private ?string $name = null;

    /**
     * @ORM\Column(type="string",length=150)
     * @Assert\NotBlank()
     * @Assert\Length(
     *     max="150"
     * )
     *
     * @var string|null
     */
    private ?string $street = null;

    /**
     * @ORM\Column(type="string",length=100)
     * @Assert\NotBlank()
     * @Assert\Length(
     *     max="100"
     * )
     *
     * @var string|null
     */
    private ?string $city = null;

    /**
     * @ORM\Column(type="string",length=15)
     * @Assert\NotBlank()
     * @Assert\Length(
     *     max="15"
     * )
     *
     * @var string|null
     */
    private ?string $postalCode = null;

    /**
     * @ORM\Column(type="string",length=3)
     * @Assert\NotBlank()
     * @Assert\Length(
     *     max="3"
     * )
     *
     * @var string|null
     */
    private ?string $country = null;

    /**
     * @ORM\Column(type="string",length=3,nullable=true)
     *
     * @var string|null
     */
    private ?string $province = null;

    /**
     * @ORM\Column(type="integer",options={"unsigned": true})
     *
     * @var int
     */
    protected int $type = self::TYPE_SENDER;

    /**
     * Address constructor.
     *
     * @param int $type
     * @param User|null $user
     */
    public function __construct(int $type = self::TYPE_SENDER,User $user = null)
    {
        $this->type = $type;
        $this->user = $user;
    }

    /**
     * @return User|null
     */
    public function getUser(): ?User
    {
        return $this->user;
    }

    /**
     * @param User|null $user
     */
    public function setUser(?User $user): void
    {
        $this->user = $user;
    }

    /**
     * @return string|null
     */
    public function getName(): ?string
    {
        return $this->name;
    }

    /**
     * @param string|null $name
     */
    public function setName(?string $name): void
    {
        $this->name = $name;
    }

    /**
     * @return string|null
     */
    public function getStreet(): ?string
    {
        return $this->street;
    }

    /**
     * @param string|null $street
     */
    public function setStreet(?string $street): void
    {
        $this->street = $street;
    }

    /**
     * @return string|null
     */
    public function getCity(): ?string
    {
        return $this->city;
    }

    /**
     * @param string|null $city
     */
    public function setCity(?string $city): void
    {
        $this->city = $city;
    }

    /**
     * @return string|null
     */
    public function getPostalCode(): ?string
    {
        return $this->postalCode;
    }

    /**
     * @param string|null $postalCode
     */
    public function setPostalCode(?string $postalCode): void
    {
        $this->postalCode = $postalCode;
    }

    /**
     * @return string|null
     */
    public function getCountry(): ?string
    {
        return $this->country;
    }

    /**
     * @param string|null $country
     */
    public function setCountry(?string $country): void
    {
        $this->country = $country;
    }

    /**
     * Get country name
     */
    public function getCountryName(): string
    {
        return Countries::getName($this->country);
    }

    /**
     * @return string|null
     */
    public function getProvince(): ?string
    {
        return $this->province;
    }

    /**
     * @param string|null $province
     */
    public function setProvince(?string $province): void
    {
        $this->province = $province;
    }

    /**
     * Get full description
     *
     * @return string
     */
    public function getFullDescription(): string
    {
        return ($this->name ? ($this->name . ' - ') : '') . $this->street . ',' . $this->postalCode . ' ' . $this->city . ',' . $this->getCountryName();
    }

    /**
     * @return int
     */
    public function getType(): int
    {
        return $this->type;
    }

    /**
     * @param int $type
     */
    public function setType(int $type): void
    {
        $this->type = $type;
    }

}

CalculationType

<?php

namespace App\Form;

use App\Entity\Address;
use App\Entity\User;
use Doctrine\ORM\EntityRepository;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Validator\Constraints\Valid;

class CalculationType extends AbstractType
{

    /**
     * @var UserInterface|User|null
     */
    private ?UserInterface $user;

    /**
     * CalculationFormType constructor.
     *
     * @param Security $security
     */
    public function __construct(Security $security)
    {
        $this->user = $security->getUser();
    }

    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     *
     */
    public function buildForm(FormBuilderInterface $builder,array $options): void
    {
        $builder
            ->add('senderAddress',[
                'label' => false,'constraints' => [new Valid(['groups' => 'NotNullAddress'])],//todo doesnt work
            ])
            ->add('recipientAddress',//todo doesnt work
                'show_name' => false,])
            ->add('package',PackageType::class,['label' => false])
            ->add('calculate',SubmitType::class,[
                'label' => 'order.calculate',]);

        $this->addressesField($builder,'senderAddresses',Address::TYPE_SENDER);
        $this->addressesField($builder,'recipientAddresses',Address::TYPE_RECIPIENT);

    }

    /**
     * @param OptionsResolver $resolver
     */
    public function configureOptions(OptionsResolver $resolver): void
    {
        $resolver->setDefaults([
            'validation_groups' => static function (FormInterface $form) {
                if (!$form->get('senderAddresses')->getData()) {
                    return ['Default','NotNullAddress'];
                }
                return ['Default'];
            },]);
    }

    /**
     * Addresses field
     *
     * @param FormBuilderInterface $builder
     * @param string $childName
     * @param int $type
     */
    private function addressesField(FormBuilderInterface $builder,string $childName,int $type): void
    {
        $builder->add($childName,EntityType::class,[
            'class' => Address::class,'mapped' => false,'required' => false,'placeholder' => 'order.newAddress','choice_label' => 'fullDescription','query_builder' => function (EntityRepository $er) use ($type) {
                return $er->createQueryBuilder('address')
                    ->andWhere('address.user = :user')
                    ->andWhere('address.type = ' . $type)
                    ->setParameter('user',$this->user);
            },'attr' => [
                'class' => 'select-existing-address',],]);
    }
}

AddressType

<?php

namespace App\Form;

use App\Entity\Address;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\CountryType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class AddressType extends AbstractType
{
    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     *
     * @throws \JsonException
     */
    public function buildForm(FormBuilderInterface $builder,array $options): void
    {
        if ($options['show_name']) {
            $builder->add('name');
        }

        $builder->add('street')
            ->add('city')
            ->add('postalCode')
            ->add('country',CountryType::class,[
                'preferred_choices' => ['CZ','DE','IT','SK'],])
            ->add('province');
    }

    /**
     * @param OptionsResolver $resolver
     */
    public function configureOptions(OptionsResolver $resolver): void
    {
        $resolver->setDefaults([
            'data_class' => Address::class,'show_name' => true,]);
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-