Reputation: 7331
I need to modify some fields in my form (label and class), based on whether the entity is the latest published version or not. So I need to be able to inject the entity manager into my formType so that in an event listener I can compare the current version with the published version of the entity. But I can't even get the entityManager
into the __construct() to begin with. Maybe there is a better way of achieving my big goal as well (e.g. modify the form in the twig template), but I NEED to understand how to do this basic dependency inject as well.
I thought that if I declare it in my service (like the documentation describes for basic Service Container and specifically Constructor Injection methods), it will be available as an argument in my construct. But when I do this, I get the error:
Catchable fatal error: Argument 1 passed to Gutensite\CmsBundle\Form\Type\ViewType::__construct() must be an instance of Doctrine\ORM\EntityManager, none given, called in /var/www/core/cms/src/Gutensite/ArticleBundle/Controller/AdminEditController.php on line 222 and defined in /var/www/core/cms/src/Gutensite/CmsBundle/Form/Type/ViewType.php on line 15
Here are the snippets from my code:
Gutensite/CmsBundle/Resources/config/service.yml
gutensite_cms.form.type.view:
class: Gutensite\CmsBundle\Form\Type\ViewType
arguments: [ "@doctrine.orm.entity_manager" ]
Gutensite/CmsBundle/Form/Type/ViewType.php
namespace Gutensite\CmsBundle\Form\Type;
use Doctrine\ORM\EntityManager;
use Symfony\Component\Form\AbstractType;
class ViewType extends AbstractType
{
private $em;
public function __construct(EntityManager $entityManager) {
$this->em = $entityManager;
}
}
Gutensite/ArticleBundle/Controller/AdminEditController.php
// Get the View Entity
$em = $this->getDoctrine()->getManager();
$viewRepo = $em->getRepository("GutensiteCmsBundle:View\View");
$view = $viewRepo->find($request->query->get('id'));
// Create the generic form for editing any View, using the view entity constructed
$form = $this->createForm(new ViewType(), $view);
I am using two entity managers, so my config.yml looks something like this. I don't know if that makes any difference in what I inject, i.e. can I inject @doctrine.orm.entity_manager
or am I supposed to inject @doctrine.orm.default_entity_manager
or something? I've tried all sorts of options and none work.
# Doctrine Configuration
doctrine:
dbal:
default_connection: cms
connections:
cms:
driver: "%db.cms.driver%"
host: "%db.cms.host%"
port: "%db.cms.port%"
dbname: "%db.cms.name%"
user: "%db.cms.user%"
password: "%db.cms.password%"
charset: "%db.cms.charset%"
billing:
driver: "%db.billing.driver%"
host: "%db.billing.host%"
port: "%db.billing.port%"
dbname: "%db.billing.name%"
user: "%db.billing.user%"
password: "%db.billing.password%"
charset: "%db.billing.charset%"
orm:
default_entity_manager: cms
entity_managers:
cms:
connection: cms
mappings:
GutensiteCmsBundle: ~
GutensiteArticleBundle: ~
billing:
connection: billing
mappings:
GutensiteBillingBundle: ~
auto_generate_proxy_classes: "%kernel.debug%"
I didn't need to define ViewType as a service, I just needed to pass in the entity manager via new viewType($em)
when I created the new ViewType form:
Gutensite/ArticleBundle/Controller/AdminEditController.php
// Get the View Entity
$em = $this->getDoctrine()->getManager();
$viewRepo = $em->getRepository("GutensiteCmsBundle:View\View");
$view = $viewRepo->find($request->query->get('id'));
// Create the generic form for editing any View, using the view entity constructed
$form = $this->createForm(new ViewType($em), $view);
Upvotes: 4
Views: 17054
Reputation: 2379
You got that error because you`re creating form type like this:
$form = $this->createForm(new ViewType(), $view);
You create new object ViewType
without any arguments and it needs to be called with EntityManager
. You can simply pass entity manager from controller, like this:
$em = $this->get('doctrine.orm.entity_manager'); // or doctrine.orm.billing_entity_manager
$form = $this->createForm(new ViewType($em), $view);
In this case you don't even need to define this form type as a service.
Use of doctrine.orm.entity_manager
or doctrine.orm.billing_entity_manager
depends on what you need to fetch inside ViewType
- (from witch database).
UPDATE:
Define form type as a service.
Add this two services to your configuration (services.yml
):
services
gutensite_cms.form.view:
factory_method: createNamed
factory_service: form.factory
class: Symfony\Component\Form\Form
arguments:
- view_form # name of the form
- view # alias of the form type
- null # data to bind, this is where your entity could go if you have that defined as a service
- { validation_groups: [Default] } # validation groups
gutensite_cms.form.type.view:
class: Gutensite\CmsBundle\Form\Type\ViewType
arguments: [ "@doctrine.orm.entity_manager" ]
tags:
- { name: form.type, alias: view }
Then you can create new form by executing this inside your controller (or whatever has container
) without manualy passing any arguments (they will be injected automaticly):
public function newAction()
{
$view = ...;
$form = $this->get( 'gutensite_cms.form.view' );
// set initial form data if needed
$form->setData( $view );
}
Upvotes: 7
Reputation: 4210
declare your form type as service:
...
<parameter key="gutensite_cms.form.type.view.class">Gutensite\CmsBundle\Form\Type\ViewVersionType</parameter
...
...
<service id="gutensite_cms.form.type.view" class="%gutensite_cms.form.type.view.class%">
<argumet type="service" id="doctrine.orm.CMS_OR_BILLING_entity_manager" />
<tag name="form.type" alias="YOUR_FORM_TYPE_NAME" />
</service>
...
in your form type:
...
private $em;
public function __construct(EntityManagerInterface $entityManager) {
$this->em = $entityManager;
}
or ou can inject whole container and use it like this:
$this->container->get('doctrine')->getManager('cms'); // or billing
Upvotes: 1
Reputation: 116
You created a new ViewType without passing the EntityManager. Get the form type from the dic with
$form = $this->createForm($this->get('gutensite_cms.form.type.view'), $view);
or create a new object with the entity manager as an argument
$form = $this->createForm(new ViewType($this->getDoctrine()->getManager()), $view);
Upvotes: 1