根据@dragoste 在 cmets 中所说的,我搜索了如何使用自己的约束来实现。
解决方案是使用Custom Constraint。知道要做什么文件和做什么有点混乱,所以这是我所做的。
为了向您解释我的文件是什么,我们的目标是验证租金,而不是根据租金的制作方式,而只是检查同一时刻是否没有租金。这就是为什么我必须使用包含 Doctrine 的约束。
在包的根目录中创建 Validator 文件夹。然后,在 Validator 文件夹中添加一个 Constraints 文件夹。
在 Validaor/Constraints 文件夹中创建文件 RentDatesConstraint.php。
这是它的外观:
<?php
namespace ApiBundle\Validator\Constraints;
use ApiBundle\Validator\RentDatesValidator;
use Symfony\Component\Validator\Constraint;
class RentDatesConstraint extends Constraint
{
public $message = 'The beginning and ending date of the rent are not available for this vehicle.'; // note that you could use parameters inside it, by naming it with % to surround it
/**
* @inheritdoc
*/
public function validatedBy()
{
return RentDatesValidator::class; // this is the name of the class that will be triggered when you need to validate this constraint
}
/**
* @inheritdoc
*/
public function getTargets()
{
return self::CLASS_CONSTRAINT; // says that this constraints is a class constraint
}
}
现在您已经创建了自己的类约束,您必须创建自己的验证器。
在Validator文件夹中创建一个文件RentDatesValidator.php。
<?php
namespace ApiBundle\Validator;
use Doctrine\Bundle\DoctrineBundle\Registry;
use Doctrine\Common\Collections\Collection;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
class RentDatesValidator extends ConstraintValidator
{
/**
* @var Registry $doctrine
*/
private $doctrine;
/**
* RentDatesValidator constructor.
* @param Registry $_doctrine
*/
public function __construct(Registry $_doctrine)
{
$this
->setDoctrine($_doctrine)
;
}
/**
* @param Registry $_doctrine
* @return $this
*/
public function setDoctrine(Registry $_doctrine)
{
$this->doctrine = $_doctrine;
return $this;
}
/**
* @inheritdoc
* @param Rent $_value
*/
public function validate($_value, Constraint $_constraint)
{
//do your stuff here
if ($testFails) {
$this
->context
->buildViolation($_constraint->message) // here you can pass an array to set the parameters of the string, surrounded by %
->addViolation()
;
}
}
}
我们快完成了,我们必须将它声明为服务,所以这里我们在 Resources/config
中编辑
services.yml
services:
# [...]
validator.rent_dates:
class: ApiBundle\Validator\RentDatesValidator
tags:
- { name: validator.constraint_validator }
arguments: [ "@doctrine" ]
你可以注意到我在这里传递了 @doctrine 服务,但实际上你可以传递任何你想要的服务,甚至很多,只要你定义了 RentDatesValidator 类正确地在其构造函数中接受这些服务。
现在,您所要做的就是在您的验证中使用它。
这里我们编辑 Resource/config/validation 中的 Rent.yml 以添加仅这一行:
ApiBundle\Entity\Rent:
constraints:
- ApiBundle\Validator\Constraints\RentDatesConstraint: ~
我们完成了!将您的对象传递给验证器服务时,验证将起作用。
您可以注意到这是使用 YAML 制作的,我个人更喜欢这种做事方式,因为它分隔了各个部分(实体定义、数据库架构、验证文件……),但您可以使用注释、XML 来做到这一点甚至是纯 PHP。这取决于您,因此如果您想查看更多语法,您仍然可以访问 Symfony 文档的链接以了解如何执行此操作。