0

I have been following http://framework.zend.com/manual/2.1/en/modules/zend.form.collections.html and it works great with validation and so on.

When the form is valid the guide just runs a var_dump on the entity and it looks something like this:

object(Application\Entity\Product)[622]
  protected 'name' => string 'Chair' (length=5)
  protected 'price' => string '25' (length=2)
  protected 'categories' =>
    array (size=2)
      0 =>
        object(Application\Entity\Category)[615]
          protected 'name' => string 'Armchair' (length=8)
      1 =>
        object(App1ication\Entity\Category)[621]
          protected 'name' => string 'Office' (length=6)

The categories can be more then 2 or just 1. How to save a normal form to a database table I understand and have no problem with. But here we have data for two different tables. I guess I could manually read the categories in my controller and fill them in to a model and save them row by row. But that doesn't feel like the best way of doing it.

How do I get the data from the entity to a model or my database? Can it be done without Doctrine?

Rickard
  • 620
  • 2
  • 7
  • 23

1 Answers1

1

You have two choices: getData() or bind().

bind() is the "automatic" way - you bind an entity to your form object which has a property on that entity which matches the name of your collection. Then, when the form's isValid() method is called, the binding mechanism will pass the values from the collection's elements to the matching property on the entity.

Alternatively, you can use getData() on the collection object and then do whatever you need to.

Once you have an entity, to save it, consider using ZfcBase as that does the hard work for you.

This is a simple example mapper:

namespace MyModule\Mapper;

use ZfcBase\Mapper\AbstractDbMapper;
use Zend\Stdlib\Hydrator\ArraySerializable;
use MyModule\Entity\MyEntity;

class MyMapper extends AbstractDbMapper
{
    protected $tableName  = 'my_table';

    public function __construct()
    {
        $this->setHydrator(new ArraySerializable());
        $this->setEntityPrototype(new MyEntity());
    }

    public function save(MyEntity $entity)
    {
        if (!$entity->getId()) {
            $result = $this->insert($entity);
            $entity->setId($result->getGeneratedValue());
        } else {
            $where = 'id = ' . (int)$entity->getId();
            $this->update($entity, $where);
        }
    }

    public function fetchAll($choiceGroupId)
    {
        $select = $this->getSelect($this->tableName);
        return $this->select($select);
    }

    public function loadById($id)
    {
        $select = $this->getSelect($this->tableName)
                       ->where(array('id' => (int)$id));

        return $this->select($select)->current();
    }        
}

This mapper is using the ArraySerializable hydrator, so your entity object (MyEntity in the example) must implement the methods getArrayCopy() and populate(). getArrayCopy() returns an array of data to be saved and populate() is used to fill the entity from an array of data from database.

Rob Allen
  • 12,643
  • 1
  • 40
  • 49
  • Yes getting the data from the entity to the form works very well and the other way to. It is after the validation is is done the guide ends with "var_dump($product);", there i sit with the entity with the data but i don't know how to make a hydrator and mapper. – Rickard Feb 19 '13 at 11:50
  • Thanks for putting your time in to this Rob! I think I am still unclear in my question :) I have updated it some now and hope that it is more clear on what I doesn't understand. – Rickard Feb 19 '13 at 22:26
  • I have given up this, going for the Doctrine way :) Thanks for the help! – Rickard Feb 28 '13 at 20:54
  • @RobAllen, I love $form->bind() with collections as it deals with the multiple child entities (using my own mappers, hydrators etc, - no doctrine). After binding in edit action I loop in the parent's child entities that were already updated upon binding and save all one by one using their own mapper's save action. This only helps for editing the existing children but I can't figure out the "new" children that could be added into the form. I can't find the new data inside getData() but only in $request->getPost(). Should I really iterate through getPost() array and create new children? Thanks. – smozgur Jul 10 '16 at 15:06
  • Sorry for adding my question here but this is the only source I can find and closest to my situation. I just wanted to explain where I stuck since I got you guys talking about the same issue hoping that you can give me an idea. Thank you very much again. – smozgur Jul 10 '16 at 15:11