我想在插件类中获取服务定位器/实体管理器,我该怎么做呢。
在我的控制器中,我得到的就像这样。
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创建了我的插件
任何指南都会受到关注。
更新
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',
),
),
);
答案 0 :(得分:8)
“插件类”是什么意思?如果你正在谈论abount控制器插件,你可以使用(来自控制器插件的范围)访问它:$this->getController()->getServiceLocator()->get('doctrine.entitymanager.orm_default');
。
对于其他类,我通常会创建一个自动注入ServiceManager实例的工厂。例如,在Module类中:
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');
答案 1 :(得分: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;
}
}
答案 2 :(得分: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);
}
}