我有以下实体(仅附上相关部分):
use ApiPlatform\Core\Annotation\ApiResource;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* @ApiResource(mercure=true)
* @ORM\Entity(repositoryClass="App\Repository\EventRepository")
*/
class Event {
/**
* @ORM\Column(type="datetime")
* @Assert\DateTime
* @Assert\NotNull
*/
private $createdAt;
public function __construct() {
$this->createdAt = new \DateTime();
}
public function getCreatedAt(): ?\DateTimeInterface {
return $this->createdAt;
}
public function setCreatedAt(\DateTimeInterface $createdAt): self {
$this->createdAt = $createdAt;
return $this;
}
}
Run Code Online (Sandbox Code Playgroud)
它的存储库:
class EventRepository extends ServiceEntityRepository {
public function __construct(ManagerRegistry $registry) {
parent::__construct($registry, Event::class);
}
}
Run Code Online (Sandbox Code Playgroud)
向事件端点(通过 Postman 或 Swagger UI)创建 …
所以这是场景:我有一个单选按钮组.基于它们的价值,我应该或不应该验证其他三个字段(它们是空白的,它们是否包含数字等).
我可以以某种方式将所有这些值传递给约束,并在那里进行比较吗?
或者直接在控制器中回调是解决此问题的更好方法?
一般来说,这种情况下的最佳做法是什么?
鉴于此输入:
[
'key' => 'value',
]
Run Code Online (Sandbox Code Playgroud)
如何验证以确保:
key 属性存在我希望这个约束能够起作用
$constraint = new Collection([
'key' => new Required([
new Type('array'),
new Collection([
'value' => new Required([
new NotBlank(),
]),
]),
]),
]);
Run Code Online (Sandbox Code Playgroud)
但它引发了一个例外:
Symfony\Component\Validator\Exception\UnexpectedTypeException: Expected argument of type "array or Traversable and ArrayAccess", "string" given
Run Code Online (Sandbox Code Playgroud)
我错过了什么?
PS:这是symfony v2.7.1
PPS:只是为了澄清:我知道可以使用回调.如果我想从头开始手动重新实现验证 - 我不会在第一时间使用symfony.所以问题特别是关于组合现有约束而不是关于使用回调约束.
我有一个包含许多字段和验证组的表单,这些字段也包含一些视图数据转换器.
我需要部分抑制验证表单(基于提交的数据的组):
use AppBundle\Entity\Client;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
// ...
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'validation_groups' => function (FormInterface $form) {
$data = $form->getData();
if (Client::TYPE_PERSON == $data->getType()) {
return array('person');
}
return array('company');
},
));
}
Run Code Online (Sandbox Code Playgroud)
当您这样做时,表单仍将运行基本完整性检查(禁用验证)和来自变换器的验证错误,它们将被抛出(创建变换器).
使用POST_SUBMIT事件,并防止ValidationListener被称为(抑制表单验证):
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormEvent;
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->addEventListener(FormEvents::POST_SUBMIT, function (FormEvent $event) {
$event->stopPropagation();
}, 900); // Always set a higher priority than …Run Code Online (Sandbox Code Playgroud) 这个想法是首先验证是否所有必填字段都不为空。如果提供了所有必需的数据,则验证输入的值是否正确。组序列的通常情况。无论如何,即使所有字段均为空白,当我申请new GroupSequence(["Basic", "Strict"])该validation_groups选项时,该表格仍然有效。如果将validation_groups值设置为["Basic", "Strict"]表单,则可以正确验证但具有所有约束,这不是我想要的。我究竟做错了什么?
这是我的代码:
class MyType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add("name", null, [
"constraints" => new NotBlank(["groups" => ["Basic"]])
])
->add("phone", MyPhoneType::class, [
"constraints" => [
new NotBlank(["groups" => ["Basic"]]),
new PhoneNumber(["groups" => ["Strict"])
]
])
->add("email", EmailType::class, [
"constraints" => [
new NotBlank(["groups" => ["Basic"]]),
new Email(["groups" => ["Strict"]]),
],
])
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
"validation_groups" => new GroupSequence(["Basic", …Run Code Online (Sandbox Code Playgroud) 编辑:这是一个带有完整代码的github来重现问题
我有以下实体
class Place
{
use Traits\HasId;
/**
* Used for form.
*
* @Assert\Image(
* mimeTypes = {"image/png", "image/jpeg"},
* minWidth = 50,
* maxWidth = 1000,
* minHeight = 50,
* maxHeight = 1000,
* maxSize = "1M"
* )
*/
private $imageFile = null;
/**
* @ORM\OneToOne(targetEntity="MyImage", orphanRemoval=true, cascade={"persist"})
*/
protected $image;
}
Run Code Online (Sandbox Code Playgroud)
使用以下表格
class AdminPlaceType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$transformer = new HasImageTransformer();
$builder->add('imageFile')->addModelTransformer($transformer);
}
public function configureOptions(OptionsResolver …Run Code Online (Sandbox Code Playgroud) 我在请求中有一个字段,可以是电子邮件或电话。现在我需要根据两个约束来验证它 - 标准电子邮件约束和自定义电话。我知道我可以传递一系列约束链接:
$constraint = new Constraints\Collection([
'name' => new Constraints\NotBlank(),
'uid' => [new Constraints\Email(), new Constraints\Phone()],
'pass' => new Constraints\NotBlank()
]);
Run Code Online (Sandbox Code Playgroud)
但是 Validator 将 AND 逻辑应用于约束数组,我需要 OR 以便如果该值适合其中之一,则验证成功。任何标准的 Symfony 手段都可以做到这一点吗?
我有一个相当简单的实体UniqueEntity验证:
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\UserInterface;
use Doctrine\ORM\Mapping\ManyToOne;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Doctrine\ORM\Mapping\HasLifecycleCallbacks;
/**
* @ORM\Entity(repositoryClass="App\Repository\UserRepository")
* @UniqueEntity("email", message="Email already in use")
*
*
*/
class User implements UserInterface
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="string", length=180, unique=true)
*/
private $email;
Run Code Online (Sandbox Code Playgroud)
表单(故意删除所有其他表单字段)
namespace App\Form;
use App\Entity\Company;
use App\Entity\User;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\CallbackTransformer;
use Symfony\Component\Form\ChoiceList\Loader\CallbackChoiceLoader;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use …Run Code Online (Sandbox Code Playgroud) 我有一个包含以下字段的表单:
$builder
->add('title', 'text')
->add('body', 'textarea')
->add('tags', 'entity', [
'class' => 'AppBundle\Entity\Tag',
'choice_label' => 'name',
'expanded' => false,
'multiple' => true,
]);
Run Code Online (Sandbox Code Playgroud)
用户可以选择多个标签.一切都很完美.但是现在当标签的数量变得非常大(超过20000个标签)时,页面呈现变得非常慢,因为实体类型将所有标签加载到选择框中.因此,我实现了一个jQuery自动完成选择框以防止加载所有实体,但是当我提交表单时,验证器仍会加载所有标签以进行验证!如何解决此验证问题?谢谢!
所以我不确定这里的问题是什么,或者这个类是如何加载的。但我的模型(或者他们实际所说的实体)看起来像这样:
<?php
namespace ImageUploader\Models;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
/**
* @ORM\Entity
* @ORM\Table(name="users")
* @UniqueEntity(fields="userName")
* @UniqueEntity(fields="email")
*/
class User {
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue
*/
protected $id;
/**
* @ORM\Column(type="string", length=32, nullable=false)
* @Assert\NotBlank()
*/
protected $firstName;
/**
* @ORM\Column(type="string", length=32, nullable=false)
* @Assert\NotBlank()
*/
protected $lastName;
/**
* @ORM\Column(type="string", length=100, unique=true, nullable=false)
* @Assert\NotBlank(
* message = "Username cannot be blank"
* )
*/
protected $userName;
/**
* @ORM\Column(type="string", …Run Code Online (Sandbox Code Playgroud) php ×10
symfony ×9
doctrine-orm ×2
jquery ×1
symfony-2.8 ×1
symfony4 ×1
symfony5 ×1
validation ×1