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:
co-authored by
Claude Code
parent
5875638f2c
commit
0793a1ee82
+37
-7
@@ -77,7 +77,7 @@ class WC_EDM_DB {
|
||||
id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
group_id bigint(20) unsigned NOT NULL,
|
||||
shipping_method_id varchar(191) NOT NULL,
|
||||
action enum('show','hide') NOT NULL DEFAULT 'show',
|
||||
action enum('show','hide','only') NOT NULL DEFAULT 'show',
|
||||
sort_order int(11) NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY (id),
|
||||
KEY group_id (group_id)
|
||||
@@ -102,10 +102,37 @@ class WC_EDM_DB {
|
||||
dbDelta( $sql );
|
||||
|
||||
self::add_foreign_keys();
|
||||
self::migrate_show_to_only();
|
||||
|
||||
update_option( 'wc_edm_db_version', WC_EDM_VERSION );
|
||||
}
|
||||
|
||||
/**
|
||||
* Once, when "only" was introduced: every existing "show" rule was reserved
|
||||
* for its group, so it becomes "only" and the shop's checkout looks exactly
|
||||
* as it did. Without this the update would silently put reserved free
|
||||
* delivery back in front of every stranger.
|
||||
*/
|
||||
private static function migrate_show_to_only() {
|
||||
global $wpdb;
|
||||
|
||||
if ( get_option( 'wc_edm_show_to_only_done' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$table = self::table( 'shipping_rules' );
|
||||
$column = $wpdb->get_row( "SHOW COLUMNS FROM {$table} LIKE 'action'" ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
|
||||
|
||||
// dbDelta did not widen the enum: converting now would store '' rather
|
||||
// than 'only'. Leave the flag unset so the next load tries again.
|
||||
if ( ! $column || false === strpos( (string) $column->Type, "'only'" ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$wpdb->query( "UPDATE {$table} SET action = 'only' WHERE action = 'show'" ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
|
||||
update_option( 'wc_edm_show_to_only_done', 1 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Run create_tables() again when the plugin was updated without
|
||||
* re-activation (dbDelta adds any missing columns).
|
||||
@@ -510,10 +537,13 @@ class WC_EDM_DB {
|
||||
/**
|
||||
* Every shipping method any group reserves for itself.
|
||||
*
|
||||
* A "show" rule means the group sees that method. It also has to mean
|
||||
* nobody else does — otherwise reserving a free-delivery method for an
|
||||
* approved group leaves it on the checkout for every other customer, which
|
||||
* is what a shop notices as lost shipping revenue rather than as a bug.
|
||||
* An "only" rule means the group sees that method AND nobody else does —
|
||||
* otherwise reserving a free-delivery method for an approved group leaves
|
||||
* it on the checkout for every other customer, which is what a shop
|
||||
* notices as lost shipping revenue rather than as a bug. A plain "show"
|
||||
* rule is a whitelist for its own group and reserves nothing: 1.6.0 made
|
||||
* "show" do both, and a group that needed to show ordinary methods next to
|
||||
* a reserved one took those ordinary methods away from everybody else.
|
||||
*
|
||||
* @return string[] Rate ids, e.g. "free_shipping:15".
|
||||
*/
|
||||
@@ -521,7 +551,7 @@ class WC_EDM_DB {
|
||||
global $wpdb;
|
||||
$table = self::table( 'shipping_rules' );
|
||||
|
||||
$ids = $wpdb->get_col( "SELECT DISTINCT shipping_method_id FROM {$table} WHERE action = 'show'" ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
|
||||
$ids = $wpdb->get_col( "SELECT DISTINCT shipping_method_id FROM {$table} WHERE action = 'only'" ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
|
||||
|
||||
return is_array( $ids ) ? $ids : array();
|
||||
}
|
||||
@@ -538,7 +568,7 @@ class WC_EDM_DB {
|
||||
$wpdb->delete( self::table( 'shipping_rules' ), array( 'group_id' => $group_id ), array( '%d' ) );
|
||||
|
||||
foreach ( $rules as $rule ) {
|
||||
if ( empty( $rule['shipping_method_id'] ) || ! in_array( $rule['action'], array( 'show', 'hide' ), true ) ) {
|
||||
if ( empty( $rule['shipping_method_id'] ) || ! in_array( $rule['action'], array( 'show', 'hide', 'only' ), true ) ) {
|
||||
continue;
|
||||
}
|
||||
$wpdb->insert(
|
||||
|
||||
Reference in New Issue
Block a user