Ocramius / ProxyManager

🎩✨🌈 OOP Proxy wrappers/utilities - generates and manages proxies of your objects
MIT License
4.95k stars 188 forks source link

Unable to render template "proxy-manager-generated-proxy" #188

Closed starker-xp closed 10 years ago

starker-xp commented 10 years ago

After reading a presentation on Slideshare about ZF3 (http://fr.slideshare.net/blanchonvincent/zf3-introduction, page 18/19), I wanted to integrate the "lazy loading" with the "proxy manager". I happen to secure with this error: Unable to render template "proxy-manager-generated-proxy/y-tox-ontz-ojc6-im-zh-y3-rvcnki-o3-m6-ndq6-il-byb3h5-tw-fu-y-wdlclx-gywn0b3-j5-x-exhenl-mb2-fka-w5n-r2hvc3-rgywn0b3-j5-ijt9/index

class IndexControllerFactory implements FactoryInterface {

    public function createService(ServiceLocatorInterface $serviceLocator) {
        $sm = $serviceLocator->getServiceLocator();
        $factory = new LazyLoadingGhostFactory();
        $proxy = $factory->createProxy("Application\Controller\IndexController", function($proxy, $method, $parameters, &$initializer) use ($sm) {
            if ($method == 'getContactForm') {
                $form = $sm->get('form.contact');
                $proxy->setContactForm($form);
            }
        });
        return $proxy;
    }

}

I test this code and i happen same result :

  $factory = new LazyLoadingGhostFactory();

by

$configuration = new \ProxyManager\Configuration();
$configuration->setProxiesTargetDir(__DIR__ . '/../../../../../../cache');
$factory = new LazyLoadingGhostFactory($configuration);

Do I forget to configure something? I tested the code on linux and windows. Under the revisions '0.5.2' and '2.0.0@dev'

Ocramius commented 10 years ago

There's nothing wrong with the proxy itself here: what is broken is https://github.com/zendframework/zf2/blob/3e6936d75c7fcb4220a9a547d78c6c217a746060/library/Zend/Mvc/View/Http/InjectTemplateListener.php#L67

Basically, the view layer is using get_class($controller) to find out which template to render.

This is easily fixable by using $viewModel->setTemplate('the/template/name') in your controller (before returning the ViewModel instance).

Otherwise, you can also use your own listener that does what the Zend\Mvc\View\Http\InjectTemplateListener is doing, but using get_parent_class() internally

get_class() against a proxy will indeed report a different class, as proxies are fake objects.

Ocramius commented 10 years ago

Additionally, I suggest you to inject the form.contact instance directly in the IndexControllerFactory, and make form.contact itself lazy instead.

blanchonvincent commented 10 years ago

@starker-xp I have a fix for this : https://gist.github.com/blanchonvincent/6d0aad60f12d19fdba04 You have to replace InjectTemplateListener by the InjectProxyTemplateListener : https://gist.github.com/blanchonvincent/609b3f8c16021437ec12

starker-xp commented 10 years ago

Thanks for you help. My problem is solved.