Module.php中的ZF3依赖注入 [英] ZF3 Dependency injection in Module.php

查看:69
本文介绍了Module.php中的ZF3依赖注入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在将ZF2应用程序迁移到ZF3. 大多数情况下,一切进展顺利,但我只能坚持一件事.

I'm currently migrating a ZF2 application to ZF3. Mostly everything is going smoothly but I'm stuck on one thing.

在我的Module.php中,我使用zend-permissions-acl进行ACL管理.

In my Module.php, I have an ACL management using zend-permissions-acl.

class Module
{
protected $defaultLang = 'fr';

public function onBootstrap(MvcEvent $e)
{
    $eventManager        = $e->getApplication()->getEventManager();
    $moduleRouteListener = new ModuleRouteListener();
    $moduleRouteListener->attach($eventManager);

    if (!$e->getRequest() instanceof ConsoleRequest){
        $eventManager->attach(MvcEvent::EVENT_RENDER_ERROR, array($this, 'onRenderError'));
        $eventManager->attach(MvcEvent::EVENT_RENDER, array($this, 'onRender'));
        $eventManager->attach(MvcEvent::EVENT_FINISH, array($this, 'onFinish'));

        $this->initAcl($e);
        $eventManager->attach('route', array($this, 'checkAcl'));
    }
}

public function checkAcl(MvcEvent $e) {
    $app = $e->getApplication();
    $sm  = $app->getServiceManager();
    $route = $e -> getRouteMatch() -> getMatchedRouteName();
    $authService = $sm->get('AuthenticationService');
    $jwtService = $sm->get('JwtService');
    $translator = $sm->get('translator');

    $identity = null;
    try {
        $identity = $jwtService->getIdentity($e->getRequest());
    } catch(\Firebase\JWT\ExpiredException $exception) {
        $response = $e->getResponse();

        $response->setStatusCode(401);
        return $response;
    }

    if(is_null($identity) && $authService->hasIdentity()) { // no header being passed on... we try to use standard validation
        $authService->setJwtMode(false);
        $identity = $authService->getIdentity();
    }

    $userRole = 'default';
    $translator->setLocale($this->defaultLang);
    if(!is_null($identity))
    {
        $userRole = $identity->getType();

        //check if client or prospect
        if($userRole >= User::TYPE_CLIENT)
        {
            $userManagementRight = UserRight::CREATE_USERS;
            if($identity->hasRight($userManagementRight))
                $userRole = 'userManagement';
        }

        $translator->setLocale($identity->getLang());
    }

    if (!$e->getViewModel()->acl->isAllowed($userRole, null, $route)) {
        $response = $e -> getResponse();

        $response->setStatusCode(403);
        return $response;
    }
public function initAcl(MvcEvent $e) {
    //here is list of routes allowed
}
}

我的问题是我仍在使用getServiceManager,因此得到了不建议使用的警告:Usage of Zend\ServiceManager\ServiceManager::getServiceLocator is deprecated since v3.0.0;

My issue here is that I'm still using the getServiceManager and therefore getting the deprecated warning : Usage of Zend\ServiceManager\ServiceManager::getServiceLocator is deprecated since v3.0.0;

基本上,我只需要将依赖项注入Module.php中. 我想否则我将必须直接将checkAcl移至Controller并将ACL注入其中?不确定执行此操作的正确方法是什么.

Basically, I just need to inject dependencies into Module.php. I guess otherwise I would have to move the checkAcl to the Controller directly and inject the ACL in them ? Not sure what is the proper way of doing this.

任何对此的反馈将不胜感激.

Any feedback on this would be greatly appreciated.

此致

罗伯特

推荐答案

要解决此问题,您应该使用Listener类和Factory.它还可以帮助您进一步分离问题:)

To solve the issue you should use a Listener class and Factory. It would also help you with more separation of concerns :)

根据您的代码判断,您似乎很有能力弄清楚问题.因此,我仅举一个我自己的示例,因此您应该使用自己的代码填写自己(我也有点懒,在我可以复制/粘贴我的代码时不希望重写所有内容在;))

You seem quite capable of figuring stuff out, judging by your code. As such, I'm just going to give you an example of my own, so you should fill yours in with your own code (I'm also a bit lazy and do not wish to rewrite everything when I can copy/paste my code in ;) )

在您的module.config.php中:

'listeners'       => [
    // Listing class here will automatically have them "activated" as listeners
    ActiveSessionListener::class,
],
'service_manager' => [
    'factories' => [
        // The class (might need a) Factory
        ActiveSessionListener::class => ActiveSessionListenerFactory::class,
    ],
],

工厂

<?php

namespace User\Factory\Listener;

use Doctrine\Common\Persistence\ObjectManager;
use Doctrine\ORM\EntityManager;
use Interop\Container\ContainerInterface;
use User\Listener\ActiveSessionListener;
use Zend\Authentication\AuthenticationService;
use Zend\ServiceManager\Factory\FactoryInterface;

class ActiveSessionListenerFactory implements FactoryInterface
{
    public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
    {
        /** @var ObjectManager $entityManager */
        $entityManager = $container->get(EntityManager::class);
        /** @var AuthenticationService $authenticationService */
        $authenticationService = $container->get(AuthenticationService::class);

        return new ActiveSessionListener($authenticationService, $entityManager);
    }
}

听众

<?php

namespace User\Listener;

use Doctrine\Common\Persistence\ObjectManager;
use Doctrine\ORM\EntityManager;
use User\Entity\User;
use Zend\Authentication\AuthenticationService;
use Zend\EventManager\Event;
use Zend\EventManager\EventManagerInterface;
use Zend\EventManager\ListenerAggregateInterface;
use Zend\Mvc\MvcEvent;

/**
 * Class ActiveSessionListener
 *
 * @package User\Listener
 *
 * Purpose of this class is to make sure that the identity of an active session becomes managed by the EntityManager.
 * A User Entity must be in a managed state in the event of any changes to the Entity itself or in relations to/from it.
 */
class ActiveSessionListener implements ListenerAggregateInterface
{
    /**
     * @var AuthenticationService
     */
    protected $authenticationService;

    /**
     * @var ObjectManager|EntityManager
     */
    protected $objectManager;

    /**
     * @var array
     */
    protected $listeners = [];

    /**
     * CreatedByUserListener constructor.
     *
     * @param AuthenticationService $authenticationService
     * @param ObjectManager         $objectManager
     */
    public function __construct(AuthenticationService $authenticationService, ObjectManager $objectManager)
    {
        $this->setAuthenticationService($authenticationService);
        $this->setObjectManager($objectManager);
    }

    /**
     * @param EventManagerInterface $events
     */
    public function detach(EventManagerInterface $events)
    {
        foreach ($this->listeners as $index => $listener) {
            if ($events->detach($listener)) {
                unset($this->listeners[$index]);
            }
        }
    }

    /**
     * @param EventManagerInterface $events
     */
    public function attach(EventManagerInterface $events, $priority = 1)
    {
        $events->attach(MvcEvent::EVENT_ROUTE, [$this, 'haveDoctrineManagerUser'], 1000);
    }

    /**
     * @param Event $event
     *
     * @throws \Doctrine\Common\Persistence\Mapping\MappingException
     * @throws \Doctrine\ORM\ORMException
     */
    public function haveDoctrineManagerUser(Event $event)
    {
        if ($this->getAuthenticationService()->hasIdentity()) {
            // Get current unmanaged (by Doctrine) session User
            $identity = $this->getAuthenticationService()->getIdentity();

            // Merge back into a managed state
            $this->getObjectManager()->merge($identity);
            $this->getObjectManager()->clear();

            // Get the now managed Entity & replace the unmanaged session User by the managed User
            $this->getAuthenticationService()->getStorage()->write(
                $this->getObjectManager()->find(User::class, $identity->getId())
            );
        }
    }

    /**
     * @return AuthenticationService
     */
    public function getAuthenticationService() : AuthenticationService
    {
        return $this->authenticationService;
    }

    /**
     * @param AuthenticationService $authenticationService
     *
     * @return ActiveSessionListener
     */
    public function setAuthenticationService(AuthenticationService $authenticationService) : ActiveSessionListener
    {
        $this->authenticationService = $authenticationService;

        return $this;
    }

    /**
     * @return ObjectManager|EntityManager
     */
    public function getObjectManager()
    {
        return $this->objectManager;
    }

    /**
     * @param ObjectManager|EntityManager $objectManager
     *
     * @return ActiveSessionListener
     */
    public function setObjectManager($objectManager)
    {
        $this->objectManager = $objectManager;

        return $this;
    }

}

重要的一点:

  • Listener必须实现ListenerAggregateInterface
  • 必须在模块配置的listeners键中激活

就是这样.然后,您有了侦听器的基本构建块.

That's it really. You then have the basic building blocks for a Listener.

除了attach函数之外,如果需要,您可以将其余部分放入抽象类中.将使用多个侦听器保存几行(读取:重复代码).

Apart from the attach function you could take the rest and make that into an abstract class if you'd like. Would save a few lines (read: duplicate code) with multiple Listeners.

注意::上面的示例使用普通的 EventManager .通过对上述代码进行简单的更改,您可以通过将它们附加到 SharedEventManager 来创建通用"侦听器,如下所示:

NOTE: Above example uses the normal EventManager. With a simple change to the above code you could create "generic" listeners, by attaching them to the SharedEventManager, like so:

/**
 * @param EventManagerInterface $events
 */
public function attach(EventManagerInterface $events, $priority = 1)
{
    $sharedManager = $events->getSharedManager();

    $sharedManager->attach(SomeClass::class, EventConstantClass::SOME_STRING_CONSTANT, [$this, 'callbackFunction']);
}

public function callbackFunction (MvcEvent $event) {...}

这篇关于Module.php中的ZF3依赖注入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆