Iam a little confused while I try to set up a doctrine entity listener with injected parameters in symfony.
First there is this page where Entity Listeners are barely mentioned:
https://symfony.com/doc/current/doctrine/event_listeners_subscribers.html
In Doctrine 2.4, a feature called Entity Listeners was introduced. It
is a lifecycle listener class used for an entity. You can read about
it in the Doctrine Documentation.
Then here is explained, that I only have to add a service with the right tags and that I don't have to register the listener in the entity when using doctrine 2.5 (which I do):
https://symfony.com/doc/master/bundles/DoctrineBundle/entity-listeners.html
If you use a version of doctrine/orm < 2.5 you have to register the
entity listener in your entity as well:
But the latter is not mentioned on the doctrine page:
http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/events.html#entity-listeners
However, following the doctrine page, I also added to my entity yaml:
AppBundle\Entity\File:
type: entity
entityListeners:
AppBundle\EventListener\FileListener:
postRemove: [postRemove]
And that is my Listener Class (still for testing):
class FileListener {
public function postRemove(File $file) {
dump($file); die();
}
}
That is what I set up in the service.yml:
file_listener:
class: AppBundle\EventListener\FileListener
arguments: ['%path_image%', '%path_thumb%', '%path_preview%']
tags:
- { name: doctrine.orm.entity_listener }
- { name: doctrine.orm.entity_listener, entity_manager: custom }
But when deleting a File Entity, the Listener Method is not called.
Related
After updating symfony2 with the dependencies to 2.8 I get the following error message when trying to override the sonata user bundle registration form:
The field type "Sonata\UserBundle\Form\Type\RegistrationFormType" is not registered with the service container.
If I switch back to Symfony 2.7 everything works again.
My services.yml:
sonata.user.registration.form.type:
class: My\Bundle\Form\Type\RegistrationFormType
arguments: [ "%fos_user.model.user.class%" , "#service_container"]
tags:
- { name: form.type, alias: sonata_user_registration }
In my controller the following line triggers the error:
$form = $this->container->get( 'sonata.user.registration.form' );
Unfortunately I couldn't find any resources on this subject (i.e. if there are any changes in overriding the registration form since the latest version)
Ok, this isn't a bug, but a new feature. You have to use the build() and boot() methods in your bundle to register your FormType via FormHelper::registerFormTypeMapping.
I have an event subscriber with Doctrine events. Inside that, I am trying to call a service I have registered. I've called it already from in a controller and it works there, but when I try to call it in my event subscriber I get an error:
Attempted to call method "get" on class "Path\To\My\Class".
Did you mean to call "getSubscribedEvents"?
The code looks like this:
$embedcode_service = $this->get('myproject.mynamespace.myfield.update');
$embedcode_service->refreshMyField($document);
Why can't I access my service inside this event subscriber? How can I get access to it?
Cerad already answered I'm just going to elaborate:
Inject your service in your subscriber:
services:
...
my.subscriber:
class: Acme\SearchBundle\EventListener\SearchIndexerSubscriber
# Service you want to inject
arguments: [ #service_i_want_to_inject.custom ]
tags:
- { name: doctrine.event_subscriber, connection: default }
...
In the php code for your subscriber, assign the injected service to a class variable to be able to access it later on:
...
class SearchIndexerSubscriber implements EventSubscriber {
private $myservice;
public function __construct($myservice) {
$this->myservice = $myservice;
}
...
Access the service methods through the class variable from any method within the subscriber:
$this->myservice->refreshMyField($document);
Listeners/subscribers in Symfony2
Services in Symfony2
Happy new year.
I have service PgHistService in subdirectory Service in DbExtensionBundle:
namespace Iba\DbExtensionBundle\Service;
class PgHistService { ...}
This service is defined in bundles's services.yml and can be sucessfully included in a controller via $this->get('pghist.service'):
parameters:
pghist.service.class: Iba\DbExtensionBundle\Service\PgHistService
services:
pghist.service:
class: %pghist.service.class%
arguments:
entityManager: "#doctrine.orm.entity_manager"
Now I want to inject it with JMS\DIExtraBundle in doctrine entity listener:
namespace Iba\DbExtensionBundle\Entity;
use JMS\DiExtraBundle\Annotation as DI;
class BaseEntityListener {
/** #DI\Inject("pghist.service") */
public $pgHist;
}
Variable pgHist is always null. What am I doing wrong, please? I tried to set this in config.yml but it doesn't work either:
jms_di_extra:
locations:
all_bundles: false
bundles: [DbExtensionBundle]
directories: ["%kernel.root_dir%/../vendor/iba/db-extension-bundle/Iba/DbExtensionBundle/Service"]
Jason Roman is right, thank you.
If you want to use JMS\DiExtraBunde together with entity listener, you have to use DIExtraBundle own system of invoking listener via annotation #DoctrineListener in listener instead of Doctrine standard one #EntityListeners in the entity.
When usieing StofDoctrineExtensions (which is a Symfony2 port of Gedmo Doctrine Extensions) Sortable behaviour I kept on getting this error:
This repository can be attached only to ORM sortable listener
Since I could not easily find the answer in official docs I'm leaving an answer here for future reference.
You need to enable any listeners you are using. In this case, Sortable.
stof_doctrine_extensions:
default_locale: en_US
orm:
default:
sortable: true
For Symfony 4, add this configuration in /config/packages/stof_doctrine_extensions.yaml. For older versions of Symfony, add it to config.yml.
In order to use Sortable behaviour you need to add an event listener to your bundle's boot method
<?php
namespace Acme\DemoBundle;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class AcmeDemoBundle extends Bundle
{
public function boot()
{
// get the doctrine 2 entity manager
$em = $this->container->get('doctrine.orm.default_entity_manager');
// get the event manager
$evm = $em->getEventManager();
$evm->addEventSubscriber(new \Gedmo\Sortable\SortableListener);
}
}
I'm currently implementing Doctrine filters in my Symfony2.1 project with the following setup:
<?php
namespace Acme\Bundle\Entity;
class Article {
/**
* #ORM\Column(type="string")
*/
private $status;
...
}
//app/config/config.yml
doctrine:
orm:
filters:
status:
class: Acme\Bundle\Filter\StatusFilter
enabled: false
....
//src/Acme/Bundle/Filter/StatusFilter.php
namespace Acme\Bundle\Filter;
use Acme\Bundle\Entity\Status;
class StatusFilter extends SQLFilter {
public function addFilterConstraint(ClassMetadata $target, $alias)
{
$filter =
$target->reflClass->implementsInterface('Acme\Bundle\Entity\Status')?
$alias . '.status = ' . Status::PUBLISHED : '';
return $filter;
}
}
Where Acme\Bundle\Entity\Status is just an interface.
The code is working as expected when the filter is enabled in config.yml.
The problem is that I cannot retrieve all articles for administration!
Is there a way to enable this filter for a certain bundle?
p.s. I know how to enable and disable the filter with the EntityManager,
I just cannot find the proper place to do it for the frontend Bundle.
my admin section is accessible by route prefix myadmin
www.example.com/myadmin/ -> admin section = disable filter (disabled by default in config)
www.example.com/... -> anything else = enable filter.
Looking at the Doctrine code, there are methods to enable and disable filters.
Once you have defined your filter in the config.yml file, you can enable/disable in a controller or service:
// 'status' is the unique name of the filter in the config file
$this->getDoctrine()->getManager()->getFilters()->enable('status');
$this->getDoctrine()->getManager()->getFilters()->disable('status');
Note: this was taken from Symfony 2.3. You would need to test this with previous versions of Symfony/Doctrine.
there is no notion of bundle at Doctrine level. The only way I see would be to detect which controller is used, by parsing its className (reflection, ...) during a kernel.request event, or a kernel.controller event.
Then, if you detect that your controller is in FrontendBundle, just disable/enable your doctrine filter.
If you prefer using routing to detect when to disable/enable, just use kernel.request event. You will have access to all request parameters, via $event->getRequest()->attributes->get('_controller') for example.