chore: initial snapshot of 2meet-data-optimizer v0.1.0
Baseline before backporting wp-data-optimizer v3.0.1-v3.4.6. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TbG1keQQ7XBa7qMQY16KCY
This commit is contained in:
@@ -0,0 +1,160 @@
|
||||
<?php
|
||||
/**
|
||||
* Error logging for WP Data Optimizer.
|
||||
*
|
||||
* @package WP_Data_Optimizer
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lightweight error logger — writes to wpdo_errors table and PHP error_log.
|
||||
*/
|
||||
class TMDO_Logger {
|
||||
|
||||
/**
|
||||
* Log an INFO-level event (event-based signature, used by v2.0.0 engine code).
|
||||
*
|
||||
* Writes only to PHP error_log; does NOT touch wpdo_errors (which is reserved
|
||||
* for actual errors). Mode changes / cache flushes / audit prunes call here
|
||||
* many times per request — keeping them out of the DB error table.
|
||||
*
|
||||
* @param string $event Event name (e.g. 'bridge_mode_changed').
|
||||
* @param array $context Structured context.
|
||||
* @return void
|
||||
*/
|
||||
public static function info( string $event, array $context = array() ): void {
|
||||
error_log( sprintf( '[WPDO][INFO][%s] %s', $event, $context ? wp_json_encode( $context, JSON_UNESCAPED_UNICODE ) : '' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Log a NOTICE-level event — alias of info() for callers that want a stronger
|
||||
* level intent. Same routing (error_log only).
|
||||
*
|
||||
* @param string $event Event name.
|
||||
* @param array $context Structured context.
|
||||
* @return void
|
||||
*/
|
||||
public static function notice( string $event, array $context = array() ): void {
|
||||
self::info( $event, $context );
|
||||
}
|
||||
|
||||
/**
|
||||
* Log a WARNING-level event — error_log + wpdo_errors row (for admin visibility).
|
||||
*
|
||||
* Use for "anomaly worth attention but not breaking" (e.g. invalid filter
|
||||
* return, unexpected fallback path). The event_name becomes the `hook` column;
|
||||
* message gets a `[WARN]` prefix to distinguish from hard errors.
|
||||
*
|
||||
* @param string $event Event name (e.g. 'wpdo_route_decision_invalid_return').
|
||||
* @param array $context Structured context.
|
||||
* @return void
|
||||
*/
|
||||
public static function warning( string $event, array $context = array() ): void {
|
||||
error_log( sprintf( '[WPDO][WARN][%s] %s', $event, $context ? wp_json_encode( $context, JSON_UNESCAPED_UNICODE ) : '' ) );
|
||||
self::error( 'engine', $event, '[WARN] ' . $event, $context );
|
||||
}
|
||||
|
||||
/**
|
||||
* Log a DEBUG-level event — only when WP_DEBUG is true; routes to error_log.
|
||||
*
|
||||
* @param string $event Event name.
|
||||
* @param array $context Structured context.
|
||||
* @return void
|
||||
*/
|
||||
public static function debug( string $event, array $context = array() ): void {
|
||||
if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
|
||||
self::info( $event, $context );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Log a module error.
|
||||
*
|
||||
* @param string $module Module name (e.g. 'reviews', 'hot_hp_listing').
|
||||
* @param string $hook The hook or method where the error occurred.
|
||||
* @param string $message Human-readable error message.
|
||||
* @param array $context Optional extra context (will be JSON-encoded).
|
||||
* @param string $zone Optional zone identifier (hot/warm/cold/archive).
|
||||
*/
|
||||
public static function error( string $module, string $hook, string $message, array $context = array(), string $zone = '' ): void {
|
||||
global $wpdb;
|
||||
|
||||
error_log( sprintf( '[WPDO][%s][%s] %s', $module, $hook, $message ) );
|
||||
|
||||
$table = TMDO_DB::table( 'wpdo_errors' );
|
||||
$wpdb->insert(
|
||||
$table,
|
||||
array(
|
||||
'module' => sanitize_key( $module ),
|
||||
'zone' => sanitize_key( $zone ),
|
||||
'hook' => substr( sanitize_text_field( $hook ), 0, 255 ),
|
||||
'message' => $message,
|
||||
'context' => $context ? wp_json_encode( $context, JSON_UNESCAPED_UNICODE ) : null,
|
||||
'created_at' => current_time( 'mysql', true ),
|
||||
),
|
||||
array( '%s', '%s', '%s', '%s', '%s', '%s' )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return recent errors, optionally filtered by module.
|
||||
*
|
||||
* @param string $module Module name (empty = all modules).
|
||||
* @param int $limit Max rows to return.
|
||||
* @return array
|
||||
*/
|
||||
public static function get_recent( string $module = '', int $limit = 100 ): array {
|
||||
global $wpdb;
|
||||
$table = TMDO_DB::table( 'wpdo_errors' );
|
||||
|
||||
// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Table name from TMDO_DB::table().
|
||||
if ( $module ) {
|
||||
return $wpdb->get_results(
|
||||
$wpdb->prepare(
|
||||
"SELECT * FROM `{$table}` WHERE module = %s ORDER BY id DESC LIMIT %d",
|
||||
$module,
|
||||
$limit
|
||||
),
|
||||
ARRAY_A
|
||||
) ?: array();
|
||||
}
|
||||
|
||||
return $wpdb->get_results(
|
||||
$wpdb->prepare( "SELECT * FROM `{$table}` ORDER BY id DESC LIMIT %d", $limit ),
|
||||
ARRAY_A
|
||||
) ?: array();
|
||||
// phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete errors older than a given number of days.
|
||||
*
|
||||
* @param int $days Keep errors from the last N days.
|
||||
* @return int Number of rows deleted.
|
||||
*/
|
||||
public static function purge( int $days = 30 ): int {
|
||||
global $wpdb;
|
||||
$table = TMDO_DB::table( 'wpdo_errors' );
|
||||
|
||||
$now = current_time( 'mysql', true );
|
||||
|
||||
if ( TMDO_IS_SQLITE ) {
|
||||
$sql = $wpdb->prepare(
|
||||
"DELETE FROM `{$table}` WHERE created_at < datetime(%s, %s)", // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
|
||||
$now,
|
||||
"-{$days} days"
|
||||
);
|
||||
} else {
|
||||
$sql = $wpdb->prepare(
|
||||
"DELETE FROM `{$table}` WHERE created_at < DATE_SUB(%s, INTERVAL %d DAY)", // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
|
||||
$now,
|
||||
$days
|
||||
);
|
||||
}
|
||||
|
||||
return (int) $wpdb->query( $sql ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user