Search code examples
dependency-injectionzend-framework2chaining

Chaining Dependency Injection in ZF2


I am trying to create a simple email templating test in ZF2, I am using Dependency injection in order to create an instance of the PhpRenderer class, with all the dependencies set.

It appears that I may be struggling with chaining the injections as the path 'email' is not present in the AggregateResolver.

inside module.config.php

'di' => array(
    'instance' => array(
        'Zend\View\Resolver\TemplatePathStack' => array(
            'options' => array(
                'script_paths'  => array(
                    'email' => __DIR__ . '/../view/application/email',
                ),
             ),
        ),
        'Zend\View\Resolver\AggregateResolver' => array(
            'attach' => array(
                'Zend\View\Resolver\TemplatePathStack',
            ),
        ),
        'Zend\View\Renderer\PhpRenderer' => array(
            'setResolver' => 'Zend\View\Resolver\AggregateResolver',
        ),
    ),
),

inside TestController.php

    $di = new \Zend\Di\Di;
    $renderer = $di->get('Zend\View\Renderer\PhpRenderer');
    $content = $renderer->render('email/test', null);

    echo($content);

Message:

    Zend\View\Renderer\PhpRenderer::render: Unable to render template "email/test"; resolver could not resolve to a file

Any help would be gratefully received.


Since writing the above, I was playing around and removed the TemplatePathStack from the di array and this had no effect at all, So I am not sure it is being used at all by the AggregateResolver, so it may be a chaining issue:

'di' => array(
    'instance' => array(
        /*'Zend\View\Resolver\TemplatePathStack' => array(
            'addPaths' => array(
                'paths'  => array(
                    'email' => __DIR__ . '/../view/application/email',
                ),
             ),
        ),*/
        'Zend\View\Resolver\AggregateResolver' => array(
            'attach' => array(
                'Zend\View\Resolver\TemplatePathStack',
            ),
        ),
        'Zend\View\Renderer\PhpRenderer' => array(
            'setResolver' => 'Zend\View\Resolver\AggregateResolver',
        ),
    ),
),

Aborgrove


Solution

  • In the end I solved it by moving the di array out of the module.conf.php and recreating it in the Module getServiceConf() method. (Although I am not sure this is the best place to put it)

     public function getServiceConfig()
    {
        return array(
            'factories' => array(
                // using the Session Manger to create one instance of the follwing models
                ......... more code here ............
                'EmailTemplatePathStack' => function($sm) {
                    $template_path_stack =  new \Zend\View\Resolver\TemplatePathStack();
                    $paths  = array('emailfolder' => __DIR__ . '/view/application/email');
                    $template_path_stack->addPaths($paths);
                    return $template_path_stack;
    
                },
                'EmailAggregateResolver' => function($sm) {
                    $resolver =  new \Zend\View\Resolver\AggregateResolver();
                    $resolver->attach($sm->get('EmailTemplatePathStack'));
                    var_dump($resolver);
                    return $resolver;
    
                },
                'EmailPhpRenderer' => function($sm) {
                    $php_renderer =  new \Zend\View\Renderer\PhpRenderer();
                    $php_renderer->setResolver($sm->get('EmailAggregateResolver'));
                    return $php_renderer;
                },
            ),
        );
    }
    

    Then changing the controller to:

        $sm = \Application\Model\ServiceLocatorFactory::getInstance();
        $renderer = $sm->get('EmailPhpRenderer');
        $content = $renderer->render('test.phtml', null);
    
        echo($content);