Hi,

I am trying to create some more complex forms (involving One-to-Many relations in my case).entirelly using annotations (no separated fieldsets created).

Is this entirely possible using annotations or I still need to create separated fieldsets aggregate manually ?

After submitting the form it seems to have a hydrator issue I cant find a solution to fix. I used 2 very simple entities illustrating my problem.


=================================
=== ERROR ===
=================================

AN ERROR OCCURRED

An error occurred during execution; please try again later.

Additional information:

Zend\Stdlib\Exception\BadMethodCallException

File:
/home/demo/vendor/zendframework/zendframework/library/Zend/Stdlib/Hydrator/ArraySerializable.php:78
Message:
Zend\Stdlib\Hydrator\ArraySerializable::hydrate expects the provided object to implement exchangeArray() or populate()
Stack trace:
#0 /home/demo/vendor/zendframework/zendframework/library/Zend/Form/Fieldset.php(597): Zend\Stdlib\Hydrator\ArraySerializable->hydrate(Array, NULL) #1 /home/demo/vendor/zendframework/zendframework/library/Zend/Form/Element/Collection.php(273): Zend\Form\Fieldset->bindValues(Array) #2 /home/demo/vendor/zendframework/zendframework/library/Zend/Form/Fieldset.php(585): Zend\Form\Element\Collection->bindValues(Array) #3 /home/demo/vendor/zendframework/zendframework/library/Zend/Form/Form.php(364): Zend\Form\Fieldset->bindValues(Array) #4 /home/demo/vendor/zendframework/zendframework/library/Zend/Form/Form.php(513): Zend\Form\Form->bindValues() #5 /home/demo/module/Imagis/src/Imagis/Controller/AnnotationController.php(....): Zend\Form\Form->isValid() #7 /home/demo/vendor/zendframework/zendframework/library/Zend/Mvc/Controller/AbstractActionController.php(83): Test\Controller\AnnotationController->addAction() #8 [internal function]: Zend\Mvc\Controller\AbstractActionController->onDispatch(Object(Zend\Mvc\MvcEvent)) #9 /home/demo/vendor/zendframework/zendframework/library/Zend/EventManager/EventManager.php(468): call_user_func(Array, Object(Zend\Mvc\MvcEvent)) #10 /home/demo/vendor/zendframework/zendframework/library/Zend/EventManager/EventManager.php(207): Zend\EventManager\EventManager->triggerListeners('dispatch', Object(Zend\Mvc\MvcEvent), Object(Closure)) #11 /home/demo/vendor/zendframework/zendframework/library/Zend/Mvc/Controller/AbstractController.php(117): Zend\EventManager\EventManager->trigger('dispatch', Object(Zend\Mvc\MvcEvent), Object(Closure)) #12 /home/demo/vendor/zendframework/zendframework/library/Zend/Mvc/DispatchListener.php(114): Zend\Mvc\Controller\AbstractController->dispatch(Object(Zend\Http\PhpEnvironment\Request), Object(Zend\Http\PhpEnvironment\Response)) #13 [internal function]: Zend\Mvc\DispatchListener->onDispatch(Object(Zend\Mvc\MvcEvent)) #14 /home/demo/vendor/zendframework/zendframework/library/Zend/EventManager/EventManager.php(468): call_user_func(Array, Object(Zend\Mvc\MvcEvent)) #15 /home/demo/vendor/zendframework/zendframework/library/Zend/EventManager/EventManager.php(207): Zend\EventManager\EventManager->triggerListeners('dispatch', Object(Zend\Mvc\MvcEvent), Object(Closure)) #16 /home/demo/vendor/zendframework/zendframework/library/Zend/Mvc/Application.php(313): Zend\EventManager\EventManager->trigger('dispatch', Object(Zend\Mvc\MvcEvent), Object(Closure))
#17 /home/demo/public_html/index.php(17): Zend\Mvc\Application->run()
#18 {main}

=================================
=== Brand entity ===
=================================

/**
 * @ORM\Entity
* @ORM\Table(name="test_brands", uniqueConstraints={@ORM\UniqueConstraint(name="name", columns={"name"})})
 */
class Brand {

    /**
     * @var int
     * @ORM\Id
* @ORM\Column(type="integer", nullable=false, options={"unsigned"=true})
     * @ORM\GeneratedValue(strategy="IDENTITY")
     * @Annotation\Exclude()
     *
     */
    protected $id;

    /**
     * @var string
     * @Annotation\Type("Zend\Form\Element\Text")
     * @Annotation\Options({"label":"Brand Name"})
     * @Annotation\Required(true)
     * @ORM\Column(type="string", length=32, unique=true, nullable=false)
     */
    protected $name;

    /**
* @Annotation\ComposedObject({"target_object":"\Test\Entity\Model", "is_collection":"true", "options":{"count":2, "should_create_template":"true", "allow_add":"true", "allow_remove":"true"}})
     * @ORM\OneToMany(targetEntity="Test\Entity\Model",
      mappedBy="product", cascade={"persist"})
     */
    protected $models;

    public function __construct() {
        $this->models = new ArrayCollection();
    }

    /**
     * Get id.
     *
     * @return int
     */
    public function getId() {
        return $this->id;
    }

    /**
     * Set id.
     *
     * @param int $id
     *
     * @return void
     */
    public function setId($id) {
        $this->id = (int) $id;
    }

    /**
     * Set name
     *
     * @param string $name
     * @return Brand
     */
    public function setName($name) {
        $this->name = $name;

        return $this;
    }

    /**
     * Get name
     *
     * @return string
     */
    public function getName() {
        return $this->name;
    }

    /**
     * Add models
     *
     * @param \Doctrine\Common\Collections\Collection  $models
     */
    public function addModels($models) {
        foreach ($models as $model) {
            $model->setBrand($this);
            $this->models->add($model);
        }
    }

    /**
     * Remove models
     *
     * @param \Doctrine\Common\Collections\Collection  $models
     */
    public function removeModels($models) {
        foreach ($models as $model) {
            $model->setBrand(null);
            $this->models->removeElement($model);
        }
    }

    /**
     * Get models
     *
     * @return \Doctrine\Common\Collections\Collection
     */
    public function getModels() {
        return $this->models;
    }

}

=================================
=== Model entity ===
=================================

/**
 * @ORM\Entity
 * @ORM\Table(name="test_models")
 * @Annotation\Name("Model")
 * @Annotation\Type("fieldset")
 */
class Model {

    /**
     * @var int
     * @ORM\Id
* @ORM\Column(type="integer", nullable=false, options={"unsigned"=true})
     * @ORM\GeneratedValue(strategy="IDENTITY")
     * @Annotation\Exclude()
     */
    protected $id;

    /**
     * @var string
     * @Annotation\Flags({"priority": 100})
     * @Annotation\AllowEmpty(true)
     * @Annotation\Type("Zend\Form\Element\Text")
     * @Annotation\Options({"label":"Model name"})
     * @ORM\Column(type="string", nullable=false)
     */
    protected $name;

    /**
     * @Annotation\Exclude()
* @ORM\ManyToOne(targetEntity="Test\Entity\Brand", inversedBy="models") * @ORM\JoinColumn(name="brand", referencedColumnName="id", onDelete="CASCADE")
     */
    protected $brand;

    /**
     * Get id
     *
     * @return integer
     */
    public function getId() {
        return $this->id;
    }

    /**
     * Set name
     *
     * @param string $name
     * @return Model
     */
    public function setName($name) {
        $this->name = $name;

        return $this;
    }

    /**
     * Get name
     *
     * @return string
     */
    public function getName() {
        return $this->name;
    }

    public function setBrand(Brand $brand = null) {
        $this->brand = $brand;
    }

    public function getBrand() {
        return $this->brand;
    }
}


=================================
=== Controller ===
=================================

$entityClass = '\Test\Entity\Brand';

$id = $this->params()->fromRoute('id');
//update
if (!empty($id)) {
    $repository = $this->getObjectManager()->getRepository($entityClass);
    $this->entity = $repository->find($id);
} else {//create
    $this->entity = new $entityClass();
}

//form generation
$builder = new DoctrineAnnotationBuilder($this->getObjectManager());
$this->form = $builder->createForm($this->entity);
$this->form->setHydrator(new DoctrineHydrator($this->getObjectManager(), $entityClass))
        ->setObject($this->entity);

$this->form->add(array(
    'type' => 'Zend\Form\Element\Csrf',
    'name' => 'security',
    'options' => array(
        'csrf_options' => array(
            'timeout' => 600
        )
    )
));

$this->form->add(array(
    'name' => 'submit',
    'type' => 'Submit',
    'attributes' => array(
        'value' => 'save',
    ),
));


//end form generation

$this->form->bind($this->entity);

$request = $this->getRequest();
if ($request->isPost()):
    $dataForm = array_replace_recursive(
            $request->getPost()->toArray(), $request->getFiles()->toArray()
    );

    $this->form->setData($dataForm);

    if ($this->form->isValid()):

$this->getObjectManager()->persist($this->entity);
        $this->getObjectManager()->flush();

    endif;
endif;


Thank you,
Cristian

Reply via email to