简体   繁体   English

以编程方式向Woocommerce添加新的送货方式

[英]Add new shipping method to Woocommerce programmatically

I'm trying to add a new shipping method to my Woocommerce suite. 我正在尝试为我的Woocommerce套件添加新的送货方式。

Basically I'm trying to apply two different Shipping rates to an order depending on their user role. 基本上我试图根据用户角色对订单应用两种不同的运费。 I'm using Flat Rate as one of them, but need a custom one made. 我使用Flat Rate作为其中之一,但需要定制一个。

I have tried the the shipping api to create a new class but nothing seems to shows up. 我已经尝试了运输api来创建一个新类但似乎没有任何东西出现。

<?php namespace MySite;

use WC_Shipping_Method;

    function your_shipping_method_init() {
        if ( ! class_exists( 'CustomShipping' ) ) {

            class CustomShipping extends WC_Shipping_Method {
                /**
                 * Constructor for your shipping class
                 *
                 * @access public
                 * @return void
                 */
                public function __construct() {
                    $this->id                 = 'your_shipping_method'; // Id for your shipping method. Should be uunique.
                    $this->method_title       = __( 'Your Shipping Method' );  // Title shown in admin
                    $this->method_description = __( 'Description of your shipping method' ); // Description shown in admin

                    $this->enabled            = "yes"; // This can be added as an setting but for this example its forced enabled
                    $this->title              = "My Shipping Method"; // This can be added as an setting but for this example its forced.

                    $this->init();
                }

                function init() {
                    // Load the settings API
                    $this->init_form_fields(); // This is part of the settings API. Override the method to add your own settings
                    $this->init_settings(); // This is part of the settings API. Loads settings you previously init.

                    // Save settings in admin if you have any defined
                    add_action( 'woocommerce_update_options_shipping_' . $this->id, array( $this, 'process_admin_options' ) );
                }

                /**
                 * calculate_shipping function.
                 *
                 * @access public
                 * @param mixed $package
                 * @return void
                 */
                public function calculate_shipping( $package ) {
                    $rate = array(
                        'id' => $this->id,
                        'label' => $this->title,
                        'cost' => '10.99',
                        'calc_tax' => 'per_item'
                    );

                    // Register the rate
                    $this->add_rate( $rate );
                }
            }
    }

    add_action( 'woocommerce_shipping_init', 'your_shipping_method_init' );

    function add_your_shipping_method( $methods ) {
        $methods[] = 'CustomShipping';
        return $methods;
    }

    add_filter( 'woocommerce_shipping_methods', 'add_your_shipping_method' );
}

I use Composer to load my classes. 我使用Composer来加载我的类。

Aren't I supposed to see the new option in the Woocommerce Shipping settings? 我不应该在Woocommerce Shipping设置中看到新选项吗? Any guidance appreciated. 任何指导赞赏。

An alternative would be the intercept the session data and just change the shipping total and taxes there. 另一种方法是拦截会话数据,只需更改那里的运费总额和税金。 That doesn't seem to work however. 但这似乎不起作用。 Where can I find more data on where the shipping info comes from; 我在哪里可以找到有关运输信息来源的更多数据; where and when it's called? 它何时何地被称为?

There are two issues in your code. 您的代码中存在两个问题。 The first is that you are adding the action for woocommerce_shipping_init inside the function that you are attaching to it (so it's never being called) and the the second is that you aren't using the namespace you specified, namespace MySite . 第一个是你在你附加到它的函数中添加woocommerce_shipping_init的动作(因此它永远不会被调用),第二个是你没有使用你指定的命名空间, namespace MySite

The first issue is easier to see if you check the indentation of your code, it's all wrapped inside the init function. 如果检查代码的缩进,第一个问题就更容易看出,它全部包含在init函数中。

The second issue would be apparent in your logs with errors like the following once WooCommerce tries to load the class, which it isn't doing due to the first issue. 第二个问题会在你的日志中显而易见,一旦WooCommerce尝试加载类,就会出现如下错误,由于第一个问题,它没有做到。

PHP Fatal error: Class 'WC_Your_Shipping_Method' not found in /wp-content/plugins/woocommerce/includes/class-wc-shipping.php on line 136 PHP致命错误:第136行/wp-content/plugins/woocommerce/includes/class-wc-shipping.php中找不到“WC_Your_Shipping_Method”类

PHP Warning: call_user_func_array() expects parameter 1 to be a valid callback, function 'add_your_shipping_method' not found or invalid function name in /wp-includes/plugin.php on line 213 PHP警告:call_user_func_array()期望参数1是有效的回调函数,函数'add_your_shipping_method'未找到或函数名无效在第213行的/wp-includes/plugin.php中

I removed your implementation code below but tested this on a dev site and it shows up as a shipping method in the WooCommerce settings. 我在下面删除了您的实施代码,但在开发网站上进行了测试,它在WooCommerce设置中显示为送货方式。

/*
  Plugin Name: WooCommerce Your Shipping Method
  Description: Test shipping method
  Version: 1.0
 */

namespace MySite;

use WC_Shipping_Method;

function your_shipping_method_init() {
    if ( ! class_exists( 'WC_Your_Shipping_Method' ) ) {

        class WC_Your_Shipping_Method extends WC_Shipping_Method {
            // ... all your code for the implementation
        }
    }
}  // <-- note that the function is closed before the add_action('woocommerce_shipping_init')

// note "MySite\" prepended to the attached function
add_action( 'woocommerce_shipping_init', 'MySite\your_shipping_method_init' );

// note "MySite\" prepended to the shipping method class name
function add_your_shipping_method( $methods ) {
    $methods[] = 'MySite\WC_Your_Shipping_Method';
    return $methods;
}

// note "MySite\" prepended to the attached function
add_filter( 'woocommerce_shipping_methods', 'MySite\add_your_shipping_method' );

I'm not sure the precise issue with your code, but other shipping plugins do it like below, so I'd probably copy them: 我不确定您的代码的确切问题,但其他运输插件如下所示,所以我可能会复制它们:

First put your method in another file classes/class-wc-your-shipping-method.php 首先将您的方法放在另一个文件classes/class-wc-your-shipping-method.php

if ( ! class_exists( 'WC_Your_Shipping_Method' ) ) {

    class WC_Your_Shipping_Method extends WC_Shipping_Method {
        // your class stuff truncated for brevity
    }

}

then include the shipping class file from somewhere in your plugin: 然后从插件中的某个位置包含运输类文件:

function so_32509983_init() {
    include_once( 'classes/class-wc-your-shipping-method.php' );
}
add_action( 'woocommerce_shipping_init', 'so_32509983_init' );

finally tell WooCommerce to initialize your method as one of its active methods: 最后告诉WooCommerce将您的方法初始化为其活动方法之一:

function so_32509983_add_method( $methods ) {
    $methods[] = 'WC_Your_Shipping_Method';
    return $methods;
}
add_filter( 'woocommerce_shipping_methods', 'so_32509983_add_method' );

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM