0

I do not have a lot of Symfony experience, but I'm working on an Symfony 4 application that is using the https://github.com/maximilienGilet/notification-bundle Adding and displaying the notifications is working well, but I'm stuck on handling the events created by the bundle.

A form in a twig template (actually in my base twig template) is calling the bundle post markasseen action which is returning a JSON true message, but now I don't know how to return to the URL (route) from which the post call is done?

This is my routers.yaml which "activates" the bundle controller:

App\EventListener\NotificationListener:
    arguments: ['@router']
    tags:
        - { name: kernel.event_listener, event: mgilet.notification.seen }

As you can see I've tried to pass a router parameter to see if that gives me the possibility to "return", but unfortunately that did not help.

This is the EventListener I've created for handling the bundle event:

<?php

namespace App\EventListener;

use Mgilet\NotificationBundle\Event;
use Mgilet\NotificationBundle\Event\NotificationEvent;

use \Symfony\Bundle\FrameworkBundle\Routing\Router;
use \Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Routing\Exception\ResourceNotFoundException;

class NotificationListener
{
    private $router;

    public function __construct(Router $router) {
        $this->router = $router;
    }

    public function OnMgiletNotificationSeen(Event\NotificationEvent $event): void {
        dd($event);
    }

}

As I mentioned, the event is caught by the listener, it is returning 'true', but I want to return to the route/controller from where the post action is called.

This is the form in the base template (because I want to show te notifications in all templates) which is calling the notification controller:

<form action="/notifications/1/mark_as_seen/8" method="post">
    <button type="submit" class="close">
        <span aria-hidden="true">×</span><span class="sr-only">Close</span>
    </button>
</form>

Can anyone please help me?

Paul Dirkx
  • 11
  • 3
  • can you add the controller where you have instanced the form? – NicolaPez Dec 14 '18 at 09:11
  • @NicolaPez Thanks for viewing my question. I'm not sure what you mean? This form is created by the Mgilit render function '{{mgilet_notification_render}} ' in the twig template. – Paul Dirkx Dec 14 '18 at 09:53
  • Ok, sorry, I didn't understand the form are totally created from the bundle. Did you tried to open a issue on the bundle doc https://github.com/maximilienGilet/notification-bundle/issues ? – NicolaPez Dec 14 '18 at 10:01
  • because I think is the better place for a specific question on the bundle – NicolaPez Dec 14 '18 at 10:04
  • @NicolaPez Once again thank you for your comment. I'll check Github, but because I thought that returning from a json response in a listener is something that happens more? – Paul Dirkx Dec 14 '18 at 10:21
  • Ok, I try to understand. What you want is a route from the action that call the form, because you have this in the base template? – NicolaPez Dec 14 '18 at 10:29
  • Indeed, that is what I want (if I understand you correctly). Without the listerer I see the JSON response in the browser. In the listener I can "catch" the repsonse but then I would like to "go back". – Paul Dirkx Dec 14 '18 at 10:37
  • I tried to answer below, think you can resolve using only frontend (twig)? – NicolaPez Dec 14 '18 at 10:41

2 Answers2

0

as https://stackoverflow.com/a/28913544/5475228 say, you can have the current route using the twig variable in this way:

app.request.attributes.get('_route')

also you can have the previous route with this:

app.request.headers.get('referer')

So, if I understand your issue, you can redirect to this route after the json response is true.

NicolaPez
  • 567
  • 1
  • 4
  • 27
  • But how can call the redirect from this listener? As well $this->redirect as $event-redirect or $this->router->redirect generates an error? – Paul Dirkx Dec 14 '18 at 10:46
  • I presume the problem is not so clearly to me, but in my solution you have the route in frontend (js?) because when i see the bundle I think a frontend behavior. So you could make the redirect with js. – NicolaPez Dec 14 '18 at 10:52
0

I've solved my problem (temporarily), though I don't think this is the best way to solve.

I disabled the bundle controller in routes.yaml and created a custom controller which handles the posts.

class NotifyController extends Controller
{
    /**
     * Set a Notification as seen
     * @Route("/notifications/{notifiable}/mark_as_seen/{notification}", name="notification_mark_as_seen", methods={"POST"})
     */
    public function markAsSeenAction($notifiable, $notification, Request $request)
    {
        $manager = $this->get('mgilet.notification');
        $manager->markAsSeen(
            $manager->getNotifiableInterface($manager->getNotifiableEntityById($notifiable)),
            $manager->getNotification($notification),
            true
        );

        return $this->redirect($request->headers->get('referer'));
    }

    /**
     * Set all Notifications for a User as seen
     * @Route("/notifications/{notifiable}/markAllAsSeen", name="notification_mark_all_as_seen", methods={"POST"})
     */
    public function markAllAsSeenAction($notifiable, Request $request)
    {
        $manager = $this->get('mgilet.notification');
        $manager->markAllAsSeen(
            $manager->getNotifiableInterface($manager->getNotifiableEntityById($notifiable)),
            true
        );

        return $this->redirect($request->headers->get('referer'));
    }
}

Thanks for the help everyone!

Paul Dirkx
  • 11
  • 3