ZF - Doctrine2 Cannot Retrieve Repository - php

whats this wrong with this? I'm new in zend framework...........................................................................................................................
this is my folder struct
UserControllerFactory.php
<?php
namespace Admin\Controller\Factory;
use Admin\Controller\UserController;
use User\Entity\User;
use Admin\Form\UserForm;
use User\Model\UserTable;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\Mapping\Entity;
use Interop\Container\ContainerInterface;
class UserControllerFactory
{
public function __invoke(ContainerInterface $container)
{
/** #var EntityManager $entityManager */
$entityManager = $container->get(EntityManager::class);
$repository = $entityManager->getRepository(User::class);
$userForm = $container->get(UserForm::class);
return new UserController($entityManager, $repository, $userForm);
}
}
UserController.php
<?php
namespace Admin\Controller;
//use User\Entity\User;
use Admin\Form\UserForm;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\EntityRepository;
use Zend\Hydrator\ClassMethods;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\Http\Request;
use Zend\View\Model\ViewModel;
class UserController extends AbstractActionController
{
/**
* #var EntityRepository
*/
private $repository;
/**
* #var EntityManager
*/
private $entityManager;
private $form;
public function __constructor(EntityManager $entityManager, EntityRepository $repository, UserForm $form){
$this->form = $form;
$this->repository = $repository;
$this->entityManager = $entityManager;
}
public function indexAction()
{
return new ViewModel([
'users' => $this->repository->fetchAll()
]);
}
public function addAction()
{
$form = $this->form;
$form->get('submit')->setValue('Adicionar');
$request = $this->getRequest();
if (!$request->isPost()) {
return ['form' => $form];
}
$form->setData($request->getPost());
if (!$form->isValid()) {
return ['form' => $form];
}
$post = $form->getData();
$this->entityManager->persist($post);
$this->entityManager->flush();
return $this->redirect()->toRoute('admin/user');
}
public function editAction()
{
$id = (int)$this->params()->fromRoute('id', 0);
if (!$id || !($post = $this->repository->find($id))) {
return $this->redirect()->toRoute('admin/user');
}
$form = $this->form;
$form->bind($post);
$form->get('submit')->setAttribute('value', 'Edit Post');
$request = $this->getRequest();
if (!$request->isPost()) {
return [
'id' => $id,
'form' => $form
];
}
$form->setData($request->getPost());
if (!$form->isValid()) {
return [
'id' => $id,
'form' => $form
];
}
$this->entityManager->flush();
return $this->redirect()->toRoute('admin/user');
}
public function deleteAction()
{
$id = (int)$this->params()->fromRoute('id', 0);
if (!$id || !($post = $this->repository->find($id))) {
return $this->redirect()->toRoute('admin/user');
}
$this->entityManager->remove($post);
$this->entityManager->flush();
return $this->redirect()->toRoute('admin/user');
}
}
UserTable.php
<?php
/**
* Created by PhpStorm.
* User: jho
* Date: 24/06/2017
* Time: 18:55
*/
namespace User\Model\Factory;
use Zend\Db\Exception\RuntimeException;
use Zend\Db\TableGateway\TableGatewayInterface;
class UserTable
{
private $tableGateway;
public function find($id)
{
$id = (int)$id;
$rowset = $this->tableGateway->select(['id' => $id]);
$row = $rowset->current();
if (!row) {
throw new RuntimeException(sprintf(
'Could not retrieve the row %d', $id
));
}
return $row;
}
public function fetchAll(){
return $this->tableGateway->select();
}
public function save(User $user){
$data = [
'username'=>$user->username,
'fullname'=>$user->fullname,
'password'=>$user->password,
];
$id = (int) $user->id;
if((int)$user->id === 0){
$this->tableGateway->insert($data);
return;
}
if(!$this->find($id)){
throw new RuntimeException(sprintf(
'Could not retrieve the row %d', $id
));
}
$this->tableGateway->update($data, ['id'=>$id]);
}
}
User.php
<?php
namespace User\Model;
class User
{
public $id;
public $fullname;
public function exchangeArray(array $data){
$this->id = (!empty($data['id'])) ? $data['id']: null;
$this->title = (!empty($data['fullname'])) ? $data['fullname']: null;
}
public function getArrayCopy(){
return[
'id'=>$this->id,
'fullname'=>$this->fullname,
];
}
}

You are mixing up two different approaches of retrieving data from your database.
You can either use the Zend approach as in TableGateway's or you can go with Doctrine (EntityManager/Repositories).
So you've got to make a choice between one of the methods you want to use within your controller.
So if you want to stick with Doctrine, you could take a look at the following slides of Ocramius: http://ocramius.github.io/presentations/doctrine-orm-and-zend-framework-2/#/59
So you pretty much have to update your User model:
namespace User\Model;
use Doctrine\ORM\Mapping AS ORM;
/**
* #ORM\Entity()
*/
class User
{
/**
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
* #ORM\Column(type="integer")
*/
public $id;
/** #ORM\Column(type="string") */
public $fullname;
public function exchangeArray(array $data){
$this->id = (!empty($data['id'])) ? $data['id']: null;
$this->title = (!empty($data['fullname'])) ? $data['fullname']: null;
}
public function getArrayCopy(){
return[
'id'=>$this->id,
'fullname'=>$this->fullname,
];
}
}
Update the following file module.config.php of your User module and add the following to your configuration:
array(
'doctrine' => array(
'driver' => array(
'application_entities' => array(
'class' =>'Doctrine\ORM\Mapping\Driver\AnnotationDriver',
'cache' => 'array',
'paths' => array(__DIR__ . '/../src/User/Model')
),
'orm_default' => array(
'drivers' => array(
'User\model' => 'application_entities'
)
),
)
),
Notice that this requires the Doctrine-ORM-module. See: https://github.com/doctrine/DoctrineORMModule

Related

Bug Symfony Can use "yield from" only with arrays

I'm creating a website with Symfony 5. I have a problem that I can't solve.
I need to be able to create entities and for that I want to use a form generated by Symfony.
Symfony sends me this error:
Can use "yield from" only with arrays and Traversables
If I modify anything in my "Entities" entity then symfony sends me back:
My field I was waiting for
Great, that's exactly what I need, but the problem is that if I refresh the page the error comes back.
<?php
namespace App\Controller\Admin;
use App\Entity\Entities;
use App\Entity\Events;
use App\Form\EntitiesType;
use App\Form\EventsType;
use App\Repository\CriteriasRepository;
use App\Repository\EntitiesRepository;
use App\Repository\EventsRepository;
use Doctrine\Persistence\ObjectManager;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
Class AdminHome extends AbstractController {
protected $event;
protected $entity;
protected $criteria;
protected $twig;
public function __construct(EventsRepository $event, EntitiesRepository $entity, CriteriasRepository $criteria, ObjectManager $em)
{
$this->event = $event;
$this->entity = $entity;
$this->criteria = $criteria;
$this->em = $em;
}
public function index(){
$event = $this->event->findOneBy(['current' => 1]);
$criterias = $this->indexCriteria($event);
$entities = $this->indexEntity($event);
return new Response($this->render('admin/home.html',[ 'event' => $event, 'entities' => $entities, 'criterias' => $criterias ]));
}
public function indexEntity(Events $event){
return $event->getEntity();
}
public function indexCriteria(Events $event){
return $event->getCriterias();
}
/**
* #Route("/admin/event/create", name="admin.event.new")
*/
public function newEvent(Request $request){
$event = new Events();
$form = $this->createForm(EventsType::class, $event);
$form->handleRequest($request);
if($form->isSubmitted() && $form->isValid()){
$this->em->persist($event);
$this->em->flush();
return $this->redirectToRoute('adminHome');
}
return $this->render('admin/event/eventNew.html', ['event' => $event, 'form' => $form->createView()]);
}
/**
* #Route("/admin/entity/create", name="admin.entity.new")
*/
public function newEntity(Request $request){
$entity = new Entities();
$form = $this->createForm(EntitiesType::class, $entity);
$form->handleRequest($request);
if($form->isSubmitted() && $form->isValid()){
$this->em->persist($entity);
$this->em->flush();
return $this->redirectToRoute('adminHome');
}
return $this->render('admin/entity/entityNew.html', ['entity' => $entity, 'form' => $form->createView()]);
}
// /**
// * #Route("/admin/entity/edit", name="admin.entity.edit")
// */
// public function editEntity(Entities $entity, Request $request){
// $form = $this->createForm(EntityType::class, $entity);
// $form->handleRequest($request);
// if($form->isSubmitted() && $form->isValid()){
// $this->em->flush();
// return $this->redirectToRoute('adminHome');
// }
// return $this->render('admin/entityEdit.html', ['entity' => $entity, 'form' => $form->createView()]);
// }
}
?>
<?php
namespace App\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity(repositoryClass=EntitiesRepository::class)
*/
class Entities
{
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", length=255)
*/
private $entityName;
/**
* #ORM\OneToMany(targetEntity=Rates::class, mappedBy="entity")
*/
private $rates;
/**
* #ORM\ManyToMany(targetEntity=Events::class, mappedBy="entity")
*/
private $event;
/**
* #ORM\Column(type="string", length=255)
*/
private $descriptionFr;
/**
* #ORM\Column(type="string", length=255, nullable=true)
*/
private $descriptionEn;
/**
* #ORM\ManyToMany(targetEntity=Themes::class, inversedBy="entities")
*/
private $theme;
public function __construct()
{
$this->rates = new ArrayCollection();
$this->event = new ArrayCollection();
$this->theme = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getEntityName(): ?string
{
return $this->entityName;
}
public function setEntityName(string $entityName): self
{
$this->entityName = $entityName;
return $this;
}
/**
* #return Collection|Rates[]
*/
public function getRates(): Collection
{
return $this->rates;
}
public function addRate(Rates $rate): self
{
if (!$this->rates->contains($rate)) {
$this->rates[] = $rate;
$rate->setEntity($this);
}
return $this;
}
public function removeRate(Rates $rate): self
{
if ($this->rates->removeElement($rate)) {
// set the owning side to null (unless already changed)
if ($rate->getEntity() === $this) {
$rate->setEntity(null);
}
}
return $this;
}
/**
* #return Collection|Events[]
*/
public function getEvent(): Collection
{
return $this->event;
}
public function addEvent(Events $event): self
{
if (!$this->event->contains($event)) {
$this->event[] = $event;
$event->addEntity($this);
}
return $this;
}
public function removeEvent(Events $event): self
{
if ($this->event->removeElement($event)) {
$event->removeEntity($this);
}
return $this;
}
public function getDescriptionFr(): ?string
{
return $this->descriptionFr;
}
public function setDescriptionFr(string $descriptionFr): self
{
$this->descriptionFr = $descriptionFr;
return $this;
}
public function getDescriptionEn(): ?string
{
return $this->descriptionEn;
}
public function setDescriptionEn(?string $descriptionEn): self
{
$this->descriptionEn = $descriptionEn;
return $this;
}
/**
* #return Collection|Themes[]
*/
public function getTheme(): Collection
{
return $this->theme;
}
public function addTheme(Themes $theme): self
{
if (!$this->theme->contains($theme)) {
$this->theme[] = $theme;
}
return $this;
}
public function removeTheme(Themes $theme): self
{
$this->theme->removeElement($theme);
return $this;
}
}
<?php
namespace App\Form;
use App\Entity\Entities;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class EntitiesType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('entityName')
->add('descriptionFr' )
->add('descriptionEn')
->add('event')
->add('theme')
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Entities::class,
]);
}
}
{{ form_start(form) }}
{{ form_rest(form) }}
<button class="btn">{{ button|default('Créer')}}</button>
{{ form_end(form) }}

ZF3: How to get view of an action from another action in the controller?

In my controller action, I want to grap a rendered full page of another action:
class MycontrollerController extends AbstractActionController
{
public function firstactionAction()
{
$html = some_function_to_get_the_rendered_page_of_secondaction();
}
public function secondactionAction()
{
return new ViewModel();
}
}
Be careful to use setTemplate()
MycontrollerControllerFactory.php
<?php
namespace Application\Controller\Service;
use Application\Controller\MycontrollerController;
use Interop\Container\ContainerInterface;
use Zend\ServiceManager\Factory\FactoryInterface;
class MycontrollerControllerFactory implements FactoryInterface
{
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
$controller = new MycontrollerController();
$controller->setRenderer($container->get('Zend\View\Renderer\PhpRenderer'));
return $controller;
}
}
MycontrollerController.php
<?php
namespace Application\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
class MycontrollerController extends AbstractActionController
{
/**
* #var \Zend\View\Renderer\PhpRenderer
*/
protected $renderer;
/**
* #return \Zend\View\Renderer\PhpRenderer
*/
public function getRenderer()
{
return $this->renderer;
}
/**
* #param \Zend\View\Renderer\PhpRenderer $renderer
* #return self
*/
public function setRenderer($renderer)
{
$this->renderer = $renderer;
return $this;
}
public function firstAction()
{
if ($this->yourMethod()) {
$secondView = $this->secondAction();
$html = $this->getRenderer()->render($secondView);
}
$view = new ViewModel();
$view->setTemplate('namespace/my-controller/first');
return $view;
}
public function secondAction()
{
$view = new ViewModel();
$view->setTemplate('namespace/my-controller/second');
return $view;
}
}
So, I suggest to create a new plugin 'htmlRender' :
module.config.php
'controller_plugins' => [
'factories' => [
'htmlRender' => Application\Mvc\Controller\Plugin\Service\HtmlRenderFactory::class,
],
],
HtmlRenderFactory.php
<?php
namespace Application\Mvc\Controller\Plugin\Service;
use Application\Mvc\Controller\Plugin\HtmlRender;
use Interop\Container\ContainerInterface;
use Zend\ServiceManager\Factory\FactoryInterface;
use Zend\View\Renderer\PhpRenderer;
class HtmlRenderFactory implements FactoryInterface
{
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
$plugin = new HtmlRender();
$plugin->setRenderer($container->get(PhpRenderer::class));
return $plugin;
}
}
HtmlRender.php
<?php
namespace Application\Mvc\Controller\Plugin;
use Zend\Mvc\Controller\Plugin\AbstractPlugin;
use Zend\View\Renderer\RendererInterface;
class HtmlRender extends AbstractPlugin
{
/**
* #var \Zend\View\Renderer\PhpRenderer
*/
protected $renderer;
/**
* #param string|\Zend\View\Model\ModelInterface $nameOrModel
* #param null|array|\Traversable $values
* #param string|bool|\Zend\View\Model\ModelInterface $layout
* #return string
*/
public function __invoke($nameOrModel, $values = null, $layout = false)
{
$content = $this->getRenderer()->render($nameOrModel, $values);
if (!$layout) {
return $content;
}
if (true === $layout) {
$layout = 'layout/layout';
}
return $this->getRenderer()->render($layout, [
'content' => $content,
]);
}
/**
* #return \Zend\View\Renderer\PhpRenderer
*/
public function getRenderer()
{
return $this->renderer;
}
/**
* #param \Zend\View\Renderer\PhpRenderer|RendererInterface $renderer
* #return self
*/
public function setRenderer(RendererInterface $renderer)
{
$this->renderer = $renderer;
return $this;
}
}
Use in the MycontrollerController.php
<?php
class MycontrollerController extends AbstractActionController
{
public function firstAction()
{
if ($this->yourMethod()) {
// Option 1 without layout
$html = $this->htmlRender($secondView);
// Option 2 without layout
$html = $this->htmlRender('namespace/my-controller/second', $yourVariables));
// Option 1 with layout
$html = $this->htmlRender($secondView, null, true);
//$html = $this->htmlRender($secondView, null, 'layout/my-custom-layout');
// Option 2 with layout
$html = $this->htmlRender('namespace/my-controller/second', $yourVariables, true));
//$html = $this->htmlRender('namespace/my-controller/second', $yourVariables, 'layout/my-custom-layout');
}
$view = new ViewModel();
$view->setTemplate('namespace/my-controller/first');
return $view;
}
public function secondAction()
{
$view = new ViewModel();
$view->setTemplate('namespace/my-controller/second');
return $view;
}
}

How do mock for viewHelper in zf2

I'm trying to do mock for viewHelper and can't do this.
When I am trying to run phpunit I get the assert error "Failed asserting that two strings are equal." because the analiticHelper hasn't been overwriten. I wrote setAllowOverride(true) for my ServiseManager, but this didn't help.
Could you please tell me how can I do mock for viewHelper in Zend Framework 2?
I will appreciate your time and help!
Thanks!
# module\Application\test\Controller\IndexControllerTest.php
<?php
namespace ApplicationTest\Controller;
use Application\Controller\IndexController;
use PHPUnit_Framework_TestCase as TestCase;
use ApplicationTest\Bootstrap;
class HttpTest extends TestCase {
/**
* #var IndexController
*/
// private $indexController;
protected $traceError = false;
public function setUp() {
$this->sm = Bootstrap::getServiceManager();
$this->em = $this->sm->get('Doctrine\ORM\EntityManager');
}
public function testAction() {
$mockAnaliticHelper = $this->getMockBuilder(\Application\View\Helper\AnaliticHelper::class)
->disableOriginalConstructor()
->disableOriginalClone()
->disableArgumentCloning()
->disallowMockingUnknownTypes()
->getMock();
$mockAnaliticHelper->method('getKey')
->willReturn('some-value');
$this->assertEquals('some-value', $mockAnaliticHelper->getKey()); // it's ok
$this->sm->setAllowOverride(true);
$this->sm->setService('analiticHelper', $mockAnaliticHelper); // before
$viewHelperManager = $this->sm->get('ViewHelperManager');
$analiticHelper = $viewHelperManager->get('analiticHelper');
$this->sm->setService('analiticHelper', $mockAnaliticHelper); // after
$key = $analiticHelper->getKey(); // return 'web'
$this->assertEquals('some-value', $analiticHelper->getKey()); // return error
}
}
# Module.php
<?php
....
public function getViewHelperConfig()
{
return array(
'factories' => array(
...,
'analiticHelper' => function($sm){
$locator = $sm->getServiceLocator();
$config = $locator->get('config');
$em = $locator->get('Doctrine\ORM\EntityManager');
$viewHelper = new \Application\View\Helper\AnaliticHelper($em, $locator, $config);
return $viewHelper;
},
),
);
}
# module\Application\src\Application\View\Helper\AnaliticHelper.php
<?php
namespace Application\View\Helper;
use Zend\View\Helper\HelperInterface;
use Zend\View\Renderer\RendererInterface as Renderer;
use Doctrine\ORM\EntityManager;
use ZfcUser\Entity\UserInterface;
use Zend\Session\Container;
class AnaliticHelper implements \Zend\View\Helper\HelperInterface{
protected $_em;
protected $_serviceLocator;
protected $_config;
const SESSION_CONTANIER = 'analitic';
const SESSION_KEY = 'analiticKey';
const DEFAULT_KEY = 'web';
public function __construct(EntityManager $em, $serviceLocator, $config) {
$this->_em = $em;
$this->_serviceLocator = $serviceLocator;
$this->_config = $config;
$router = $this->_serviceLocator->get('router');
$request = $this->_serviceLocator->get('request');
$this->routeMatch = $router->match($request);
}
public function __invoke(){
return $this;
}
public function getKey(){
// some actions
return self::DEFAULT_KEY;
}
/**
* Set the View object
*
* #param Renderer $view
* #return HelperInterface
*/
public function setView(Renderer $view)
{
$this->view = $view;
return $this;
}
/**
* Get the View object
*
* #return Renderer
*/
public function getView()
{
return $this->view;
}
}

MongoDB + Doctrine + Zend

I'm integrating Zend and Doctrine 2 to work with MongoDB.
I'm using the quickstart skeleton.
Here is the Doctrine.php
<?php
use Doctrine\MongoDB\Connection;
use Doctrine\ODM\MongoDB\DocumentManager;
use Doctrine\ODM\MongoDB\Mapping\Annotations;
use Doctrine\ODM\MongoDB\Mapping\Driver\AnnotationDriver;
use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM;
class Resource_Doctrine extends Zend_Application_Resource_ResourceAbstract
{
protected $_options = array();
private $manager;
public function __set($config, $null) {
$this->_options = array(
'connection' => array(
'dbname' => $config['connection']['dbname'],
),
'modelDir' => $config['modelDir'],
'proxyDir' => $config['proxyDir'],
'proxyNamespace' => $config['proxyNamespace'],
'hydratorDir' => $config['proxyDir'],
'hydratorNamespace' => $config['proxyNamespace'],
'autoGenerateProxyClasses' => $config['autoGenerateProxyClasses']
);
}
public function init()
{
$zendConfig = $this->getOptions();
if(!empty($zendConfig)) Zend_Registry::set('config', $zendConfig);
$options = Zend_Registry::get('config');
$this->__set($options,null);
$config = new \Doctrine\ODM\MongoDB\Configuration;
$config->setDefaultDB($options['connection']['dbname']);
$config->setProxyDir($this->_options['proxyDir']);
$config->setProxyNamespace($this->_options['proxyNamespace']);
$config->setHydratorDir($this->_options['hydratorDir']);
$config->setHydratorNamespace($this->_options['hydratorNamespace']);
$config->setMetadataDriverImpl(AnnotationDriver::create($this->_options['modelDir']));
Doctrine\ODM\MongoDB\Mapping\Driver\AnnotationDriver::registerAnnotationClasses();
$dm = DocumentManager::create(new Connection(), $config);
return $dm;
}
}
The class
<?php
use Doctrine\ODM\MongoDB\Mapping\ClassMetadata;
use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM;
/** #ODM\Document */
class Application_Model_Guestbook
{
/**
* #ODM\Id
*/
public $id;
/** #ODM\String */
public $email;
/** #ODM\String */
public $comment;
/** #ODM\Date */
public $created;
public function setGuestbook($comment)
{
$this->email = $comment['email'];
$this->comment = $comment['comment'];
$this->created = date('d-m-Y H:i:s');
}
public function getGuestbook()
{
return $this;
}
}
And the action
public function signAction()
{
$request = $this->getRequest();
$this->getHelper('loadResource')->form('sign', 'Guestbook');
$form = new Application_Form_Guestbook();
if ($this->getRequest()->isPost()) {
if ($form->isValid($request->getPost())) {
$guestbook = new Application_Model_Guestbook;
$guestbook->setGuestbook($form->getValues());
try
{
$this->em->persist($guestbook);
$this->em->flush($guestbook);
return $this->_helper->redirector('index');
}
catch (Exception $e)
{
throw new Exception($e);
}
}
}
$this->view->form = $form;
}
I'm geting the error: Catchable fatal error: Argument 3 passed to Doctrine\ODM\MongoDB\Hydrator\HydratorFactory::hydrate() must be of the type array, null given, called in /home/gabiru/www/twitradar_mongo/library/Doctrine/ODM/MongoDB/UnitOfWork.php on line 2518
I've searched and don't find any result of anyone with the same problem, anyone have any idea about it?
The 3rd argument is the variable $hint, and I don't know where the argument is set.

ZF2 getServiceLocator in ControllerPlugin class

I am trying to get service locator/entity manager in plugin class, How can I get that.
In my controller I am getting it like this.
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;
}
but in plugin class I am getting error on $this->getServiceLocator() line. because this is not available in plugin class.
How can I do the same so that I can fetch some records and insert few in database in plugin.
I do have MvcEvent $e object in my plugin class, I can make use of this to get entity manager?
I have used this plugin to create my plugin
Any guide will be appriciated.
update:
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;
}
}
I am calling above class in 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...
}
I am registering this plugin in 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',
),
),
);
What do you mean with "Plugin Class"? In case you're talking abount controller plugins, you can access it using (from the controller plugin's scope): $this->getController()->getServiceLocator()->get('doctrine.entitymanager.orm_default');.
For other classes, I usually create a factory that injects the ServiceManager instance automatically. For example, in the Module class:
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');
changed the above AclPlugin class as below
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;
}
}
Actually getting ServiceManager in controller plugin is quite easy!
Just use: $this->getController()->getServiceLocator()
Example:
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);
}
}

Categories