1.7.0: shipping rule "Only" reserves a method, "Show" no longer does

Since 1.6.0 "Show" both whitelisted a method for its group and hid it from
everybody else. A group shown ordinary methods next to a free one therefore
took the ordinary ones away from every stranger, who was left with only the
free method. "Only" now carries the reservation; "Show" is just the group's
whitelist. Existing show rules are converted to only once on update so the
checkout does not change until the shop chooses.

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
kristianwind
2026-10-02 12:28:45 +02:00
co-authored by Claude Code
parent 5875638f2c
commit 0793a1ee82
11 changed files with 129 additions and 37 deletions
+6 -4
View File
@@ -340,7 +340,7 @@ class WC_EDM_Frontend {
//
// This used to return $rates untouched, and a test asserted that
// as intended: "an unmatched customer sees every method". It made
// a "show" rule a whitelist FOR THE GROUP and nothing more, so
// a "show" rule (now "only") a whitelist FOR THE GROUP and nothing more, so
// reserving free delivery for approved addresses left it on the
// checkout for every other customer. Reported from a live shop,
// where a gmail address could pick a free-delivery method meant
@@ -389,7 +389,9 @@ class WC_EDM_Frontend {
* Apply a group's show/hide shipping rules.
*
* If the group has no rules, all rates pass through untouched.
* "show" rules act as a whitelist; "hide" rules remove rates.
* "show" and "only" rules act as a whitelist; "hide" rules remove rates.
* "only" additionally reserves the method for the group (see
* WC_EDM_DB::restricted_shipping_methods()).
* Rates are reordered to follow the rules' sort order.
*
* @param array $rates Available shipping rates (rate_id => WC_Shipping_Rate).
@@ -413,7 +415,7 @@ class WC_EDM_Frontend {
$hide = array();
foreach ( $rules as $rule ) {
if ( 'show' === $rule->action ) {
if ( 'show' === $rule->action || 'only' === $rule->action ) {
$show[] = $rule->shipping_method_id;
} else {
$hide[] = $rule->shipping_method_id;
@@ -422,7 +424,7 @@ class WC_EDM_Frontend {
$filtered = array();
// Reserved by some group, but not by THIS one.
// Reserved ("only") by some group, but not shown to THIS one.
$others = array_diff( WC_EDM_DB::restricted_shipping_methods(), $show );
foreach ( $rates as $rate_id => $rate ) {