0, 'info' => 1, 'warning' => 2, 'error' => 3, ); private int $threshold; public function __construct() { $level = get_option( 'wppilot_log_level', 'info' ); $this->threshold = self::LEVEL_MAP[ $level ] ?? 1; } public function debug( string $message, array $context = array() ): void { $this->log( 'debug', $message, $context ); } public function info( string $message, array $context = array() ): void { $this->log( 'info', $message, $context ); } public function warning( string $message, array $context = array() ): void { $this->log( 'warning', $message, $context ); } public function error( string $message, array $context = array() ): void { $this->log( 'error', $message, $context ); } private function log( string $level, string $message, array $context ): void { $numeric = self::LEVEL_MAP[ $level ] ?? 1; if ( $numeric < $this->threshold ) { return; } global $wpdb; $table = $wpdb->prefix . 'wppilot_log'; // Append-only custom log table; $wpdb->insert sanitizes values internally and the format is fixed. // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $wpdb->insert( $table, array( 'level' => sanitize_text_field( $level ), 'message' => sanitize_textarea_field( $message ), 'context' => empty( $context ) ? null : wp_json_encode( $context ), ), array( '%s', '%s', '%s' ) ); } }