Inject DoctrineORM EntityManager in ZF2 Form

This one took me a while to figure out so I thought I would write it up real quick in case somebody else is trying to figure  this out.

TLDR – “Cut the crap and just show me how it’s done” – LINK

I was setting up a Zend Framework 2 project with Doctrine. You can find quite a lot of tutorials for that. For starters you could check out Jason Grimes’ ZF2 Doctrine tutorial.

Setting up the entities and my edit forms was no problem. But making use of DoctrineModule\Form\Element\ObjectSelect took some more work. I wanted to use it for a category select. But the form element needs the Doctrine entityManager. So I wrote up my form like this:

Hand-ish, not very elegant way of injecting Doctrine EntityManager in Zf2 Form

Look at how I inject the entityManager and keep dragging it through the application just so I can use it in the one form field below.

And in my Controller I had to create the form like this:

Note that there is a BaseController which provides the getEntityManager() function. I created it because I need more than one form with the entityManager and providing the function at a central place seemed like the best idea at that point.

The BaseController looks something like that:

All pretty tedious and not very elegant. So I started looking for a more elegant way to do things.

(Semi)-automated injection of Doctrine EntityManager

The configuration of Zf2 is quite mighty and worth looking at if you want things to be done FOR you instead of just tediously trying to build and maintain stuff yourself. Still haven’t found a comprehensive guide to it so it took me  a lot of digging around.

First of all you instead of creating your form directly like that:

you get your form through the FormElementManager like this:

This way you can make use of the getFormElementConfig() function in your Module.php:

What you can see here is that there is a function called  getFormElementConfig() which accepts an array. Most important part here are the “initializers”. You can have more than one initializer and the names (in my case ObjectManagerInitializer) can be anything you like. Though it makes sense to chose a speaking name of course.

As soon as you get your form via the FormElementManager (don’t forget to add your FormName to the invokables part of the array) Zf2 recognizes there is some work to be done on getting your new – much cooler – form.

The initializer will check if your form implements the ObjectManagerAwareInterface and if so it will get the entityManager via the serviceLocator and set it using setObjectManager().

One thing that remains to be done is change the form accordingly. Here is the Code:

The Form now implements the ObjectManagerAwareInterface – which requires the functions getObjectManager() and setObjectManager(). When creating the formElements you only have to call the getObjectManager() function now and you are done.

Note that you have to add the fields not in __construct but in init() now. At the point of construction the objectManager will not yet be present.

Voilà! Now you can create your form without worrying about creating and injecting anything beforehand! :)

 

Getagged mit: , , ,
Veröffentlicht unter Programming
2 Kommentare auf “Inject DoctrineORM EntityManager in ZF2 Form
  1. Michael sagt:

    Thanks for the great Tutorial. I just found out that in the latest version of ZF2 (I have 2.2.5 here) it´s not necessary any more to pass the entityManager via the module config.

    You only have to implement the “ObjectManagerAwareInterface” in the form class (as well as the required getter + setter) and you will have access via $this->getObjetManager().

  2. Sandy sagt:

    Really? I’ll try that asap. Thanx. :)

Hinterlasse eine Antwort

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind markiert *

*

Du kannst folgende HTML-Tags benutzen: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">