<?php
namespace App\Event;
use App\Entity\Parametre\Utilisateur;
use App\Helper\MailerHelper;
use Doctrine\ORM\EntityManager;
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Security\Core\Authentication\Token\Storage\UsageTrackingTokenStorage;
use Twig\Environment;
use Webservice\Controller\AbstractWebserviceController;
/**
* KernelExceptionEvent.
*
* @author John Doe
* @package App\Event
*/
class KernelExceptionEvent {
/** @var EntityManager */
private $em;
/** @var array */
private $smtpParameters;
/** @var UsageTrackingTokenStorage */
private $tokenStorage;
/** @var Environment */
private $twig;
public function __construct(EntityManager $em, Environment $twig, UsageTrackingTokenStorage $tokenStorage, $smtpParameters) {
$this->em = $em;
$this->twig = $twig;
$this->tokenStorage = $tokenStorage;
$this->smtpParameters = $smtpParameters;
}
/**
* @return EntityManager
*/
private function em() {
return $this->em;
}
/**
* @return Utilisateur|null
*/
private function getUser() {
if (null === $this->tokenStorage->getToken()) {
return null;
}
return $this->tokenStorage->getToken()->getUser();
}
/**
* @param ExceptionEvent $e
* @throws \Throwable
* @throws \Twig\Error\LoaderError
* @throws \Twig\Error\RuntimeError
* @throws \Twig\Error\SyntaxError
*/
private function notifyTechnicalStaff(ExceptionEvent $e) {
$date = new \DateTime();
$currentUser = $this->getUser();
$currentUserName = "Non authentifié";
if (null !== $currentUser) {
$currentUserName = "{$currentUser->getPrenomNom()} ({$currentUser->getEmail()}) - ID : {$currentUser->getId()}";
}
// Skip notify for specific host.
if (true === in_array($_SERVER["HTTP_HOST"], [
"club-la-pelle.local:8080",
"app.px.local:8080",
"c9999999.px.local:8080",
"c9999998.px.local:8080",
])) {
// http_response_code(500);
// echo "<h4 class='text-danger'>Erreur 500:</h4>";
// dump($e);
// exit;
return;
}
// Ignore when text is into exception.
$ignoreMessageEvent = [
"No route found",
"Integrity constraint violation",
"object not found by the @ParamConverter",
];
// Checking ignore message.
foreach ($ignoreMessageEvent as $message) {
if (false !== strpos(strtolower($e->getThrowable()->getMessage()), strtolower($message))) {
return;
}
}
$notifyTo = ["sysadmin@adheria.eu"];
$postData = $_POST;
foreach ($postData as $k => $v) {
if ($k === "_password" || $k === "password" || $k === "_csrf_token") {
$postData[$k] = "<obfuscated content>";
}
}
// Submit mail to user.
$mailer = new MailerHelper($this->smtpParameters, $this->twig, "fr");
$mailer->sendMail(
"Layout/email/kernel-exception.html.twig",
[
"userName" => $currentUserName,
"date" => $date,
"subject" => "Erreur 500",
"description" => "Une erreur interne s'est produite.",
"request" => $e->getRequest(),
"postData" => $postData,
"getData" => $_GET,
"exception" => $e->getThrowable(),
],
$notifyTo
);
}
/**
* @param ExceptionEvent $e
* @throws \Throwable
* @throws \Twig\Error\LoaderError
* @throws \Twig\Error\RuntimeError
* @throws \Twig\Error\SyntaxError
*/
public function onKernelException(ExceptionEvent $e) {
if (1 === preg_match("/^\/api/", $e->getRequest()->getRequestUri())) {
return $this->onKernelExceptionWebservice($e);
}
$this->notifyTechnicalStaff($e);
}
/**
* @param ExceptionEvent $e
*/
public function onKernelExceptionWebservice(ExceptionEvent $e) {
header("Content-Type: application/json");
$throw = $e->getThrowable();
$output = [
"errorCode" => $e->getThrowable()->getCode(),
"errorMessage" => $e->getThrowable()->getMessage(),
];
switch (get_class($throw)) {
default:
break;
case NotFoundHttpException::class:
$output = [
"errorCode" => "ROUTE_NOT_FOUND",
"errorMessage" => "This route was not found.",
];
break;
}
AbstractWebserviceController::criticalJsonResponse($output);
}
}