2012-09-14 31 views
7

我想要在插件類中獲取服務定位器/實體管理器,我怎麼能得到它。在ControllerPlugin類中的ZF2 getServiceLocator

在我的控制器中,我是這樣得到的。

public function getEntityManager() 
{ 
    if(null === $this->em){ 
     $this->em = $this->getServiceLocator()->get('doctrine.entitymanager.orm_default'); 
    } 
    return $this->em; 
} 

public function setEntityManager(EntityManager $em) 
{ 
    $this->em = $em; 
} 

但在插件類中我得到錯誤$ this-> getServiceLocator()行。因爲這在插件類中不可用。

我該怎麼做,以便我可以獲取一些記錄並在插件中插入少量數據庫。

我在我的插件類中有MvcEvent $ e對象,我可以利用這個來獲取實體管理器嗎?

我用this plugin創建我的插件

任何指南將appriciated。

更新:

namespace Auth\Controller\Plugin; 

use Zend\Mvc\Controller\Plugin\AbstractPlugin; 
use Zend\EventManager\EventInterface as Event; 
use Zend\Authentication\AuthenticationService; 

use Doctrine\ORM\EntityManager; 
use Auth\Entity\User; 
use Zend\Mvc\MvcEvent; 
class AclPlugin extends AbstractPlugin 
{ 

    /* 
    * @var Doctrine\ORM\EntityManager 
    */ 
    protected $em; 

    public function checkAcl($e) 
    { 

     $auth = new AuthenticationService(); 
     if ($auth->hasIdentity()) { 
      $storage = $auth->getStorage()->read();    
      if (!empty($storage->role)) 
       $role = strtolower ($storage->role);    
      else 
       $role = "guest";    
     } else { 
      $role = "guest";    
     } 
     $app = $e->getParam('application'); 
     $acl   = new \Auth\Acl\AclRules(); 

     $matches  = $e->getRouteMatch(); 
     $controller = $matches->getParam('controller'); 
     $action  = $matches->getParam('action', 'index'); 

     $resource = strtolower($controller); 
     $permission = strtolower($action); 

     if (!$acl->hasResource($resource)) { 
      throw new \Exception('Resource ' . $resource . ' not defined'); 
     } 

     if ($acl->isAllowed($role, $resource, $permission)) { 

      $query = $this->getEntityManager($e)->createQuery('SELECT u FROM Auth\Entity\User u'); 
      $resultIdentities = $query->execute(); 

      var_dump($resultIdentities); 
      exit(); 


      return; 

     } else { 
      $matches->setParam('controller', 'Auth\Controller\User'); // redirect 
      $matches->setParam('action', 'accessdenied');  

      return; 
     } 


    } 


    public function getEntityManager($e) { 

     var_dump($this->getController()); // returns null 
     exit(); 
     if (null === $this->em) { 
      $this->em = $this->getController()->getServiceLocator()->get('doctrine.entitymanager.orm_default'); 

     } 
     return $this->em; 
    } 

    public function setEntityManager(EntityManager $em) { 
     $this->em = $em; 
    } 

} 

我打電話上面類module.php

public function onBootstrap(Event $e) 
    { 

     $application = $e->getApplication();   
     $services = $application->getServiceManager();   

     $eventManager = $e->getApplication()->getEventManager(); 
     $eventManager->attach('dispatch', array($this, 'loadConfiguration'),101); 

    } 

public function loadConfiguration(MvcEvent $e) 
    { 

     $e->getApplication()->getServiceManager() 
        ->get('ControllerPluginManager')->get('AclPlugin') 
        ->checkAcl($e); //pass to the plugin...  

    } 

我在module.config.php註冊這個插件

return array( 
'controllers' => array(
     'invokables' => array(
      'Auth\Controller\User' => 'Auth\Controller\UserController', 
     ), 
    ), 

    'controller_plugins' => array(
     'invokables' => array(
      'AclPlugin' => 'Auth\Controller\Plugin\AclPlugin', 
    ), 
    ), 
); 

回答

8

你這是什麼意思是「插件類」?如果您正在討論abount控制器插件,您可以使用(從控制器插件的範圍)訪問它:$this->getController()->getServiceLocator()->get('doctrine.entitymanager.orm_default');

對於其他類,我通常會創建一個自動注入ServiceManager實例的工廠。例如,在模塊類:

public function getServiceConfig() 
{ 
    return array(
     'factories' => array(
      'myServiceClass' => function(ServiceManager $sm) { 
       $instance = new Class(); 
       $instance->setServiceManager($sm); 
       // Do some other configuration 

       return $instance; 
      }, 
     ), 
    ); 
} 

// access it using the ServiceManager where you need it 
$myService = $sm->get('myService'); 
+0

插件類是下控制器\插件\和是可調用通過使用返回的數組( 'controller_plugins'=>數組( 'invokables'=>數組( 'AclPlugin'=>'Auth \ Controller \ Plugin \ AclPlugin', ), ),);但不知何故,當我使用$ this-> getController() - > getServiceLocator() - > get('doctrine.entitymanager.orm_default');在插件類錯誤是致命錯誤:在/module/Auth/src/Auth/Controller/Plugin/AclPlugin.php中的非對象調用成員函數getServiceLocator() – Developer

+0

你可以請粘貼你的控制器插件類嗎?我這樣做的方式完全一樣,對我來說也適用。另外,請說明您的ZF2版本(betaN/RCn/2.0.0)。 –

+0

版本是zf2穩定relase 2.0.0。請參閱上述課程 – Developer

2

改變上述AclPlugin類,如下

namespace Auth\Controller\Plugin; 

use Zend\Mvc\Controller\Plugin\AbstractPlugin; 
use Zend\EventManager\EventInterface as Event; 
use Zend\Authentication\AuthenticationService; 

use Doctrine\ORM\EntityManager; 
use Auth\Entity\User; 
use Zend\Mvc\MvcEvent; 

use Zend\ServiceManager\ServiceManagerAwareInterface; 
use Zend\ServiceManager\ServiceManager; 
class AclPlugin extends AbstractPlugin implements ServiceManagerAwareInterface 
{ 

    /* 
    * @var Doctrine\ORM\EntityManager 
    */ 
    protected $em; 

    protected $sm; 

    public function checkAcl($e) 
    { 

     $this->setServiceManager($e->getApplication()->getServiceManager()); 

     $auth = new AuthenticationService(); 
     if ($auth->hasIdentity()) { 
      $storage = $auth->getStorage()->read();    
      if (!empty($storage->role)) 
       $role = strtolower ($storage->role);    
      else 
       $role = "guest";    
     } else { 
      $role = "guest";    
     } 
     $app = $e->getParam('application'); 
     $acl   = new \Auth\Acl\AclRules(); 

     $matches  = $e->getRouteMatch(); 
     $controller = $matches->getParam('controller'); 
     $action  = $matches->getParam('action', 'index'); 

     $resource = strtolower($controller); 
     $permission = strtolower($action); 

     if (!$acl->hasResource($resource)) { 
      throw new \Exception('Resource ' . $resource . ' not defined'); 
     } 

     if ($acl->isAllowed($role, $resource, $permission)) { 

      $query = $this->getEntityManager($e)->createQuery('SELECT u FROM Auth\Entity\User u'); 
      $resultIdentities = $query->execute(); 

      var_dump($resultIdentities); 
      foreach ($resultIdentities as $r) 
       echo $r->username; 
      exit(); 


      return; 

     } else { 
      $matches->setParam('controller', 'Auth\Controller\User'); // redirect 
      $matches->setParam('action', 'accessdenied');  

      return; 
     } 

    } 



    public function getEntityManager() { 

     if (null === $this->em) { 
      $this->em = $this->sm->getServiceLocator()->get('doctrine.entitymanager.orm_default'); 

     } 
     return $this->em; 
    } 

    public function setEntityManager(EntityManager $em) { 
     $this->em = $em; 
    } 

    /** 
    * Retrieve service manager instance 
    * 
    * @return ServiceManager 
    */ 
    public function getServiceManager() 
    { 
     return $this->sm->getServiceLocator(); 
    } 

    /** 
    * Set service manager instance 
    * 
    * @param ServiceManager $locator 
    * @return void 
    */ 
    public function setServiceManager(ServiceManager $serviceManager) 
    { 
     $this->sm = $serviceManager; 
    } 

} 
1

在控制器插件實際上得到的ServiceManager是很容易的!

只需使用:$this->getController()->getServiceLocator()

實施例:

namespace Application\Controller\Plugin; 

use Zend\Mvc\Controller\Plugin\AbstractPlugin; 

class Translate extends AbstractPlugin 
{ 

    public function __invoke($message, $textDomain = 'default', $locale = null) 
    { 
     /** @var \Zend\I18n\Translator\Translator $translator */ 
     $translator = $this->getController()->getServiceLocator()->get('translator'); 

     return $translator->translate($message, $textDomain, $locale); 
    } 
}