| @@ -9,14 +9,16 @@ | ||
| 9 | 9 | private $log_directory; |
| 10 | 10 | private $wp_filesystem; |
| 11 | 11 | private $max_log_files; |
| 12 | 12 | |
| 13 | + private $ready = false; | |
| 14 | + | |
| 13 | 15 | /** |
| 14 | 16 | * Constructor for the Logger class. |
| 15 | 17 | * |
| 16 | - * Initializes the logger with a specified log directory, prefix for log entries, | |
| 17 | - * and the maximum number of log files to keep. Ensures the log directory exists and | |
| 18 | - * performs cleanup of old log files. | |
| 18 | + * Only records the log directory and retention limit. Filesystem setup (WP_Filesystem, | |
| 19 | + * mkdir, old-log cleanup) is deferred to the first log() call because Logger instances | |
| 20 | + * are created on every request by classes that rarely log. | |
| 19 | 21 | */ |
| 20 | 22 | public function __construct( $log_directory = null, $max_log_files = 30 ) { |
| 21 | 23 | if ( ! $log_directory ) { |
| 22 | 24 | $log_directory = WP_CONTENT_DIR . '/yaymail-logs'; |
| @@ -22,8 +24,18 @@ | ||
| 22 | 24 | $log_directory = WP_CONTENT_DIR . '/yaymail-logs'; |
| 23 | 25 | } |
| 24 | 26 | $this->log_directory = $log_directory; |
| 25 | 27 | $this->max_log_files = $max_log_files; |
| 28 | + } | |
| 29 | + | |
| 30 | + /** | |
| 31 | + * Initializes the filesystem, ensures the log directory exists and prunes old logs. Runs once. | |
| 32 | + */ | |
| 33 | + private function ensure_ready() { | |
| 34 | + if ( $this->ready ) { | |
| 35 | + return; | |
| 36 | + } | |
| 37 | + $this->ready = true; | |
| 26 | 38 | $this->initialize_filesystem(); |
| 27 | 39 | |
| 28 | 40 | // Ensure the log directory exists (only if filesystem is available) |
| 29 | 41 | if ( $this->wp_filesystem && ! $this->wp_filesystem->is_dir( $this->log_directory ) ) { |
| @@ -91,8 +103,10 @@ | ||
| 91 | 103 | } |
| 92 | 104 | } |
| 93 | 105 | |
| 94 | 106 | public function log( $message ) { |
| 107 | + $this->ensure_ready(); | |
| 108 | + | |
| 95 | 109 | // Return early if filesystem is not available |
| 96 | 110 | if ( ! $this->wp_filesystem ) { |
| 97 | 111 | return; |
| 98 | 112 | } |
| @@ -114,10 +128,14 @@ | ||
| 114 | 128 | $this->wp_filesystem->put_contents( $log_file, $log_message, FS_CHMOD_FILE ); |
| 115 | 129 | } |
| 116 | 130 | |
| 117 | 131 | /** |
| 118 | - * Logs an exception message and sends a JSON error response. | |
| 119 | - * Message will display in folder wp-content/yaymail-logs | |
| 132 | + * Logs an exception message to wp-content/yaymail-logs and returns. | |
| 133 | + * | |
| 134 | + * Does not terminate the request: rendering can be triggered inside another | |
| 135 | + * plugin's request (e.g. WooCommerce checkout AJAX), where dying would break | |
| 136 | + * the host response. Callers that need to abort (YayMail's own AJAX endpoints) | |
| 137 | + * must call wp_send_json_error() themselves. | |
| 120 | 138 | */ |
| 121 | 139 | public function log_exception_message( $ex, $log_type = 'error', $additional_data = null ) { |
| 122 | 140 | $prefix = ( $log_type === 'warning' ) ? __( 'WARNING:', 'yaymail' ) : __( 'SYSTEM ERROR:', 'yaymail' ); |
| 123 | 141 | |
| @@ -135,11 +153,6 @@ | ||
| 135 | 153 | } |
| 136 | 154 | } |
| 137 | 155 | |
| 138 | 156 | $this->log( $message ); |
| 139 | - | |
| 140 | - // Only send JSON response for errors, not for warnings | |
| 141 | - if ( $log_type === 'error' ) { | |
| 142 | - wp_send_json_error( [ 'mess' => $message ] ); | |
| 143 | - } | |
| 144 | 157 | } |
| 145 | 158 | } |