在 symfony2 中的自定义验证器中访问 EntityManager
您可以在控制器操作中检查以前的值...但这不会是一个干净的解决方案!
正常的表单验证将仅访问绑定到表单的数据...默认情况下无法访问“以前”的数据。
您尝试使用的回调约束无权访问容器或任何其他服务...因此,您无法轻松访问实体管理器(或任何以前的数据提供程序)来检查以前的值。
您需要的是类级别的自定义验证程序。需要类级,因为如果要获取实体,则需要访问整个对象而不仅仅是单个值。
验证程序本身可能如下所示:
namespace Vendor\YourBundle\Validation\Constraints;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
class StatusValidator extends ConstraintValidator
{
protected $container;
public function __construct(ContainerInterface $container)
{
$this->container = $container;
}
public function validate($status, Constraint $constraint)
{
$em = $this->container->get('doctrine')->getEntityManager('default');
$previousStatus = $em->getRepository('YourBundle:Status')->findOneBy(array('id' => $status->getId()));
// ... do something with the previous status here
if ( $previousStatus->getValue() != $status->getValue() ) {
$this->context->addViolationAt('whatever', $constraint->message, array(), null);
}
}
public function getTargets()
{
return self::CLASS_CONSTRAINT;
}
public function validatedBy()
{
return 'previous_value';
}
}
...然后将验证器注册为服务并将其标记为验证器
services:
validator.previous_value:
class: Vendor\YourBundle\Validation\Constraints\StatusValidator
# example! better inject only the services you need ...
# i.e. ... @doctrine.orm.entity_manager
arguments: [ @service_container ]
tags:
- { name: validator.constraint_validator, alias: previous_value }
最后使用状态实体的约束(即使用注释)
use Vendor\YourBundle\Validation\Constraints as MyValidation;
/**
* @MyValidation\StatusValidator
*/
class Status
{