264 lines
9.3 KiB
PHP
264 lines
9.3 KiB
PHP
<?php
|
|
namespace DynCom\mysyde\common\classes;
|
|
use Monolog\Formatter\HtmlFormatter;
|
|
use Monolog\Formatter\LineFormatter;
|
|
use Monolog\Handler\RotatingFileHandler;
|
|
use Monolog\Handler\SwiftMailerHandler;
|
|
use Monolog\Logger;
|
|
use Psr\Log\LoggerInterface;
|
|
|
|
/**
|
|
* Created by PhpStorm.
|
|
* User: Bauer
|
|
* Date: 06.05.2016
|
|
* Time: 10:42
|
|
*/
|
|
class GeneralErrorExceptionHandling
|
|
{
|
|
|
|
const DEFAULT_ERROR_LOG_PATH = '/logs/unhandled_errors.log';
|
|
const DEFAULT_ERROR_LOGGER_NAME = 'UnhandledErrorLogging';
|
|
|
|
const DEFAULT_EXCEPTION_LOG_PATH = '/logs/unhandled_exceptions.log';
|
|
const DEFAULT_EXCEPTION_LOGGER_NAME = 'UnhandledExceptionLogging';
|
|
|
|
const DEFAULT_ERROR_MAIL_SENDER_ADDR = 'error@projectname.dc-solution';
|
|
const DEFAULT_ERROR_MAIL_SUBJECT = 'Unhandled Error in project projectname';
|
|
|
|
const DEFAULT_EXCEPTION_MAIL_SENDER_ADDR = 'exception@projectname.dc-solution';
|
|
const DEFAULT_EXCEPTION_MAIL_SUBJECT = 'Unhandled Exception in project projectname';
|
|
|
|
const DEFAULT_ERROR_EXCEPTION_MAIL_RECIPIENT_ADDRESS = '';
|
|
const DEFAULT_ERROR_EXCEPTION_MAIL_RECIPIENT_NAME = '';
|
|
|
|
|
|
private static $isSetAsErrorHandler;
|
|
private static $isSetAsExceptionHandler;
|
|
private static $redirectErrorPath;
|
|
private static $redirectErrorMsg;
|
|
private static $redirectExceptionPath;
|
|
private static $redirectExceptionMsg;
|
|
|
|
/**
|
|
* @var \Psr\Log\LoggerInterface
|
|
*/
|
|
private static $defaultErrorLogger;
|
|
|
|
/**
|
|
* @var \Psr\Log\LoggerInterface
|
|
*/
|
|
private static $defaultExceptionLogger;
|
|
|
|
|
|
/**
|
|
* @return LoggerInterface
|
|
*/
|
|
public static function getDefaultErrorLogger()
|
|
{
|
|
if (self::$defaultErrorLogger === null) {
|
|
$baseDir = dirname(dirname(dirname(__DIR__)));
|
|
$loggerPath = rtrim($baseDir,'/') . self::DEFAULT_ERROR_LOG_PATH;
|
|
if (empty($_SERVER['DOCUMENT_ROOT'])) { //Output only on CLI
|
|
//echo "Class " . __CLASS__ . " logging errors to path [$loggerPath]" . PHP_EOL;
|
|
}
|
|
self::$defaultErrorLogger = self::createDefaultLogger($loggerPath, self::DEFAULT_ERROR_LOGGER_NAME,self::DEFAULT_ERROR_MAIL_SUBJECT,self::DEFAULT_ERROR_MAIL_SENDER_ADDR);
|
|
}
|
|
return self::$defaultErrorLogger;
|
|
}
|
|
|
|
/**
|
|
* @return Logger|LoggerInterface
|
|
*/
|
|
public static function getDefaultExceptionLogger()
|
|
{
|
|
if (self::$defaultExceptionLogger === null) {
|
|
$baseDir = dirname(dirname(dirname(__DIR__)));
|
|
$loggerPath = rtrim($baseDir,'/') . self::DEFAULT_EXCEPTION_LOG_PATH;
|
|
if (empty($_SERVER['DOCUMENT_ROOT'])) { //Output only on CLI
|
|
//echo "Class " . __CLASS__ . " logging exceptions to path [$loggerPath]" . PHP_EOL;
|
|
}
|
|
self::$defaultExceptionLogger = self::createDefaultLogger($loggerPath, self::DEFAULT_EXCEPTION_LOGGER_NAME,self::DEFAULT_EXCEPTION_MAIL_SUBJECT,self::DEFAULT_EXCEPTION_MAIL_SENDER_ADDR);
|
|
}
|
|
return self::$defaultExceptionLogger;
|
|
}
|
|
|
|
/**
|
|
* @param $logFilePath
|
|
* @param $loggerName
|
|
* @param $mailSubject
|
|
* @param $mailFromAddr
|
|
* @return \Monolog\Logger
|
|
*/
|
|
private static function createDefaultLogger($logFilePath,$loggerName,$mailSubject,$mailFromAddr)
|
|
{
|
|
$handlers = [];
|
|
$rotatingFileHandler = new RotatingFileHandler($logFilePath, 10);
|
|
$formatter = new LineFormatter(null, null, false, true);
|
|
$rotatingFileHandler->setFormatter($formatter);
|
|
$handlers[] = $rotatingFileHandler;
|
|
|
|
$mailRecipientAddr = self::DEFAULT_ERROR_EXCEPTION_MAIL_RECIPIENT_ADDRESS;
|
|
if ($mailRecipientAddr !== '' && filter_var($mailRecipientAddr,FILTER_VALIDATE_EMAIL)) {
|
|
$handlers[] = self::getDefaultMailHandler($mailSubject,$mailFromAddr,self::DEFAULT_ERROR_EXCEPTION_MAIL_RECIPIENT_ADDRESS,self::DEFAULT_ERROR_EXCEPTION_MAIL_RECIPIENT_NAME);
|
|
}
|
|
$logger = new Logger($loggerName,$handlers);
|
|
return $logger;
|
|
}
|
|
|
|
/**
|
|
* @param $subject
|
|
* @param $fromAddr
|
|
* @param $toAddr
|
|
* @param $toName
|
|
* @return SwiftMailerHandler
|
|
*/
|
|
private static function getDefaultMailHandler($subject, $fromAddr, $toAddr, $toName)
|
|
{
|
|
$smtpTransporter = \Swift_SmtpTransport::newInstance();
|
|
$mailer = \Swift_Mailer::newInstance($smtpTransporter);
|
|
$msg = \Swift_Message::newInstance($subject);
|
|
$msg->addFrom($fromAddr);
|
|
$msg->addTo($toAddr, $toName);
|
|
$mailFormatter = new HtmlFormatter();
|
|
$mailHandler = new SwiftMailerHandler($mailer, $msg);
|
|
$mailHandler->setFormatter($mailFormatter);
|
|
return $mailHandler;
|
|
}
|
|
|
|
/**
|
|
* @param $exception
|
|
*/
|
|
public static function handleException($exception)
|
|
{
|
|
$logger = self::getDefaultExceptionLogger();
|
|
$msg = 'An unhandled exception occurred! ' . PHP_EOL .
|
|
" Errno: {$exception->getCode()}" . PHP_EOL .
|
|
" Msg: {$exception->getMessage()}" . PHP_EOL;
|
|
|
|
$fileName = $exception->getFile();
|
|
if ($fileName !== '') {
|
|
$msg .= " File: $fileName " . PHP_EOL;
|
|
}
|
|
|
|
$lineNo = $exception->getLine();
|
|
if ($lineNo !== 0) {
|
|
$msg .= " Line: $lineNo" . PHP_EOL;
|
|
}
|
|
|
|
$traceString = str_replace("\n",PHP_EOL,$exception->getTraceAsString());
|
|
if ($traceString !== '') {
|
|
$msg .= " Trace: $traceString" . PHP_EOL;
|
|
}
|
|
$msg .= PHP_EOL;
|
|
|
|
$logger->addError($msg);
|
|
self::doConditionalRedirect(self::$redirectExceptionPath,self::$redirectExceptionMsg);
|
|
}
|
|
|
|
/**
|
|
* @param $errno
|
|
* @param $errstr
|
|
* @param string $errfileName
|
|
* @param null $errLine
|
|
* @param array|null $errContext
|
|
*/
|
|
public static function handleError($errno, $errstr, $errfileName = '', $errLine = null, array $errContext = null)
|
|
{
|
|
$logger = self::getDefaultErrorLogger();
|
|
$msg = 'An error occurred!' . PHP_EOL .
|
|
" Errno: $errno" . PHP_EOL .
|
|
" Msg: $errstr" . PHP_EOL;
|
|
if ($errfileName !== '') {
|
|
$msg .= " File: $errfileName" . PHP_EOL;
|
|
}
|
|
if ($errLine !== null) {
|
|
$msg .= " Line: $errLine" . PHP_EOL;
|
|
}
|
|
if ($errContext !== null && count($errContext) > 0) {
|
|
$msg .= ' Context Variables: ' . print_r($errContext,1) . PHP_EOL;
|
|
}
|
|
$msg .= PHP_EOL;
|
|
|
|
$logger->addError($msg);
|
|
self::doConditionalRedirect(self::$redirectErrorPath,self::$redirectErrorMsg);
|
|
}
|
|
|
|
/**
|
|
* @param string $redirectToPagePath
|
|
* @param string $redirectWithMessage
|
|
*/
|
|
public static function setExceptionHandler($redirectToPagePath = '', $redirectWithMessage = '')
|
|
{
|
|
if (!self::$isSetAsExceptionHandler) {
|
|
self::$redirectExceptionPath = $redirectToPagePath;
|
|
self::$redirectExceptionMsg = $redirectWithMessage;
|
|
$callable = array(__CLASS__,'handleException');
|
|
set_exception_handler($callable);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param string $redirectToPagePath
|
|
* @param string $redirectWithMessage
|
|
*/
|
|
public static function setErrorHandler($redirectToPagePath = '', $redirectWithMessage = '')
|
|
{
|
|
if (!self::$isSetAsErrorHandler) {
|
|
self::$redirectErrorPath = $redirectToPagePath;
|
|
self::$redirectErrorMsg = $redirectWithMessage;
|
|
$callable = array(__CLASS__,'handleError');
|
|
set_error_handler($callable,self::getErrorHandlingLevel());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @return int
|
|
*/
|
|
private static function getErrorHandlingLevel()
|
|
{
|
|
return E_ALL^E_NOTICE^E_STRICT^E_WARNING;
|
|
}
|
|
|
|
/**
|
|
* @param string $path
|
|
* @param string $msg
|
|
*/
|
|
private static function doConditionalRedirect($path = '', $msg = '')
|
|
{
|
|
if ($path !== '' && !self::isPathCurrentUrl($path)) {
|
|
self::saveErrorFlashMessageToSession($msg);
|
|
universal_redirect($path);
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* @param string $msg
|
|
*/
|
|
private static function saveErrorFlashMessageToSession($msg = '')
|
|
{
|
|
static $i = null;
|
|
if ($msg !== '') {
|
|
$errorMsgs = isset($_SESSION['msgBag']['errors']) ? $_SESSION['msgBag']['errors'] : [];
|
|
if (!in_array($msg,$errorMsgs,true)) {
|
|
$errorMsgs[] = $msg;
|
|
}
|
|
$_SESSION['msgBag']['errors'] = $errorMsgs;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param string $path
|
|
* @return bool
|
|
*/
|
|
private static function isPathCurrentUrl($path = '')
|
|
{
|
|
$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://";
|
|
$domainName = $_SERVER['HTTP_HOST'];
|
|
$request = $_SERVER['REQUEST_URI'];
|
|
$currPath = $protocol.$domainName.$request;
|
|
return $path === $currPath;
|
|
}
|
|
|
|
}
|