Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nested OneToMany fieldsets in a ZF2 Form #455

Closed
tigs001 opened this issue Dec 4, 2014 · 0 comments
Closed

Nested OneToMany fieldsets in a ZF2 Form #455

tigs001 opened this issue Dec 4, 2014 · 0 comments
Labels

Comments

@tigs001
Copy link

tigs001 commented Dec 4, 2014

I am using Doctrine, with ZF2, and Zend From Annotations.

The main object in the Form is implemented as a fieldset, and I often have a OneToMany relationship to show zero or more sub-fieldsets (objects) in a form. (for example, a "product" that has zero or more "descriptions" in different languages).

To get this all working, each entity has its own Hydrator, which extends DoctrineModule\Stdlib\Hydrator\DoctrineObject as DoctrineHydrator. I am using the fezfez/ServiceLocatorFactory, in each Hydrator's __construct() to enable me to create the DoctrineHydrator with the entity manager. (This is to make Zend Form Annotations work with Doctrine, it probably does not have anything to do with the issue).

All the above is working well for forms that have at most 1 sub-fieldset.

Now, when I want nested fieldsets, I get problems. (for example, a "product", that has zero or more "suppliers", where a supplier has zero or more "locations")

To make this situation work, I had to implement two things:

1 - Implement extractValue() of the level 1 Hydrator,

so it would recursively hydrate the level 2 objects.

use DoctrineModule\Stdlib\Hydrator\DoctrineObject as DoctrineHydrator;

class suppliers extends DoctrineHydrator
{
    public function __construct()
    {
        $servicelocator = ServiceLocatorFactory::getInstance();
        $entitymanager = $servicelocator->get('Doctrine\ORM\EntityManager');

        parent::__construct($entitymanager,
            'Directory\Entity\suppliers',  // The FQCN of the hydrated/extracted object
            false                          // If set to true, hydrator will always use entity's public API
        );
   }

    public function extractValue($name, $value, $object = null)
    {
        switch ($name)
        {
            case 'locations':
                $hyd = new locations();
                $data = array();
                foreach ($value as $v)
                    $data[] = $hyd->extract($v);

                return $data;
                break;


            default:
                return parent::extractValue($name, $value, $object);
                break;
        }
    }
}

#### 2 - Implement extract() of the level 2 Hydrator,

so it would check if the object passed to it is already an array (which I assume means that it was already hydrated), and just return the array.

use DoctrineModule\Stdlib\Hydrator\DoctrineObject as DoctrineHydrator;

class locations extends DoctrineHydrator
{
    public function __construct()
    {
        $servicelocator = ServiceLocatorFactory::getInstance();
        $entitymanager = $servicelocator->get('Doctrine\ORM\EntityManager');

        parent::__construct($entitymanager,
            'Directory\Entity\locations',  // The FQCN of the hydrated/extracted object
            false                          // If set to true, hydrator will always use entity's public API
        );
    }

    public function extract($object)
    {
        /*
         * Check to see if the $object is already an
         * array.  If it is, then just return it.
         */
        if (is_array($object))
            return $object;

        return parent::extract($object);
    }
}

So basically, I am wondering if this is the best approach to solve this problem ?

I am also unsure what would happen if there were further nesting involved. I expect I would need to implement more pairs of the above functions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants