Принудительно использовать способ доставки, когда действительный купон применяется в Woocommerce. - PullRequest
1 голос
/ 05 апреля 2019

Используя Woocommerce, я хочу принудительно назначить способ доставки, когда на этапе корзины / оформления заказа применяется определенный действительный купон.

Ниже моего кода. Он расширяет WC_Shipping_Method, получает полный список купонов woocommerce, позволяет администратору выбрать один или несколько, сохранять их, а затем, когда заказчик применяет один из выбранных купонов для проверки, вынуждает использовать только один этот метод доставки.

if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ) ) {




 /* Custom LocalPickup Class */
   class WC_Shipping_LocalPickUp_On_Coupon extends WC_Shipping_Method {

            public $requires = '';

            public function __construct( $instance_id = 0 ) {
                $this->id                 = 'localpickup_on_coupon';
                $this->instance_id        = absint( $instance_id );
                $this->method_title       = __( 'Pickup with Coupon', 'Valeo' );
            $this->method_description = __( 'Pickup with Coupon', 'Valeo' );
            $this->supports           = array(
                'shipping-zones',
                'instance-settings',


                'instance-settings-modal',
                );

                /*Getting Coupon List */
                $args = array(
                        'posts_per_page'   => -1,
                        'orderby'          => 'title',
                        'order'            => 'asc',
                        'post_type'        => 'shop_coupon',
                        'post_status'      => 'publish',
                );

                $coupons = get_posts( $args );
                $this->list = [];

                foreach($coupons as $item){
                        $this->list[$item->post_name] = $item->post_title;
                }

                $this->init();

                add_action( 'woocommerce_update_options_shipping_' . $this->id, array( $this, 'process_admin_options' ) );
            }

            public function init() {
              $this->init_form_fields();
              $this->init_settings();

              $this->title      = $this->get_option( 'title' );
              $this->requires   = $this->get_option( 'requires' );

        }

        public function init_form_fields() { 

            $this->instance_form_fields = array(
                'title'      => array(
                    'title'       => __( 'Title', 'woocommerce' ),
                    'type'        => 'text',
                    'description' => __( 'This controls the title which the user sees during checkout.', 'woocommerce' ),
                    'default'     => $this->method_title,
                    'desc_tip'    => true,
                ),


                'requires'   => array(
                    'title'   => __( 'Il ritiro in sede richiede...', 'Valeo' ),
                    'type'    => 'multiselect',
                    'class'   => 'valeo_multiselect',
                    'default' => '',
                    'options' =>  $this->list
                ),
            );
        }

        public function is_available( $package ) {

            $has_coupon = false;
            $coupons = WC()->cart->get_coupons();

            if(!empty($coupons)) {
                $couponKey = array_keys($coupons)[0];
                if ( in_array( $couponKey, $this->requires ) ) {

                    if ( $coupons ) {
                        foreach ( $coupons as $code => $coupon ) {
                            if ( $coupon->is_valid() ) {
                                $has_coupon = true;
                                break;
                            }
                        }
                    }
                } 
            }

            return apply_filters( 'woocommerce_shipping_' . $this->id . '_is_available', $has_coupon, $package, $this );
        }

        public function calculate_shipping( $package = array() ) {

            $rate = array(
                'id'      => $this->get_rate_id(),
                'label'   => $this->title,
                'cost'    => 0,
                'taxes'     => 0,
                'package' => $package,
            );

            $this->add_rate($rate);

            do_action( 'woocommerce_' . $this->id . '_shipping_add_rate', $this, $rate );

        }


    }

    add_filter( 'woocommerce_shipping_methods', 'register_devso_method' );
    function register_devso_method( $methods ) {
            $methods[ 'localpickup_on_coupon' ] = 'WC_Shipping_LocalPickUp_On_Coupon';
            return $methods;
    }
}

Здесь фильтр, который проверяет, вставил ли клиент выбранный купон (ы) и («плохим» образом), удаляет все ставки пакета woocommerce, кроме той, которую я объявил в классе.

function filter_woocommerce_package_rates( $array ) { 

        $check = FALSE;
        foreach($array as $index => $value){
            if(strpos($index, 'localpickup_on_coupon') !== false) { $check = TRUE; }
        }

        if($check){ 
            foreach($array as $index => $value){
                if(!(strpos($index, 'localpickup_on_coupon') !== false)) { unset($array[$index]); }
            }
        }

        return $array; 
    }; 

    // add the filter 
    add_filter( 'woocommerce_package_rates', 'filter_woocommerce_package_rates', 10, 1 );

Есть ли лучший способ сделать это?

...