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

Documentation seems to be wrong ... #3

Open
weierophinney opened this issue Dec 31, 2019 · 17 comments · May be fixed by #20 or #19
Open

Documentation seems to be wrong ... #3

weierophinney opened this issue Dec 31, 2019 · 17 comments · May be fixed by #20 or #19
Labels
Bug Something isn't working Documentation

Comments

@weierophinney
Copy link
Member

I found this code snippet in den documenation for the zend-navigation component (ZF3):

Docs » Reference » View Helpers » Intro

The Code snippet provided is not working for me:

<?php
// module/MyModule/Module.php

namespace MyModule;

use Zend\View\HelperPluginManager;
use Zend\Permissions\Acl\Acl;
use Zend\Permissions\Acl\Role\GenericRole;
use Zend\Permissions\Acl\Resource\GenericResource;

class Module
{
    /* ... */
    public function getViewHelperConfig()
    {
        return [
            'factories' => [
                // This will overwrite the native navigation helper
                'navigation' => function(HelperPluginManager $pm) {
                    // Setup ACL:
                    $acl = new Acl();
                    $acl->addRole(new GenericRole('member'));
                    $acl->addRole(new GenericRole('admin'));
                    $acl->addResource(new GenericResource('mvc:admin'));
                    $acl->addResource(new GenericResource('mvc:community.account'));
                    $acl->allow('member', 'mvc:community.account');
                    $acl->allow('admin', null);

                    // Get an instance of the proxy helper
                    $navigation = $pm->get('Zend\View\Helper\Navigation');

                    // Store ACL and role in the proxy helper:
                    $navigation->setAcl($acl);
                    $navigation->setRole('member');

                    // Return the new navigation helper instance
                    return $navigation;
                }
            ]
        ];
    }
    /* ... */
}

First it seems that in ZF3 the HelperPluginManager is not passed to the closure. Instead, I found out that the parent ServiceManager is passed.

If I change it to the code below, then the example is working for me:

class Module
{
    /* ... */
    public function getViewHelperConfig()
    {
        return [
            'factories' => [
                // This will overwrite the native navigation helper
                Helper\Navigation::class => function(\Zend\ServiceManager\ServiceLocatorInterface $serviceManager)
                {
                    $navigationViewHelper = new \Zend\View\Helper\Navigation();
                    $navigationViewHelper->setServiceLocator($serviceManager);

                    // Store ACL and role in the proxy helper:
                    $navigationViewHelper->setAcl($this->acl);
                    $navigationViewHelper->setRole($this->role);

                    // Return the new navigation helper instance
                    return $navigationViewHelper;
                }
            ]
        ];
    }
    /* ... */
}

Am I right? Is the documentation for ZF3 not correct?


Originally posted by @ksba at zendframework/zend-navigation#55

@weierophinney weierophinney added Bug Something isn't working Documentation labels Dec 31, 2019
@weierophinney
Copy link
Member Author

Am I right? Is the documentation for ZF3 not correct?

You are right. The documentation for ZF3 is wrong, because the Plugin Managers in version 3 of zend-servicemanager have changed.

Thanks for reporting!


Originally posted by @froschdesign at zendframework/zend-navigation#55 (comment)

@weierophinney
Copy link
Member Author

Btw. there is no need to override the view helper configuration. A (lazy) listener, which listen on the Zend\Mvc\MvcEvent::EVENT_RENDER is a better choice. The navigation is not required on every request.


Originally posted by @froschdesign at zendframework/zend-navigation#55 (comment)

@weierophinney
Copy link
Member Author

Thanks for the hint!

May I ask you to provide an example how to use a lazy listener which listen on the "render" Event?


Originally posted by @ksba at zendframework/zend-navigation#55 (comment)

@weierophinney
Copy link
Member Author

May I ask you to provide an example how to use a lazy listener which listen on the "render" Event?

The example uses zend-navigation as module.

config/application.config.php:

return [
    'modules' => [
        'Zend\Navigation',
        // …
    ],
];

config/autoload/global.php:

return [
    'event_manager'   => [
        'lazy_listeners' => [
            [
                'listener' => MyModule\Listener\NavigationListener::class,
                'method'   => 'addAcl',
                'event'    => Zend\Mvc\MvcEvent::EVENT_RENDER,
                'priority' => -100,
            ],
        ],
    ],
];

module/MyModule/src/MyModule/Listener/NavigationListener.php

namespace MyModule\Listener;

use Zend\Mvc\MvcEvent;

class NavigationListener
{
    /**
     * @param MvcEvent $event
     */
    public function addAcl(MvcEvent $event)
    {
        // Get service manager
        $serviceManager = $event->getApplication()->getServiceManager();

        // Get view helper plugin manager
        /** @var \Zend\View\HelperPluginManager $helperPluginManager */
        $helperPluginManager = $serviceManager->get('ViewHelperManager');

        // Get navigation plugin
        /** @var \Zend\View\Helper\Navigation $plugin */
        $plugin = $helperPluginManager->get('navigation');

        // Fetch ACL and role from service manager or identity (authentication service)
        // …

        $plugin->setAcl($acl);
        $plugin->setRole($role);
    }
}

At the moment, there is no factory for Event manager and (lazy) listeners. Therefore, we use the module class in this short example.

module/MyModule/Module.php:

namespace MyModule;

use Zend\EventManager\EventInterface;
use Zend\EventManager\LazyListenerAggregate;
use Zend\ModuleManager\Feature\BootstrapListenerInterface;

class Module implements BootstrapListenerInterface
{
    /**
     * @inheritdoc
     */
    public function onBootstrap(EventInterface $e)
    {
        /** @var \Zend\Mvc\MvcEvent $e */

        $application = $e->getApplication();

        /** @var array $config */
        $config = $application->getServiceManager()->get('config');

        if (array_key_exists('event_manager', $config)
            && is_array($config['event_manager'])
            && array_key_exists('lazy_listeners', $config['event_manager'])
        ) {
            $aggregate = new LazyListenerAggregate(
                $config['event_manager']['lazy_listeners'],
                $application->getServiceManager()
            );
            $aggregate->attach($application->getEventManager());
        }
    }
}

Added benefit: you can add more listeners in your config.


Originally posted by @froschdesign at zendframework/zend-navigation#55 (comment)

@weierophinney
Copy link
Member Author

Now I get the Picture. Works like a charm, Thanks a lot!


Originally posted by @ksba at zendframework/zend-navigation#55 (comment)

@weierophinney
Copy link
Member Author

Hi, I add code that written under but get 500 errror in this line $aggregate->attach($application->getEventManager()); .
$aggregate - object(Zend\EventManager\LazyListenerAggregate)#166 (4)
$application->getEventManager() - object(Zend\EventManager\EventManager)#74 (4)
but whan try to attach get 500 error. Can help me somebody?


Originally posted by @newmind507 at zendframework/zend-navigation#55 (comment)

@weierophinney
Copy link
Member Author

@newmind507
Please provide the complete error message, otherwise we would have to guess.


Originally posted by @froschdesign at zendframework/zend-navigation#55 (comment)

@weierophinney
Copy link
Member Author

Fatal error: Uncaught Zend\ServiceManager\Exception\ServiceNotFoundException: Unable to resolve service "Listener\NavigationListener" to a factory; are you certain you provided it during configuration? in /home/u850051480/vendor/zendframework/zend-servicemanager/src/ServiceManager.php:681 Stack trace: #0 /home/u850051480/vendor/zendframework/zend-servicemanager/src/ServiceManager.php(757): Zend\ServiceManager\ServiceManager->getFactory('Listener\Naviga...') #1 /home/u850051480/vendor/zendframework/zend-servicemanager/src/ServiceManager.php(200): Zend\ServiceManager\ServiceManager->doCreate('Listener\Naviga...') #2 /home/u850051480/vendor/zendframework/zend-eventmanager/src/LazyListener.php(119): Zend\ServiceManager\ServiceManager->get('Listener\Naviga...') #3 /home/u850051480/vendor/zendframework/zend-eventmanager/src/LazyListener.php(98): Zend\EventManager\LazyListener->fetchListener() #4 /home/u850051480/vendor/zendframework/zend-eventmanager/src/EventManager.php(322): Zend\EventManager\LazyListener->__invoke(Object( in /home/u850051480/vendor/zendframework/zend-servicemanager/src/ServiceManager.php on line 681


Originally posted by @newmind507 at zendframework/zend-navigation#55 (comment)

@weierophinney
Copy link
Member Author

@newmind507
Please recheck the namespace of your listener and the module class. I have updated to code example, because an error was included. (Application vs. MyModule)


Originally posted by @froschdesign at zendframework/zend-navigation#55 (comment)

@weierophinney
Copy link
Member Author

Module.php(namespace Application), NavigationListener.php(namespace Application\Listener)


Originally posted by @newmind507 at zendframework/zend-navigation#55 (comment)

@weierophinney
Copy link
Member Author

Do have also the namespace in your config? The Service Manager says something different in your error message: "Listener\NavigationListener"


Originally posted by @froschdesign at zendframework/zend-navigation#55 (comment)

@weierophinney
Copy link
Member Author

'event_manager'   => [
    'lazy_listeners' => [
        [
            'listener' => Application\Listener\NavigationListener::class,
            'method'   => 'addAcl',
            'event'    => Zend\Mvc\MvcEvent::EVENT_RENDER,
            'priority' => -100,
        ],
    ],
],

http://aquariunm.esy.es/ - error here


Originally posted by @newmind507 at zendframework/zend-navigation#55 (comment)

@weierophinney
Copy link
Member Author

Add the listener to your service-manager configuration.

module/Application/config/module.config.php:

'service_manager'    => [
	'factories' => [
		Application\Listener\NavigationListener::class => Zend\ServiceManager\Factory\InvokableFactory::class,
	],
],

(I'm sorry, at the moment I can not test this behaviour in an application. I'm on the road.)


Originally posted by @froschdesign at zendframework/zend-navigation#55 (comment)

@weierophinney
Copy link
Member Author

new error http://aquariunm.esy.es/


Originally posted by @newmind507 at zendframework/zend-navigation#55 (comment)

@weierophinney
Copy link
Member Author

@newmind507
Very simple: add ::class add the end! (see my code example)

Btw. if you need some more support, then please use the forum or the chat. Thanks!


Originally posted by @froschdesign at zendframework/zend-navigation#55 (comment)

@weierophinney
Copy link
Member Author

http://aquariunm.esy.es/ - still don't want work((


Originally posted by @newmind507 at zendframework/zend-navigation#55 (comment)

@weierophinney
Copy link
Member Author

@newmind507
Let's continue at the forum. (I have tested it with the skeleton application without problems.)


Originally posted by @froschdesign at zendframework/zend-navigation#55 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Something isn't working Documentation
Projects
None yet
1 participant