prefix . self::TABLE_NAME; // Validate severity $validSeverities = array( self::SEVERITY_INFO, self::SEVERITY_WARNING, self::SEVERITY_ERROR, self::SEVERITY_CRITICAL ); if ( ! in_array( $severity, $validSeverities, true ) ) { $severity = self::SEVERITY_INFO; } $result = $wpdb->insert( $table, array( 'event_type' => sanitize_text_field( $type ), 'severity' => $severity, 'message' => sanitize_text_field( $message ), 'user_id' => get_current_user_id() ?: null, 'details' => ! empty( $details ) ? wp_json_encode( $details ) : null, 'created_at' => current_time( 'mysql', true ), ), array( '%s', '%s', '%s', '%d', '%s', '%s' ) ); return $result ? $wpdb->insert_id : false; } /** * Get audit events with filtering and pagination. * * @param array $args Query arguments. * * @return array { events: array, total: int, pages: int } */ public static function getEvents( array $args = array() ): array { global $wpdb; $defaults = array( 'period' => 30, 'type' => '', 'severity' => '', 'page' => 1, 'per_page' => 15, ); $args = wp_parse_args( $args, $defaults ); $table = $wpdb->prefix . self::TABLE_NAME; $where = array( '1=1' ); $params = array(); // Period filter if ( $args['period'] > 0 ) { $where[] = 'created_at >= %s'; $params[] = gmdate( 'Y-m-d H:i:s', strtotime( "-{$args['period']} days" ) ); } // Type filter. Empty AND the literal "all" sentinel both mean // "no filter" — the React SPA's