prefix . 'schema_ai_schemas' ); $usage_table = esc_sql( $wpdb->prefix . 'schema_ai_usage' ); $current_user_id = get_current_user_id(); $today = gmdate( 'Y-m-d' ); $month_start = gmdate( 'Y-m-01' ); // Fetch all schemas for this post. // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Required for custom table; no WP API alternative exists. $schemas = $wpdb->get_results( $wpdb->prepare( // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Table name is sanitized via esc_sql() and not user input. "SELECT id, schema_type, confidence_score, validation_status, updated_at FROM {$schemas_table} WHERE post_id = %d ORDER BY updated_at DESC", $post_id ) ); // Get plan and monthly limit. $plan = get_user_meta( $current_user_id, 'schema_ai_plan', true ); if ( empty( $plan ) ) { $plan = 'free'; } $limits = array( 'free' => 30, 'pro' => 300, 'premium' => 1000 ); $monthly_limit = isset( $limits[ $plan ] ) ? $limits[ $plan ] : 30; // Monthly usage from the usage table (correct table + correct user variable). // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Required for custom table; no WP API alternative exists. $monthly_used = (int) $wpdb->get_var( $wpdb->prepare( // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Table name is sanitized via esc_sql() and not user input. "SELECT COALESCE( SUM( ai_generations ), 0 ) FROM {$usage_table} WHERE user_id = %d AND date >= %s", $current_user_id, $month_start ) ); $monthly_remaining = max( 0, $monthly_limit - $monthly_used ); $usage_percent = $monthly_limit > 0 ? min( 100, ( $monthly_used / $monthly_limit ) * 100 ) : 0; $post_url = get_permalink( $post_id ); // Calculate schema health score. $health = class_exists( 'Schema_AI_Health_Score' ) ? Schema_AI_Health_Score::calculate( $post_id ) : null; ?> array( 'bg' => '#f0fdf4', 'border' => '#bbf7d0', 'text' => '#15803d', 'dot' => '#22c55e' ), 'fair' => array( 'bg' => '#fffbeb', 'border' => '#fde68a', 'text' => '#92400e', 'dot' => '#f59e0b' ), 'poor' => array( 'bg' => '#fef2f2', 'border' => '#fecaca', 'text' => '#b91c1c', 'dot' => '#ef4444' ), ); $colors = isset( $grade_colors[ $health['grade'] ] ) ? $grade_colors[ $health['grade'] ] : $grade_colors['poor']; ?>