Создание пользовательского метода доставки для WooCommerce

Создание пользовательского метода доставки для WooCommerce

От автора: если вы когда-либо разрабатывали что-то для WordPress, будь то тема или просто плагин, значит, вы уже знакомы с модульностью WordPress. WooCommerce также разработан, расширяя свои возможности. В этом уроке мы создадим простой метод доставки WooCommerce, который рассчитает стоимость доставки, и добавим некоторые ограничения для нашего плагина, чтобы наш способ доставки был доступен только для определенных стран.

Для этого нам понадобятся:

WordPress

Установленный и активированный плагин WooCommerce

Редактор выбора

WooCommerce: Быстрый старт, первые результаты

Создайте ваш интернет-магазин на WooCommerce с полного нуля уже сегодня!

Узнать подробнее

Правила для метода доставки

Прежде чем мы начнем, нам нужно будет определить, как наш метод доставки рассчитает стоимость и куда доступна отправка. Стоимость будет определяться весом, который нам нужно отправить, и зоной, в которою нам нужно отправить. Зона — это номер, который присваивается странам и ценам. Чем выше число, тем дольше расстояние доставки. Наша вымышленная компания по доставке отправляет товар только в несколько стран:

США

Канада

Германия

Великобритания

Италия

Испания

Хорватия

Наша компания находится в Хорватии, поэтому Хорватия находится в зоне 0. Давайте определим зоны для других стран:

США: 3

Канада: 3

Германия: 1

Соединенное Королевство: 2

Италия: 1

Испания: 2

Теперь, когда у нас есть все страны, доступные для доставки с соответствующей зоной, определим цены.

Зона 0: $ 10

Зона 1: $30

Зона 2: $ 50

Зона 3: $70

Также я упомянул о весе. Наша компания может поставлять до 100 кг, а цены:

0-10 кг: $ 0

11-30 кг: $ 5

31-50 кг: $ 10

51-100 кг: $ 20

У нас есть все, что нам нужно для создания нашего метода доставки. Теперь давайте немного узнаем о WooCommerce Shipping API.

Введение в Shipping Method API WooCommerce

При создании метода доставки нам нужно расширить класс из абстрактного класса WooCommerce WC_Shipping_Method. Определенные атрибуты в этом классе:

$id: ID (slug, keyword) нашей доставки. Обязательный.

$number: Целочисленный идентификатор.

$method_title: Название нашей доставки показано в admin.

$method_description: Краткое описание нашей доставки показано в admin (необязательно).

$enabled: String Boolean («yes» или «no»), который дает информацию, включена ли наша доставка и может быть использована или нет.

$title: Используется для отображения отгрузочного наименования на нашем сайте.

$availability: Определяет, доступна доставка или нет.

$countries: Массив стран, для которых этот метод включен. Значение по умолчанию — пустой массив.

$tax_status: Значение по умолчанию taxable. Если он облагается налогом, взимается налог.

$fee: Значение по умолчанию равно 0 . Сборы за метод.

$minimum_fee: Минимальная плата за метод. Значение по умолчанию равно null.

$has_settings: Определяет, имеет ли этот метод какие-либо настройки. Значение по умолчанию — true.

$supports: Массив, содержащий функции, поддерживаемые этим методом. Значение по умолчанию — пустой массив.

$rates: Массив ставок. Это необходимо заполнить, чтобы зарегистрировать стоимость доставки. Значение по умолчанию — пустой массив.

Определенные методы в WC_Shipping_Method:

is_taxable(): Возвращает, нужно ли нам рассчитать налог сверху ставки доставки.

add_rate( $args = array() ): Передаёт цену доставки, определенную в параметре $ args, в атрибут $rates.

has_settings(): Возвращает значение атрибута $has_settings.

is_available(): Возвращает значение, доступна ли доставка. Если в атрибуте есть страны $countries, и если установлены значения для атрибута $availability, включающие, конкретные или исключающие, он вернет true или false, если страна доступна для доставки.

get_title(): Возвращает название доставки.

WooCommerce: Быстрый старт, первые результаты

Создайте ваш интернет-магазин на WooCommerce с полного нуля уже сегодня!

Узнать подробнее

get_fee( $fee, $total ): Возвращает стоимость платежа для этой доставки на основе проанализированных $fee и $total.

supports( $feature ): Возвращает, поддерживает ли этот способ доставки функцию.

Существует больше атрибутов и методов, которые не будут объясняться здесь ради упрощения, поскольку класс WC_Shipping_Method расширяет класс WC_Settings_API. Существуют также другие методы, которые необходимо определить, чтобы доставка могла получить или установить настройки, а также рассчитать фактическую стоимость. Эти методы:

init(): Создает поля формы и настройки (их можно называть по-разному, если мы используем методы внутри нее и вызываем ее в __constructor методе).

calculate_shipping( $package ): Это метод, используемый для расчета стоимости доставки. Пакет – это массив с продуктами для отправки.

В calculate_shipping методе мы добавляем цену с помощью метода add_rate. Этот метод принимает массив с несколькими параметрами:

id: Идентификатор цены.

label: Метка для цены.

cost: Объем доставки. Это может быть одно значение или array стоимость каждого товара в корзине.

taxes: Он принимает или array налоги или ничего, поэтому налог рассчитывается WooCommerce. Он может даже принять false, если вы не хотите, чтобы налог был рассчитан.

calc_tax: Принимает per_order или per_item. Если используется per_item, array необходимо будет предоставить стоимость.

Чтобы зарегистрировать способ доставки, нам необходимо добавить наш метод доставки в array зарегистрированного метода, передав имя нашего класса. Мы можем получить доступ к этому array и отправить измененный array назад с помощью фильтра WordPress, который определен внутри плагина WooCommerce. Этот фильтр вызывается woocommerce_shipping_methods.

Создание нового класса доставки

Создадим наш метод доставки в качестве нового плагина, который расширяет плагин WooCommerce. Создаём новую папку tutsplus-shipping под wp-content/plugins. Кроме того, создаём файл с тем же именем tutsplus-shipping.php и добавляем этот код:

<?php
 
/**
 * Plugin Name: TutsPlus Shipping
 * Plugin URI: http://code.tutsplus.com/tutorials/create-a-custom-shipping-method-for-woocommerce--cms-26098
 * Description: Custom Shipping Method for WooCommerce
 * Version: 1.0.0
 * Author: Igor Benić
 * Author URI: http://www.ibenic.com
 * License: GPL-3.0+
 * License URI: http://www.gnu.org/licenses/gpl-3.0.html
 * Domain Path: /lang
 * Text Domain: tutsplus
 */
 
if ( ! defined( 'WPINC' ) ) {
 
 die;
 
}
 
/*
 * Check if WooCommerce is active
 */
if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ) ) {
 
 function tutsplus_shipping_method() {
 if ( ! class_exists( 'TutsPlus_Shipping_Method' ) ) {
 class TutsPlus_Shipping_Method extends WC_Shipping_Method {
 /**
 * Constructor for your shipping class
 *
 * @access public
 * @return void
 */
 public function __construct() {
 $this->id = 'tutsplus'; 
 $this->method_title = __( 'TutsPlus Shipping', 'tutsplus' ); 
 $this->method_description = __( 'Custom Shipping Method for TutsPlus', 'tutsplus' ); 
 
 $this->init();
 
 $this->enabled = isset( $this->settings['enabled'] ) ? $this->settings['enabled'] : 'yes';
 $this->title = isset( $this->settings['title'] ) ? $this->settings['title'] : __( 'TutsPlus Shipping', 'tutsplus' );
 }
 
 /**
 * Init your settings
 *
 * @access public
 * @return void
 */
 function init() {
 // Load the settings API
 $this->init_form_fields(); 
 $this->init_settings(); 
 
 // Save settings in admin if you have any defined
 add_action( 'woocommerce_update_options_shipping_' . $this->id, array( $this, 'process_admin_options' ) );
 }
 
 /**
 * Define settings field for this shipping
 * @return void 
 */
 function init_form_fields() { 
 
 // We will add our settings here
 
 }
 
 /**
 * This function is used to calculate the shipping cost. Within this function we can check for weights, dimensions and other parameters.
 *
 * @access public
 * @param mixed $package
 * @return void
 */
 public function calculate_shipping( $package ) {
 
 // We will add the cost, rate and logics in here
 
 }
 }
 }
 }
 
 add_action( 'woocommerce_shipping_init', 'tutsplus_shipping_method' );
 
 function add_tutsplus_shipping_method( $methods ) {
 $methods[] = 'TutsPlus_Shipping_Method';
 return $methods;
 }
 
 add_filter( 'woocommerce_shipping_methods', 'add_tutsplus_shipping_method' );
}

Может показаться, что слишком много всего, чтобы понять, но на самом деле это довольно просто. Сначала мы проверяем, определена ли константа WPINC, потому что если не определена, это означает, что кто-то пытается получить доступ к этому файлу напрямую или из места, которое не доступно из WordPress.

Теперь, когда мы уверены, что это будет доступно из WordPress, мы можем двигаться дальше. Прежде чем начнем создавать наш метод доставки для WooCommerce, мы должны быть уверены, что WooCommerce активен. Проверяем, находится ли файл woocommerce.php в массиве активных плагинов, который сохраняется в базе данных по этой опции active_plugins.

Затем мы создаем функцию tutsplus_shipping_method, которую мы также добавляем в экшен woocommerce_shipping_init. Действие woocommerce_shipping_init является основным действием для WooCommerce Shippings, которое включает все классы доставки, прежде чем они будут созданы. Используя это действие, мы уверены, что наш метод доставки будет включен после того, как WooCommerce будет инициализирован в правильном для использования WooCommerce месте.

__construct метод нашего класса установит некоторые общие атрибуты. Некоторые из них могут быть легко перезаписаны после загрузки параметров из базы данных в методе init. Два других метода остаются пустыми, потому что мы их позже определим.

Настройка доступности страны

Наш метод доставки доступен только в ранее определенном списке стран. Это будет установлено перед методом init внутри метода __construct. Добавьте это в метод __construct:

<?php
//...
$this->method_description = __( 'Custom Shipping Method for TutsPlus', 'tutsplus' ); 
 
// Availability & Countries
$this->availability = 'including';
$this->countries = array(
 'US', // Unites States of America
 'CA', // Canada
 'DE', // Germany
 'GB', // United Kingdom
 'IT', // Italy
 'ES', // Spain
 'HR' // Croatia
 );
 
$this->init();
//...

Атрибут availability устанавливается в ‘including’ так, чтобы эта доставка была доступна только для стран, включенных в атрибут countries. Когда WooCommerce хочет отобразить доступные отгрузки нашему клиенту, он проверяет, включена ли страна доставки в атрибут countries для этой доставки.

Создание настроек

Если присмотреться к нашему методу __construct, то можно увидеть, что мы проверяем настройки для enabled и title свойств. Создадим поля, которые позволят изменить наши свойства. Скопируйте этот код и заполните метод init_form_fields:

<?php
 
  function init_form_fields() { 
 
 $this->form_fields = array(
 
 'enabled' => array(
 'title' => __( 'Enable', 'tutsplus' ),
 'type' => 'checkbox',
 'description' => __( 'Enable this shipping.', 'tutsplus' ),
 'default' => 'yes'
 ),
 
 'title' => array(
 'title' => __( 'Title', 'tutsplus' ),
 'type' => 'text',
 'description' => __( 'Title to be display on site', 'tutsplus' ),
 'default' => __( 'TutsPlus Shipping', 'tutsplus' )
 ),
 
 );
 
 }

Теперь вы можете перейти в панель администратора WordPress и изменить эти настройки в WooCommerce> Настройки> Доставка> Доставка TutsPlus.

Создание пользовательского метода доставки для WooCommerce

Попробуйте изменить параметр « Включить». На вкладке « Параметры доставки» будет видно, включен наш способ доставки или нет.

Мы также определили, что наш метод доставки может перевозить до 100 кг. Что делать, если это правило изменится в будущем? Мы можем легко разрешить редактирование в настройках. Добавим эту настройку, чтобы наш метод init_form_fields выглядел следующим образом:

<?php
 
 function init_form_fields() { 
 
 $this->form_fields = array(
 
 'enabled' => array(
 'title' => __( 'Enable', 'tutsplus' ),
 'type' => 'checkbox',
 'description' => __( 'Enable this shipping.', 'tutsplus' ),
 'default' => 'yes'
 ),
 
 'title' => array(
 'title' => __( 'Title', 'tutsplus' ),
 'type' => 'text',
 'description' => __( 'Title to be display on site', 'tutsplus' ),
 'default' => __( 'TutsPlus Shipping', 'tutsplus' )
 ),
 
 'weight' => array(
 'title' => __( 'Weight (kg)', 'tutsplus' ),
 'type' => 'number',
 'description' => __( 'Maximum allowed weight', 'tutsplus' ),
 'default' => 100
 ),
 
 );
 
}

Теперь мы можем установить максимальный вес в настройках. Можно сделать наши страны, зоны и все остальное тоже настраиваемыми, но для простоты пропустим эту часть.

Расчет стоимости доставки

Мы все задали, но у нас есть еще кое-что, что нужно сделать прежде, чем мы сможем использовать наш метод доставки при продаже товаров. Нам нужно рассчитать стоимость доставки на основе товаров в корзине покупателя.

Мы собираемся обновить метод calculate_shipping пошагово, чтобы вы могли понять всё, что мы делаем. Первый шаг — получить стоимость по весу. Добавьте этот код к этому методу:

<?php
//...
public function calculate_shipping( $package ) {
 
 $weight = 0;
 $cost = 0;
 $country = $package["destination"]["country"];
 
 foreach ( $package['contents'] as $item_id => $values ) 
 { 
 $_product = $values['data']; 
 $weight = $weight + $_product->get_weight() * $values['quantity']; 
 }
 
 $weight = wc_get_weight( $weight, 'kg' );
 
 if( $weight <= 10 ) {
 
 $cost = 0;
 
 } elseif( $weight <= 30 ) {
 
 $cost = 5;
 
 } elseif( $weight <= 50 ) {
 
 $cost = 10;
 
 } else {
 
 $cost = 20;
 
 }
 
}
 
//...

Мы определили несколько исходных переменных: $weight, $cost, и $country. Переменная $weight будет удерживать общий вес от всех продуктов, переменная $cost будет удерживать стоимость этого метода доставки, а переменная $country будет содержать код ISO для выбранной страны доставки.

Мы получаем общий вес путем итерации корзины и добавления веса для каждого товара к переменной $weight. Когда у нас есть общий вес, мы используем функцию wc_get_weight для преобразования веса в килограммы, так как это единица, в которой наш метод доставки установил предел.

Последнее, что нужно, это получить стоимость рассчитанного веса. Если вы внимательно посмотрите на последнюю часть, мы не установили предел на 100 кг, как мы сказали. Наша стоимость доставки покажет стоимость даже для корзины с общим весом 101 кг и более. Эта часть лимитов доставки будет сделана позже в статье про ограничение при обработке заказа или обновлении заказа.

Расчет стоимости для выбранной страны доставки

Теперь, когда у нас есть стоимость, основанная на весе корзины, мы должны рассчитать стоимость выбранной страны доставки. Добавьте следующий код:

<?php
//...
public function calculate_shipping( $package ) {
 
 //...
 
 $countryZones = array(
 'HR' => 0,
 'US' => 3,
 'GB' => 2,
 'CA' => 3,
 'ES' => 2,
 'DE' => 1,
 'IT' => 1
 );
 
 $zonePrices = array(
 0 => 10,
 1 => 30,
 2 => 50,
 3 => 70
 );
 
 $zoneFromCountry = $countryZones[ $country ];
 $priceFromZone = $zonePrices[ $zoneFromCountry ];
 
 $cost += $priceFromZone;
 
}
//...

Один массив $countryZones содержит зоны для каждой страны. Второй массив $zonePrices содержит цены для каждой зоны. Как только мы установили оба этих массива, мы получим стоимость по зонам следующим образом:

Передаем код страны ISO в массив $countryZones, чтобы получить зону.

Передаем возвращенную зону массиву $zonePrices, чтобы получить стоимость.

Добавляем возвращаемую стоимость переменной $cost.

Регистрация стоимости

Мы рассчитали стоимость на общий вес и добавили стоимость страны доставки. Последним шагом будет — зарегистрировать скорость, поэтому добавьте эту последнюю часть:

<?php
 
//...
public function calculate_shipping( $package ) {
 //...
 $rate = array(
 'id' => $this->id,
 'label' => $this->title,
 'cost' => $cost
 );
 
 $this->add_rate( $rate );
}
//...

Вот весь код для этого метода, если у вас возникли проблемы с его выполнением:

<?php
 
//...
 
public function calculate_shipping( $package ) {
 
 $weight = 0;
 $cost = 0;
 $country = $package["destination"]["country"];
 
 foreach ( $package['contents'] as $item_id => $values ) 
 { 
 $_product = $values['data']; 
 $weight = $weight + $_product->get_weight() * $values['quantity']; 
 }
 
 $weight = wc_get_weight( $weight, 'kg' );
 
 if( $weight <= 10 ) {
 
 $cost = 0;
 
 } elseif( $weight <= 30 ) {
 
 $cost = 5;
 
 } elseif( $weight <= 50 ) {
 
 $cost = 10;
 
 } else {
 
 $cost = 20;
 
 }
 
 $countryZones = array(
 'HR' => 0,
 'US' => 3,
 'GB' => 2,
 'CA' => 3,
 'ES' => 2,
 'DE' => 1,
 'IT' => 1
 );
 
 $zonePrices = array(
 0 => 10,
 1 => 30,
 2 => 50,
 3 => 70
 );
 
 $zoneFromCountry = $countryZones[ $country ];
 $priceFromZone = $zonePrices[ $zoneFromCountry ];
 
 $cost += $priceFromZone;
 
 $rate = array(
 'id' => $this->id,
 'label' => $this->title,
 'cost' => $cost
 );
 
 $this->add_rate( $rate );
 
}
 
//...

Если вы попробуете просмотреть свою корзину или перейти на страницу проверки и выбрать страну, доступную для этой доставки, вы получите стоимость доставки, указанную с помощью этого способа доставки. Вот пример со страной из зоны 3:

Создание пользовательского метода доставки для WooCommerce

Добавление ограничений

Поскольку мы разрешили методу доставки вычислять его стоимость, даже если общий вес нашей корзины больше, чем предельный, мы должны добавить некоторые ограничения. Это ограничение уведомит клиента о том, что заказ не может быть отправлен из-за превышения веса.

Создание пользовательского метода доставки для WooCommerce

Функция ограничения

В нашей функции мы будем искать способ доставки, который был выбран. Если наш метод TutsPlus_Shipping_Method, тогда мы проверим лимит веса и общий вес в корзине. Если вес корзины превышает лимит веса, мы уведомим об этом нашего клиента.

Для этого нужно добавить следующий код после фильтра woocommerce_shipping_methods:

<?php
 
function tutsplus_validate_order( $posted ) {
 
 $packages = WC()->shipping->get_packages();
 
 $chosen_methods = WC()->session->get( 'chosen_shipping_methods' );
 
 if( is_array( $chosen_methods ) && in_array( 'tutsplus', $chosen_methods ) ) {
 
 foreach ( $packages as $i => $package ) {
 
 if ( $chosen_methods[ $i ] != "tutsplus" ) {
 
 continue;
 
 }
 
 $TutsPlus_Shipping_Method = new TutsPlus_Shipping_Method();
 $weightLimit = (int) $TutsPlus_Shipping_Method->settings['weight'];
 $weight = 0;
 
 foreach ( $package['contents'] as $item_id => $values ) 
 { 
 $_product = $values['data']; 
 $weight = $weight + $_product->get_weight() * $values['quantity']; 
 }
 
 $weight = wc_get_weight( $weight, 'kg' );
 
 if( $weight > $weightLimit ) {
 
 $message = sprintf( __( 'Sorry, %d kg exceeds the maximum weight of %d kg for %s', 'tutsplus' ), $weight, $weightLimit, $TutsPlus_Shipping_Method->title );
 
 $messageType = "error";
 
 if( ! wc_has_notice( $message, $messageType ) ) {
 
 wc_add_notice( $message, $messageType );
 
 }
 }
 } 
 } 
}

Мы получаем пакеты, которые разделены доставкой. Если все товары используют одну и ту же доставку, то вернется только один пакет со всеми товарами. После этого мы получаем выбранные методы, а затем проверяем для каждого пакета, отправлен ли он нашим методом доставки.

Если пакет должен быть отправлен нашим методом доставки, то устанавливаем лимит веса из настроек, и после этого рассчитываем общий вес нашего пакета. Если общий вес превышает наш лимит веса, клиент получит уведомление.

Уведомление об обновлении заказа

Обновление заказа происходит каждый раз, когда клиент меняет что-то на контрольной странице. Мы добавляем функцию tutsplus_validate_order к действию woocommerce_review_order_before_cart_contents. Это действие вызывается после того, как все настроено так, чтобы мы могли получить выбранные методы доставки с сеанса и пакеты для доставки. Как только клиент что-то изменит, это действие вызовет нашу функцию и добавит уведомление, если это необходимо. Добавьте этот код после функции tutsplus_validate_order:

<?php
 
add_action( 'woocommerce_review_order_before_cart_contents', 'tutsplus_validate_order' , 10 );

Уведомление о доставке

Когда клиент нажимает кнопку, чтобы разместить заказ или купить его, WooCommerce будет обрабатывать все данные фактуры и доставки вместе с содержимым корзины и выбранной доставкой.

Если есть уведомления об ошибках WooCommerce, это остановит процесс проверки и отобразит все эти уведомления для клиента. Поскольку мы создали функцию, использующую сеанс для получения выбранных методов доставки, мы должны добавить эту функцию к действию, которое будет запущено после того, как будет установлен сеанс. woocommerce_after_checkout_validation — действие, которое будет запускаться непосредственно перед тем, как WooCommerce проверит, есть ли какое-либо сообщение об ошибке. Добавим нашу функцию к этому действию:

<?php
 
add_action( 'woocommerce_after_checkout_validation', 'tutsplus_validate_order' , 10 );

Полный код

Здесь предоставлен полный код для этого настраиваемого метода доставки, поэтому, если у вас возникли проблемы, посмотрите:

<?php
 
/**
 * Plugin Name: TutsPlus Shipping
 * Plugin URI: http://code.tutsplus.com/tutorials/create-a-custom-shipping-method-for-woocommerce--cms-26098
 * Description: Custom Shipping Method for WooCommerce
 * Version: 1.0.0
 * Author: Igor Benić
 * Author URI: http://www.ibenic.com
 * License: GPL-3.0+
 * License URI: http://www.gnu.org/licenses/gpl-3.0.html
 * Domain Path: /lang
 * Text Domain: tutsplus
 */
 
if ( ! defined( 'WPINC' ) ) {
 
 die;
 
}
 
/*
 * Check if WooCommerce is active
 */
if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ) ) {
 
 function tutsplus_shipping_method() {
 if ( ! class_exists( 'TutsPlus_Shipping_Method' ) ) {
 class TutsPlus_Shipping_Method extends WC_Shipping_Method {
 /**
 * Constructor for your shipping class
 *
 * @access public
 * @return void
 */
 public function __construct() {
 $this->id = 'tutsplus'; 
 $this->method_title = __( 'TutsPlus Shipping', 'tutsplus' ); 
 $this->method_description = __( 'Custom Shipping Method for TutsPlus', 'tutsplus' ); 
 
 // Availability & Countries
 $this->availability = 'including';
 $this->countries = array(
 'US', // Unites States of America
 'CA', // Canada
 'DE', // Germany
 'GB', // United Kingdom
 'IT', // Italy
 'ES', // Spain
 'HR'  // Croatia
 );
 
 $this->init();
 
 $this->enabled = isset( $this->settings['enabled'] ) ? $this->settings['enabled'] : 'yes';
 $this->title = isset( $this->settings['title'] ) ? $this->settings['title'] : __( 'TutsPlus Shipping', 'tutsplus' );
 }
 
 /**
 * Init your settings
 *
 * @access public
 * @return void
 */
 function init() {
 // Load the settings API
 $this->init_form_fields(); 
 $this->init_settings(); 
 
 // Save settings in admin if you have any defined
 add_action( 'woocommerce_update_options_shipping_' . $this->id, array( $this, 'process_admin_options' ) );
 }
 
 /**
 * Define settings field for this shipping
 * @return void 
 */
 function init_form_fields() { 
 
 $this->form_fields = array(
 
 'enabled' => array(
 'title' => __( 'Enable', 'tutsplus' ),
 'type' => 'checkbox',
 'description' => __( 'Enable this shipping.', 'tutsplus' ),
 'default' => 'yes'
 ),
 
 'title' => array(
 'title' => __( 'Title', 'tutsplus' ),
 'type' => 'text',
 'description' => __( 'Title to be display on site', 'tutsplus' ),
 'default' => __( 'TutsPlus Shipping', 'tutsplus' )
 ),
 
 'weight' => array(
 'title' => __( 'Weight (kg)', 'tutsplus' ),
 'type' => 'number',
 'description' => __( 'Maximum allowed weight', 'tutsplus' ),
 'default' => 100
 ),
 
 );
 
 }
 
 /**
 * This function is used to calculate the shipping cost. Within this function we can check for weights, dimensions and other parameters.
 *
 * @access public
 * @param mixed $package
 * @return void
 */
 public function calculate_shipping( $package ) {
 
 $weight = 0;
 $cost = 0;
 $country = $package["destination"]["country"];
 
 foreach ( $package['contents'] as $item_id => $values ) 
 { 
 $_product = $values['data']; 
 $weight = $weight + $_product->get_weight() * $values['quantity']; 
 }
 
 $weight = wc_get_weight( $weight, 'kg' );
 
 if( $weight <= 10 ) {
 
 $cost = 0;
 
 } elseif( $weight <= 30 ) {
 
 $cost = 5;
 
 } elseif( $weight <= 50 ) {
 
 $cost = 10;
 
 } else {
 
 $cost = 20;
 
 }
 
 $countryZones = array(
 'HR' => 0,
 'US' => 3,
 'GB' => 2,
 'CA' => 3,
 'ES' => 2,
 'DE' => 1,
 'IT' => 1
 );
 
 $zonePrices = array(
 0 => 10,
 1 => 30,
 2 => 50,
 3 => 70
 );
 
 $zoneFromCountry = $countryZones[ $country ];
 $priceFromZone = $zonePrices[ $zoneFromCountry ];
 
 $cost += $priceFromZone;
 
 $rate = array(
 'id' => $this->id,
 'label' => $this->title,
 'cost' => $cost
 );
 
 $this->add_rate( $rate );
 
 }
 }
 }
 }
 
 add_action( 'woocommerce_shipping_init', 'tutsplus_shipping_method' );
 
 function add_tutsplus_shipping_method( $methods ) {
 $methods[] = 'TutsPlus_Shipping_Method';
 return $methods;
 }
 
 add_filter( 'woocommerce_shipping_methods', 'add_tutsplus_shipping_method' );
 
 function tutsplus_validate_order( $posted ) {
 
 $packages = WC()->shipping->get_packages();
 
 $chosen_methods = WC()->session->get( 'chosen_shipping_methods' );
 
 if( is_array( $chosen_methods ) && in_array( 'tutsplus', $chosen_methods ) ) {
 
 foreach ( $packages as $i => $package ) {
 
 if ( $chosen_methods[ $i ] != "tutsplus" ) {
 
 continue;
 
 }
 
 $TutsPlus_Shipping_Method = new TutsPlus_Shipping_Method();
 $weightLimit = (int) $TutsPlus_Shipping_Method->settings['weight'];
 $weight = 0;
 
 foreach ( $package['contents'] as $item_id => $values ) 
 { 
 $_product = $values['data']; 
 $weight = $weight + $_product->get_weight() * $values['quantity']; 
 }
 
 $weight = wc_get_weight( $weight, 'kg' );
 
 if( $weight > $weightLimit ) {
 
 $message = sprintf( __( 'Sorry, %d kg exceeds the maximum weight of %d kg for %s', 'tutsplus' ), $weight, $weightLimit, $TutsPlus_Shipping_Method->title );
 
 $messageType = "error";
 
 if( ! wc_has_notice( $message, $messageType ) ) {
 
 wc_add_notice( $message, $messageType );
 
 }
 }
 } 
 } 
 }
 
 add_action( 'woocommerce_review_order_before_cart_contents', 'tutsplus_validate_order' , 10 );
 add_action( 'woocommerce_after_checkout_validation', 'tutsplus_validate_order' , 10 );
}

Заключение

WooCommerce Shipping API позволяет вам создать свой собственный метод доставки с помощью простых шагов. Ограничения и доступность могут быть установлены внутри метода доставки при расчете доступности или стоимости метода доставки, но они также могут быть установлены за пределами способа доставки с использованием действий WooCommerce.

Автор: Igor Benić

Источник: https://code.tutsplus.com/

Редакция: Команда webformyself.

WooCommerce: Быстрый старт, первые результаты

Создайте ваш интернет-магазин на WooCommerce с полного нуля уже сегодня!

Узнать подробнее
Самые свежие новости IT и веб-разработки на нашем Telegram-канале

WooCommerce: быстрый старт, первые результаты

Создайте свой первый интернет-магазин на WooCommerce с полного нуля!

Получить

Метки:

Похожие статьи:

Комментарии Вконтакте:

Комментарии Facebook:

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Я не робот.

Spam Protection by WP-SpamFree