Symfony2: сущность утверждает, что принимает массив типов? - PullRequest
5 голосов
/ 27 июня 2011

У меня есть лицо с полем $ компании.В этом поле должен храниться массив объектов Компании.Итак, я описал утверждение следующим образом:

@Assert\Type("Acme\MyBundle\Entity\Company")

Но это всегда неверно, потому что из моей формы я получаю массив компаний, но этот утверждение хочет, чтобы это был не массив, а только одна компания.

Так какпреодолеть это?Я предполагаю, что это должно быть что-то вроде этого:

@Assert\Array(Type("Acme\MyBundle\Entity\Company"))

Ответы [ 2 ]

13 голосов
/ 14 ноября 2012

Поскольку вопрос помечен для Symfony2.x , для полноты картины я должен указать, что новое ограничение проверки Все введено с версии 2.1 * 1006. * может сделать всю работу.

Для каждого массива или пройденных объектов (например, Доктрина ArrayCollection) вы можете сделать следующее:

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

Итак, пользователи Symfony2.1 , которые читают ваш вопрос, должны предпочесть это элегантное и чистое решение.

7 голосов
/ 27 июня 2011

Нет встроенного ограничения, которое отвечало бы вашим требованиям, поэтому вам придется определить свое собственное.

Определение ограничения:

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');
    }
}

Определение валидатора:

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;
    }
}

Приведенный выше валидатор работает как для коллекций, так и для массивов.


Редактировать (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;
}

Чтобы использовать ограничения аннотаций, вам необходимо включить их в файле подтверждения:

framework:
    ...
    validation:
        enable-annotations: true
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...