Bonjour,

J'ai bien compris le concept du subscriber et du listener avec symfony
J'ai bien réussi à installer mon subscriber,
J'ai réussi à appeler ma méthode processException en premier, aucun soucis.

Maintenant, j'aimerai appeler ma méthode toto, que lorsque que je fais appel à une route particulière ou controller particulier.

Merci à tous, je bloque totalement !

namespace App\EventSubscriber;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
use Symfony\Component\HttpKernel\KernelEvents;

class ExceptionSubscriber implements EventSubscriberInterface
{
    public static function getSubscribedEvents()
    {
        // return the subscribed events, their methods and priorities
        return [
            KernelEvents::EXCEPTION => [
                ['processException', 10],
                ['toto', 0],,
            ],
        ];
    }

    public function processException(ExceptionEvent $event)
    {
        // il est appelé automatiquement à chaque fois
    }

    public function toto(ExceptionEvent $event)
    {
        // je souhaote l'appeler seulement dans mon controller lorsque la route est
    }
    }
}

4 réponses


Cybercraft
Réponse acceptée

Ahh, je comprend mieux :) Tu va être ravi car il existe une annotation pour appelr ton Repository. Ca s'appele du Fetching via une Expression :

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Entity;

// ....

/**
  * @Route("/{item_id}")
  * @Entity("Item", expr="repository.findItemById(id)")
  */
public function showItem(Item $item)
{
    // ....
}

Aprés, il te faut adapter ton repository :

     public function findItemById($itemId) 
    {
        $item = $this->find($itemId);
        if (!$item) {
            throw new Exception("L'item que vous rechercher n'existe pas",404);
        }

        return $item;   
    }

KernelEvents::EXCEPTION est utilisé pour les évènements levant des exceptions.

Dans ton cas, il te faudrais un KernelEvent::REQUEST et dans ta méthode, tu peux récupérer le nom de ta route depuis l'event :

    public static function getSubscribedEvents()
    {
        // return the subscribed events, their methods and priorities
        return [
            KernelEvents::EXCEPTION => [['processException', 10]],
            kernelEvents::REQUEST => [['toto', 33]]
        ];
    }

    // ....

    public function toto(RequestEvent $event)
    {
        $request = $event->getRequest();
         if ($request->attributes->has('_controller') && $request->attributes->has('_route'))
         {
                $routeName = $event->attributes->get('_route');
                if ($routeName === "le_nom_de_ta_route") {
                     // Mon super code
                 }
          }
    }    

PS : Nhésite pas à regarder quels sont les EventSubcriber déjà en cours sur ton application :

php bin/console debug:event-dispatcher kernel.request

PPS : La priorité de ton Listener doit être supérieur à 32 (aprés le RouterListener, sinon la requête ne contiendra pas "_route")

Ok super intéréssant à savoir.
Oui en gros mon objectifs est de vérifier un élément depuis mes Repository, si il n'existe pas je relève une exception et cela avant le paramConverter.

J'ai donc créer un service, utilisant mes repository, comme findall()
Et je relève une exception si celui-ci est introuvable dans la base de donnée.

Maintenant j'aimerai faire cette vérification avant même que le paramconverter retourne lui-même une réponse.
Le but étant de pouvoir écrire mon propre message d'erreur

Exemple :
CONTROLLER

public function showItem(Item $item) // ici le paramconverter me retourne une erreur item introuvable si celui-ci n'existe pas selon l'id
    {
        ---
    }

SERVICE

namespace App\Service;

use App\Entity\Item;
use App\Repository\ItemRepository;
use Exception;

class ItemSearch{

    private ItemRepository $itemRepository;

    public function __construct(ItemRepository $itemRepository)
    {
        $this->itemRepository = $itemRepository;
    }

   public function findItemById(Item $item) 
    {
        if (!$item) {
            throw new Exception("L'item que vous rechercher n'existe pas",404);
        }

        return $item;   
    }

Merci cybercraft pour ton premier retour, super sympa.

Ok merci beaucoup, je vais regarder et essayer tout ça ! :)
Merci cybercraft d'avoir pris le temps de répondre à ma reqûete ! ^^