0

我有两个涉及 Zend\Form\Annotation\AnnotationBuilder 的问题。

首先,我想告诉 AnnotationBuilder 创建 Zend\Form\Fieldset 而不是 Zend\Form\Form(因为文档说为实体使用字段集是一种很好的做法)。所以我的实体类说@Annotation\Type("Fieldset"),当我在 AnnotationBuilder 上调用时,一个 Fieldset 被实例化createForm()——到目前为止一切都很好。但我无法让验证器针对字段集元素运行。作为一个实验,我有一个控制器操作:

$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 的正确方法。请注意,当我使用注释创建的表单而不是 Fieldset 执行所有这些操作时,一切正常。

其次,我希望能够混合和匹配通过注释创建的元素(以及过滤器和验证器)与动态添加的其他元素。为什么?好吧,在指定列宽的 Doctrine 注释旁边有一个字符串的最大长度验证器的想法对我来说很有意义,加上这些注释的所有其他好处——我知道不是每个人都对它们着迷。因此,下面示例中的“Hat”元素就是这样一个元素,即我想在表单被实例化或以其他方式初始化后添加的元素。同样,这确实适用于表单而不是字段集。(实际上,我很乐意通过注释添加元素,但是对于构造函数具有依赖关系的奇异表单元素似乎不可能做到这一点——改天再问。)

作为记录,这里是相关部分的实体类

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 

}

提前谢谢了。

4

0 回答 0