zf2 表单收集 hydration 在 hydrator 中出错 $data

zf2 form collection hydration gets wrong $data in hydrator

我使用 doctrine ODM + Zend Form 并且在使用 Hydration 时遇到了问题。 我定义了一个集合 "Stores",其中包含 "storeName" 等元素和一个 "address" 或 "contactPerson" 等字段集。 像 "storeName" 这样的简单元素会很好地保存,但是像 "address" 这样的字段集它总是会保存最后一个条目数据。

所以我保存的 Json-对象看起来像这样

    {
        "_id" : ObjectId("5541e8a50203ff4c1e00002a"),
        ...
        "stores" : [ 
            {
                "_id" : "12345678998",
                "storeName" : "test1",
                "openingTimes" : "123",
                "address" : {
                    "placeId" : "ChIJYbqFGmnKuEcRm-J84sWlfMY",
                    "street" : "Karolingerstraße 10",
                    "queryString" : "Karolingerstraße 10", ...
                },
                "contactPerson" : {
                    "salutation" : "1",
                    "firstname" : "foo",
                    "lastname" : "bar",
...
                }
            }, 
            {
                "_id" : "557fe9a92d86d",
                "storeName" : "test 3",
                "openingTimes" : "hgfhgfhgf",
                "address" : {
                    "placeId" : "ChIJYbqFGmnKuEcRm-J84sWlfMY",
                    "street" : "Karolingerstraße 10",
                    "queryString" : "Karolingerstraße 10", ...
                },
                "contactPerson" : {
                    "salutation" : "1",
                    "firstname" : "foo",
                    "lastname" : "bar",
...
                }
            }
        ]
    }

我发现,我的基础字段集 CompanyStoresFieldset 的 Hydrator 在 hydrate(array $data, $object) 中获取了错误的 $data。 $object 是正确的。所以。它并不是真正的 Hydration 出错,我认为它是按 Form 设置的 $data ......但我不知道为什么。我只是将数据设置为表单,如 $form->setData($form) 并且我不覆盖任何表单方法。 所有其他 Hydrators(在 fieldsets 中)似乎都获得了正确的 $data 并且工作正常。 有人有想法吗?

这就是我正在做的事情。 我的表单只是添加了一个 Fieldset CompanyStoresFieldset。 字段集是 "used as base fieldset"。此 Fieldset 有一个 Collection Element,如下所示:

公司商店字段集:

$this
            ->setHydrator(new ClassMethods(false))
            ->setObject(new Company())
        ;

$this->add(array(
            'type' => 'Zend\Form\Element\Collection',
            'name' => 'stores',
            'options' => array(
                'should_create_template' => true,
                'allow_add' => true,
                'allow_remove' => true,
                'create_new_objects' => true,
                'target_element' => array(
                    'type' => 'Application\Form\Fieldset\StoreEntityFieldset',
                ),
            ),
        ));

StoreEntityFieldset 添加了简单的元素和字段集元素。

StoreEntityFieldset:

        $this
            ->setHydrator(new ClassMethods(false))
            ->setObject(new Store())
        ;


        $this->add(array(
            'name' => 'storeName',
            ...
        ));

        //AddressFieldset
        $this->add(array(
            'name' => 'address',
            'type' => 'Application\Form\Fieldset\AddressFieldset',
        ));

        //ContactPersonFieldset
        $this->add(array(
            'name' => 'contactPerson',
            'type' => 'Application\Form\Fieldset\ContactPersonFieldset',
        ));

        $this->add(array(
            'name' => 'openingTimes',
            'type' => 'Textarea',
            ...
        ));

    }

在表单和字段集中,我刚刚设置了 Zend\Stdlib\Hydrator\ClassMethods 我不修改任何 Hydrators。

My Main Document Model Company 像这样嵌入 $stores

公司:

/**
     * @var \Doctrine\Common\Collections\ArrayCollection
     * @ODM\EmbedMany (targetDocument="\Application\Model\Mongo\Company\Store")
     */
    private $stores = array();

我的 EmbeddedDocument Store 添加了这样的元素

商店:

class Store {

    /**
     *
     * @var string
     * @ODM\Id(strategy="NONE")
     */
    private $id;

    /**
     *
     * @var string
     * @ODM\String
     */
    private $storeName;

    /**
     *
     * @var string
     * @ODM\String
     */
    private $openingTimes;

    /**
     * @var \Application\Model\Mongo\Company\Address
     * @ODM\EmbedOne(targetDocument="\Application\Model\Mongo\Company\Address")
     */
    private $address;

    /**
     * @var \Application\Model\Mongo\Company\ContactPerson
     * @ODM\EmbedOne(targetDocument="\Application\Model\Mongo\Company\ContactPerson")
     */
    private $contactPerson;

模型 ContactPersonAddress 仅包含 setter 和 getter class属性 + getArrayCopy 和 exchangeArray。

getArrayCopy 和 exchangeArray 如下所示:

    public function getArrayCopy() {
        $ref = new \Zend\Stdlib\Hydrator\Reflection();
        return $ref->extract($this);
    }

    public function exchangeArray($data = array()){
        $ref = new \Zend\Stdlib\Hydrator\Reflection();
        return $ref->hydrate($data, $this);
    }

问题是我在商店模型构造函数中为 ContactPerson 和 Address 添加了新实例。错了..