YetiForceCompany/YetiForceCRM

View on GitHub
app/ErrorHandler.php

Summary

Maintainability
A
0 mins
Test Coverage
F
29%
<?php
/**
 * Exception error handler class.
 *
 * @package App
 *
 * @copyright YetiForce S.A.
 * @license   YetiForce Public License 6.5 (licenses/LicenseEN.txt or yetiforce.com)
 * @author    Mariusz Krzaczkowski <m.krzaczkowski@yetiforce.com>
 */

namespace App;

/**
 * Exception error handler class.
 */
class ErrorHandler
{
    /**
     * Errors level.
     *
     * @var string[]
     */
    private static $levelNames = [
        E_ERROR => 'E_ERROR',
        E_WARNING => 'E_WARNING',
        E_PARSE => 'E_PARSE',
        E_NOTICE => 'E_NOTICE',
        E_STRICT => 'E_STRICT',
        E_CORE_ERROR => 'E_CORE_ERROR',
        E_CORE_WARNING => 'E_CORE_WARNING',
        E_COMPILE_ERROR => 'E_COMPILE_ERROR',
        E_COMPILE_WARNING => 'E_COMPILE_WARNING',
        E_USER_ERROR => 'E_USER_ERROR',
        E_USER_WARNING => 'E_USER_WARNING',
        E_USER_NOTICE => 'E_USER_NOTICE',
    ];

    /**
     * Error init.
     *
     * @return void
     */
    public static function init(): void
    {
        if (\class_exists('rcmail')) {
            return;
        }
        register_shutdown_function([__CLASS__, 'fatalHandler']);
        set_error_handler([__CLASS__, 'errorHandler'], \App\Config::debug('EXCEPTION_ERROR_LEVEL'));
    }

    /**
     * PHP fatal handler function.
     *
     * @return void
     */
    public static function fatalHandler(): void
    {
        $error = error_get_last();
        if (isset($error['type']) && \in_array($error['type'], [E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, E_COMPILE_WARNING])) {
            static::errorHandler($error['type'], $error['message'], $error['file'], $error['line']);
        }
    }

    /**
     * PHP error handler function.
     *
     * @see https://secure.php.net/manual/en/function.set-error-handler.php
     *
     * @param int    $no
     * @param string $str
     * @param string $file
     * @param int    $line
     *
     * @return void
     */
    public static function errorHandler(int $no, string $str, string $file, int $line): void
    {
        $errorString = static::error2string($no);
        $msg = reset($errorString) . ": $str in $file, line $line";
        if (\App\Config::debug('EXCEPTION_ERROR_TO_FILE')) {
            $logFile = ROOT_DIRECTORY . '/cache/logs/errors.log';
            $content = print_r($msg, true) . PHP_EOL . \App\Debuger::getBacktrace(2) . PHP_EOL;
            file_put_contents($logFile, $content, FILE_APPEND);
        }
        if (\App\Config::debug('EXCEPTION_ERROR_TO_SHOW')) {
            \vtlib\Functions::throwNewException($msg, false);
        }
    }

    /**
     * Convert error number to string.
     *
     * @param int $value
     *
     * @return string[]
     */
    public static function error2string(int $value): array
    {
        $levels = [];
        if (E_ALL == ($value & E_ALL)) {
            $levels[] = 'E_ALL';
            $value &= ~E_ALL;
        }
        foreach (self::$levelNames as $level => $name) {
            if (($value & $level) == $level) {
                $levels[] = $name;
            }
        }
        return $levels;
    }
}