'ERROR', 2 => 'WARNING', 4 => 'PARSE', 8 => 'NOTICE', 16 => 'CORE_ERROR', 32 => 'CORE_WARNING', 64 => 'COMPILE_ERROR', 128 => 'COMPILE_WARNING', 256 => 'USER_ERROR', 512 => 'USER_WARNING', 1024 => 'USER_NOTICE', 2048 => 'STRICT', 4096 => 'RECOVERABLE_ERROR', 8192 => 'DEPRECATED', 16384 => 'USER_DEPRECATED', 32767 => 'ALL' ]; /** * Magic to string * * @param void * * @return string * * @codeCoverageIgnore */ public function __toString() { return $this->importExceptionTemplate($this->getMessage(), $this->getFile(), $this->getLine(), $this->getTrace()); } /** * Throw exception * * @param string $message = NULL * @param string $key = NULL * @param mixed $send = NULL * * @return void */ public static function throws(?string $message = NULL, ?string $key = NULL, $send = NULL) { $debug = self::throwFinder(debug_backtrace(2), 0, 2); if( $lang = Lang::default('ZN\CoreDefaultLanguage')::select($message, $key, $send) ) { $message = '['.self::cleanInternalPrefixFromClassName($debug['class']).'::'.$debug['function'].'()] '.$lang; } self::table('self', $message, $debug['file'], $debug['line']); } /** * Get exception table * * @param mixed $no = NULL * @param string $msg = NULL * @param string $file = NULL * @param string $line = NULL * @param array $trace = NULL * * @return void */ public static function table($no = NULL, ?string $msg = NULL, ?string $file = NULL, ?string $line = NULL, ?array $trace = NULL) { if( is_object($no) ) { $msg = $no->getMessage(); $file = $no->getFile(); $line = $no->getLine(); $trace = $no->getTrace(); $no = 'NULL'; } $lang = Lang::default('ZN\ErrorHandling\ErrorHandlingDefaultLanguage')::select('Templates'); $message = $lang['line'].':'.$line.', '.$lang['file'].':'.$file.', '.$lang['message'].':'.$msg; Helper::report('ExceptionError', $message, 'ExceptionError'); $table = self::importExceptionTemplate($msg, $file, $line, $no, $trace); $projectError = Config::default('ZN\ErrorHandling\ErrorHandlingDefaultConfiguration')::get('Project'); if ( in_array($no, $projectError['exitErrors'] ?? [], true) || in_array(self::$errorCodes[$no] ?? NULL, $projectError['exitErrors'] ?? [], true) ) { defined('ZN_REDIRECT_NOEXIT') || exit($table); // @codeCoverageIgnore } echo $table; } /** * Continue exception * * @param string $msg * @param string $file * @param string $line * * @return string */ public static function continue($msg, $file, $line) { return self::importExceptionTemplate($msg, $file, $line, NULL, NULL); } /** * Restore exception * * @param void * * @return bool */ public static function restore() : bool { return restore_exception_handler(); } /** * Set exception handler * * @param void * * @return void */ public static function handler() { set_exception_handler([__CLASS__, 'table']); } /** * protected exception template * * @param string $msg * @param string $file * @param string $line * @param string $no * @param array $trace * * @return string */ private static function importExceptionTemplate($msg, $file, $line, $no, $trace) { $projects = Config::default('ZN\ErrorHandling\ErrorHandlingDefaultConfiguration')::get('Project'); if( ! $projects['errorReporting'] ) { return false; } if( in_array($no, $projects['escapeErrors'], true) || in_array(self::$errorCodes[$no] ?? NULL, $projects['escapeErrors'], true) ) { return false; // @codeCoverageIgnore } $wizardErrorData = self::getTemplateWizardErrorData($file, $line); $exceptionData = [ 'type' => self::$errorCodes[$no] ?? 'ERROR', 'msg' => $msg, 'file' => $wizardErrorData->file, 'line' => $wizardErrorData->line, 'trace' => $trace ]; ob_end_clean(); return Inclusion\View::use('Table', $exceptionData, true, __DIR__ . '/Resources/'); } /** * protected clean class name * * @param string $class * * @return string */ protected static function cleanInternalPrefixFromClassName($class) { return str_ireplace(INTERNAL_ACCESS, '', Datatype::divide($class, '\\', -1)); } /** * Throw finder * * @param array $trace * @param int $p1 = 2 * @param int $p2 = 0 * * @return array */ protected static function throwFinder($trace, $p1 = 3, $p2 = 5) { $classInfo = $trace[$p1]; $fileInfo = $trace[$p2]; // @codeCoverageIgnoreStart if( ! isset($classInfo['class']) && isset($classInfo['function']) ) { $classInfo['class'] = $classInfo['function']; $fileInfo['file'] = $classInfo['file']; $fileInfo['line'] = $classInfo['line']; } // @codeCoverageIgnoreEnd return [ 'class' => self::cleanInternalPrefixFromClassName($classInfo['class']), 'function' => $classInfo['function'], 'file' => $fileInfo['file'], 'line' => $fileInfo['line'], 'trace' => $trace ]; } /** * Handle template wizard * * @param void * * @return string|null * * @codeCoverageIgnore */ protected static function getTemplateWizardErrorData($file, $line) { if( strstr($file, DS . 'Buffering.php') ) { $trace = debug_backtrace()[6]['args'] ?? [NULL]; $args = debug_backtrace()[1]['args'][4] ?? []; self::searchErrorWizardFile($args, $file, $line); self::isWizardOrStandartFileExists($file, $trace); } return (object) [ 'file' => $file, 'line' => $line ]; } /** * Protected search error wizard file * * @codeCoverageIgnore */ protected static function searchErrorWizardFile($args, &$file, &$line) { foreach( $args as $key => $value ) { if( is_array($value) ) { if( ! isset($line) && isset($value['file']) && stristr($value['file'], DS . 'Buffering.php') ) { $line = $value['line'] ?? NULL; } $find = $value['args'][0] ?? NULL; if( is_string($find) && preg_match('/(Views\/)*.*?\.\wizard(\.php)*/', $find) ) { $file = $find; break; } } } } /** * Protected is wizard or standart file exists * * @codeCoverageIgnore */ protected static function isWizardOrStandartFileExists(&$file, $trace) { if( ! is_file($file) ) { $file = Base::prefix($file, VIEWS_DIR); if( ! is_file($file) ) { if( ! is_file($rfile = $file . '.php') ) { if( ! is_file($rfile = $file . '.wizard.php') ) { if( isset($trace[0]) && is_file($rfile = Base::suffix(Base::prefix($trace[0], VIEWS_DIR), '.php')) ) { $file = $rfile; } else { if( ! is_file($rfile) ) { $file = VIEWS_DIR . CURRENT_CONTROLLER . '/' . CURRENT_CFUNCTION . '.wizard.php'; } } } else { $file = $rfile; } } else { $file = $rfile; } } } } /** * Display exception table * * @param string $file * @param string $line * @param string $key * * @return void */ public static function display($file, $line, $key) { ?>