我有两个涉及Zend \ Form \ Annotation \ AnnotationBuilder的问题。
首先,我想告诉AnnotationBuilder创建一个Zend \ Form \ Fieldset而不是Zend \ Form \ Form(因为文档说它是为你的实体使用fieldsets的好方法)。所以我的实体类说@Annotation\Type("Fieldset")
,当我在AnnotationBuilder上调用createForm()
时,实例化了一个Fieldset - 到目前为止一直很好。但是我无法让验证器针对fieldset元素运行。作为一个实验,我有一个控制器动作这样做:
$em = $this->serviceManager->get('entity-manager');
$builder = new \Zend\Form\Annotation\AnnotationBuilder($em);
$form = new \Zend\Form\Form('person-form');
$hydrator = new \DoctrineModule\Stdlib\Hydrator\DoctrineObject($em);
$form->setHydrator($hydrator);
$fieldset = $builder->createForm(\Application\Entity\Person::class);
$fieldset->setHydrator($hydrator)
->setObject(new \Application\Entity\Person())
->setUseAsBaseFieldset(true);
// more about this later....
$element = new \DoctrineModule\Form\Element\ObjectSelect('hat',
[
'object_manager' => $em,
'target_class' => 'Application\Entity\Hat',
'property' => 'name',
'label' => 'hat',
'display_empty_item' => true,
]);
$fieldset->add($element);
$form->add($fieldset);
$filter = $form->getInputFilter();
$filter->add([
'person' => [
'name' => 'hat',
'validators' =>[
[
'name' => 'Zend\Validator\NotEmpty',
'options' => [
'messages' => [
'isEmpty' => 'the "hat" is required'
],
],
],
],
],
]);
// so anyway...
$viewModel = new ViewModel(['form' => $form]);
$request = $this->getRequest();
if ($request->isPost()) {
$data = $request->getPost();
$person = new \Application\Entity\Person();
$form->bind($person);
$form->setData($data);
if (! $form->isValid()) {
echo "not valid ...messages? ";
\Zend\Debug\Debug::dump($fieldset->getMessages());
return $viewModel;
}
$em->persist($person);
$em->flush();
$this->flashMessenger()->addMessage("congratulations! you inserted an entity.");
return $this->redirect()->toRoute('home');
}
return $viewModel;
}
当我提交表单时会发生什么,ìsValid()
返回false,我得到通用"值是必需的,并且不能为空"对于"帽子"我在事后添加的元素,并且没有任何验证器似乎对其他字段运行(错误消息数组否则为空)。所以,我想知道通过注释和AnnotationBuilder创建Fieldset而不是Form的正确方法。请注意,当我使用注释创建的Form而不是Fieldset执行所有操作时,一切正常。
其次,我希望能够混合和匹配通过注释创建的元素(以及过滤器和验证器)与动态添加的其他元素。为什么?好吧,为一个字符串生成一个最大长度验证器以及指定列宽的Doctrine注释的想法对我来说很有意义,加上这些注释的所有其他好处 - 我知道不是每个人都对它们感到疯狂。所以,"帽子"下面的示例中的元素是这样一个元素,即我想在实例化形式并以其他方式初始化之后添加的元素。而且,这确实适用于Form而不是Fieldset。 (实际上,我很乐意通过注释添加元素,但似乎不可能使用构造函数具有依赖关系的异构形式元素来做到这一点 - 另一天的问题。)
对于记录,这里是相关部分中的Entity类
namespace Application\Entity;
use Doctrine\ORM\Mapping as ORM;
use Zend\Form\Annotation;
* @Annotation\Name("person")
* @Annotation\Type("Fieldset")
* //Annotation\Type("Form")
* @ORM\Entity @ORM\Table(name="people",uniqueConstraints={@ORM\UniqueConstraint(name="hat_email_idx",columns={"email","hat_id"})})
* @ORM\InheritanceType("JOINED")
*
* @ORM\DiscriminatorColumn(name="discr", type="string")
* @ORM\DiscriminatorMap({"person" = "Person", "interpreter"="Interpreter", "judge"="Judge"})
*/
class Person
{
/**
* entity id
* @Annotation\Exclude()
* @ORM\Id @ORM\GeneratedValue @ORM\Column(type="smallint",options={"unsigned":true})
*/
protected $id;
/**
* the Person's email address.
*
* @ORM\Column(type="string",length=50,nullable=true)
*
* @var string
*/
protected $email;
/**
* the Person's last name.
*
* @Annotation\Options({"label":"last name"})
* @Annotation\Filter({"name":"StringTrim"})
* @Annotation\Validator({"name":"NotEmpty",
* "break_chain_on_failure": true,
* "options":{"messages":{"isEmpty":"last name is required"}
* }})
* @Annotation\Validator({
* "break_chain_on_failure": true,
* "name":"Application\Form\Validator\ProperName",
* "options" : {"type":"last"}
* })
* @Annotation\Validator({"name":"StringLength", "options":{"min":2, "max":50,
* "messages":{"stringLengthTooShort":"name must be at least 2 characters long",
* "stringLengthTooLong":"name exceeds maximum length of 50 characters"}}})
*
* @ORM\Column(type="string",length=50,nullable=false)
* @var string
*/
protected $lastname;
/**
* Everyone must where a hat in this life.
*
* @ORM\ManyToOne(targetEntity="Hat",fetch="EAGER")
* @ORM\JoinColumn(nullable=false)
*
* @var Hat
*/
protected $hat;
// etc etc omitted
}
非常感谢提前。