Skip to content
This repository has been archived by the owner on May 14, 2018. It is now read-only.

Zend\Di tries to initialize a guard causing error Missing instance/object for parameter rules for BjyAuthorize\Guard\Controller::__construct #59

Closed
japaveh opened this issue Jan 16, 2013 · 10 comments

Comments

@japaveh
Copy link

japaveh commented Jan 16, 2013

Well upgrading to the latest master solves the current error, but introduces a new one for me.
Uncaught exception 'Zend\Di\Exception\MissingPropertyException' with message 'Missing instance/object for parameter rules for BjyAuthorize\Guard\Controller::__construct'

It might be related to my own config, but disabling my own modules doesn't resolve the issue though


@japaveh yes, that's basically because you got Zend\Di crunching behind your locator. As soon as you enable a guard, $serviceLocator->has('BjyAuthorize\Guard\Controller') will return true even if no service by that name is defined (because Zend\Di can initialize it without service definition).

So that's basically the problem. The fact is that my latest patch puts the guard coming from the locator as prioritized. A solution may be to check if (!empty($guardOptions)) { /* construct / } else { / attempt to use locator */}.

This anyway is not optimal, since the maximum degree of flexibility is anyway provided by the locator.

For your specific case, the solution is to have following service definition:

return array(
    'factories' => function (\Zend\ServiceManager\ServiceLocatorInterface $sl) {
        return new \BjyAuthorize\Guard\Controller(
            array(
                array('controller' => 'admin', 'roles' => array(1)),
            ),
            $sl
        );
    },
);

@Ocramius Well, with that definition I don't have any error anymore of course, but also no guards are loaded.

A second, more fundamental problem I have with that is I need to decouple the guard configuration between the service configuration and the rest of the rules. In version 1.0 I have the possibility to have a dedicated file for authorization (per module) and a small service configuration.

Besides that, is my specific case so different compared to the default example (shouldn't we split this issue into a new one?)

@japaveh
Copy link
Author

japaveh commented Jan 16, 2013

Split from issue #56 (comment)

@Ocramius
Copy link
Contributor

@japaveh you can replace the part with

return array(
    'factories' => function (\Zend\ServiceManager\ServiceLocatorInterface $sl) {
        return new \BjyAuthorize\Guard\Controller(
            array(
                array('controller' => 'admin', 'roles' => array(1)),
            ),
            $sl
        );
    },
);

in your factory with something like:

return array(
    'factories' => function (\Zend\ServiceManager\ServiceLocatorInterface $sl) {
        $config = $sl->get('config');

        return new \BjyAuthorize\Guard\Controller($config['bjyauthorize']['guards']['BjyAuthorize\Guard\Controller'], $sl);
    },
);

This will do the trick and keep your config as before.

@japaveh
Copy link
Author

japaveh commented Jan 16, 2013

Yes, that works :)

Isn't it an idea to include this in the module.config.php of bjyauthorize itself?

But, I need to specify the index, to point the SL to the correct result

'service_manager' => array(
        'factories' => array(
            'translator'                    => 'Zend\I18n\Translator\TranslatorServiceFactory',
            'navigation'                    => 'Zend\Navigation\Service\DefaultNavigationFactory',
            'BjyAuthorize\Guard\Controller' => function (\Zend\ServiceManager\ServiceLocatorInterface $sl) {
                $config = $sl->get('config');
                return new \BjyAuthorize\Guard\Controller($config['bjyauthorize']['guards']['BjyAuthorize\Guard\Controller'], $sl);
            },
            'BjyAuthorize\Guard\Route'      => function (\Zend\ServiceManager\ServiceLocatorInterface $sl) {
                $config = $sl->get('config');
                return new \BjyAuthorize\Guard\Controller($config['bjyauthorize']['guards']['BjyAuthorize\Guard\Controller'], $sl);
            },
        ),
    ),

Tnx

I have a second problem with the config (ignorance of Doctrine Information), but I will create a dedicated ticket.

@Ocramius
Copy link
Contributor

@japaveh the default behavior seems ok to me. Zend\Di can try to outsmart things, especially when $serviceLocator->has(...) comes into play.

I would leave the end user define factories, but of course this doesn't deny you from opening a PR :)

(tests!)

@Ocramius
Copy link
Contributor

@japaveh news on this one? Can we close it?

@japaveh
Copy link
Author

japaveh commented Jan 25, 2013

@Ocramius. You can close this one.

If needed, I will create a PR for public review.

@nXqd
Copy link
Contributor

nXqd commented Feb 11, 2013

@Ocramius Should we put the service configuration :

'BjyAuthorize\Guard\Controller' => function (\Zend\ServiceManager\ServiceLocatorInterface $sl) {
                $config = $sl->get('config');
                return new \BjyAuthorize\Guard\Controller($config['bjyauthorize']['guards']['BjyAuthorize\Guard\Controller'], $sl);
            },
            'BjyAuthorize\Guard\Route'      => function (\Zend\ServiceManager\ServiceLocatorInterface $sl) {
                $config = $sl->get('config');
                return new \BjyAuthorize\Guard\Controller($config['bjyauthorize']['guards']['BjyAuthorize\Guard\Controller'], $sl);
            }

to the current configuration of the module, so it works out of the box. Need your comment, since I'm still newbie in zf2 :)

@Ocramius
Copy link
Contributor

Your fix at #79 looks good!

@webdevilopers
Copy link

Attention: the service configuration for the route must not be a controller otherwise you get an error that the resource id already exists in the ACL:

'BjyAuthorize\Guard\Controller' => function (\Zend\ServiceManager\ServiceLocatorInterface $sl) { $config = $sl->get('config'); return new \BjyAuthorize\Guard\Controller($config['bjyauthorize']['guards']['BjyAuthorize\Guard\Controller'], $sl); }, 'BjyAuthorize\Guard\Route' => function (\Zend\ServiceManager\ServiceLocatorInterface $sl) { $config = $sl->get('config'); return new \BjyAuthorize\Guard\Route($config['bjyauthorize']['guards']['BjyAuthorize\Guard\Route'], $sl); }

@Ocramius
Copy link
Contributor

Fixed in #81

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

No branches or pull requests

4 participants