Symfony2:实体声明接受一系列类型?

Vit*_*lyP 5 validation annotations symfony

我有一个实体与$ $公司.该字段必须存储一组Company对象.所以我用这种方式描述断言:

@Assert\Type("Acme\MyBundle\Entity\Company")
Run Code Online (Sandbox Code Playgroud)

但它总是无效的,因为从我的表格我得到的公司阵列,但这个断言希望它不是阵列而只是一个公司.

那么如何克服这个呢?我想它必须是这样的:

@Assert\Array(Type("Acme\MyBundle\Entity\Company"))
Run Code Online (Sandbox Code Playgroud)

Jea*_*ean 13

由于这个问题被标记为Symfony2.x,为了完整起见,我必须指出的是,新的验证约束所有自推出2.1版本,可以做整个工作.

对于每个数组或可遍历对象(例如Doctrine ArrayCollection),您可以执行以下操作:

/**
 * @Assert\All({
 *     @Assert\Type(type="Acme\MyBundle\Entity\EntityType")
 * })
 */    
protected $arrayOfEntities;
Run Code Online (Sandbox Code Playgroud)

因此,正在阅读您的问题的Symfony2.1用户应该更喜欢这个优雅而干净的解决方案.


Cro*_*zin 7

没有符合您要求的内置约束,因此您必须定义自己的约束.

约束定义:

namespace MyProject\Validator\Constraints;

use Symfony\Component\Validator\Constraint;

/**
* @Annotation
*/
class CollectionOf extends Constraint {
    public $message = 'This value should be a collection of type {{ type }}';
    public $type;

    public function getDefaultOption() {
        return 'type';
    }

    public function getRequiredOptions() {
        return array('type');
    }
}
Run Code Online (Sandbox Code Playgroud)

验证器定义:

namespace MyProject\Validator\Constraints;

use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
use Symfony\Component\Validator\Exception\UnexpectedTypeException;

class CollectionOfValidator extends ConstraintValidator {
    public function isValid($value, Constraint $constraint) {
        if ($value === null) {
            return true;
        }

        if (!is_array($value) && !$value instanceof \Traversable) {
            throw new UnexpectedTypeException($value, 'collection');
        }

        if (count($value) === 0) {
            return true;
        }

        $type = $constraint->type == 'boolean' ? 'bool' : $constraint->type;
        $function = 'is_' . $type;

        $primitiveTest = function_exists($function);

        foreach ($value as $item) {
            if (
                ($primitiveTest && !call_user_func($function, $item)) ||
                (!$primitiveTest && !$item instanceof $type)
            ) {
                $this->setMessage($constraint->message, array(
                    '{{ value }}' => is_object($item) ? get_class($item) : gettype($item),
                    '{{ type }}'  => $constraint->type
                ));

                return false;
            }
        }

        return true;
    }
}
Run Code Online (Sandbox Code Playgroud)

上面的验证器适用于集合和数组.


编辑(2011-06-29)

导入您自己的约束:

// My\TestBundle\Entity\Company

use Doctrine\ORM\Mapping as ORM;
use MyProject\Validator\Constraints as MyAssert;
use Symfony\Component\Validator\Constraints as Assert;

class Company {
    ...

    /**
     * @ORM\ManyToOne(...)
     * @Assert\NotNull
     * @MyAssert\CollectionOf("My\TestBundle\Entity\Employee")
     */
    private $employees;
}
Run Code Online (Sandbox Code Playgroud)

要使用注释约束,您必须在确认文件中启用它们:

framework:
    ...
    validation:
        enable-annotations: true
Run Code Online (Sandbox Code Playgroud)