我有一些实体,但我想验证数据库中最多 X 个条目。例如,数据库中允许的类别不超过 5 个。我尝试查看某些约束验证是否解决了我的麻烦,但我没有发现任何有用的东西。提前致谢
如果需要在多个位置验证实体或对多个实体类执行此类验证,则可以编写自定义验证约束来执行此操作。这确实感觉有点矫枉过正,但从技术上讲,这是"正确"的解决方案。这记录在如何创建自定义验证约束的Symfony手册中。例如:
约束类:
<?php
namespace YourBundleValidatorConstraints;
use SymfonyComponentValidatorConstraint;
class MaxEntries extends Constraint
{
public $message = 'The maximum %max% %name% entries already exist.';
public $max = 5;
public function validatedBy()
{
return 'maxEntries';
}
public function getTargets()
{
return self::CLASS_CONSTRAINT;
}
}
约束验证器类:
<?php
namespace YourBundleValidatorConstraints;
use DoctrineORMEntityManager;
use SymfonyComponentValidatorConstraint;
use SymfonyComponentValidatorConstraintValidator;
class MaxEntriesValidator extends ConstraintValidator
{
private $entityManager;
public function __construct(EntityManager $entityManager)
{
$this->entityManager = $entityManager;
}
public function validate($protocol, Constraint $constraint)
{
/** @var MaxEntries $constraint */
$protocolClass = new ReflectionClass(get_class($protocol));
$entityName = $protocolClass->getShortName();
// alternative to next 2 lines - you could use dql to do a select count
$repository = $this->entityManager->getRepository('YourBundle:' . $entityName);
$entities = $repository->findAll();
if (count($entities) == $constraint->max)
{
$this->context->addViolation($constraint->message, array(
'%max%' => $constraint->max,
'%name%' => $entityName,
));
}
}
}
服务.yml:
validator.max_entries:
class: BullittTargetNeutralSpectatorBundleValidatorConstraintsMaxEntriesValidator
arguments: [@doctrine.orm.entity_manager]
tags:
- { name: validator.constraint_validator, alias: maxEntries }
验证.yml:
YourBundleYourEntity:
constraints:
- YourBundleValidatorConstraintsMaxEntries:
# You can override the default constraint attributes here
message: "Failed! The maximum %max% %name% entries already exist."
max: 42
请注意,您也许能够想出一个比MaxEntrys更好的名称(我通常会花更多时间思考最有意义的名称)。此外,验证器类当前不包含将其应用于非教义实体的类的保护。
您可能必须自己实现它。 我还没有见过这样的事情,但自己做一个并不难。 只需添加一个函数来检查数据库中有多少条目,并在插入任何内容之前调用此函数。
可以做这样的事情:
public function newAction(){
$isAllowed = $this->checkMaxRecords();
if($isAllowed){
//save to the database
}
}
private function checkMaxRecords(){
$em = $this->getDoctrine()->getManager();
$query = $em->createQuery(
'SELECT c
FROM AcmeStoreBundle:Category c'
);
$category = $query->getResult();
if(count($category) >= 5){
return false;
}
return true;
}
这是未经测试的代码,但类似这些内容应该可以让您走上正确的轨道。