Match saved (canonical) rate IDs against chosen rates

Generates canonical rate IDs (`method_id:instance_id`) from package rates and order shipping line items.

Requires https://github.com/woocommerce/woocommerce/pull/18483
This commit is contained in:
Manos Psychogyiopoulos 2018-01-25 16:40:31 +02:00
parent d86a948f04
commit d10987d813
1 changed files with 61 additions and 6 deletions

View File

@ -182,15 +182,16 @@ class WC_Gateway_COD extends WC_Payment_Gateway {
// Only apply if all packages are being shipped via chosen method, or order is virtual.
if ( ! empty( $this->enable_for_methods ) && $needs_shipping ) {
$chosen_shipping_methods = array();
if ( is_object( $order ) ) {
$chosen_shipping_methods = array_unique( array_map( 'wc_get_string_before_colon', $order->get_shipping_methods() ) );
} elseif ( $chosen_shipping_methods_session = WC()->session->get( 'chosen_shipping_methods' ) ) {
$chosen_shipping_methods = array_unique( array_map( 'wc_get_string_before_colon', $chosen_shipping_methods_session ) );
$canonical_rate_ids = array();
if ( is_object( $order ) && ( $order_shipping_items = $order->get_shipping_methods() ) ) {
$canonical_rate_ids = $this->get_canonical_order_shipping_item_rate_ids( $order_shipping_items );
} elseif ( $chosen_package_rate_ids = WC()->session->get( 'chosen_shipping_methods' ) ) {
$canonical_rate_ids = $this->get_canonical_package_rate_ids( $chosen_package_rate_ids );
}
if ( 0 < count( array_diff( $chosen_shipping_methods, $this->enable_for_methods ) ) ) {
if ( ! sizeof( $this->get_matching_rates( $canonical_rate_ids ) ) ) {
return false;
}
}
@ -198,6 +199,60 @@ class WC_Gateway_COD extends WC_Payment_Gateway {
return parent::is_available();
}
/**
* Converts the chosen rate IDs generated by Shipping Methods to a canonical 'method_id:instance_id' format.
*
* @since 3.4.0
*
* @param array $order_shipping_items Array of WC_Order_Item_Shipping objects.
* @return array $canonical_rate_ids Rate IDs in a canonical format.
*/
private function get_canonical_order_shipping_item_rate_ids( $order_shipping_items ) {
$canonical_rate_ids = array();
foreach ( $order_shipping_items as $order_shipping_item ) {
$canonical_rate_ids[] = $order_shipping_item->get_method_id() . ':' . $order_shipping_item->get_instance_id();
}
return $canonical_rate_ids;
}
/**
* Converts the chosen rate IDs generated by Shipping Methods to a canonical 'method_id:instance_id' format.
*
* @since 3.4.0
*
* @param array $rate_ids Rate IDs as generated by shipping methods. Can be anything if a shipping method doesn't honor WC conventions.
* @return array $canonical_rate_ids Rate IDs in a canonical format.
*/
private function get_canonical_package_rate_ids( $chosen_package_rate_ids ) {
$shipping_packages = WC()->shipping->get_packages();
$canonical_rate_ids = array();
foreach ( $chosen_package_rate_ids as $package_key => $chosen_package_rate_id ) {
if ( ! empty( $shipping_packages[ $package_key ][ 'rates' ][ $chosen_package_rate_id ] ) ) {
$chosen_rate = $shipping_packages[ $package_key ][ 'rates' ][ $chosen_package_rate_id ];
$canonical_rate_ids[] = $chosen_rate->get_method_id() . ':' . $chosen_rate->get_instance_id();
}
}
return $canonical_rate_ids;
}
/**
* Indicates whether a rate exists in an array of canonically-formatted rate IDs that activates this gateway.
*
* @since 3.4.0
*
* @param array $rate_ids
* @return boolean
*/
private function get_matching_rates( $rate_ids ) {
// First, match entries in 'method_id:instance_id' format. Then, match entries in 'method_id' format by stripping off the instance ID from the candidates.
return array_unique( array_merge( array_intersect( $this->enable_for_methods, $rate_ids ), array_intersect( $this->enable_for_methods, array_unique( array_map( 'wc_get_string_before_colon', $rate_ids ) ) ) ) );
}
/**
* Process the payment and return the result.