2

i'm trying to implement the RowGateway class to my entities, I already have a form working with the entity and I'm trying to set the hydrator to work with ClassMethods.

I also noticed that ArraySerializable hydrator calls the populate() method or exchangeArray() and this method set the appropriate primary key when editing a row, unfortunately ClassMethods Hydrator doesn't do that.

What would be the best way to set the correct primary key value when using the Classmethod hydrator, should I set this value before binding the entity to the form? Or, should I extend the Classmethod H. to perform this task on initialize?

akond
  • 15,865
  • 4
  • 35
  • 55
Jean Paul Rumeau
  • 343
  • 4
  • 16

2 Answers2

2

I'm not fond of using knowledge of the data layer in my entity. When using exchangeArray() you create mapping in the entity itself. I did some research about Zend's hydrators and came across serval posts including this one. Andrew's example of extending the ClassMethods hydrator seemed a good approach to map column names to getters/setters names.

When extending the ClassMethods hydrator you could also implement Zend\Stdlib\Hydrator\HydratorInterface.

For data manipulation use hydrator strategies.

http://framework.zend.com/manual/2.0/en/modules/zend.stdlib.hydrator.strategy.html http://juriansluiman.nl/nl/article/125/strategies-for-hydrators-a-practical-use-case

To sepperate your entity over mutliple data sources you can use hydrator filters. For example, by default the ClassMethods hydrator extracts all entity methods starting with get.

http://framework.zend.com/manual/2.1/en/modules/zend.stdlib.hydrator.filter.html

  • I'm accepting this answer because after a lot of reading i found that object population should be made through Hydrators and a custom Hydrator would be the best approach. Also i finally ended up using [Doctrine2](http://www.doctrine-project.org/) as it provides an extended db layer and the Hydrator included provides the desired functionality. – Jean Paul Rumeau Aug 01 '13 at 20:10
1

You could extend Zend\Stdlib\Hydrator\ClassMethods and do any transformations you require here, assuming this is what you mean.

You can then use mapField to map from one of your fields to the correct id field name.

namespace Application\Model;

use Zend\Stdlib\Hydrator\ClassMethods;

class MyHydrator extends ClassMethods
{
    /**
     * Extract values from an object
     *
     * @param   object $object
     * @return  array
     * @throws  Exception\InvalidArgumentException
     */
    public function extract($object)
    {            
        $data = parent::extract($object);
        $data = $this->mapField('id', 'user_id', $data);

        return $data;
    }

    /**
     * Map fields
     * 
     * @param type $keyFrom
     * @param type $keyTo
     * @param array $array
     * @return array
     */
    protected function mapField($keyFrom, $keyTo, array $array)
    {
        $array[$keyTo] = $array[$keyFrom];
        unset($array[$keyFrom]);

        return $array;
    }
}

Alternatively you could make a getter and setter for the id field you need setting/getting, for example if you have an id called 'user_id' :

public function getUserId() { .. }

public function setUserId($id) { .. }
Andrew
  • 12,617
  • 1
  • 34
  • 48
  • I think your classmethods extension is very good. I think there's a problem with your getter/setter suggestion though, it won't work with classmethods because the values will never be set initially (if UserId doesn't exist as a column name then 'setUserID()' will never be called). – Beeblebrox Nov 06 '13 at 11:18