От автора: если вы когда-либо разрабатывали что-то для WordPress, будь то тема или просто плагин, значит, вы уже знакомы с модульностью WordPress. WooCommerce также разработан, расширяя свои возможности. В этом уроке мы создадим простой метод доставки WooCommerce, который рассчитает стоимость доставки, и добавим некоторые ограничения для нашего плагина, чтобы наш способ доставки был доступен только для определенных стран.
Для этого нам понадобятся:
WordPress
Установленный и активированный плагин 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(): Возвращает название доставки.
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 и добавляем этот код:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
<?php /** * Plugin Name: TutsPlus Shipping * Plugin URI: //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: //www.ibenic.com * License: GPL-3.0+ * License URI: //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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<?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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
<?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.
Попробуйте изменить параметр « Включить». На вкладке « Параметры доставки» будет видно, включен наш способ доставки или нет.
Мы также определили, что наш метод доставки может перевозить до 100 кг. Что делать, если это правило изменится в будущем? Мы можем легко разрешить редактирование в настройках. Добавим эту настройку, чтобы наш метод init_form_fields выглядел следующим образом:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
<?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 пошагово, чтобы вы могли понять всё, что мы делаем. Первый шаг — получить стоимость по весу. Добавьте этот код к этому методу:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
<?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 кг и более. Эта часть лимитов доставки будет сделана позже в статье про ограничение при обработке заказа или обновлении заказа.
Расчет стоимости для выбранной страны доставки
Теперь, когда у нас есть стоимость, основанная на весе корзины, мы должны рассчитать стоимость выбранной страны доставки. Добавьте следующий код:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
<?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.
Регистрация стоимости
Мы рассчитали стоимость на общий вес и добавили стоимость страны доставки. Последним шагом будет — зарегистрировать скорость, поэтому добавьте эту последнюю часть:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<?php //... public function calculate_shipping( $package ) { //... $rate = array( 'id' => $this->id, 'label' => $this->title, 'cost' => $cost ); $this->add_rate( $rate ); } //... |
Вот весь код для этого метода, если у вас возникли проблемы с его выполнением:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
<?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:
Добавление ограничений
Поскольку мы разрешили методу доставки вычислять его стоимость, даже если общий вес нашей корзины больше, чем предельный, мы должны добавить некоторые ограничения. Это ограничение уведомит клиента о том, что заказ не может быть отправлен из-за превышения веса.
Функция ограничения
В нашей функции мы будем искать способ доставки, который был выбран. Если наш метод TutsPlus_Shipping_Method, тогда мы проверим лимит веса и общий вес в корзине. Если вес корзины превышает лимит веса, мы уведомим об этом нашего клиента.
Для этого нужно добавить следующий код после фильтра woocommerce_shipping_methods:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
<?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:
1 2 3 |
<?php add_action( 'woocommerce_review_order_before_cart_contents', 'tutsplus_validate_order' , 10 ); |
Уведомление о доставке
Когда клиент нажимает кнопку, чтобы разместить заказ или купить его, WooCommerce будет обрабатывать все данные фактуры и доставки вместе с содержимым корзины и выбранной доставкой.
Если есть уведомления об ошибках WooCommerce, это остановит процесс проверки и отобразит все эти уведомления для клиента. Поскольку мы создали функцию, использующую сеанс для получения выбранных методов доставки, мы должны добавить эту функцию к действию, которое будет запущено после того, как будет установлен сеанс. woocommerce_after_checkout_validation — действие, которое будет запускаться непосредственно перед тем, как WooCommerce проверит, есть ли какое-либо сообщение об ошибке. Добавим нашу функцию к этому действию:
1 2 3 |
<?php add_action( 'woocommerce_after_checkout_validation', 'tutsplus_validate_order' , 10 ); |
Полный код
Здесь предоставлен полный код для этого настраиваемого метода доставки, поэтому, если у вас возникли проблемы, посмотрите:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 |
<?php /** * Plugin Name: TutsPlus Shipping * Plugin URI: //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: //www.ibenic.com * License: GPL-3.0+ * License URI: //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ć
Источник: //code.tutsplus.com/
Редакция: Команда webformyself.
Комментарии (2)