Short answer
Not with the current WPCC stack.
- Static grep rules and the PHP golden rules analyzer are designed for local, syntactic patterns (e.g., “unbounded WP_Query”, “unsanitized superglobal”, “file_get_contents on URL”), not cross‑function data‑structure contract checks.
- The bug you described is a contract mismatch across multiple functions/classes (
search_customers() → filter interface → Ajax handler → JS expectations). That’s semantic / type‑shape logic, which our current grep‑based system doesn’t model.
So: this specific “flat array vs hash” mismatch would not be reliably caught by the existing scanner or golden rules analyzer.
Why this kind of bug is hard for grep / golden rules
Your bug is essentially:
- Producer:
search_customers() returns array<Customer> (flat list).
- Filter contract:
apply( $results ) expects ['customers' => [...], 'guest_orders' => [...], 'orders' => [...]].
- Filter
apply() checks isset( $results['customers'] ) and, if not present, returns ['customers' => [], 'guest_orders' => [], 'orders' => []].
- Ajax handler then:
- Treats this hash as “customers payload”
- JS expects
data.customers to be an array, but instead gets { customers: [], guest_orders: [], orders: [] }.
To detect this statically you’d need to:
- Track what shape
search_customers() returns.
- Track that it passes that value through a filter (or interface method).
- Know the intended shape in the filter interface (
interface-kiss-woo-order-filter.php).
- Compare the shapes and see they’re incompatible.
Our current system:
- Doesn’t track return types or array shapes across functions.
- Doesn’t understand hook/filter contracts beyond string matching on hook names.
- Golden rules are largely single‑file, regex + small validator script checks, not inter‑procedural type analysis.
That’s the kind of thing tools like PHPStan/Psalm with strict types or runtime tests are good at, but it’s beyond what a pure grep + line‑window validator can reliably do.
Could we add some heuristic for this class of bug?
We could design very narrow, heuristic rules for this plugin, for example:
- Flag filters whose
apply():
- Return a structure like
['customers' => [], 'guest_orders' => [], 'orders' => []], and
- Are wired into code that later treats the filter result as a flat array (e.g.,
foreach ( $customers as $customer ) without going through $customers['customers']).
Or:
- Flag any place where a function named
*search_customers*:
- Calls
apply_filters( 'kiss_woo_wholesale_filter', $results ), and
- Subsequently treats
$results as a flat list, while there exists a filter implementation that wraps it into a hash.
But:
- That would be highly plugin‑specific and brittle.
- It still wouldn’t be generally reliable across arbitrary codebases.
For a general solution, you’d want one or more of:
- Static typing (PHPStan/Psalm) with:
- Return type for
search_customers(): array<Customer>
- Interface defining
apply(array{customers: list<Customer>, guest_orders: list<...>, orders: list<...>})
- Those tools would then complain when the types don’t line up.
- Runtime tests:
- Unit test that calls
search_customers() with the “Wholesale only” flag and asserts the result shape matches what JS expects, and that customers aren’t wiped.
Bottom line
If you want, I can outline what a minimal test (PHPUnit or WP_UnitTestCase) would look like to lock this bug down, or sketch how a PHPStan rule for your KISS_Woo_Order_Filter interface might be structured.
Short answer
Not with the current WPCC stack.
search_customers()→ filter interface → Ajax handler → JS expectations). That’s semantic / type‑shape logic, which our current grep‑based system doesn’t model.So: this specific “flat array vs hash” mismatch would not be reliably caught by the existing scanner or golden rules analyzer.
Why this kind of bug is hard for grep / golden rules
Your bug is essentially:
search_customers()returnsarray<Customer>(flat list).apply( $results )expects['customers' => [...], 'guest_orders' => [...], 'orders' => [...]].apply()checksisset( $results['customers'] )and, if not present, returns['customers' => [], 'guest_orders' => [], 'orders' => []].data.customersto be an array, but instead gets{ customers: [], guest_orders: [], orders: [] }.To detect this statically you’d need to:
search_customers()returns.interface-kiss-woo-order-filter.php).Our current system:
That’s the kind of thing tools like PHPStan/Psalm with strict types or runtime tests are good at, but it’s beyond what a pure grep + line‑window validator can reliably do.
Could we add some heuristic for this class of bug?
We could design very narrow, heuristic rules for this plugin, for example:
apply():['customers' => [], 'guest_orders' => [], 'orders' => []], andforeach ( $customers as $customer )without going through$customers['customers']).Or:
*search_customers*:apply_filters( 'kiss_woo_wholesale_filter', $results ), and$resultsas a flat list, while there exists a filter implementation that wraps it into a hash.But:
For a general solution, you’d want one or more of:
search_customers(): array<Customer>apply(array{customers: list<Customer>, guest_orders: list<...>, orders: list<...>})search_customers()with the “Wholesale only” flag and asserts the result shape matches what JS expects, and that customers aren’t wiped.Bottom line
Today:
To catch this class of issue well, you’d need:
If you want, I can outline what a minimal test (PHPUnit or WP_UnitTestCase) would look like to lock this bug down, or sketch how a PHPStan rule for your
KISS_Woo_Order_Filterinterface might be structured.