我对仅为一个关联实体应用验证有一些困难。
所以我有两个实体News
和NewsTranslation
。新闻可以用多种语言翻译。但我想仅在语言环境为en
时才应用验证。
// AppBundle/Entity/News.php
class News
{
use ORMBehaviors\Translatable\Translatable;
use ORMBehaviors\Timestampable\Timestampable;
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var int
*
* @ORM\Column(name="status", type="smallint")
* @Assert\NotBlank
*/
private $status;
...
}
// AppBundle/Entity/NewsTranslation.php
class NewsTranslation
{
use ORMBehaviors\Translatable\Translation;
/**
* @var string
*
* @ORM\Column(name="title", type="string", length=255, nullable=true)
* @Assert\NotBlank
* @Assert\Length(max = 255)
*/
private $title;
/**
* @var string
*
* @ORM\Column(name="text", type="string", nullable=true)
* @Assert\NotBlank
*/
private $text;
}
# AppBundle/Resources/config/validation.yml
AppBundle\Entity\News:
properties:
translations:
- Valid: ~
我尝试将Closure
用于validation_groups
表单选项。但看起来Symfony对News
实体进行了验证,Valid
约束在NewsTranslation
上应用相同的组。
我知道我可以使用Callback
约束,但这意味着我自己重做NotBlank
,Length
和其他现有约束。如果可能的话我想避免它。
修改
我正在使用Symfony 2.8。*
我尝试使用en
验证组。但看起来验证是在News
实体上使用validation_groups
启动的。通过Valid
约束,en
验证组将用于验证NewsTranlation
。因此,即使是en或fr翻译,在这种情况下,小组也不会改变任何内容。
我也尝试使用validation medatada到@Assert\Callback
或使用loadValidatorMetadata
方法进入NewsTranslation
实体。问题保持不变。我无法对特定的集合实体应用约束。
答案 0 :(得分:2)
我终于通过创建自定义验证器找到了一种方法。 像这样我可以轻松使用核心约束。
在翻译实体中,我可以使用我的验证器:
/**
* @var string
*
* @ORM\Column(name="title", type="string", length=255, nullable=true)
* @Assert\Length(max = 255)
* @AppAssert\ValidTranslation(locales = {"fr"}, constraints = {
* @Assert\NotBlank
* })
*/
private $title;
验证员:
<?php
namespace AppBundle\Validator\Constraints;
use Symfony\Component\Validator\Constraints\Composite;
/**
* @Annotation
* @Target({"PROPERTY", "METHOD", "ANNOTATION"})
*
* @author Nicolas Brousse
*/
class ValidTranslation extends Composite
{
public $locales = array();
public $constraints = array();
public function getCompositeOption()
{
return 'constraints';
}
public function getRequiredOptions()
{
return array('locales', 'constraints');
}
}
<?php
namespace AppBundle\Validator\Constraints;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
/**
* @author Nicolas Brousse
*/
class ValidTranslationValidator extends ConstraintValidator
{
/**
* If property constraint
* {@inheritdoc}
*/
public function validate($value, Constraint $constraint)
{
if (!$constraint instanceof ValidTranslation) {
throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\ValidTranslation');
}
if (false) { // @todo check by interface or trait
throw new UnexpectedTypeException($value, 'not a translation entity');
}
$context = $this->context;
$entity = $this->context->getObject();
if (in_array($entity->getLocale(), $constraint->locales)) {
$context = $this->context;
if ($context instanceof ExecutionContextInterface) {
$validator = $context->getValidator()->inContext($context);
$validator->validate($value, $constraint->constraints);
} else {
// 2.4 API
$context->validateValue($value, $constraint->constraints);
}
}
}
}
答案 1 :(得分:0)
你需要返回2个validations_groups,&#34;默认&#34;和对应于&#34; en&#34;的验证组。区域设置