Symfony2 DoctrineExtensions preSoftDelete event call - events

I've got a problem implementing the preSoftDelete Event from the L3pp4ard DoctrineExtensions Bundle for Symfony2. The softDelete function is working just fine, but I want to add an deletedBy (userid) next to the deletedAt (datetime). To do that, I want to listen to the event that is called (preSoftDelete), but I can't get it to work. `
The file that (should) calls the event can be found at github. I have confirmed that this script runs.
I have already added a service in my config.yml:
utwente.idbbundle.presoftdelete:
class: Utwente\IdbBundle\EventListener\UtwenteIdbSoftDeleteListener
tags:
- { name: gedmo.listener.softdeleteable, event: preSoftDelete, method: onPreSoftDelete }
and I have made the class/method that should do something. For now it echo's hello, and stops the script execution (for testing).
<?php
namespace Utwente\IdbBundle\EventListener;
class UtwenteIdbSoftDeleteListener {
public function onPreSoftDelete(LifecycleEventArgs $args){
echo "Hoi";
die();
}
}
?>
But it doesn't work. Any ideas?
(It does work when I use name: kernel.event_listener, event: kernel.request, and leave LifecycleEventArgs $args out).

using
tags:
- { name: doctrine.event_listener, event: preSoftDelete, connection: default }
was the answer...

Related

exclude blocks in twig during ajax requests [duplicate]

I need, for each action in my controller, check if these actions are called by an ajax request or not.
If yes, nothing append, if no, i need to redirect to the home page.
I have just find if($this->getRequest()->isXmlHttpRequest()), but i need to add this verification on each action..
Do you know a better way ?
It's very easy!
Just add $request variable to your method as use. (For each controller)
<?php
namespace YOUR\Bundle\Namespace
use Symfony\Component\HttpFoundation\Request;
class SliderController extends Controller
{
public function someAction(Request $request)
{
if($request->isXmlHttpRequest()) {
// Do something...
} else {
return $this->redirect($this->generateUrl('your_route'));
}
}
}
If you want to do that automatically, you have to define a kernel request listener.
For a reusable technique, I use the following from the base template
{# app/Resources/views/layout.html.twig #}
{% extends app.request.xmlHttpRequest
? '::ajax-layout.html.twig'
: '::full-layout.html.twig' %}
So all your templates extending layout.html.twig can automatically be stripped of all your standard markup when originated from Ajax.
Source
First of all, note that getRequest() is deprecated, so get the request through an argument in your action methods.
If you dont want to polute your controller class with the additional code, a solution is to write an event listener which is a service.
You can define it like this:
services:
acme.request.listener:
class: Acme\Bundle\NewBundle\EventListener\RequestListener
arguments: [#request_stack]
tags:
- { name: kernel.event_listener, event: kernel.request, method: onRequestAction }
Then in the RequestListener class, make a onRequestAction() method and inject request stack through the constrcutor. Inside onRequestAction(), you can get controller name like this:
$this->requestStack->getCurrentRequest()->get('_controller');
It will return the controller name and action (I think they are separated by :). Parse the string and check if it is the right controller. And if it is, also check it is XmlHttpRequest like this:
$this->requestStack->getCurrentRequest()->isXmlHttpRequest();
If it is not, you can redirect/forward.
Also note, that this will be checked upon every single request. If you check those things directly in one of your controllers, you will have a more light-weight solution.

Disabling eventListener on doctrine onFlush while loading fixtures

I have to persist new entities when app users make modifications on a bunch of existing entities (traceability issue). I created an EventListener on Doctrine onFlush event. The problem is: This is not supposed to happen on fixtures loading.
I did this to prevent fixtures from triggering the listener but I wonder if it is a good solution:
In my services.yaml:
App\DataFixtures\:
class: App\DataFixtures\LoadFixtures
tags: [name: doctrine.fixture.orm]
arguments:
- '#doctrine.orm.default_entity_manager.event_manager'
In my App\DataFixtures\LoadFixtures:
public function __construct(EventManager $eventManager)
{
$this->eventManager = $eventManager;
}
public function load(ObjectManager $manager)
{
$historizationManager = null;
foreach ($this->eventManager->getListeners() as $event =>$listeners){
foreach ($listeners as $key => $listener){
if($listener instanceof HistorizationManager){
$historizationManager = $listener;
}
}
}
if($historizationManager){
$this->eventManager->removeEventListener(array('onFlush'),$onFlushHistoryListener);
}
// doing some work
}
This is the simplest solution I've come with, please let me know if there is something wrong with that.
If this is still an issue, you could try the following:
add an enabled flag to the EventSubscriber class, default true
use autowiring to make that subscriber available in your fixture loader
set the flag to false before loading the first fixture
finally, check for that flag before handling the event
But if you've found a better way, I'd be happy to hear from you
To clarify about how to set the flag to false: you are usually running your tests in the test environment. By using a configuration file like config_test.yaml, you can override the default service configuration like:
services:
App\EventSubscribers\YourSubscriber:
calls:
- ['setEnabled', [false]]

Symfony2, check if an action is called by ajax or not

I need, for each action in my controller, check if these actions are called by an ajax request or not.
If yes, nothing append, if no, i need to redirect to the home page.
I have just find if($this->getRequest()->isXmlHttpRequest()), but i need to add this verification on each action..
Do you know a better way ?
It's very easy!
Just add $request variable to your method as use. (For each controller)
<?php
namespace YOUR\Bundle\Namespace
use Symfony\Component\HttpFoundation\Request;
class SliderController extends Controller
{
public function someAction(Request $request)
{
if($request->isXmlHttpRequest()) {
// Do something...
} else {
return $this->redirect($this->generateUrl('your_route'));
}
}
}
If you want to do that automatically, you have to define a kernel request listener.
For a reusable technique, I use the following from the base template
{# app/Resources/views/layout.html.twig #}
{% extends app.request.xmlHttpRequest
? '::ajax-layout.html.twig'
: '::full-layout.html.twig' %}
So all your templates extending layout.html.twig can automatically be stripped of all your standard markup when originated from Ajax.
Source
First of all, note that getRequest() is deprecated, so get the request through an argument in your action methods.
If you dont want to polute your controller class with the additional code, a solution is to write an event listener which is a service.
You can define it like this:
services:
acme.request.listener:
class: Acme\Bundle\NewBundle\EventListener\RequestListener
arguments: [#request_stack]
tags:
- { name: kernel.event_listener, event: kernel.request, method: onRequestAction }
Then in the RequestListener class, make a onRequestAction() method and inject request stack through the constrcutor. Inside onRequestAction(), you can get controller name like this:
$this->requestStack->getCurrentRequest()->get('_controller');
It will return the controller name and action (I think they are separated by :). Parse the string and check if it is the right controller. And if it is, also check it is XmlHttpRequest like this:
$this->requestStack->getCurrentRequest()->isXmlHttpRequest();
If it is not, you can redirect/forward.
Also note, that this will be checked upon every single request. If you check those things directly in one of your controllers, you will have a more light-weight solution.

How to override FOSUserBundle's EmailConfirmationListener

I activated user confirmation for FOSUserBundle. But I don't want to take the response from the original listener
$url = $this->router->generate('fos_user_registration_check_email');
$event->setResponse(new RedirectResponse($url));
I want to chose another route. I tried to extend the EventListener
namespace Acme\MyBundle\EventListener;
use FOS\UserBundle\EventListener\EmailConfirmationListener as BaseListener;
// ...
class EmailConfirmationListener extends BaseListener
{
public function onRegistrationSuccess(FormEvent $event)
{
$url = $this->router->generate('fos_user_registration_check_email');
$event->setResponse(new RedirectResponse($url));
}
}
Unfortunately, EventListeners don't seem to be extendable, just as Controllers or Forms are. (Just in case you wonder: of course my bundle is a child of the FOSUserBundle.)
So I want to avoid editing those two lines directly in the vendor folder (as it would be very bad practice to do so!). So what are my ways out of this calamity?
Just override the service fos_user.listener.email_confirmation by creating a service with the same name in your config.yml ...
# app/config/config.yml
services:
fos_user.listener.email_confirmation:
class: "Acme\MyBundle\EventListener\EmailConfirmationListener"
arguments: ["#fos_user.mailer", "#fos_user.util.token_generator", "#router", "#session"]
tags:
- { name: kernel.event_subscriber }
... or even cleaner - create a parameter that's being used by your service:
parameters:
my.funky_parameter.class: "Acme\MyBundle\EventListener\EmailConfirmationListener"
services:
fos_user.listener.email_confirmation:
class: "%my.funky_parameter.class%"
# ...
... or inside your bundle's xml/yml/php configuration file loaded by the bundle's extension. Make sure your bundle is being registered after FOSUserBundle in AppKernel.php when choosing this way.
... or the best method:
change the original service's class name in a compiler pass as the documentation chapter How to Override any Part of a Bundle suggests.
Maybe take a dive into the chapter How to work with Compiler Passes before choosing this option.

Symfony2 Listeners and Sessions

I'm trying to set data of a session in a Symfony2 Listener (Symfony v. 2.0.16) but somehow the listener won't register the session variables.
I have the following:
My services.yml entry:
kernel.listener.domain_listener:
class: Etiam\ClubWebBundle\Listener\SubdomainListener
arguments: [#service_container]
tags:
- { name: kernel.event_listener, event: kernel.request, method: onDomainParse }
And here's my listener:
namespace Etiam\ClubWebBundle\Listener;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\EventDispatcher\Event;
class SubdomainListener {
private $container;
public function __construct($container)
{
$this->container = $container;
}
public function onDomainParse(Event $event) {
$session = $this->container->get('session');
$session->set('siteData', '123');
$session->save();
}
}
Can anyone tell me why my session data isn't being saved when the listener is being accessed?
Okay, I figured it out.
If anyone ever comes across something similar with Listeners that you're changing things and nothing happens:
If you have multiple bundles you've maybe got 2 identical listeners and you're editing the wrong one. Listeners are apparently global, and you need only one to be valid across multiple bundles.
You can see your loaded listeners in the profiler under events.

Resources