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

Hydration in combination with an abstract factory doesn't work #3

Open
weierophinney opened this issue Dec 31, 2019 · 2 comments
Open

Comments

@weierophinney
Copy link
Contributor

I've a problem to use the zf-hal hydrator in combination with an abstract factory. This is my module configuration:

public function getConfig()
{
    return [
        'hydrators' => [
            'abstract_factories' => [
                AbstractHydratorFactory::class,
            ]
        ],
        'service_manager' => [
            'factories' => [
                ModuleOptions::class => ModuleOptionsFactory::class,
            ],
        ],
        'zf-hal' => [
            'renderer' => [
                'default_hydrator' => 'reflection'
            ],
        ]
    ];
}

My abstract factory looks like this:

class AbstractHydratorFactory implements AbstractFactoryInterface
{
    public function canCreate(ContainerInterface $container, $requestedName)
    {
        $moduleOptions = $container->get(ModuleOptions::class);
        $configuration = $moduleOptions->getClass();
        return isset($configuration[$requestedName]['property_name_translation']);
    }

    public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
    {
        $moduleOptions = $container->get(ModuleOptions::class);
        $configuration = $moduleOptions->getClass();
        $hydrator = $container->get($moduleOptions->getHydrator());
        $hydrator->setNamingStrategy(
            new ArrayMapNamingStrategy(
                $configuration[$requestedName]['property_name_translation']
            )
        );
        return $hydrator;
    }
}

To test my module I created some unit tests. One of them is:

class HalEntityHydratorTest extends TestCase
{
    protected $moduleLoader;

    protected function setUp()
    {
        $this->moduleLoader = new ModuleLoader([
            'modules' => [
                'Zend\Hydrator',
                'Zend\Router',
                'ZF\Hal',
                'MyHalHydratorModule',
                'MyHalHydratorModuleTest\Integration\Hydrator\HalEntityHydratorTest',
            ],
            'module_listener_options' => [],
        ]);

        $this->moduleLoader->getApplication()->bootstrap();
    }

    public function testHalRendererWithHalEntities()
    {
        $halPlugin = $this->moduleLoader->getServiceManager()->get('ViewHelperManager')->get('Hal');

        $rootTestEntity = new RootTestEntity();
        $childTestEntity = new ChildTestEntity();

        $rootTestEntity->setChildEntity(new Entity($childTestEntity));
        $rootTestEntity->setUnkownChildEntity(new Entity(new UnkownChildTestEntity()));

        $expectedArray = [
            '_embedded' => [
                'phpunit:test-entity' => [
                    '_links' => [],
                ],
                'unkownChildEntity' => [
                    'unkownChildTestProperty' => 'phpunit',
                    '_links' => [],
                ],
            ],
            '_links' => [],
        ];

        $this->assertSame($expectedArray, $halPlugin->renderEntity(new Entity($rootTestEntity)));
    }
}

These are my test entities:

class ChildTestEntity
{
}

class UnkownChildTestEntity
{
    protected $unkownChildTestProperty = 'phpunit';
}

class RootTestEntity
{
    protected $childEntity;
    protected $unkownChildEntity;

    public function setUnkownChildEntity($unkownChildEntity)
    {
        $this->unkownChildEntity = $unkownChildEntity;
    }

    public function setChildEntity($childEntity)
    {
        $this->childEntity = $childEntity;
    }
}

And then it could be good to know what my test module configuration looks like:

public function getConfig()
{
    return [
        'zf-hal' => [
            'metadata_map' => [
                ChildTestEntity::class => [
                    'force_self_link' => false,
                ],
                UnkownChildTestEntity::class => [
                    'force_self_link' => false,
                ],
            ],
        ],
        'my-hal-hydrator-module' => [
            'class' => [
                RootTestEntity::class => [
                    'property_name_translation' => [
                        'childEntity' => 'phpunit:test-entity',
                    ],
                ],
            ],
        ],
    ];
}

Ok, enough sourcecode. What happens now?
I run my test suite and the test above fails because of the arrays are different. That's why the first key of the result array is still 'childEntity' and not 'phpunit:test-entity' as expected.
So I think the property replacement has not take place but I don't know why.


Originally posted by @kschroeer at zfcampus/zf-hal#171

@weierophinney
Copy link
Contributor Author

Can you show us the ModuleOptions class, please?


Originally posted by @weierophinney at zfcampus/zf-hal#171 (comment)

@weierophinney
Copy link
Contributor Author

No problem, here's the class:

use Zend\Stdlib\AbstractOptions;

class ModuleOptions extends AbstractOptions
{
    protected $hydrator = 'reflection';
    protected $class = [];

    public function getClass()
    {
        return $this->class;
    }

    public function setClass(array $class)
    {
        $this->class = $class;
        return $this;
    }

    public function getHydrator()
    {
        return $this->hydrator;
    }
}

And the corresponding factory:

use Interop\Container\ContainerInterface;
use Zend\ServiceManager\Factory\FactoryInterface;

class ModuleOptionsFactory implements FactoryInterface
{
    public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
    {
        $config = $container->get('config');

        $moduleConfig = [];
        if (isset($config['my-hal-hydrator-module'])) {
            $moduleConfig = $config['my-hal-hydrator-module'];
        }

        return new ModuleOptions($moduleConfig);
    }
}

Originally posted by @kschroeer at zfcampus/zf-hal#171 (comment)

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

No branches or pull requests

1 participant