Symonfy: How to use doctrine manager in form subscriber? - symfony

I have a form subscriber, i want to use doctrine manager in it. but i got the error message:
"Catchable Fatal Error: Argument 1 passed to ...\ProductEavAttributesSubscriber::__construct() must be an instance of Doctrine\ORM\EntityManager, instance of Symfony\Component\Form\FormFactory given。
there is my subscriber file code:
namespace Demo\Bundle\ProductBundle\EventListener;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\EntityManager;
class ProductEavAttributesSubscriber implements EventSubscriberInterface
{
private $entityManager;
public function __construct(EntityManager $entityManager)
{
$this->entityManager = $entityManager;
}
// coding
}
in service.yml
demo.product.eav.attribute:
class: ...\EventListener\ProductEntityAttributesSubscriber
arguments: ["#doctrine.orm.entity_manager"]
tags:
- { name: form.type, alias: product_eav_attribute }
In form type:
$builder->add('specifications', ProductEavAttributeType::class);
In the ProductEavAttributeType file:
class ProductEavAttributeType extends AbstractType
{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$factory = $builder->getFormFactory();
$productEavAttributes = new ProductEavAttributesSubscriber($factory);
$builder->addEventSubscriber($productEavAttributes);
}
}
So, how to do now?

Related

Could not load type "app_filter": class does not exist

I have upgraded the symfony 2.8 project to symfony 3.4. After fixing some issue I am getting the above issue when loading the page which has form with filters.
The app_filter attribute is configured in my form.yml file inside the bundle/resources/config directory and it looks like the below,
parameters:
app.abstract_filter.form.type.class: AppBundle\Form\Type\Filter\FilterType
services:
app.abstract_filter.form.type:
class: '%app.abstract_filter.form.type.class%'
arguments:
- '#translator.default'
- '#doctrine.orm.entity_manager'
tags:
- { name: form.type, alias: app_filter}
app.abstract_filter.form:
class: Symfony\Component\Form\Form
factory: ['#form.factory', createNamed]
arguments:
- 'app_filter'
- '%app.abstract_filter.form.type.class%'
app_abstract_fitler_form_type class:
namespace AppBundle\Form\Type\Filter;
use Doctrine\ORM\EntityManager;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Translation\Translator;
class FilterType extends AbstractType
{
/** #var Translator */
protected $translator;
/** #var EntityManager */
protected $entityManager;
public function __construct(Translator $translator, EntityManager $entityManager)
{
$this->translator = $translator;
$this->entityManager = $entityManager;
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
}
public function getName()
{
return 'app_filter';
}
}

Symfony3 Use Entity Manager in Custom Container

I want to create HelperController for my project. I generate a controller with doctrine:generate:controller and I need to use entity manager in it.
I enjected to services.yml but it is giving an error like this:
Argument 1 passed to CampingBundle\Controller\HelperController::__construct() must be an instance of Doctrine\ORM\EntityManager, none given ...
My Controller Code :
namespace CampingBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Doctrine\ORM\EntityManager;
class HelperController extends Controller
{
protected $manager;
public function __construct(EntityManager $manager)
{
$this->manager = $manager;
}
My Services.yml :
services:
camping.helper_controller:
class: CampingBundle\Controller\HelperController
arguments: ["#doctrine.orm.entity_manager"]
Why it doesn't work ? Shoudl I clear cache or something else or is there anything wrong in definition ?
Thanks
Try to use EntityManagerInterface and remove extends Controller.
Check this link if you need CAS (Controllers as Services).
Change protected $manager; to private $manager;
namespace CampingBundle\Controller;
use Doctrine\ORM\EntityManagerInterface;
class HelperController
{
/**
* #var EntityManagerInterface $entityManager
*/
private $entityManager;
/**
* #param $entityManager
*/
public function __construct(EntityManagerInterface $entityManager)
{
$this->entityManager = $entityManager;
}
}
I'll leave my two cents here as I had same issue and fixed it by adding tags to service.
something.validate.some_service:
class: Path\To\Some\Validator
arguments:
- '#doctrine.orm.entity_manager'
tags:
- { name: validator.constraint_validator, alias: some_validator_alias }
How to Work with Service Tags by Symfony

__construct() must be an instance of Doctrine\Common\Persistance\ObjectManager

I use Objectmanger for use Doctrine .. I create instance of objectManager and I create service but I have this bug:
Catchable Fatal Error: Argument 1 passed to Tag\TagBundle\Form\Types\TagsType::__construct() must be an instance of Doctrine\Common\Persistance\ObjectManager, instance of Doctrine\ORM\EntityManager given, called in /var/www/html/TagProject/var/cache/dev/appDevDebugProjectContainer.php on line 2412 and defined
code TagsType:
<?php
namespace Tag\TagBundle\Form\Types;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Tag\TagBundle\Form\DataTransformer\TagsTransformer;
use Symfony\Bridge\Doctrine\Form\DataTransformer\CollectionToArrayTransformer;
use Symfony\Component\Form\FormBuilderInterface;
use Doctrine\Common\Persistance\ObjectManager;
class TagsType extends AbstractType {
/**
* #var ObjectManager
*/
private $manager;
public function __construct(ObjectManager $manager){
$this->manager = $manager;
}
public function buildForm(FormBuilderInterface $builder, array $options){
$builder
->addModelTransformer(new CollectionToArrayTransformer(),true)
->addModelTransformer(new TagsTransformer($this->manager),true);
}
public function getParent(){
return TextType::class;
}
}
code TagsTransformer:
<?php
namespace Tag\TagBundle\Form\DataTransformer;
use Symfony\Component\Form\DataTransformerInterface;
use Tag\TagBundle\Entity\Tag;
use Doctrine\Common\Persistance\ObjectManager;
class TagsTransformer implements DataTransformerInterface {
/**
* #var ObjectManager
*/
private $manager;
public function __construct(ObjectManager $manager){
$this->manager = $manager;
}
public function transform($value) {
dump($value);
return implode(',',$value);
}
public function reverseTransform($string)
{
$names = explode(',',$string);
$tags = $this->manager->getRepository('TagBundle:Tag')->findBy(['name' => $names]);
$newNames = array_diff($names, $tags);
foreach($names as $name){
$tag = new tag();
$tag->setName($name);
$tags[] = $tag;
}
return $tags;
}
}
code services.yml:
services:
tag.form.types.tages:
class: Tag\TagBundle\Form\Types\TagsType
arguments: ["#doctrine.orm.entity_manager"]
tags:
- { name: form.type }
# tag.example:
# class: Tag\TagBundle\Example
# arguments: ["#service_id", "plain_value", "%parameter%"]
You're injecting an instance of EntityManager so you should use the corresponding interface Doctrine\ORM\EntityManagerInterface for typehinting.
use Doctrine\ORM\EntityManagerInterface;
class TagsTransformer implements DataTransformerInterface
{
/**
* #var EntityManagerInterface
*/
private $manager;
public function __construct(EntityManagerInterface $manager)
{
$this->manager = $manager;
}

Inject EntityManager in an EventSubscriberInterface

I've done an EventSubscriber, but I need to use EntityManager in. I've filled the services.yml like this:
app.subscriber.tube_dynamic_field:
class: AppBundle\Form\EventListener\TubeDynamicFieldSubscriber
arguments: ["#doctrine.orm.entity_manager"]
I try to use it in the EventSubscriber like this:
class TubeDynamicFieldSubscriber implements EventSubscriberInterface
{
private $em;
public function __construct(EntityManager $em)
{
$this->em = $em;
}
...
}
Finally I use the EventSubscriber in a FormType like this:
class TubeType extends AbstractType
{
private $dynamicFieldSubscriber;
public function __construct(TubeDynamicFieldSubscriber $subscriber)
{
$this->dynamicFieldSubscriber = $suscriber;
}
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->addEventSubscriber($this->dynamicFieldSubscriber);
}
...
}
But I've an error:
Type error: Argument 1 passed to AppBundle\Form\TubeType::__construct()
must be an instance of AppBundle\Form\EventListener
\TubeDynamicFieldSubscriber, none given
I've try to use it: $builder->addEventSubscriber(new TubeDynamicFieldSuscriber()) but I've again an error: it don't recover the EntityManager.
If you know how I can inject the EntityManager in the EventSubscriber :)
Thanks a lot.
While your code snippets are not very clear, if your form type has dependencies, it needs to be registered in the service container so that Symfony (and the form factory) know how to construct it.
services:
my_form_type:
class: AppBundle\Form\TubeType
arguments: ["#my_event_subscriber"]
tags: [{ name: form.type }]
However, a better way of doing this is probably to inject the entity manager in the form type:
services:
my_form_type:
class: AppBundle\Form\TubeType
arguments: ["#doctrine.orm.entity_manager"]
tags: [{ name: form.type }]
That way, in your code, you can just do:
$builder->addEventSubscriber(new TubeDynamicFieldSuscriber($this->manager));

sylius how to get container inside a form type class without use of constructor?

i want to use the service container inside a form type class, but $this->container always return null.
here the class of my form
<?php
namespace St\AppBundle\Form\Type;
use Sylius\Bundle\CoreBundle\Form\Type\ShippingMethodType as BaseShippingMethodType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
class ShippingMethodType extends BaseShippingMethodType implements ContainerAwareInterface
{
protected $container;
public function setContainer(ContainerInterface $container = null)
{
$this->container = $container;
}
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
parent::buildForm($builder, $options);
$builder
->add('file', 'file', ['required' => false])
;
var_dump($this->container);
$builder->addEventListener(FormEvents::POST_SUBMIT, function(FormEvent $event) {
$data = $event->getData();
$tools = $this->container->get('a_tools');
$tools->saveImage($data);
});
}
}
and here the service for this form, i use the setter injection method, but it seem not working because the var_dump of $this->container in the class return null
a_shipping_method.form.type:
class: St\AppBundle\Form\Type\ShippingMethodType
calls:
- [setContainer, ['#service_container']]
tags:
- { name: form.type, alias: sylius_shipping_method }
why the setter injection doesn't work for this case ?

Resources