Home  >  Q&A  >  body text

Customize Woocommerce shipping area method

<p>I spent several hours trying to find the right way to implement a solution for creating a custom shipping area method. </p> <p>WC:7.2.2 Work stress: 6.0.3</p> <p>Site is in good health, no permission errors etc (only updates available information)</p> <p>I used a number of sources such as: https://woocommerce.github.io/woocommerce-rest-api-docs/?php#shipping-zone-methods</p> <p>https://github.com/woocommerce/woocommerce/wiki/Shipping-Method-API#properties</p> <p>https://gist.github.com/mikejolley/3b37b9cc19a774665f31</p> <p>https://code.tutsplus.com/tutorials/create-a-custom-shipping-method-for-woocommerce--cms-26098</p> <p>There are many others. </p> <p>Basically, I need sample code to create (plugin) for a shipping zone method with a custom shipping cost function. We are based on od Woocommerce Easy Booking and have days in the metadata that's why we can't use one of the woocommerce official premium plugins to handle that.</p> <p>我最终得到了以下代码:</p> <pre class="brush:php;toolbar:false;"><?php if (!defined('ABSPATH')) { exit; // Exit if accessed directly } function your_shipping_method_init() { if (!class_exists('WC_Your_Shipping_Method')) { class WC_Your_Shipping_Method extends WC_Shipping_Method { /*** Constructor for your shipping class * * @access public * @return void*/ public function __construct() { $this->id = 'diet_day_shipping'; // Id for your shipping method. Should be uunique. $this->method_title = __('Shipping per diet day'); // Title shown in admin $this->method_description = __('Shipping cost per booking'); // Description shown in admin $this->enabled = "yes"; // This can be added as an setting but for this example its forced enabled //$this->title = "Easy Booking Shipping per day"; // This can be added as an setting but for this example its forced. //$this->rates = array('calculate_shipping'); $this->supports = array( 'shipping-zones', 'instance-settings', 'instance-settings-modal', ); $this->instance_form_fields = array( 'title' => array( 'title' => __('Method Title'), 'type' => 'text', 'description' => __('This controls the title which the user sees during checkout.'), 'default' => __('Daily delivery for Your diet'), ), 'cost' => array( 'title' => __('Cost'), 'type' => 'number', 'description' => __('This controls the cost per day.'), 'default' => 7, ) ); $this->init(); $this->title = $this->get_option('title'); $this->cost = $this->get_option('cost'); add_action('woocommerce_update_options_shipping_' . $this->id, array($this, 'process_admin_options')); }/*** Init your settings * * @access public * @return void*/ function init() { // Load the settings API $this->init_form_fields(); // 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( 'title' => array( 'title' => __('Method Title'), 'type' => 'text', 'description' => __('This controls the title which the user sees during checkout.'), 'default' => __('Daily diet shipping cost'), ), 'cost' => array( 'title' => __('Cost'), 'type' => 'number', 'description' => __('This controls the cost per day.'), 'default' => 7, ) ); } /*** calculate_shipping function. * @param array $package (default: array())*/ public function calculate_shipping($package = array()) { //hardcode for testing $shipping_number = 7; //probably way to calculate final shipping cost /* foreach ($package['contents'] as $item_id => $values) { $_product = $values['data']; $shipping_number = $shipping_number $_product->wceb_get_product_booking_duration() * $values['quantity']; }*/ $this->add_rate(array( 'id' => $this->id . $this->instance_id, 'label' => 'Dostawa poza Wa-wa', 'cost' => $shipping_number, )); } } } } add_action('woocommerce_shipping_init', 'your_shipping_method_init'); function add_your_shipping_method($methods) { $methods['diet_day_shipping'] = 'WC_Your_Shipping_Method'; return $methods; } add_filter('woocommerce_shipping_methods', 'add_your_shipping_method');</pre> <p>我需要有 2 个设置(只能在区域、方法中,不需要全局)标题(向客户显示)和成本 - 了解多人游戏天数的价值。</p> <p>我想要“编辑”按钮显示以下关于运输区域方法的方法,我可以在其中设置这些值。</p> <p>Can anyone help fix my code? </p> <p>There are currently no settings options displayed in the admin panel. Not in the shipping area method line, and not in the sgipping settings panel. </p> <p>Also, when I send a zip code from a zone using a custom shipping method - the cart shows that there is no shipping method available for that zip code)</p>
P粉558478150P粉558478150389 days ago422

reply all(1)I'll reply

  • P粉833546953

    P粉8335469532023-08-30 00:08:08

    I also spent three hours yesterday and another hour today trying to figure out a very similar problem. I believe I now have a solution, or at least help get you into the right direction. The official WooCommerce documentation seems to differentiate between settings and instance settings (or I can't find documentation on instance settings - more in the next paragraph).

    The following is based on what I have discovered so far through trial and error. If anyone has any "official" documentation on this, I'd look forward to comments on this reply.

    It is very important to distinguish between "settings" and "instance settings". See this image for a visual comparison on WooCommerce backend:

    set up

    Settings refer to "Global Shipping Mode Settings", i.e. they appear in the global submenu, but not within the shipping area. The official WooCommerce documentation shows how to use settings and how to add a new settings page:

    https://woocommerce.com/document/shipping-method-api/

    https://woocommerce.com/document/settings-api/

    To use the settings function/API, you must specify

    $this->supports = array('settings'); // You may also need to include shipping-zones

    In your constructor.

    "Settings" are applied/used/stored globally, i.e. independently of individual delivery regions.

    Instance settings

    Instance settings are settings that can be saved separately for each shipping area. To use them you must use

    $this->supports = array('shipping-zones', 'instance-settings', 'instance-settings-modal');

    In your constructor.

    The following example lets me understand the subtle but important differences of the instance setup API:

    https://gist.github.com/malkafly/57a5e07fd03d6fd5cab84c6182d84c86

    Code differences and regarding your original question

    Please note that there are subtle differences in the exact functionality and properties of the two APIs. Depending on your situation, you should decide to use one of these APIs and then strictly use that API. You're confusing the two APIs, which is probably why you can't get your custom shipping method to work.

    If you wish to use the (global) settings API:

    • $this->supports = array('shipping-zones', 'settings');
    • Use $this->form_fields (instead of $this->instance_form_fields)
    • Use $this->settings['title'] to retrieve saved settings

    If you wish to use the (delivery region specific) instance settings API:

    • Make sure your constructor looks like this/contains the following code:

      public function __construct( $instance_id = 0 ) {
                $this->instance_id = absint( $instance_id );
                //...
          }
    • Use $this->instance_settings['title'] to retrieve saved settings

    The links in the corresponding Settings/Instance Settings categories I posted above contain extensive additional (working) code examples for each method.

    reply
    0
  • Cancelreply