Skip to content

Smart Coupons Debugging Script #39

@noelsaw1

Description

@noelsaw1

MU Plugin: Query Dump with Backtraces

1. Create the MU plugin file

Path: {site-root}/wp-content/mu-plugins/query-dump.php

<?php
/**
 * Query Dump — writes all $wpdb->queries to /tmp/wpdebug-queries.log on shutdown.
 * Remove or rename this file when done.
 */
define( 'SAVEQUERIES', true );

add_action( 'shutdown', function () {
    global $wpdb;
    if ( empty( $wpdb->queries ) ) return;

    $url    = $_SERVER['REQUEST_URI'] ?? '(unknown)';
    $time   = date( 'Y-m-d H:i:s' );
    $pid    = getmypid();
    $out    = "\n\n=== REQUEST pid=$pid $time $url ===\n";

    foreach ( $wpdb->queries as $i => $q ) {
        // $q = [ sql, elapsed_ms, backtrace_string ]
        $sql     = trim( $q[0] );
        $elapsed = round( $q[1] * 1000, 2 ); // ms
        $trace   = $q[2] ?? '';
        $out    .= "\n--- Query #" . ( $i + 1 ) . " ({$elapsed}ms) ---\n$sql\n$trace\n";
    }

    file_put_contents( '/tmp/wpdebug-queries.log', $out, FILE_APPEND | LOCK_EX );
} );

Why MU plugin: zero activation friction, survives plugin toggles, loads before everything else.


2. Verify it's loading

wp --path="$WP_PATH" eval 'echo defined("SAVEQUERIES") ? "ON" : "OFF";'

Should print ON. If it prints OFF, SAVEQUERIES was already defined earlier in wp-config.php — check there.


3. Clear the log and run your confirmed Playwright flow

rm -f /tmp/wpdebug-queries.log

node temp/pw-xdebug-profile-run.js   # or whichever script drives the full prep flow

The flow hits: homepage → add-to-cart → coupon URL → homepage-after-prep. Each of those is a separate PHP process and will write a separate === REQUEST === block.


4. Read the log — find the right request block first

grep "=== REQUEST" /tmp/wpdebug-queries.log

You'll see one line per PHP request, with the URI. Identify which block is:

  • the coupon URL request (/?coupon-code=binoid15...)
  • the final homepage request (after prep)

5. Search for the coupon lookup SQL specifically

grep -n "shop_coupon" /tmp/wpdebug-queries.log

This will show exactly which request block contains the binoid15 / shop_coupon query and its line number. Then read that block's backtrace:

# example: query showed up at line 84, read surrounding context
sed -n '80,120p' /tmp/wpdebug-queries.log

The backtrace string (field $q[2]) is a comma-separated call chain from $wpdb->query() up through WooCommerce/Smart Coupons. That chain will either show WC_SC_URL_Coupon, WC_SC_Coupon_Actions, or something else entirely.


6. Clean up

Once you have your answer, either delete the file or rename it so it stops running:

mv wp-content/mu-plugins/query-dump.php wp-content/mu-plugins/query-dump.php.off

What you're looking for

Finding Implication
shop_coupon lookup is in the coupon URL block The query fires during coupon application, not homepage rehydration
shop_coupon lookup is in the homepage-after-prep block Cart/session rehydration on homepage is the source — primary theory confirmed
Backtrace shows WC_SC_Coupon_Actions Coupon-actions path is the issuer — patch there
Backtrace shows WC_SC_URL_Coupon URL/session rehydration path is the issuer
Backtrace shows WC core (WC_Coupon->__construct) May be a WC core issue unrelated to Smart Coupons specifically

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions