Search code examples
phpformszend-framework2initializer

How to build and initializers without closure


I have this code:

public function getFormElementConfig()
    {
        return array(
            'initializers' => array(
                'ObjectManagerInitializer' => function ($element, FormElementManager $formElements) {
                    if ($element instanceof ObjectManagerAwareInterface) {
                        /** @var ServiceLocatorInterface $serviceLocator */
                        $serviceLocator = $formElements->getServiceLocator();
                        $entityManager = $serviceLocator->get('doctrine.entitymanager.orm_default');

                        $element->setObjectManager($entityManager);
                    }
                },
            ),
        );
    }

This formElement config give me the Object manager for hydrators and Doctrine ObjectSelect in my forms when they implements ObjectManagerAwareInterface.

How to move this out of a closure ? I don't have any clues, because initializers are auto. Do I need a factory ?

So far I tried to create a config key like this

 'form_elements'   => array(// here because getFormElementConfig
    'initializers' => array(
        'ObjectManagerInitializer' => 'Application\Initializers\ObjectManagerInitializer',
    ),
),

Then create an object

<?php
namespace Application\Initializers;

class ObjectManagerInitializer // implements or extends ??
{

}

But I don't know which interface or architecture it needs, i don't know how to build this.


Solution

  • Initializers just need to be callable, you can make a class callable by declaring the __invoke() magic method, then you just need to move the code from your anonymous function into that method, and finally add the FQCN for your initializer to the service manager you're attaching it to.

    So your class should look something like this...

    <?php
    namespace Application\Initializers;
    
    use DoctrineModule\Persistence\ObjectManagerAwareInterface;
    use Zend\Form\FormElementManager;
    use Zend\ServiceManager\ServiceLocatorInterface;
    
    class ObjectManagerInitializer
    {
        public function __invoke($element, FormElementManager $formElements) {
            if ($element instanceof ObjectManagerAwareInterface) {
                /** @var ServiceLocatorInterface $serviceLocator */
                $serviceLocator = $formElements->getServiceLocator();
                $entityManager = $serviceLocator->get('doctrine.entitymanager.orm_default');
    
                $element->setObjectManager($entityManager);
            }
        }
    }
    

    Add the FQCN to the form element manager in module.config.php

    'form_elements'   => array(
        'initializers' => array(
            'ObjectManagerInitializer' => 'Application\Initializers\ObjectManagerInitializer',
        ),
    ),