<?php
namespace AppBundle\EventSubscriber;
use AppBundle\Annotation\Webhook;
use AppBundle\Logger\ApiLoggerInterface;
use AppBundle\Logger\ZohoSubcriptionWebhookLogger;
use Doctrine\Common\Annotations\AnnotationReader;
use Doctrine\ORM\Exception\ORMException;
use Psr\Container\ContainerInterface;
use Symfony\Contracts\Service\ServiceSubscriberInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
class WebhookSubscriber implements ServiceSubscriberInterface, EventSubscriberInterface
{
/**
* @var ContainerInterface
*/
private $container;
public function __construct(ContainerInterface $container)
{
$this->container = $container;
}
/**
* @return array<mixed>
*/
public static function getSubscribedEvents(): array
{
return [
KernelEvents::RESPONSE => ['onKernelResponse', 1000],
];
}
/**
* @return array<string>
*/
public static function getSubscribedServices(): array
{
return [
ZohoSubcriptionWebhookLogger::class,
];
}
/**
* @param ResponseEvent $responseEvent
* @return void
* @throws ORMException
*/
public function onKernelResponse(ResponseEvent $responseEvent): void
{
$request = $responseEvent->getRequest();
$response = $responseEvent->getResponse();
$annotation = $this->getWehookAnnotation($request);
if ($annotation && $annotation->getLogger()) {
/** @var ApiLoggerInterface $logger */
$logger = $this->container->get((string) $annotation->getLogger());
$logger->log($request, $response);
}
}
/**
* @param Request $request
* @return Webhook|null
*/
private function getWehookAnnotation(Request $request): ?Webhook {
try {
$annotations = [];
if ($controller = $request->attributes->get('_controller')) {
/** @var string[] $splittedController */
$splittedController = explode(':', $controller);
/** @var string $controllerName */
$controllerName = count($splittedController) > 0 ? $splittedController[0] : $controller;
$reflectedMethod = new \ReflectionClass($controllerName);
$annotations = array_filter(
(new AnnotationReader())->getClassAnnotations($reflectedMethod),
static function ($annotation) { return $annotation instanceof Webhook; }
);
}
return count($annotations) > 0 ? current($annotations) : null;
} catch (\Exception $e) {
}
return null;
}
}