=')) {
register_shutdown_function([__CLASS__, 'shutdownHandler']);
set_exception_handler([__CLASS__, 'exceptionHandler']);
set_error_handler([__CLASS__, 'errorHandler']);
}
}
public static function isPluginScreen(): bool
{
$screen = function_exists('get_current_screen') ? get_current_screen() : null;
if(!empty($screen)) {
return strpos($screen->base, 'page_' . self::$slug) !== false;
}
if(!empty($_GET['page'])) {
$page = sanitize_text_field($_GET['page']);
return strpos($page, self::$slug) !== false;
}
return false;
}
public static function shutdownHandler()
{
$error = error_get_last();
if ($error) {
self::errorHandler($error['type'], $error['message'], $error['file'], $error['line']);
}
}
public static function exceptionHandler(Throwable $exception)
{
self::errorHandler(-1, $exception->getMessage(), $exception->getFile(), $exception->getLine());
}
public static function errorHandler($error_type, $error_message, $error_file, $error_line)
{
if (!$error_type) {
return;
}
$fatal = false;
switch ($error_type) {
case -1:
case E_ERROR:
case E_USER_ERROR:
case E_PARSE:
case E_CORE_ERROR:
case E_COMPILE_ERROR:
case E_RECOVERABLE_ERROR:
$fatal = true;
break;
}
switch ($error_type) {
case -1: // -1 //
$typestr = 'EXCEPTION';
break;
case E_ERROR: // 1 //
$typestr = 'E_ERROR';
break;
case E_WARNING: // 2 //
$typestr = 'E_WARNING';
break;
case E_PARSE: // 4 //
$typestr = 'E_PARSE';
break;
case E_NOTICE: // 8 //
$typestr = 'E_NOTICE';
break;
case E_CORE_ERROR: // 16 //
$typestr = 'E_CORE_ERROR';
break;
case E_CORE_WARNING: // 32 //
$typestr = 'E_CORE_WARNING';
break;
case E_COMPILE_ERROR: // 64 //
$typestr = 'E_COMPILE_ERROR';
break;
case E_COMPILE_WARNING: // 128 //
$typestr = 'E_COMPILE_WARNING';
break;
case E_USER_ERROR: // 256 //
$typestr = 'E_USER_ERROR';
break;
case E_USER_WARNING: // 512 //
$typestr = 'E_USER_WARNING';
break;
case E_USER_NOTICE: // 1024 //
$typestr = 'E_USER_NOTICE';
break;
case E_STRICT: // 2048 //
$typestr = 'E_STRICT';
break;
case E_RECOVERABLE_ERROR: // 4096 //
$typestr = 'E_RECOVERABLE_ERROR';
break;
case E_DEPRECATED: // 8192 //
$typestr = 'E_DEPRECATED';
break;
case E_USER_DEPRECATED: // 16384 //
$typestr = 'E_USER_DEPRECATED';
break;
}
$message = '' . $typestr . ': ' . $error_message . ' in ' . $error_file . ' on line ' . $error_line . '
';
//Logging error on php file error log...
if (defined('WP_DEBUG_LOG') && WP_DEBUG_LOG) {
error_log(strip_tags($message), 0);
}
if ($fatal) {
$lockfile = self::backupDir().'.lock';
$backup_file = self::findBackupFile($error_file);
// If backup exists
if (!empty($backup_file) && file_exists($backup_file)) {
if (ob_get_length()) ob_end_clean();
// If on admin side, show file recovery wizard
if (is_admin()) {
$recover = !empty($_GET['recover']);
if ($recover) {
$success = self::recoverFile($error_file, $backup_file);
if(file_exists($lockfile)) {
@unlink($lockfile);
}
wp_send_json([
'success' => $success
]);
} else {
self::recoverTemplate($typestr, $error_message, $error_file, $error_line, $backup_file);
file_put_contents($lockfile, '1');
}
// If on the frontend, try to recover the file silently
} else if(!file_exists($lockfile)){
if(file_exists($lockfile)) {
@unlink($lockfile);
}
$success = self::recoverFile($error_file, $backup_file);
// redirect home on success
if ($success) {
die('');
} else {
// if failed, show error message
self::displayError($message);
}
}
die();
}
}
}
public static function displayError($message) {
// Display error only if WP_DEBUG & WP_DEBUG_DISPLAY are enabled and not DOING_AJAX
if(!self::isPluginScreen() && defined('WP_DEBUG') && WP_DEBUG && defined('WP_DEBUG_DISPLAY') && WP_DEBUG_DISPLAY && !defined('DOING_AJAX')) {
printf('%s', $message);
}
}
public static function backupDir(): string
{
$uploadsBaseDir = function_exists('wp_upload_dir') ? wp_upload_dir()['basedir'] : __DIR__.'/uploads/';
return $uploadsBaseDir.self::$backupDir;
}
public static function findBackupFile($error_file): ?string
{
$backupFolders = scandir(self::backupDir());
if(empty($backupFolders)) {
return null;
}
// Get backup folders
$backupFolders = array_filter($backupFolders, function ($folder) {
if ($folder === '.' || $folder === '..') {
return false;
}
$date = date_create_from_format('Y-m-d', $folder);
return $date !== false;
});
// Sort from latest to oldest
sort($backupFolders);
$backupFolders = array_reverse($backupFolders);
// Loop and find the latest backup file
foreach ($backupFolders as $folder) {
$backup_file = self::backupDir() . $folder . '/' . str_replace(ABSPATH, "", $error_file);
if (file_exists($backup_file)) {
return $backup_file;
}
}
return null;
}
public static function recoverFile($error_file, $backup_file): bool
{
ob_start();
$backup_file_content = file_get_contents($backup_file);
$result = file_put_contents($error_file, $backup_file_content);
ob_end_clean();
return $result !== false;
}
public static function recoverTemplate($error_type, $error_message, $error_file, $error_line, $backup_file)
{
?>
File
Line
Backup