ZF2 - 输入过滤器,字段集和表格

时间:2016-02-13 17:27:02

标签: php zend-framework2

我正在处理一个订单,该订单包含OrderPerson和与之关联的PersonAddress:

Order -> OrderPerson
Order -> PersonAddress

倾销时的PRG如下所示:

array (size=4)
  'csrfcheck' => string '' (length=65)
  'order' => 
    array (size=4)
      'id' => string '' (length=0)
      'orderPerson' => 
        array (size=9)
          'id' => string '0' (length=1)
          'firstname' => string '' (length=0)
          'surname' => string '' (length=0)... etc
      'personAddress' => 
        array (size=9)
          'id' => string '0' (length=1)
          'address' => string '' (length=0)
          'country' => string '197' (length=3)... etc
      'deliveryNote' => string '' (length=0)
  'deliveryMethod' => string '2' (length=1)
  'submit' => string 'Confirm Details And Make Payment' (length=32)

我想要做的是将InPutFilters添加到OrderPersonFieldSet.php和PersonAddressFieldSet.php。

我在OrderFieldSet的CheckoutForm上有一个InputFilter但是我不确定如何添加到其他字段集?

以下是详细信息:

现在我要一次创建这个对象,我创建了以下类:

CheckoutForm.php
OrderFieldSet.php
OrderPersonFieldSet.php
PersonAddressFieldSet.php

以下是详细信息:

CheckoutForm.php

<?php
namespace MyCart\Form;

use Zend\Form\Element;
use Zend\Form\Form;
use Zend\InputFilter\InputFilterInterface;

class CheckoutForm extends Form
{

    public function __construct(
        InputFilterInterface $orderFilter,
        $name = null,
        $options = array()
    ) {
        parent::__construct('checkout', $options);

        $this->orderFilter = $orderFilter;
    }

    public function init()
    {
        $this->add(
            [
                'name' => 'csrfcheck',
                'type' => 'csrf',
                'csrf_options' => [
                    'message' => 'The sender verification credentials have expired, please re-submit the form.',
                    'timeout' => 1200
                ]
            ]
        );

        $this->add(
            [
                'name' => 'order',
                'type' => OrderFieldset::class,
                'options' => [
                    'use_as_base_fieldset' => true
                ]
            ]
        );

        $this->add(
            [
                'name'       => 'submit',
                'type'       => 'submit',
                'attributes' => [
                    'value' => 'Update',
                    'class' => 'form-element'
                ]
            ]
        );

        $this->getInputFilter()->add($this->orderFilter, 'order');


    }
}

OrderFieldSet.php

<?php
namespace MyCart\Form;

use Doctrine\Common\Persistence\ObjectManager;
use DoctrineModule\Stdlib\Hydrator\DoctrineObject;
use MyCart\Entity\Order;
use Zend\Form\Element;
use Zend\Form\Fieldset;

class OrderFieldset extends Fieldset
{
    /**
     * @var \Doctrine\Common\Persistence\ObjectManager
     * @access protected
     */
    protected $objectManager;

    /**
     * @param ObjectManager $objectManager
     * @param Order $orderPrototype
     * @param null $name
     * @param array $options
     */
    public function __construct(
        ObjectManager   $objectManager,
        Order           $orderPrototype,
        $name           = null,
        $options        = array()
    ) {
        parent::__construct($name, $options);

        $this->objectManager = $objectManager;
        $this->setHydrator(new DoctrineObject($objectManager));
        $this->setObject($orderPrototype);
    }

    public function init()
    {

        $this->add(
            [
                'name'       => 'id',
                'type'       => 'hidden',
            ]
        );


        $this->add(
            [
                'name' => 'orderPerson',
                'type' => OrderPersonFieldset::class,
            ]
        );

        $this->add(
            [
                'name' => 'personAddress',
                'type' => PersonAddressFieldset::class,
            ]
        );

        $this->add(
            [
                'name'       => 'deliveryNote',
                'type'       => 'textarea',
                'options'    => [
                    'label' => 'Delivery Note',
                    'instructions' => 'While a delivery note is not required, it may be helpful.',
                ],
                'attributes' => [
                    'class' => 'form-control',
                    'rows'  => '5',
                    'id'    => 'delivery-note',
                ]
            ]
        );



    }
} 

OrderPersonFieldset.php

<?php
namespace MyCart\Form;

use Doctrine\Common\Persistence\ObjectManager;
use DoctrineModule\Stdlib\Hydrator\DoctrineObject;
use MyCart\Entity\OrderPerson;
use RoleBasedUser\Form\UserFieldset;
use Zend\Form\Element;
use Zend\Form\Fieldset;

class OrderPersonFieldset extends Fieldset
{
    /**
     * @var \Doctrine\Common\Persistence\ObjectManager
     * @access protected
     */
    protected $objectManager;

    /**
     * @param ObjectManager $objectManager
     * @param OrderPerson $orderPrototype
     * @param null $name
     * @param array $options
     */
    public function __construct(
        ObjectManager   $objectManager,
        OrderPerson     $orderPrototype,
        $name           = null,
        $options        = array()
    ) {
        parent::__construct($name, $options);

        $this->objectManager = $objectManager;
        $this->setHydrator(new DoctrineObject($objectManager));
        $this->setObject($orderPrototype);
    }

    public function init()
    {

        $this->add(
            [
                'name'       => 'id',
                'type'       => 'hidden',
            ]
        );

//        $this->add(
//            [
//                'name'       => 'rbuUser',
//                'type'       => UserFieldset::class,
//            ]
//        );

        $this->add([
            'type' => 'Toolbox\Library\Form\View\Helper\MyObjectHidden',
            'name' => 'rbuUser',
            'options' => [
                'object_manager' => $this->objectManager,
                'target_class' => 'RoleBasedUser\Entity\User'
            ]
        ]);

        $this->add(
            [
                'type' => 'text',
                'name' => 'companyName',
                'attributes' => [
                    'class'     => 'form-control',
                ],
                'options' => [
                    'label'  => 'Company Name',
                    'instructions' => 'This is optional',
                ],
            ]
        );

        $this->add(
            [
                'type' => 'text',
                'name' => 'vatNumber',
                'attributes' => [
                    'class'     => 'form-control',
                ],
                'options' => [
                    'label'  => 'Vat Number',
                    'instructions' => 'This is optional',
                ],
            ]
        );

        $this->add(
            [
                'type' => 'text',
                'name' => 'email',
                'attributes' => [
                    'class'     => 'form-control',
                    'required' => 'required',
                ],
                'options' => [
                    'label'  => 'Email Address',
                    'instructions' => 'Please enter your email address',
                ],
            ]
        );

        $this->add(
            [
                'type' => 'text',
                'name' => 'firstname',
                'attributes' => [
                    'class'     => 'form-control',
                    'required' => 'required',
                ],
                'options' => [
                    'label'  => 'First Name',
                    'instructions' => 'Please enter your first name',
                ],
            ]
        );

        $this->add(
            [
                'type' => 'text',
                'name' => 'surname',
                'attributes' => [
                    'class'     => 'form-control',
                    'required' => 'required',
                ],
                'options' => [
                    'label'  => 'Last Name',
                    'instructions' => 'Please enter your last name',
                ],
            ]
        );

        $this->add(
            [
                'type' => 'text',
                'name' => 'tell',
                'attributes' => [
                    'class'     => 'form-control',
                    'required' => 'required',
                ],
                'options' => [
                    'label'  => 'Telephone',
                    'instructions' => 'Please enter your land line number',
                ],
            ]
        );

        $this->add(
            [
                'type' => 'text',
                'name' => 'cell',
                'attributes' => [
                    'class'     => 'form-control',
                    'required' => 'required',
                ],
                'options' => [
                    'label'  => 'Mobile',
                    'instructions' => 'Please enter your mobile number',
                ],
            ]
        );

    }
} 

PersonAddressFieldset.php

<?php
namespace MyCart\Form;

use Doctrine\Common\Persistence\ObjectManager;
use DoctrineModule\Stdlib\Hydrator\DoctrineObject;
use MyCart\Entity\PersonAddress;
use Zend\Form\Element;
use Zend\Form\Fieldset;

class PersonAddressFieldset extends Fieldset
{
    /**
     * @var \Doctrine\Common\Persistence\ObjectManager
     * @access protected
     */
    protected $objectManager;

    /**
     * @param ObjectManager $objectManager
     * @param PersonAddress $orderPrototype
     * @param null $name
     * @param array $options
     */
    public function __construct(
        ObjectManager   $objectManager,
        PersonAddress   $orderPrototype,
        $name           = null,
        $options        = array()
    ) {
        parent::__construct($name, $options);

        $this->objectManager = $objectManager;
        $this->setHydrator(new DoctrineObject($objectManager));
        $this->setObject($orderPrototype);
    }

    public function init()
    {

        $this->add(
            [
                'name'       => 'id',
                'type'       => 'hidden',
            ]
        );

        $this->add(
            [
                'name' => 'orderPerson',
                'type' => OrderPersonFieldset::class,
            ]
        );

        $this->add(
            [
                'type' => 'text',
                'name' => 'address',
                'attributes' => [
                    'class'     => 'form-control',
                    'required'  => 'required'
                ],
                'options' => [
                    'label'  => 'Delivery address',
                    'instructions' => 'Please enter your delivery address',
                ],
            ]
        );

        $this->add(
            [
                'type' => 'text',
                'name' => 'city',
                'attributes' => [
                    'class'     => 'form-control'
                ],
                'options' => [
                    'label'  => 'City',
                    'instructions' => 'Delivery city',
                ],
            ]
        );

        $this->add(
            [
                'type' => 'text',
                'name' => 'postCode',
                'attributes' => [
                    'class'     => 'form-control'
                ],
                'options' => [
                    'label'  => 'Post Code',
                    'instructions' => 'Delivery post code',
                ],
            ]
        );

        $this->add(
            [
                'type' => 'text',
                'name' => 'region',
                'attributes' => [
                    'class'     => 'form-control',
                    'required' => 'required',
                ],
                'options' => [
                    'label'  => 'Region',
                    'instructions' => 'Enter your region',
                ],
            ]
        );

        $this->add(
            [
                'type' => 'DoctrineModule\Form\Element\ObjectSelect',
                'name' => 'country',
                'options' => [
                    'object_manager' => $this->objectManager,
                    'target_class'   => 'Toolbox\Entity\Countries',
                    'property'       => 'name',
                    'label' => 'Country',
                    'instructions' => 'Your country'

                ],
                'attributes' => [
                    'class'     => 'form-control',
                    'options' => [
                        '197' => 'South Africa'
                    ],
                    'multiple' => false,
                ]
            ]
        );


    }
} 

1 个答案:

答案 0 :(得分:0)

有很多方法可以解决这个问题。冷杉就像IslandDev所建议的那样。我觉得这太糟糕了,虽然它工作得非常好。

第二个是根据ZF2手册,您可以找到它here和另一个类似的here:虽然这有效但我觉得解决方案限制了过滤器的使用。理想情况下,您希望能够在不同的场景中重复使用InputFilters,并且手册中建议的解决方案不允许这样做,因此在我看来,它也是一个黑客。

我要解决的问题实际上很简单:

在我的OrderFieldset.php类中,我实现了InputAwareInterfac,以便我可以访问setInputFilter和getInputFilter(通常在传统的Form类中可用)。

然后我注入了orderPersonFilter和personAddressFilter。

新课程如下所示:

<?php namespace MyCart\Form;

use Doctrine\Common\Persistence\ObjectManager; 
use DoctrineModule\Stdlib\Hydrator\DoctrineObject; 
use MyCart\Entity\Order; 
use Zend\Form\Element; 
use Zend\Form\Fieldset; 
use Zend\InputFilter\InputFilter; 
use Zend\InputFilter\InputFilterAwareInterface; 
use Zend\InputFilter\InputFilterInterface;

class OrderFieldset extends Fieldset implements InputFilterAwareInterface {

    /**
     * @var \Doctrine\Common\Persistence\ObjectManager
     * @access protected
     */
    protected $objectManager;

    /**
     * @var
     */
    protected $inputFilter;

    /**
     * @param ObjectManager $objectManager
     * @param Order $orderPrototype
     * @param InputFilterInterface $orderPersonFilter
     * @param InputFilterInterface $personAddressFilter
     * @param null $name
     * @param array $options
     */
    public function __construct(
        ObjectManager   $objectManager,
        Order           $orderPrototype,
        InputFilterInterface $orderPersonFilter,
        InputFilterInterface $personAddressFilter,
        $name           = null,
        $options        = array()
    ) {
        parent::__construct($name, $options);

        $this->objectManager = $objectManager;
        $this->setHydrator(new DoctrineObject($objectManager));
        $this->setObject($orderPrototype);
        $this->orderPersonFilter = $orderPersonFilter;
        $this->personAddressFilter = $personAddressFilter;

        $this->inputFilter = new InputFilter();
    }

    public function init()
    {

        $this->add(
            [
                'name'       => 'id',
                'type'       => 'hidden',
            ]
        );


        $this->add(
            [
                'name' => 'orderPerson',
                'type' => OrderPersonFieldset::class,
            ]
        );

        $this->add(
            [
                'name' => 'personAddress',
                'type' => PersonAddressFieldset::class,
            ]
        );

        $this->add(
            [
                'name'       => 'deliveryNote',
                'type'       => 'textarea',
                'options'    => [
                    'label' => 'Delivery Note',
                    'instructions' => 'While a delivery note is not required, it may be helpful.',
                ],
                'attributes' => [
                    'class' => 'form-control',
                    'rows'  => '5',
                    'id'    => 'delivery-note',
                ]
            ]
        );

        $this->getInputFilter()->add($this->orderPersonFilter, 'orderPerson');
        $this->getInputFilter()->add($this->personAddressFilter, 'personAddress');


    }

    public function setInputFilter(InputFilterInterface $inputFilter)
    {
        $this->inputFilter = $inputFilter;

        return $this;
    }

    /**
     * Retrieve input filter
     *
     * @return InputFilterInterface
     */
    public function getInputFilter()
    {
        return $this->inputFilter;
    }

}

我的CheckoutForm.php类需要更新如下:

$this->getInputFilter()->add($this->get('order')->getInputFilter(), 'order');

一个很好的干净解决方案,如果需要,我可以在其他场景中使用输入过滤器。