wp-staging
Last commit date
Backend
1 month ago
Backup
1 month ago
Basic
3 months ago
Component
1 month ago
Core
1 month ago
Framework
1 month ago
Frontend
5 months ago
Notifications
8 months ago
Staging
1 month ago
assets
1 month ago
languages
1 month ago
resources
1 year ago
vendor_wpstg
1 month ago
views
1 month ago
CONTRIBUTING.md
1 year ago
Deactivate.php
8 months ago
README.md
3 months ago
SECURITY.md
2 years ago
autoloader.php
1 month ago
bootstrap.php
1 month ago
constantsFree.php
1 month ago
freeBootstrap.php
1 month ago
install.php
1 year ago
opcacheBootstrap.php
1 month ago
readme.txt
1 month ago
runtimeRequirements.php
3 months ago
uninstall.php
2 months ago
wp-staging-error-handler.php
6 months ago
wp-staging.php
1 month ago
wp-staging-error-handler.php
141 lines
| 1 | <?php |
| 2 | |
| 3 | /* |
| 4 | * Low-level error handler and debugger for WP STAGING |
| 5 | */ |
| 6 | |
| 7 | namespace WPStaging\functions; |
| 8 | |
| 9 | /** |
| 10 | * @param string $message The debug message. |
| 11 | * @param string $logType A PSR-3 compatible-log type. If "debug", it only logs if WPSTG_DEBUG is true. |
| 12 | * @param bool $logInDebugLog Whether to log the message in the WP_DEBUG_LOG file. |
| 13 | * |
| 14 | * @see \Psr\Log\LogLevel |
| 15 | */ |
| 16 | function debug_log($message, $logType = 'info', $logInDebugLog = true) |
| 17 | { |
| 18 | // Keep the file handler open for the duration of the request for performance. |
| 19 | static $fileHandler; |
| 20 | |
| 21 | if ($logType === 'debug' && !defined('WPSTG_DEBUG') || defined('WPSTG_DEBUG') && !WPSTG_DEBUG) { |
| 22 | return; |
| 23 | } |
| 24 | |
| 25 | if ($logInDebugLog && defined('WP_DEBUG_LOG') && WP_DEBUG_LOG) { |
| 26 | error_log('[' . $logType . '] WP Staging - ' . $message, 0); |
| 27 | } |
| 28 | |
| 29 | if (!defined('WPSTG_DEBUG_LOG_FILE')) { |
| 30 | return; |
| 31 | } |
| 32 | |
| 33 | if (is_null($fileHandler)) { |
| 34 | // Open the file handler once per request, and keep it open, as we might need to write to it multiple times. |
| 35 | $fileHandler = @fopen(WPSTG_DEBUG_LOG_FILE, 'a'); |
| 36 | |
| 37 | // On Windows OS locking doesn't work as expected, so we don't lock the file on Windows OS. |
| 38 | // Make sure the lock is shared, as we might need to open the handler again if a fatal error occurs. |
| 39 | if (stripos(PHP_OS, "WIN") !== 0 && is_resource($fileHandler)) { |
| 40 | flock($fileHandler, LOCK_SH | LOCK_NB); |
| 41 | } |
| 42 | } |
| 43 | |
| 44 | $message = sprintf( |
| 45 | "[WP STAGING Manual Logging][%s][%s] %s\n", |
| 46 | $logType, |
| 47 | current_time('mysql'), |
| 48 | $message |
| 49 | ); |
| 50 | |
| 51 | if (is_resource($fileHandler)) { |
| 52 | try { |
| 53 | fwrite($fileHandler, $message, 5 * MB_IN_BYTES); |
| 54 | } catch (\Throwable $ex) { |
| 55 | // If we can't write to the file, we should at least log the error to the PHP error log. |
| 56 | error_log('WP Staging - Error writing to the debug log file: ' . $ex->getMessage()); |
| 57 | } |
| 58 | } |
| 59 | } |
| 60 | |
| 61 | /** |
| 62 | * Logs fatal errors in the WP STAGING debug file. |
| 63 | */ |
| 64 | function shutdown_function() |
| 65 | { |
| 66 | if (!defined('WPSTG_DEBUG_LOG_FILE') || !defined('WPSTG_PLUGIN_SLUG')) { |
| 67 | return; |
| 68 | } |
| 69 | |
| 70 | $error = error_get_last(); |
| 71 | |
| 72 | if (!is_array($error)) { |
| 73 | return; |
| 74 | } |
| 75 | |
| 76 | // Errors that bring PHP to a halt. |
| 77 | $fatalErrorTypes = [ |
| 78 | E_ERROR => 'E_ERROR', |
| 79 | E_PARSE => 'E_PARSE', |
| 80 | E_USER_ERROR => 'E_USER_ERROR', |
| 81 | E_COMPILE_ERROR => 'E_COMPILE_ERROR', |
| 82 | E_RECOVERABLE_ERROR => 'E_RECOVERABLE_ERROR', |
| 83 | ]; |
| 84 | |
| 85 | // Provide friendly-names for the error codes |
| 86 | $allErrorTypes = [ |
| 87 | E_ERROR => "E_ERROR", |
| 88 | E_WARNING => "E_WARNING", |
| 89 | E_PARSE => "E_PARSE", |
| 90 | E_NOTICE => "E_NOTICE", |
| 91 | E_CORE_ERROR => "E_CORE_ERROR", |
| 92 | E_CORE_WARNING => "E_CORE_WARNING", |
| 93 | E_COMPILE_ERROR => "E_COMPILE_ERROR", |
| 94 | E_COMPILE_WARNING => "E_COMPILE_WARNING", |
| 95 | E_USER_ERROR => "E_USER_ERROR", |
| 96 | E_USER_WARNING => "E_USER_WARNING", |
| 97 | E_USER_NOTICE => "E_USER_NOTICE", |
| 98 | E_RECOVERABLE_ERROR => "E_RECOVERABLE_ERROR", |
| 99 | E_DEPRECATED => "E_DEPRECATED", |
| 100 | E_USER_DEPRECATED => "E_USER_DEPRECATED", |
| 101 | E_ALL => "E_ALL", |
| 102 | ]; |
| 103 | |
| 104 | // E_STRICT is deprecated in PHP 8.4+, so only add it for older versions |
| 105 | if (version_compare(PHP_VERSION, '8.4.0', '<')) { |
| 106 | $allErrorTypes[E_STRICT] = "E_STRICT"; |
| 107 | } |
| 108 | |
| 109 | $isFatalError = isset($fatalErrorTypes[$error['type']]); |
| 110 | $comesFromWpStaging = strpos($error['file'], WPSTG_PLUGIN_SLUG) !== false; |
| 111 | |
| 112 | /* |
| 113 | * Logs fatal errors that happens anywhere, |
| 114 | * and notices, warnings that comes from a WP STAGING file. |
| 115 | * |
| 116 | * (It will only log notices and errors from WP STAGING |
| 117 | * if it was the last notice/warning triggered before PHP shutdown) |
| 118 | */ |
| 119 | if ($isFatalError || $comesFromWpStaging) { |
| 120 | // Opening a file handler gives us more control than error_log('foo', 3, 'custom-file.log'); |
| 121 | $fileHandler = @fopen(WPSTG_DEBUG_LOG_FILE, 'a'); |
| 122 | |
| 123 | $message = sprintf( |
| 124 | "[WP STAGING Shutdown Function][%s][%s] %s - File: %s Line: %s | Is it Fatal Error? %s | Is it Thrown by WP STAGING? %s\n", |
| 125 | $allErrorTypes[$error['type']], |
| 126 | current_time('mysql'), |
| 127 | $error['message'], |
| 128 | $error['file'], |
| 129 | $error['line'], |
| 130 | $isFatalError ? 'Yes' : 'No', |
| 131 | $comesFromWpStaging ? 'Yes' : 'No' |
| 132 | ); |
| 133 | |
| 134 | if (is_resource($fileHandler)) { |
| 135 | fwrite($fileHandler, $message, 5 * MB_IN_BYTES); |
| 136 | } |
| 137 | } |
| 138 | } |
| 139 | |
| 140 | register_shutdown_function('\WPStaging\functions\shutdown_function'); |
| 141 |