<?php/** * Created by PhpStorm. * User: eph * Date: 27/10/16 * Time: 15:30 */namespace Oi\BugBundle\Listener;use Doctrine\Bundle\DoctrineBundle\Registry;use Doctrine\ORM\EntityManager;use Oi\BugBundle\Entity\Bug;use Oi\BugBundle\Entity\BugCookie;use Oi\BugBundle\Entity\BugTrace;use Oi\BugBundle\Entity\LastUpdate;use Symfony\Component\HttpFoundation\Request;use Symfony\Component\HttpKernel\Event\ExceptionEvent;use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;use Twig\Environment;class CatchExceptionListener{ /** * @var Registry */ private $doctrine; /** * @var ExceptionEvent */ private $event = null; /** * @var Request */ private $request = null; /** * @var TokenStorageInterface */ private $tokenStorage = null; /** * @var EntityManager */ private $em = null; private $user; private $options; public function __construct( Registry $doctrine, TokenStorageInterface $tokenStorage, $options ) { $this->doctrine = $doctrine; $this->tokenStorage = $tokenStorage; $this->em = $doctrine->getManager(); $this->options = $options; if ($this->tokenStorage) { if (null !== $token = $this->tokenStorage->getToken()) { if (is_object($user = $token->getUser())) { $this->user = $user; } } } } /** * @param ExceptionEvent $event */ public function onKernelException(ExceptionEvent $event) { $this->event = $event; $this->request = $event->getRequest(); $exception = $event->getThrowable(); if (!strpos($exception->getMessage(), 'GET /uploads')) { $cookies = $this->request->cookies->all(); $exceptionType = 'Exception'; if (!is_null($exception->getPrevious())) { $exceptionType = get_class($exception->getPrevious()); } if ($exceptionType == 'Oi\BugBundle\Listener\CatchExceptionListener') { $exceptionType = get_class($exception); } $message = $exception->getMessage(); $route = $this->request->get('_route'); $routeParams = $this->request->get('_route_params', []); $url = $this->request->getUri(); $baseUrl = $this->request->getBaseUrl(); $query = $this->request->getQueryString(); $userAgent = $this->request->server->get('HTTP_USER_AGENT'); $host = $this->request->getHost(); $ip = $this->request->getClientIp(); $username = $this->user ? $this->user->getUsername() : "Anonymous"; $statusCode = $this->getStatusCode($exceptionType); if (isset($this->options['filter']) && isset($this->options['filter']['status'])) { switch ($statusCode) { case 400: if (!$this->options['filter']['status']['400']) { return false; } break; case 401: if (!$this->options['filter']['status']['401']) { return false; } break; case 403: if (!$this->options['filter']['status']['403']) { return false; } break; case 404: if (!$this->options['filter']['status']['404']) { return false; } break; case 405: if (!$this->options['filter']['status']['405']) { return false; } break; case 406: if (!$this->options['filter']['status']['406']) { return false; } break; case 407: if (!$this->options['filter']['status']['407']) { return false; } break; case 500: if (!$this->options['filter']['status']['500']) { return false; } break; default: if (!$this->options['filter']['status']['others']) { return false; } break; } } if (isset($this->options['database']['enable']) && $this->options['database']['enable']) { if ($this->em->isOpen()) { $this->em->close(); //If some transactions are currently active, rollbacking them all before starting. $conn = $this->em->getConnection(); while ($conn->getTransactionNestingLevel() > 0) { $conn->rollBack(); } } $this->em = $this->doctrine->resetManager(); $this->em->beginTransaction(); try { $last = $this->em->getRepository(LastUpdate::class)->findOneBy([], ['id' => 'DESC']); $bug = new Bug(); $bug->setExceptionType($exceptionType); $bug->setMessage($message); $bug->setRoute($route); $bug->setRouteParams($routeParams); $bug->setUrl($url); $bug->setBaseUrl($baseUrl); $bug->setQuery($query); $bug->setUserAgent($userAgent); $bug->setHost($host); $bug->setIpAddress($ip); $bug->setUsername($username); $bug->setStatusCode($statusCode); $bug->setUpdate($last); $this->em->persist($bug); $this->em->flush(); foreach ($exception->getTrace() as $trace) { $bugTrace = new BugTrace(); $bugTrace->setBug($bug); $fx = ''; if (isset($trace['file'])) { $bugTrace->setFile($trace['file']); } if (isset($trace['class'])) { $fx .= $trace['class']; } if (isset($trace['type'])) { $fx .= $trace['type']; } if (isset($trace['function'])) { $fx .= $trace['function']; } $bugTrace->setFunction($fx); if (isset($trace['line'])) { $bugTrace->setLine($trace['line']); } if (isset($trace['line'])) { $bugTrace->setLine($trace['line']); } $this->em->persist($bugTrace); } $this->em->flush(); foreach ($cookies as $key => $value) { $bugCookie = new BugCookie(); $bugCookie->setBug($bug); $bugCookie->setKey($key); $bugCookie->setValue($value); $this->em->persist($bugCookie); } $this->em->flush(); $this->em->commit(); } catch (\Exception $e) { $this->em->rollback(); } } } } private function getStatusCode($exceptionType) { switch ($exceptionType) { case 'Symfony\Component\Routing\Exception\ResourceNotFoundException': return 404; case 'Symfony\Component\HttpKernel\Exception\NotFoundHttpException': case 'Symfony\Component\Debug\Exception\FatalThrowableError': default: return 500; } }}