如何在 WooCommerce 3 中添加自定义工作运输方式

Posted

技术标签:

【中文标题】如何在 WooCommerce 3 中添加自定义工作运输方式【英文标题】:How to add a custom working Shipping Method in WooCommerce 3 【发布时间】:2017-12-23 22:31:00 【问题描述】:

我已经成功创建了一种新的运输方式,并为其提供了对运输区域的支持。但是,当我从下拉列表中选择方法以将其添加到区域时,它不会出现在“选定方法列表”中。

我录了一个screencast gif来演示:

我一生都无法弄清楚为什么它不起作用。如果我选择其中一种标准方法(Screencast GIF),它就可以正常工作

有人知道这里发生了什么以及如何让它工作吗?

这是我拥有的代码from this official thread: Shipping Method API:

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

    function request_a_shipping_quote_init() 
        if ( ! class_exists( 'WC_Request_Shipping_Quote_Method' ) ) 
            class WC_Request_Shipping_Quote_Method extends WC_Shipping_Method 
                /**
                 * Constructor for your shipping class
                 *
                 * @access public
                 * @return void
                 */
                public function __construct() 
                    $this->id                 = 'request_a_shipping_quote'; // Id for your shipping method. Should be uunique.
                    $this->method_title       = __( 'Request a Shipping Quote' );  // Title shown in admin
                    $this->method_description = __( 'Shipping method to be used where the exact shipping amount needs to be quoted' ); // Description shown in admin

                    $this->title = "Request a Shipping Quote"; // This can be added as an setting but for this example its forced.

                    $this->supports = array(
                        'shipping-zones'
                    );

                    $this->init();
                

                /**
                 * Init your settings
                 *
                 * @access public
                 * @return void
                 */
                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' ) );
                

                function init_form_fields() 

                    $this->form_fields = array(

                        'enabled' => array(
                            'title'       => __( 'Enable', 'dc_raq' ),
                            'type'        => 'checkbox',
                            'description' => __( 'Enable this shipping method.', 'dc_raq' ),
                            'default'     => 'yes'
                        ),

                        'title' => array(
                            'title'       => __( 'Title', 'dc_raq' ),
                            'type'        => 'text',
                            'description' => __( 'Title to be displayed on site', 'dc_raq' ),
                            'default'     => __( 'Request a Quote', 'dc_raq' )
                        ),

                    );

                

                /**
                 * calculate_shipping function.
                 *
                 * @access public
                 *
                 * @param mixed $package
                 *
                 * @return void
                 */

                public function calculate_shipping( $packages = array() ) 
                    $rate = array(
                        'id'       => $this->id,
                        'label'    => $this->title,
                        'cost'     => '0.00',
                        'calc_tax' => 'per_item'
                    );

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

    add_action( 'woocommerce_shipping_init', 'request_a_shipping_quote_init' );

    function request_shipping_quote_shipping_method( $methods ) 
        $methods['request_shipping_quote_shipping_method'] = 'WC_Request_Shipping_Quote_Method';

        return $methods;
    

    add_filter( 'woocommerce_shipping_methods', 'request_shipping_quote_shipping_method' );

【问题讨论】:

这在 woocommerce 3+ 中不再起作用,请参阅此未回答的支持线程:wordpress.org/support/topic/… 与 WC_Shipping_Method calculate_shipping() 核心方法和你的代码插件中定义的那个有冲突……这就是需要解决的问题。因为抛出此错误严格标准:WC_Request_Shipping_Quote_Method::calculate_shipping() 的声明应与 /www/wp-content/plugins 中的 WC_Shipping_Method::calculate_shipping($package = Array) 兼容/request_shipping_quote_method.php 第 18 行 @LoicTheAztec 这个成功了吗? 我最终不得不放弃这条路线,因为我无法让它工作。相反,我重新使用了货到付款运输方式,将其重新标记为“计算运输”以及其他一些自定义位以使其正常工作。不是有史以来最整洁的解决方案,但它在生产现场运行良好。我确信有一种适用于自定义运输方式的解决方案,只是我无法在我拥有的时间内开始工作。 【参考方案1】:

改变这一行

public function calculate_shipping( $package ) 

到这一行

public function calculate_shipping( $package = array() ) 

【讨论】:

谢谢。我确实实现了该代码,但它仍然无法正常工作。该站点当前处于远程状态,因此我看不到引发了哪些错误,将使其在本地运行,然后查看是否可以看到任何错误。 所以当我添加 $package = array() 时,现在不会抛出任何错误,但行为保持不变 - 运输方式未添加到运输方式列表中。 您遇到了什么错误? bcoz 现在你必须检查你是如何在你的函数中处理包的,bcoz 现在它是包数组 是否在任何地方记录了 packages 数组的结构,以便我知道如何正确实现它? 你能给我看看你的calculate_shipping()函数代码吗?【参考方案2】:

“woocommerce_shipping_methods”上的方法键应与运输方式 ID 匹配

在您的情况下: 你应该改变

function request_shipping_quote_shipping_method( $methods ) 
    $methods['request_shipping_quote_shipping_method'] = 'WC_Request_Shipping_Quote_Method';

    return $methods;


add_filter( 'woocommerce_shipping_methods', 'request_shipping_quote_shipping_method' );

收件人:

function request_shipping_quote_shipping_method( $methods ) 
    $methods['request_a_shipping_quote'] = 'WC_Request_Shipping_Quote_Method';

    return $methods;


add_filter( 'woocommerce_shipping_methods', 'request_shipping_quote_shipping_method' );

【讨论】:

刚刚发现这个回复 - 修复了它!非常感谢您的回答,非常感谢【参考方案3】:

WC_Custom_Shipping_Method 是一个抽象类,您正在尝试更改其继承方法calculate_shipping,这是抽象类不允许的。

尝试这样做。

<?php

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

function request_a_shipping_quote_init() 
    class Abs_Custom_Shipping extends WC_Shipping_Method
    if ( ! class_exists( 'WC_Request_Shipping_Quote_Method' ) ) 
        class WC_Request_Shipping_Quote_Method extends Abs_Custom_Shipping 
            /**
             * Constructor for your shipping class
             *
             * @access public
             * @return void
             */
            public function __construct() 
                $this->id                 = 'request_a_shipping_quote'; // Id for your shipping method. Should be uunique.
                $this->method_title       = __( 'Request a Shipping Quote' );  // Title shown in admin
                $this->method_description = __( 'Shipping method to be used where the exact shipping amount needs to be quoted' ); // Description shown in admin

                $this->title = "Request a Shipping Quote"; // This can be added as an setting but for this example its forced.

                $this->supports = array(
                    'shipping-zones'
                );

                $this->init();
            

            /**
             * Init your settings
             *
             * @access public
             * @return void
             */
            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' ) );
            

            function init_form_fields() 

                $this->form_fields = array(

                    'enabled' => array(
                        'title'       => __( 'Enable', 'dc_raq' ),
                        'type'        => 'checkbox',
                        'description' => __( 'Enable this shipping method.', 'dc_raq' ),
                        'default'     => 'yes'
                    ),

                    'title' => array(
                        'title'       => __( 'Title', 'dc_raq' ),
                        'type'        => 'text',
                        'description' => __( 'Title to be displayed on site', 'dc_raq' ),
                        'default'     => __( 'Request a Quote', 'dc_raq' )
                    ),

                );

            

            /**
             * calculate_shipping function.
             *
             * @access public
             *
             * @param mixed $package
             *
             * @return void
             */

            public function calculate_shipping( $packages = array() ) 
                $rate = array(
                    'id'       => $this->id,
                    'label'    => $this->title,
                    'cost'     => '0.00',
                    'calc_tax' => 'per_item'
                );

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


add_action( 'woocommerce_shipping_init', 'request_a_shipping_quote_init' );

function request_shipping_quote_shipping_method( $methods ) 
    $methods['request_shipping_quote_shipping_method'] = 'WC_Request_Shipping_Quote_Method';

    return $methods;


add_filter( 'woocommerce_shipping_methods', 'request_shipping_quote_shipping_method' );

(将 shipping 方法扩展为子类,然后将子类扩展为孙类,您可以在其中修改 calculate_shipping 方法)。

希望它有意义。

问候

【讨论】:

【参考方案4】:

在我尝试使用有问题的代码并将我在 cmets 中发现的所有错误修复到这些帖子之后,我仍然遇到了一些问题。例如,即使我成功将其添加到运输区域后,我也无法编辑运输方式。

在编辑标准的免费送货 woocommerce 方法后,我终于得到了对我有用的所需代码。希望它会为某人节省时间。

function request_a_shipping_quote_init() 
    if ( ! class_exists( 'Imp_WC_Shipping_Local_Pickup' ) ) 

        class Imp_WC_Pickup_Shipping_Method extends WC_Shipping_Method 
            /**
             * Constructor.
             *
             * @param int $instance_id
             */
            public function __construct( $instance_id = 0 ) 
                $this->id           = 'imp_pickup_shipping_method';
                $this->instance_id  = absint( $instance_id );
                $this->method_title = __( "Самовывоз из точки выдачи ( MO г. Дзержинский )", 'imp' );
                $this->supports     = array(
                    'shipping-zones',
                    'instance-settings',
                    'instance-settings-modal',
                );
                $this->init();
            

            /**
             * Initialize custom shiping method.
             */
            public function init() 

                // Load the settings.
                $this->init_form_fields();
                $this->init_settings();

                // Define user set variables
                $this->title = $this->get_option( 'title' );

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

            /**
             * Calculate custom shipping method.
             *
             * @param array $package
             *
             * @return void
             */
            public function calculate_shipping( $package = array() ) 
                $this->add_rate( array(
                    'label'   => $this->title,
                    'package' => $package,
                ) );
            

            /**
             * Init form fields.
             */
            public function init_form_fields() 
                $this->instance_form_fields = array(
                    'title' => array(
                        'title'       => __( 'Самовывоз из точки выдачи ( MO г. Дзержинский )', 'imp' ),
                        'type'        => 'text',
                        'description' => __( 'This controls the title which the user sees during checkout.', 'woocommerce' ),
                        'default'     => __( 'Самовывоз из точки выдачи ( MO г. Дзержинский )', 'imp' ),
                        'desc_tip'    => true,
                    ),
                );
            
        
    

add_action( 'woocommerce_shipping_init', 'request_a_shipping_quote_init' );

function request_shipping_quote_shipping_method( $methods ) 
    $methods['imp_pickup_shipping_method'] = 'Imp_WC_Pickup_Shipping_Method';

    return $methods;

add_filter( 'woocommerce_shipping_methods', 'request_shipping_quote_shipping_method' );

【讨论】:

这帮助我让我的运输方式发挥作用。构造函数方法中缺少 $instance_id,并且在删除或处理此运输方法时没有它会导致意外行为。 这也帮助了我。再次需要 instance_id。在设置支撑之前,我也无法显示它。【参考方案5】:

我遇到了这个问题,这让我发疯了几天,直到在查看 Woocommerce 代码以了解发生了什么时,我发现在为 woocommerce_shipping_methods 设置过滤方法时,我需要创建索引我添加到此数组中的条目与我的运输方法类中的 ID 属性相同。一旦我这样做了,它就很好地添加了运输方式,并为该区域正确显示了它。以前,我一直在没有索引的过滤器方法中将条目添加到数组中,这在 WC 看到该方法时工作正常,这就是为什么它看起来没问题。但是,保存设置的代码使用 ID 作为索引来识别运输方式。从其他 cmets,我想这个特定的索引是在 WC 版本 3 中添加的。希望这会有所帮助。

【讨论】:

【参考方案6】:

如果您的送货方式似乎仍然不起作用,您必须确保

    instance_id 必须在构造函数中定义,就像在这个 sn-p 中一样
公共函数 __construct($instance_id = 0) $this->instance_id = absint($instance_id); // 其他行如下
    没有过时数据:删除临时数据和客户数据(WooCommerce 设置 > 状态 > 工具)

【讨论】:

以上是关于如何在 WooCommerce 3 中添加自定义工作运输方式的主要内容,如果未能解决你的问题,请参考以下文章

WooCommerce 中特定产品的基于地理位置的自定义重定向

php [WooCommerce Instagram]如果您想将其更改为缩略图或其他图像尺寸,请将此代码添加到您的“自定义功能”区域

WooCommerce 中多个国家/地区的基于地理位置的自定义重定向

WooCommerce订阅 - 续订时未触发动作挂钩

如何在 Laravel 5.3 中添加自定义通知通道

在 WooCommerce 中将购物车商品限制为来自同一产品类别