Я хочу использовать свои объекты внутри своего настраиваемого плагина. Итак, я делаю в таком порядке:
1) Объявил мой плагин в модуле \src\Plugin\Plugin.php
namespace Application\Plugin;
use Zend\Mvc\Controller\Plugin\AbstractPlugin;
use Doctrine\ORM\EntityManager;
use User\Entity\UserProfile;
use Zend\ServiceManager\ServiceManager;
class AuthenticationPlugin extends AbstractPlugin {
protected $entityManager;
protected $serviceManager;
public function setServiceManager(ServiceManager $locator) {
$this->serviceManager = $locator;
}
public function getServiceManager() {
return $this->serviceManager;
}
public function getEntityManager() {
$userEntityFactory = new \Application\Factory\UserEntityFactory();
$this->entityManager = $userEntityFactory->createService($this->getServiceManager());
return $this->entityManager;
}
public function someAction($user_email) {
$user = $this->getEntityManager()->getRepository('User\Entity\User')->findBy(array('email'=>$user_email));
}
}
2) Создал мою фабрику:
namespace User\Factory;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
class UserEntityFactory implements FactoryInterface {
public function createService(ServiceLocatorInterface $serviceLocator) {
return $serviceLocator->get('doctrine.entitymanager.orm_default');
}
}
3) Определяет его в module.config.php:
'service_manager' => array(
'factories' => array(
'UserEntityFactory' => 'Application\Factory\UserEntityFactory',
),
),
'controller_plugins' => array(
'invokables' => array(
'AuthenticationPlugin' => 'Application\Plugin\AuthenticationPlugin',
)
),
4) Отправка ServiceLocator в мой плагин в Module.php:
public function getServiceConfig() {
return array(
'factories' => array(
'AuthenticationPlugin' => function($sm) {
$locator = $sm->getServiceLocator();
$instance = new \Application\Plugin\AuthenticationPlugin();
$instance->setServiceManager($locator);
return $instance;
},
),
);
}
5)... и называя это inBootstrap:
$em->attach('ZfcUser\Service\User', 'register', function($e) {
$user = $e->getParam('user'); // User account object
$authenticationPlugin = new AuthenticationPlugin();
$authenticationPlugin->someAction($user->getEmail());
});
Но я получил ошибку, что $ locator в плагине пуст... Я смущен, и я уверен, что я делаю что-то неправильно... или все. Я был бы счастлив, если кто-то поделится опытом или покажет порядок действий. Благодарю.
Вам не нужно вводить весь объект сервис-менеджера в свой класс плагина.
Вам нужно всего лишь ввести объект репозитория User\Entity\User, это будет единственная зависимость, требуемая в вашем классе плагинов.
Вы должны передать это в конструктор вашего класса плагина через свой завод:
public function getServiceConfig() {
return array(
'factories' => array(
'AuthenticationPlugin' => function($sm) {
return new \Application\Plugin\AuthenticationPlugin($sm->get('doctrine.entitymanager.orm_default')->getRepository('User\Entity\User'));
},
),
);
}
в вашем классе плагина:
class AuthenticationPlugin extends AbstractPlugin {
private $userRepository;
public function __construct(\User\Entity\User $userRepository){
$this->userRepository=$userRepository;
}
public function someAction($user_email) {
$user = $this->userRepository->findBy(array('email'=>$user_email));
}
}
Поскольку вы настраиваете плагин через module.php, вам не нужно также объявлять плагин как invokable в вашем файле конфигурации. Поэтому удалите следующую строку из модуля module.config.php
'AuthenticationPlugin' => 'Application\Plugin\AuthenticationPlugin'
В качестве побочного примечания есть разные плюсы и минусы между объявлением ваших сервисов/плагинов в файле module.php или module.config. Это, однако, не было вопросом, поэтому я не буду вдаваться в подробности здесь.