I\'m new to ZF2 and am having some trouble with what should be a basic idea.
I\'m using the ZfCommons User module for authentication, it\'s been installed and is ope
The exception is thrown because you are requesting the plugin in the constructor. Because of how plugins are tied to controllers, it is simply not possible to use plugins inside the constructor of the controller.
Background
The constructor is called first when an object is created. There is no other method called before __construct()
. If you inject something in this new instance via a setter method, you therefore have no access to this in the constructor.
A code example:
$obj = new MyClass();
$obj->setFoo('foo');
class MyClass()
{
protected $foo;
public function __construct()
{
var_dump($this->foo); // null!
}
public function setFoo($foo)
{
$this->foo = $foo;
}
}
This seems obvious, but it is exactly what is going on in Zend Framework 2 with controllers and the controller plugin manager. The manager is injected after the object is created:
$controller = new MySomethingController;
$controller->setPluginManager($plugins);
See also the code which injects the plugin manager in the controller on Github. Thus: you do not have access to the plugins in your constructor, unfortunately.
Alternative
You can access the plugins in any action you have:
class IndexController extends AbstractActionController
{
public function indexAction()
{
// This works!
$plugin = $this->plugin('ZfcUserAuthentication');
return new ViewModel();
}
public function testAction()
{
// This works too!
$plugin = $this->plugin('ZfcUserAuthentication');
return new ViewModel();
}
}
You can also attach a listener to the dispatch of the controller, so a function call is made for every action, not the ones you specify:
use Zend\Mvc\MvcEvent;
class IndexController extends AbstractActionController
{
public function indexAction()
{
return new ViewModel();
}
public function testAction()
{
return new ViewModel();
}
protected function attachDefaultListeners()
{
parent::attachDefaultListeners();
$events = $this->getEventManager();
$events->attach(MvcEvent::EVENT_DISPATCH, array($this, 'checkUserIdentity'));
}
public function checkUserIdentity()
{
// This works!
// It is called for both indexAction() and testAction()
$plugin = $this->plugin('ZfcUserAuthentication');
}
}
You can even remove this logic out of the controller, so you can reuse it for multiple controllers:
class Module
{
public function onBootstrap($e)
{
$app = $e->getApplication();
$em = $app->getEventManager()->getSharedManager();
$em->attach('MyModule\Controller\MyController', MvcEvent::EVENT_DISPATCH, function($e) {
$controller = $e->getController();
// This works!
$plugin = $controller->plugin('ZfcUserAuthentication');
});
}
}
So, depending on how DRY you want it, there are many possibilities to access the plugin outside the constructor.
According to the docs, you can use the following
$this->zfcUserAuthentication()->hasIdentity()
$this->zfcUserAuthentication()->getIdentity()