使用自定义验证约束检查数据库中是否存在条目
Check if entry exists in database with custom validation constraint
所以在我的 Symfony 应用程序中,我有一个名为 Post
的实体。
我的 Post 实体具有以下属性:
post_start
、post_end
等等。
实体:
/**
* @ORM\Entity
* @ORM\Table(name="post")
*/
class Post
{
/**
* @var int
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
* @ORM\Column(type="integer")
*/
private $id;
/**
* @var DateType
* @ORM\Column(type="date")
*/
private $post_start;
/**
* @var DateType
* @ORM\Column(type="date")
* @Assert\GreaterThanOrEqual(propertyPath="post_start")
*/
private $post_end;
.....
}
格式类型:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add(
'post_start',
DateType::class,
[
'widget' => 'single_text',
'format' => 'dd.MM.yyyy',
'required' => true,
'attr' => [
'class' => 'form-control input-inline datepicker',
'data-provide' => 'datepicker',
'data-date-format' => 'dd.mm.yyyy',
]
]
);
$builder->add(
'post_end',
DateType::class,
[
'widget' => 'single_text',
'format' => 'dd.MM.yyyy',
'required' => true,
'attr' => [
'class' => 'form-control input-inline datepicker',
'data-provide' => 'datepicker',
'data-date-format' => 'dd.mm.yyyy'
]
]
);
$builder->add('submit', SubmitType::class, [
'label' => 'save post',
'attr' => array('class' => 'btn btn-success')
]);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Post::class
]);
}
当我提交表单时,我想检查数据库是否已经有一个条目具有相同的开始日期和结束日期,并且当然来自同一用户。
1. If YES -> Show error message
2. If NO -> Create post request.
当条目已经存在,但它来自不同的用户时,继续创建 post。
我想用自定义验证器约束来做到这一点。但是接下来会发生什么我必须以某种方式将数据相互比较
ContainsEqualDate:
/**
* @Annotation
*/
class ContainsEqualDate extends Constraint
{
public $message = 'Post request is already exists.';
public function getTargets()
{
return self::CLASS_CONSTRAINT;
}
}
ContainsEqualDateValidator:
class ContainsEqualDateValidator extends ConstraintValidator
{
/**
* @var ORMUserRepository
*/
private $userRepository;
/**
* @var ORMPostRepository
*/
private $postRepository;
/**
* @param ORMUserRepository $userRepository
* @param ORMPostRepository $postRepository
*/
public function __construct(ORMUserRepository $userRepository, ORMPostRepository $postRepository)
{
$this->userRepository = $userRepository;
$this->postRepository = $postRepository;
}
/**
* Checks if the passed value is valid.
*
* @param mixed $value The value that should be validated
* @param Constraint $constraint The constraint for the validation
*/
public function validate($value, Constraint $constraint)
{
$userId = $this->getUser();
$postExists = $this->postRepository->findBy(array(
'post_start' => $value,
'app_user_id' => $userId
));
}
/**
* @return User
*/
private function getUser(): User
{
return $this->storage->getToken()->getUser();
}
}
}
@Max Trui,你没有提到用户和 Post 实体在你的数据库中是如何相关的。
如果您在 Post 实体中有 UserId,则可以执行以下操作。
$userId = $this->userRepository->getUser()->getId();
$entryExists = ($this->postRepository->findBy(array('post_start' => $value, 'user_id' => $userId)) == null) ? true : false;
您可以将 'post_start' 替换为动态字段名称值(post_start 或 post_end),您可以从调用验证程序的地方提供该值。
如果您想同时检查两个日期,请在验证器中提供两个值。
所以在我的 Symfony 应用程序中,我有一个名为 Post
的实体。
我的 Post 实体具有以下属性:
post_start
、post_end
等等。
实体:
/**
* @ORM\Entity
* @ORM\Table(name="post")
*/
class Post
{
/**
* @var int
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
* @ORM\Column(type="integer")
*/
private $id;
/**
* @var DateType
* @ORM\Column(type="date")
*/
private $post_start;
/**
* @var DateType
* @ORM\Column(type="date")
* @Assert\GreaterThanOrEqual(propertyPath="post_start")
*/
private $post_end;
.....
}
格式类型:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add(
'post_start',
DateType::class,
[
'widget' => 'single_text',
'format' => 'dd.MM.yyyy',
'required' => true,
'attr' => [
'class' => 'form-control input-inline datepicker',
'data-provide' => 'datepicker',
'data-date-format' => 'dd.mm.yyyy',
]
]
);
$builder->add(
'post_end',
DateType::class,
[
'widget' => 'single_text',
'format' => 'dd.MM.yyyy',
'required' => true,
'attr' => [
'class' => 'form-control input-inline datepicker',
'data-provide' => 'datepicker',
'data-date-format' => 'dd.mm.yyyy'
]
]
);
$builder->add('submit', SubmitType::class, [
'label' => 'save post',
'attr' => array('class' => 'btn btn-success')
]);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Post::class
]);
}
当我提交表单时,我想检查数据库是否已经有一个条目具有相同的开始日期和结束日期,并且当然来自同一用户。
1. If YES -> Show error message
2. If NO -> Create post request.
当条目已经存在,但它来自不同的用户时,继续创建 post。
我想用自定义验证器约束来做到这一点。但是接下来会发生什么我必须以某种方式将数据相互比较
ContainsEqualDate:
/**
* @Annotation
*/
class ContainsEqualDate extends Constraint
{
public $message = 'Post request is already exists.';
public function getTargets()
{
return self::CLASS_CONSTRAINT;
}
}
ContainsEqualDateValidator:
class ContainsEqualDateValidator extends ConstraintValidator
{
/**
* @var ORMUserRepository
*/
private $userRepository;
/**
* @var ORMPostRepository
*/
private $postRepository;
/**
* @param ORMUserRepository $userRepository
* @param ORMPostRepository $postRepository
*/
public function __construct(ORMUserRepository $userRepository, ORMPostRepository $postRepository)
{
$this->userRepository = $userRepository;
$this->postRepository = $postRepository;
}
/**
* Checks if the passed value is valid.
*
* @param mixed $value The value that should be validated
* @param Constraint $constraint The constraint for the validation
*/
public function validate($value, Constraint $constraint)
{
$userId = $this->getUser();
$postExists = $this->postRepository->findBy(array(
'post_start' => $value,
'app_user_id' => $userId
));
}
/**
* @return User
*/
private function getUser(): User
{
return $this->storage->getToken()->getUser();
}
}
}
@Max Trui,你没有提到用户和 Post 实体在你的数据库中是如何相关的。
如果您在 Post 实体中有 UserId,则可以执行以下操作。
$userId = $this->userRepository->getUser()->getId();
$entryExists = ($this->postRepository->findBy(array('post_start' => $value, 'user_id' => $userId)) == null) ? true : false;
您可以将 'post_start' 替换为动态字段名称值(post_start 或 post_end),您可以从调用验证程序的地方提供该值。
如果您想同时检查两个日期,请在验证器中提供两个值。