FORM 中的 SYMFONY 自定义约束,来自 `class ****validator extends ConstraintValidator` 的 `validate()`,未通过 buildForm() 实现触发
SYMFONY Custom Constraint in FORM, `validate()` from `class ****validator extends ConstraintValidator`, not triggered thru buildForm() implementation
我在使用 SYMFONY 中设计的自定义约束时遇到问题,我使它工作然后它停止工作,我想弄清楚我做错了什么。
关于这里的代码是我几天前发布的一个问题,其中包含关于我的自定义约束的完整代码:
我将复制导致这个新问题的代码部分。
我放了一些 dump()
来查看 class 扩展约束的 __construct()
函数中的工作原理:
/**
* @Annotation
*/
class CheckValueAlreadyInDB extends Constraint{
public $message;
public $fieldToSearch;
public $tableToSearch;
public $idToCheck;
public $idToCheckFieldName;
public function __construct($options){
dump($options);
if(count($options)>0){
$this->idToCheck = $options['idToCheck'];
$this->idToCheckFieldName = $options['idToCheckFieldName'];
$this->fieldToSearch = $options['fieldToSearch'];
$this->tableToSearch = $options['tableToSearch'];
$this->message = $options['message'];
}
}
public function validatedBy()
{
dump('validatedBy() starts');
return 'validator_check_value_already_in_db';
}
}
并且,ConstraintValidator 扩展 class 链接到它:
class CheckValueAlreadyInDBValidator extends ConstraintValidator
{
private $con;
public function __construct($con){
$this->con = $con;
}
public function validate($value, Constraint $constraint)
{
dump('validate starts');
////My stuff to get a record from the DB////
$sel = new PdoSelect($this->con);
$search = $sel->returnRecordsInTableForSpecificKey([$constraint->fieldToSearch],[$value], $constraint->tableToSearch,false);
//////////////////////////////////////////////
$sameId = false;
if($constraint->idToCheck!==null){
$idToCheckInRetrieveRecord = $search->{$constraint->idToCheckFieldName};
$sameId = ($idToCheckInRetrieveRecord==$constraint->idToCheck)?true:false;
}
if($search!=null&&!$sameId){
$this->context->buildViolation($constraint->message)
->setParameter('%string%', $value)
->addViolation();
}
}
}
并且在表单设计中:
class MyEntityType extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options)
{
....
$builder->add('myValue',****Type::class,array(
'constraints' => array(
new CheckValueAlreadyInDB(array(
'idToCheck'=>$options['data']->getId(),
'idToCheckFieldName'=>'id',
'fieldToSearch'=>'my_value',
'tableToSearch'=>'my_table',
'message' => "value_already_exists_in_db"))
)
));
...
}
}
当我提交表单时,它没有正确进行,因为它没有触发约束。我可以通过 SYMFONY _profiler 看到 class CheckValueAlreadyInDB 的 __construct()
中的 dump($options)
有效,但我没有看到 class CheckValueAlreadyInDB 中的 dump('validatedBy() starts')
class CheckValueAlreadyInDBValidator 中的 dump('validate starts')
也没有。
有谁知道我做错了什么或者有任何关于我应该调查哪里的提示吗?
有关代码的其他信息:
我的实体class:
class MyEntity{
/**
* @MyBundleAssert\CheckValueAlreadyInDB(
* message = "already_exists_in_db",
* fieldToSearch = "my_value",
* tableToSearch = "my_table"
*)
*/
private myValue;
}
还有我的服务:
validator.unique.check_value_already_in_db:
class: MyBundle\Form\CustomConstraints\CheckValueAlreadyInDBValidator
arguments: ['@doctrine.dbal.default_connection']
tags:
- { name: validator.constraint_validator, alias: validator_check_value_already_in_db }
我找到了解决方案。
我的错误是试图在 class MyEntityType extends AbstractType
中使用 constraints
:
$builder->add('myValue',****Type::class,array(
'constraints' => array(
new CheckValueAlreadyInDB(array(
'idToCheck'=>$options['data']->getId(),
'idToCheckFieldName'=>'id',
'fieldToSearch'=>'my_value',
'tableToSearch'=>'my_table',
'message' => "value_already_exists_in_db"))
)
));
不要在这里使用它
查看文档中的 class-constraint-validator 部分。
在实体的 class 之上实施 ConstraintValidator
扩展 class,验证器必须在其中执行其检查,而不是在实体的一个属性之上 class。这样就可以访问实体的其他属性并将其用作 ConstraintValidator
扩展 class.
中的条件
我在使用 SYMFONY 中设计的自定义约束时遇到问题,我使它工作然后它停止工作,我想弄清楚我做错了什么。
关于这里的代码是我几天前发布的一个问题,其中包含关于我的自定义约束的完整代码:
我将复制导致这个新问题的代码部分。
我放了一些 dump()
来查看 class 扩展约束的 __construct()
函数中的工作原理:
/**
* @Annotation
*/
class CheckValueAlreadyInDB extends Constraint{
public $message;
public $fieldToSearch;
public $tableToSearch;
public $idToCheck;
public $idToCheckFieldName;
public function __construct($options){
dump($options);
if(count($options)>0){
$this->idToCheck = $options['idToCheck'];
$this->idToCheckFieldName = $options['idToCheckFieldName'];
$this->fieldToSearch = $options['fieldToSearch'];
$this->tableToSearch = $options['tableToSearch'];
$this->message = $options['message'];
}
}
public function validatedBy()
{
dump('validatedBy() starts');
return 'validator_check_value_already_in_db';
}
}
并且,ConstraintValidator 扩展 class 链接到它:
class CheckValueAlreadyInDBValidator extends ConstraintValidator
{
private $con;
public function __construct($con){
$this->con = $con;
}
public function validate($value, Constraint $constraint)
{
dump('validate starts');
////My stuff to get a record from the DB////
$sel = new PdoSelect($this->con);
$search = $sel->returnRecordsInTableForSpecificKey([$constraint->fieldToSearch],[$value], $constraint->tableToSearch,false);
//////////////////////////////////////////////
$sameId = false;
if($constraint->idToCheck!==null){
$idToCheckInRetrieveRecord = $search->{$constraint->idToCheckFieldName};
$sameId = ($idToCheckInRetrieveRecord==$constraint->idToCheck)?true:false;
}
if($search!=null&&!$sameId){
$this->context->buildViolation($constraint->message)
->setParameter('%string%', $value)
->addViolation();
}
}
}
并且在表单设计中:
class MyEntityType extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options)
{
....
$builder->add('myValue',****Type::class,array(
'constraints' => array(
new CheckValueAlreadyInDB(array(
'idToCheck'=>$options['data']->getId(),
'idToCheckFieldName'=>'id',
'fieldToSearch'=>'my_value',
'tableToSearch'=>'my_table',
'message' => "value_already_exists_in_db"))
)
));
...
}
}
当我提交表单时,它没有正确进行,因为它没有触发约束。我可以通过 SYMFONY _profiler 看到 class CheckValueAlreadyInDB 的 __construct()
中的 dump($options)
有效,但我没有看到 class CheckValueAlreadyInDB 中的 dump('validatedBy() starts')
class CheckValueAlreadyInDBValidator 中的 dump('validate starts')
也没有。
有谁知道我做错了什么或者有任何关于我应该调查哪里的提示吗?
有关代码的其他信息:
我的实体class:
class MyEntity{
/**
* @MyBundleAssert\CheckValueAlreadyInDB(
* message = "already_exists_in_db",
* fieldToSearch = "my_value",
* tableToSearch = "my_table"
*)
*/
private myValue;
}
还有我的服务:
validator.unique.check_value_already_in_db:
class: MyBundle\Form\CustomConstraints\CheckValueAlreadyInDBValidator
arguments: ['@doctrine.dbal.default_connection']
tags:
- { name: validator.constraint_validator, alias: validator_check_value_already_in_db }
我找到了解决方案。
我的错误是试图在 class MyEntityType extends AbstractType
中使用 constraints
:
$builder->add('myValue',****Type::class,array(
'constraints' => array(
new CheckValueAlreadyInDB(array(
'idToCheck'=>$options['data']->getId(),
'idToCheckFieldName'=>'id',
'fieldToSearch'=>'my_value',
'tableToSearch'=>'my_table',
'message' => "value_already_exists_in_db"))
)
));
不要在这里使用它
查看文档中的 class-constraint-validator 部分。
在实体的 class 之上实施 ConstraintValidator
扩展 class,验证器必须在其中执行其检查,而不是在实体的一个属性之上 class。这样就可以访问实体的其他属性并将其用作 ConstraintValidator
扩展 class.