<?php
namespace App\Component\Console\Listener;
use App\Component\Console\Output\ConsoleLogOutput;
use App\Component\Traits\Service\EmailerServiceTrait;
use Symfony\Component\Console\Event\ConsoleCommandEvent;
use Symfony\Component\Console\Event\ConsoleErrorEvent;
use Symfony\Component\Console\Event\ConsoleTerminateEvent;
use Symfony\Component\Console\Input\ArgvInput;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Component\Mailer\Exception\TransportExceptionInterface;
class ConsoleEventListener
{
use EmailerServiceTrait;
protected $kernel;
public function __construct(KernelInterface $kernel)
{
$this->kernel = $kernel;
}
/**
* @param ConsoleCommandEvent $event
* @throws \Exception
*/
public function onConsoleCommand(ConsoleCommandEvent $event)
{
/** @var ArgvInput $input */
$input = $event->getInput();
$event->getOutput()->writeln('START ' . $this->getDisplayedName($input));
/** @var ConsoleLogOutput $output */
$output = $event->getOutput();
set_error_handler(function ($errno, $errstr, $errfile, $errline/*, $errContext*/) use ($output) {
$file = $this->getRelativePath($errfile);
$message = $errstr . ' in ' . $file . ':' . $errline;
$trace = (new \Exception)->getTraceAsString();
// Remove first item from backtrace as it's this function which is redundant.
$trace = preg_replace('/^#0.+' . 'ConsoleEventListener' . "[^\n]*\n/", '', $trace, 1);
switch ($errno) {
case E_WARNING:
case E_USER_WARNING:
$output->addWarning($message, $trace, $errno);
break;
case E_NOTICE:
case E_USER_NOTICE:
$output->addNotice($message, $trace, $errno);
break;
case E_DEPRECATED:
case E_USER_DEPRECATED:
// pas de log des "deprecated"
return true;
default:
$output->addError($message, $trace, $errno);
}
return true;
});
}
/**
* @param ConsoleTerminateEvent $event
* @throws \Exception
* @throws TransportExceptionInterface
*/
public function onConsoleTerminate(ConsoleTerminateEvent $event)
{
/** @var ArgvInput $input */
$input = $event->getInput();
$event->getOutput()->writeln('END ' . $this->getDisplayedName($input));
if (method_exists($event->getOutput(), 'getErrors') && !empty($event->getOutput()->getErrors())) {
$this->emailerService
->setTo($this->kernel->getContainer()->getParameter('app.default_recipient'))
->setSubject('Erreur de CRON (' . $event->getCommand()->getName() . ')')
->setTemplate('email/console-error.html.twig')
->setParameters([
'cron' => $this->getDisplayedName($input),
'date' => new \DateTime(),
'erreurs' => $event->getOutput()->getErrors(),
])
->send();
}
// // On supprime le fichier si rien n'est loggé
// $a = $event->getCommand()->getApplication();
// if ($a instanceof ConsoleApplication) {
// $f = $a->logFile;
// $c = file_get_contents($f);
// $l = substr_count($c, "\n");
// if ($l === 2) {
// (new Filesystem())->remove($f);
// }
// }
}
/**
* @param ConsoleErrorEvent $event
*/
public function onConsoleError(ConsoleErrorEvent $event)
{
$error = $event->getError();
/** @var ConsoleLogOutput $output */
$output = $event->getOutput();
$output->addError($error->getMessage(), $error->getTraceAsString(), $error->getCode());
}
/**
* @param ArgvInput|InputArgument $input
* @return string
*/
protected function getDisplayedName($input)
{
$args = $input->__toString();
return trim(str_replace('"', '', $args));
}
/**
* @param string $file
* @return string
*/
protected function getRelativePath($file)
{
$filesystem = new Filesystem();
return $filesystem->makePathRelative(dirname($file), $this->kernel->getProjectDir()) . basename($file);
}
}