Categories » =) Home Work

#29. WC: Extending

WooCommerce Hooks: Actions and filters

Что такое hooks?

Использование hooks

Пример

Документация по API

Доступные action hooks и filters WooCommerce

Importing WooCommerce Dummy Data

Установка данных Dummy WooCommerce

Создание плагина для WooCommerce

Проверьте, активна ли WooCommerce

Именование основного файла

Text domains

Локализация

Следуйте рекомендациям WordPress PHP

Пользовательские таблицы базы данных и хранилище данных

Предотвращение утечки данных

Readme

Plugin Author Name

Plugin URI

Использовать пользовательский интерфейс WordPress / WooCommerce

Admin Menu Screens

Сделать это расширяемым

Удалить неиспользуемый код

Комментарий

Избегайте God Objects

Проверьте свой код с помощью WP_DEBUG

Отдельная логика бизнес-логики и представления

Использовать Transients для хранения внешней информации

Данные журнала

Пользовательский интерфейс для плагинов интеграции служб

Settings API

Определение полей формы

Отображение параметров администратора

Сохранение параметров администратора

Загрузка настроек

Shipping Method API

Создание плагина

Создайте функцию для размещения своего класса

Создайте свой класс

Определение settings/options

Метод calculate_shipping()

Собирая все это вместе

Создание Custom Shipping Method  для WooCommerce

Правила доставки для нашего Shipping Method

Введение в API метода доставки WooCommerce

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

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

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

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

Калькуляция затрат для выбранной страны доставки

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

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

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

Уведомление Checkout

WooCommerce Hooks: Actions and filters

Что такое hooks?

Hooks в WordPress по существу позволяют изменять или добавлять код без редактирования основных файлов. Они широко используются в WordPress и WooCommerce и очень полезны для разработчиков.

Существует два типа хука: действия и фильтры. Action Hooks позволяют вам вставлять собственный код в различных точках (везде, где выполняется hook). Filter Hooks позволяют вам манипулировать и возвращать передаваемую им переменную (например, цену продукта).

Использование hooks

Если вы используете hook для добавления или манипулирования кодом, вы можете добавить свой собственный код в файл functions.php вашей темы.

Использование action hooks

Чтобы выполнить свой собственный код, вы подключаетесь с помощью действия hook do_action (‘action_name’) ;.

add_action( ‘action_name’, ‘your_function_name’ );

function your_function_name() {

// Your code

}

Использование filter hooks

Фильтрующие хуки вызываются повсеместно — это код с помощью apply_filter(‘filter_name’, $variable) ;. Чтобы манипулировать переданной переменной, вы можете сделать что-то вроде следующего:

add_filter( ‘filter_name’, ‘your_function_name’ );

function your_function_name( $variable ) {

// Your code

return $variable;

}

С фильтрами вы должны вернуть значение.

Пример

В приведенном ниже примере используются hooks действий и hooks фильтра. В этом учебном руководстве рассказывается, как изменить и добавить поля к оформлению заказа.

  • Действия используются для:
    • Добавить новое поле к checkout
    • Добавьте это новое поле в order
  • Фильтры используются для:
    • Заменить labels и placeholders существующих полей
    • Сделать существующее поле необязательным, пока оно требовалось
    • Удалить существующие поля

Документация по API

Полный обзор API WooCommerce см. В документации API.

Доступные action hooks и filters WooCommerce

Для получения подробной информации о том, что делают hooks действий и фильтры, обратитесь к ссылке WooCommerce Hooks Reference.

Importing WooCommerce Dummy Data

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

Но, возможно, вам захочется посмотреть, как выглядят образцы заказов и продукты. Если так, у нас есть образец данных только для вас!

Этот образец данных для WooCommerce находится в файле dummy-data.xml, который находится в папке плагина WooCommerce под названием woocommerce / dummy-data /. Вы можете повторно загрузить WooCommerce на свой компьютер или получить файл с вашего сервера через SFTP и т. Д., Но проще всего просто щелкнуть правой кнопкой мыши и скачать его здесь.

Установка данных Dummy WooCommerce

Независимо от того, как вы получите файл, пришло время его загрузить! В администраторе WordPress перейдите: Tools > Import и выберите вариант WordPress.

Если у вас нет установленного импортера WordPress, сначала установите его, выбрав «Установить сейчас».

Как только он будет установлен, выберите «Выполнить импорт». Здесь выберите кнопку «Выбрать файл» и выберите файл dummy-data.xml, который вы загрузили ранее.

С помощью этого набора выберите кнопку Загрузить файл и кнопку импорта.

После этого у вас будет возможность импортировать автора по умолчанию для wooteam, создать нового пользователя или назначить записи существующему пользователю. Это ваш призыв сделать, хотя мы бы рекомендовали назначать должности существующему пользователю. После этого обязательно установите или снимите флажок «Загружать и импортировать вложенные файлы». Это позволит импортировать все изображения образцового продукта на ваш сайт, если этот флажок установлен.

Нажмите Submit, и ваши фиктивные данные будут импортированы. Поздравляю, теперь у вас есть образцы данных в WooCommerce, чтобы учиться!

Создание плагина для WooCommerce

Хотите создать плагин для расширения WooCommerce? Плагины, по сути, такие же, как и обычные плагины WordPress. Дополнительная информация доступна по адресу: Написание плагина

Примечание. Мы предоставляем эту страницу в качестве руководства для сторонних разработчиков. WooCommerce.com больше не принимает новые заявки, которые будут проданы на нашем веб-сайте с 1 февраля 2016 года.

Проверьте, активна ли WooCommerce

Большинство плагинов WooCommerce не нужно запускать, если WooCommerce не активирован. Вы можете обернуть свой плагин в чеке, чтобы проверить, установлен ли WooCommerce:

/**

* Check if WooCommerce is active

**/

if ( in_array( ‘woocommerce/woocommerce.php’, apply_filters( ‘active_plugins’, get_option( ‘active_plugins’ ) ) ) ) {

   // Put your plugin code here

}

Именование основного файла

Основной файл плагина должен принять имя плагина, например, плагин с именем каталога plugin-name будет иметь свой основной файл с именем plugin-name.php.

Text domains

Следуйте рекомендациям для интернационализации для разработчиков WordPress, текстовый домен должен соответствовать вашему имени каталога плагинов, например, плагин с именем каталога plugin-name будет иметь text domain plugin-name.

Локализация

Все текстовые строки в коде плагина должны быть на английском языке. Это языковой стандарт по умолчанию WordPress, и английский язык всегда должен быть первым. Если ваш плагин предназначен для определенного рынка (например, Испании или Италии), соответствующие файлы перевода для этих языков должны быть включены в ваш пакет плагинов. Подробнее на: Использование Makepot для перевода вашего плагина.

Следуйте рекомендациям WordPress PHP

WordPress содержит ряд рекомендаций, которые помогут вам сделать код WordPress более понятным и удобным для чтения. Это включает в себя цитаты, отступы, стиль скобок, стенографические теги php, условия йоды, соглашения об именах и многое другое. Ознакомьтесь с рекомендациями.

Пользовательские таблицы базы данных и хранилище данных

Следует избегать создания пользовательских таблиц базы данных. По мере возможности вы всегда должны использовать WordPress post types, taxonomies и options.

Учитывайте постоянство ваших данных. Вот простой пример:

  • Если данные не всегда присутствуют (т. Е. Срок их действия истекает), используйте transient.
  • Если данные постоянны, но не всегда присутствуют, рассмотрите возможность использования кэша WP.
  • Если данные постоянны и всегда присутствуют, рассмотрите таблицу wp_options.
  • Если тип данных — это сущность с n единицами, рассмотрите тип post type.
  • Если данные являются средством или сортируют / категорируют сущность, рассмотрим таксономию.

Logs должны быть записаны в файл с использованием класса WC_Logger.

Предотвращение утечки данных

Попытайтесь предотвратить утечку данных прямого доступа. Добавьте эту строку кода после открывающего тега PHP в каждом файле PHP:

if ( ! defined( ‘ABSPATH’ ) ) {

   exit; // Exit if accessed directly

}

Readme

Все плагины нуждаются в стандартном readme WordPress. Кроме того, вы должны добавить два дополнительных заголовка в начало файла readme.

  • WC требует как минимум
  • WC протестировано до

Ваш файл может выглядеть примерно так:

=== Plugin Name ===

Contributors: (this should be a list of wordpress.org userid’s)

Tags: comments, spam

Requires at least: 4.0.1

Tested up to: 4.3

Stable tag: 4.3

License: GPLv3 or later License

URI: http://www.gnu.org/licenses/gpl-3.0.html

WC requires at least: 2.2

WC tested up to: 2.3

Plugin Author Name

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

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

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

  • Plugin Author — WooCommerce
  • Заголовок разработчика — YourName / YourCompany, поле URI разработчика указано как http://yourdomain.com/.
  • Информация об авторских правах — «WooCommerce»

Например:

/**

* Plugin Name: WooCommerce Extension

* Plugin URI: http://woocommerce.com/products/woocommerce-extension/

* Description: Your extension’s description text.

* Version: 1.0.0

* Author: WooCommerce

* Author URI: http://woocommerce.com/

* Developer: Your Name

* Developer URI: http://yourdomain.com/

* Text Domain: woocommerce-extension

* Domain Path: /languages

*

* Copyright: © 2009-2015 WooCommerce.

* License: GNU General Public License v3.0

* License URI: http://www.gnu.org/licenses/gpl-3.0.html

*/

В плагине WooCommerce Helper — требуемом для клиентов для получения обновлений продуктов — информация разработчика включена как часть информации о плагине, чтобы разработчикам был предоставлен кредит, которого они заслуживают.

Plugin URI

Убедитесь, что указан заголовок Plugin URI указанного выше заголовка плагина. Эта строка должна содержать URL-адрес страницы продукта / продажи плагина на WooCommerce.com (если продается WooCommerce) или на отдельной странице для плагина на вашем сайте.

Использовать пользовательский интерфейс WordPress / WooCommerce

Важно поддерживать последовательный интерфейс между плагинами. Все плагины должны быть подключены к пользовательскому интерфейсу WordPress / WooCommerce. Данные приложений должны загружаться через API вместо iframe

Admin Menu Screens

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

tl;dr  — что использовать, когда и почему

  • Если ваш плагин интегрируется со сторонним сервисом (например, для получения ставок налогов или подключения к службе поддержки), вы должны использовать класс интеграции(integration class).
  • Если ваш плагин добавляет экран настроек для настройки плагина, настройки должны находиться на соответствующей вкладке на экране WooCommerce> Settings.
  • Если у вашего плагина есть настройки, которые не укладываются в существующие вкладки, а создание дополнительной вкладки не подходит, создайте вкладку настроек верхнего уровня.
  • Если в вашем плагине добавлены экраны администрирования, которые не содержат настроек (например, в Checkout Add-Ons есть экран для управления дополнительными полями в Checkout), используйте подменю в элементе меню администрирования WooCommerce.

WooCommerce Integrations Sub-Menu

WooCommerce предоставляет возможность регистрации интеграции продуктов. Если регистрации интеграции зарегистрированы, вкладка «Интеграция» становится доступной на экране WooCommerce > Settings.

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

Если вы интегрируете плагин с WooCommerce, мы настоятельно рекомендуем вам использовать класс WC_Integration.

WordPress Settings Sub-Menu

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

Поскольку расширения WooCommerce не являются автономными продуктами, экран настроек будет выглядеть неуместным в главном меню настроек WordPress.

Как будет выглядеть плагин, если он находится под настройками WordPress, вдали от администратора WooCommerce.

WooCommerce Sub-Menu

Если ваш плагин добавляет экраны администрирования, которые не требуют настройки вашего плагина, эти экраны могут находиться в подменю WooCommerce. Например, купон-кампании добавляют элемент подменю WooCommerce для создания, редактирования и удаления кампаний купонов; Checkout Add-Ons добавляет экран для управления дополнительными полями экрана оформления.

Другая причина заключается в том, что не все экраны администрирования входят в подменю WooCommerce. Если бы все разместили здесь свой экран настроек, было бы длинное меню администрирования. Это неудобно для владельца или менеджера магазина WooCommerce.

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

Если бы все разместили здесь ссылки на экран, то это увидит владелец магазина WooCommerce.

WooCommerce Settings Tab

Вкладки WooCommerce Settings предназначены для обсуждения на высоком уровне широких вопросов, связанных с настройкой WooCommerce.

Если ваш плагин требует настройки, которые не соответствуют ни одной из предоставленных вкладок настроек, и не взаимодействует со сторонним сервисом, используйте новую вкладку «Настройки WooCommerce».

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

Если бы все разместили настройки на новой вкладке настроек, у нас не хватило места!

WooCommerce Settings Section

Начиная с версии 2.2 появился новый фильтр, который позволяет добавить раздел под вкладкой «Основные настройки»:

Если для ваших настроек требуется страница, но подпадают под одну из вкладок верхнего уровня, например «Продукты», добавьте их в раздел, чтобы он был организованным и удобным для пользователя.

Дополнительная информация в разделе Добавление раздела на вкладку «Параметры» — всего лишь несколько строк кода.

Сделать это расширяемым

Разработчики должны использовать действия и фильтры WordPress, чтобы допускать модификацию / настройку без необходимости касаться базового кода кода плагина.

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

Дополнительные сведения см. В статье Pippin «Написание расширяемых плагинов с помощью действий и фильтров».

Удалить неиспользуемый код

С контролем версий нет никаких оснований оставлять в закомментированном коде, что может раздражать прокрутку и чтение. Удалите его и добавьте позже, если это необходимо.

Комментарий

Если у вас есть функция, что делает функция? Там должны быть комментарии для большинства, если не каждая функция в вашем коде. Кто-то / Может захотеть изменить, и комментарии для этого полезны. Мы рекомендуем использовать PHP Doc Blocks, похожие на WooCommerce.

Избегайте God Objects

God Objects — объекты, которые знают или делают слишком много. Точка объектно-ориентированного программирования берет большую проблему и разбивает ее на более мелкие части. Благодаря тому, что функции делают слишком много, трудно следовать этой логике, и ошибка будет труднее исправить. Вместо того, чтобы иметь массовые функции, разбейте их на более мелкие части.

Проверьте свой код с помощью WP_DEBUG

Всегда работайте в режиме WP_DEBUG, поэтому вы можете увидеть все предупреждения PHP, отправленные на экран. Обычно такие вещи, как проверка наличия переменной перед проверкой значения.

Отдельная логика бизнес-логики и представления

Хорошая практика состоит в том, чтобы отделить бизнес-логику (то есть как работает плагин) от логики представления (т. Е. Как она выглядит). Две отдельные части логики более легко поддерживаются и, при необходимости, меняются местами. Примером может быть два разных класса: один для отображения конечных результатов и один для страницы настроек администратора.

Использовать Transients для хранения внешней информации

Если вы предоставляете сервис через API, лучше хранить эту информацию, чтобы в будущем запросы могли выполняться быстрее, а нагрузка на ваш сервис уменьшилась. WordPress transients  могут использоваться для хранения данных в течение определенного времени.

Данные журнала

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

  • Разрешить любой вход в систему как «выбор».
  • Используйте класс WC_Logger. Пользователь может просматривать журналы на своей странице состояния системы.

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

$label = __( ‘Enable Logging’, ‘your-textdomain-here’ );

$description = __( ‘Enable the logging of errors.’, ‘your-textdomain-here’ );

if ( defined( ‘WC_LOG_DIR’ ) ) {

$log_url = add_query_arg( ‘tab’, ‘logs’, add_query_arg( ‘page’, ‘wc-status’, admin_url( ‘admin.php’ ) ) );

$log_key = ‘your-plugin-slug-here-‘ . sanitize_file_name( wp_hash( ‘your-plugin-slug-here’ ) ) . ‘-log’;

$log_url = add_query_arg( ‘log_file’, $log_key, $log_url );

$label .= ‘ | ‘ . sprintf( __( ‘%1$sView Log%2$s’, ‘your-textdomain-here’ ), ‘<a href=»‘ . esc_url( $log_url ) . ‘»>’, ‘</a>’ );

}

$form_fields[‘wc_yourpluginslug_debug’] = array(

‘title’       => __( ‘Debug Log’, ‘your-textdomain-here’ ),

‘label’       => $label,

‘description’ => $description,

‘type’        => ‘checkbox’,

‘default’     => ‘no’

);

Пользовательский интерфейс для плагинов интеграции служб

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

Чтобы сделать это, мы рекомендуем уведомление администратора, связанное с конкретным экраном интеграции услуг в WooCommerce.

Мы рекомендуем уведомление в этом текстовом формате, поскольку оно согласовано и информирует пользователя.

Следующий код был взят непосредственно из интеграции, которую мы разработали с Mailchimp, и является частью более крупного PHP-класса. Код был сохранен, а не модифицирован для примера, для вашей ссылки в контексте класса PHP.

// Display an admin notice, if setup is required.

add_action( ‘admin_notices’, array( $this, ‘maybe_display_admin_notices’ ) );

/**

* Display an admin notice, if not on the integration screen and if the account isn’t yet connected.

* @access public

* @since  1.0.0

* @return void

*/

public function maybe_display_admin_notices () {

if ( isset( $_GET[‘page’] ) && ‘wc-settings’ == $_GET[‘page’] && isset( $_GET[‘section’] ) && ‘mailchimp’ == $_GET[‘section’] ) return; // Don’t show these notices on our admin screen.

// Find a different method of retrieving this value.

$api_key = WC()->integrations->integrations[‘mailchimp’]->get_option( ‘wc_mailchimp_api_key’ );

if ( » == $api_key ) {

$url = $this->get_settings_url();

echo ‘<div class=»updated fade»><p>’ . sprintf( __( ‘%sWooCommerce MailChimp is almost ready.%s To get started, %sconnect your MailChimp account%s.’, ‘woocommerce-mailchimp-integration’ ), ‘<strong>’, ‘</strong>’, ‘<a href=»‘ . esc_url( $url ) . ‘»>’, ‘</a>’ ) . ‘</p></div>’ . «\n»;

}

} // End maybe_display_admin_notices()

/**

* Generate a URL to our specific settings screen.

* @access public

* @since  1.0.0

* @return string Generated URL.

*/

public function get_settings_url () {

$url = admin_url( ‘admin.php’ );

$url = add_query_arg( ‘page’, ‘wc-settings’, $url );

$url = add_query_arg( ‘tab’, ‘integration’, $url );

$url = add_query_arg( ‘section’, ‘mailchimp’, $url );

return $url;

}

Settings API

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

Определение полей формы

Вы можете определить свои поля с помощью метода init_form_fields в вашем конструкторе:

$this->init_form_fields();

Прежде чем вы сможете загрузить их, вы должны определить свои настройки. Определите ваши options следующим образом:setting  установите массив form_fields:

/**

* Initialise Gateway Settings Form Fields

*/

function init_form_fields() {

    $this->form_fields = array(

    ‘title’ => array(

         ‘title’ => __( ‘Title’, ‘woocommerce’ ),

         ‘type’ => ‘text’,

         ‘description’ => __( ‘This controls the title which the user sees during checkout.’, ‘woocommerce’ ),

         ‘default’ => __( ‘PayPal’, ‘woocommerce’ )

         ),

    ‘description’ => array(

         ‘title’ => __( ‘Description’, ‘woocommerce’ ),

         ‘type’ => ‘textarea’,

         ‘description’ => __( ‘This controls the description which the user sees during checkout.’, ‘woocommerce’ ),

         ‘default’ => __(«Pay via PayPal; you can pay with your credit card if you don’t have a PayPal account», ‘woocommerce’)

          )

    );

} // End init_form_fields()

В приведенном выше примере мы определяем 2 варианта — заголовок и описание. Заголовок — текстовое поле, тогда как описание — это текстовое поле. Обратите внимание, как вы можете установить значение по умолчанию и добавить описание для самой опции.

Добавьте параметры в следующем формате:

‘option_name’ => array(

    ‘title’ => ‘Title for your option shown on the settings page’,

    ‘description’ => ‘Description for your option shown on the settings page’,

    ‘type’ => ‘text|password|textarea|checkbox|select|multiselect’,

    ‘default’ => ‘Default value for the option’,

    ‘class’ => ‘Class for the input’,

    ‘css’ => ‘CSS rules added line to the input’,

    ‘label’ => ‘Label’, // checkbox only

    ‘options’ => array(

         ‘key’ => ‘value’

    ) // array of options for select/multiselects only

)

Отображение параметров администратора

Создайте метод с именем admin_options, содержащий следующее:

function admin_options() {

?>

<h2><?php _e(‘You plugin name’,’woocommerce’); ?></h2>

<table class=»form-table»>

<?php $this->generate_settings_html(); ?>

</table> <?php

}

Это выведет ваши настройки в правильном формате.

Сохранение параметров администратора

Чтобы ваши options сохранялись, вам просто нужно hook функцию process_admin_options в вашем конструкторе. Сохранение транзакций шлюза:

add_action(‘woocommerce_update_options_payment_gateways’, array(&$this, ‘process_admin_options’));

Плагины имеют одинаковый хук:

add_action(‘woocommerce_update_options_shipping_methods’, array(&$this, ‘process_admin_options’));

Загрузка настроек

В конструкторе вы можете загрузить ранее определенные настройки:

// Load the settings.

$this->init_settings();

После этого вы можете загрузить свои настройки из настроек API — метод init_settings выше заполняет переменную settings для вас:

// Define user set variables

$this->title = $this->settings[‘title’];

$this->description = $this->settings[‘description’];

Shipping Method API

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

Создание плагина

Во-первых, создайте регулярный плагин WordPress / WooCommerce — см. Раздел Создание плагина. Вы определите свой класс метода доставки в этом файле плагина и сохраните его за пределами WooCommerce.

Создайте функцию для размещения своего класса

Чтобы обеспечить классы, которые необходимо расширить, необходимо обернуть свой класс в функцию, которая вызывается после загрузки всех плагинов:

function your_shipping_method_init() {

// Your class will go here

}

add_action( ‘woocommerce_shipping_init’, ‘your_shipping_method_init’ );

Создайте свой класс

Создайте свой класс и поместите его внутри функции, которую вы только что создали. Убедитесь, что он расширяет класс метода доставки, чтобы у вас был доступ к API. Вы увидите ниже, мы также запустим наш метод доставки.

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                 = ‘your_shipping_method’;

$this->title       = __( ‘Your Shipping Method’ );

$this->method_description = __( ‘Description of your shipping method’ ); //

$this->enabled            = «yes»; // This can be added as an setting but for this example its forced enabled

$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’ ) );

}

/**

* calculate_shipping function.

*

* @access public

* @param mixed $package

* @return void

*/

public function calculate_shipping( $package ) {

// This is where you’ll add your rates

}

Помимо объявления класса, вы также должны указать WooCommerce, что он существует с другой функцией:

function add_your_shipping_method( $methods ) {

$methods[‘your_shipping_method’] = ‘WC_Your_Shipping_Method’;

return $methods;

}

add_filter( ‘woocommerce_shipping_methods’, ‘add_your_shipping_method’ );

Определение settings/options

Затем вы можете определить свои параметры, используя API настроек. В приведенных выше фрагментах вы увидите init_form_fields и init_settings. Они загружают API настроек. Подробнее о добавлении параметров см. В разделе «Параметры настройки WooCommerce».

Метод calculate_shipping()

calculate_shipping () — метод, который вы используете для добавления своих ставок — WooCommerce будет вызывать это при выполнении расчетов по отгрузке. Выполните здесь расчет конкретных плагинов, а затем добавьте цены через API. Как ты это делаешь? Вот так:

$rate = array(

‘id’       => $this->id,

‘label’    => «Label for the rate»,

‘cost’     => ‘10.99’,

‘calc_tax’ => ‘per_item’

);

// Register the rate

$this->add_rate( $rate );

Add_rate принимает массив опций. По умолчанию / возможные значения для массива следующие:

$defaults = array(

‘id’    => »,   // ID for the rate

‘label’ => »,   // Label for the rate

‘cost’  => ‘0’,  // Amount for shipping or an array of costs (for per item shipping)

‘taxes’ => »,   // Pass an array of taxes, or pass nothing to have it calculated for you, or pass ‘false’ to calculate no tax for this method

‘calc_tax’ => ‘per_order’ // Calc tax per_order or per_item. Per item needs an array of costs passed via ‘cost’

);

Ваш способ доставки может проходить столько ставок, сколько вы хотите — просто убедитесь, что идентификатор для каждого отличается. Пользователь может выбрать ставку во время оформления заказа.

Собирая все это вместе

Код способа доставки скелета, составленный всеми вместе, выглядит следующим образом:

<?php

/*

Plugin Name: Your Shipping plugin

Plugin URI: http://woothemes.com/woocommerce

Description: Your shipping method plugin

Version: 1.0.0

Author: WooThemes

Author URI: http://woothemes.com

*/

/**

* Check if WooCommerce is active

*/

if ( in_array( ‘woocommerce/woocommerce.php’, apply_filters( ‘active_plugins’, get_option( ‘active_plugins’ ) ) ) ) {

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                 = ‘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();

}

/**

* 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’ ) );

}

/**

* 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[‘your_shipping_method’] = ‘WC_Your_Shipping_Method’;

return $methods;

}

add_filter( ‘woocommerce_shipping_methods’, ‘add_your_shipping_method’ );

}

Для получения дополнительной информации, пожалуйста, ознакомьтесь Shipping Method API Wiki.

Создание Custom Shipping Method  для WooCommerce

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

Правила доставки для нашего Shipping Method

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

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

  • USA
  • Canada
  • Germany
  • United Kingdom
  • Italy
  • Spain
  • Croatia

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

  • USA: 3
  • Canada: 3
  • Germany: 1
  • United Kingdom: 2
  • Italy: 1
  • Spain: 2

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

  • Zone 0: $10
  • Zone 1: $30
  • Zone 2: $50
  • Zone 3: $70

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

  • 0–10 kg: $0
  • 11–30 kg: $5
  • 31–50 kg: $10
  • 51–100 kg: $20

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

Введение в API метода доставки WooCommerce

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

  • $id: ID (slug, keyword) нашего shipping. Обязательный.
  • $number: Integer ID.
  • $method_title:Название нашей доставки показано в админке.
  • $method_description: Краткое описание нашей доставки показано в админке(Optional).
  • $enabled: String Boolean («yes» или «no»), которое дает информацию, если наша доставка включена и может использоваться или нет.
  • $title: Используется для отображения нашего имени доставки на нашем сайте.
  • $availability: Определяет, доступна ли отправка или нет.
  • $countries: Массив стран, для которого этот метод включен. Значение по умолчанию — пустой массив.
  • $tax_status: Значение по умолчанию облагается налогом. Если он облагается налогом, взимается налог.
  • $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(): Создает поля формы и settings (можно назвать по-разному, если мы используем внутри себя методы и вызываем их в методе __constructor).
  • calculate_shipping( $package ): этот метод используется для расчета стоимости доставки. Пакет представляет собой массив с продуктами для отправки.

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

  • id: ID для rate.
  • label: Label для rate.
  • cost: Сумма shipping. Это может быть одно значение или массив с затратами для каждого элемента в корзине.
  • taxes : Он принимает множество налогов или ничего, так что налог рассчитывается WooCommerce. Он может даже принять false, если вы не хотите, чтобы налог рассчитывался.
  • calc_tax: Принимает per_order или per_item. Если вы используете per_item, вам нужно будет предоставить массив затрат.

Чтобы зарегистрировать метод доставки, нам необходимо добавить наш метод доставки в массив зарегистрированного метода, передав имя нашего класса. Мы можем получить доступ к этому массиву и отправить модифицированный массив обратно с помощью фильтра 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();

//…

Наличие атрибута устанавливается в «including» так, что доставка доступна только для стран, включенных в странах атрибутов. Когда WooCommerce хочет отобразить доступные shippings нашему клиенту, он проверяет, включена ли страна доставки в страны-атрибуты для этой доставки.

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

Если вы внимательно посмотрите на наш метод __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 > Settings > Shipping > TutsPlus Shipping. 

Попробуйте изменить параметр Enable и увидеть на вкладке  Shipping Options, если наш метод доставки включен или нет.Мы также определили, что наш способ доставки может доставлять до 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 для преобразования веса в килограммы, так как это единица, в которой наш метод доставки установил limit.

Последнее, что нужно сделать, это получить стоимость рассчитанного веса. Если вы внимательно посмотрите на последнюю часть, мы не установили лимит на 100 кг, как мы сказали. Наша стоимость доставки покажет стоимость даже для cart с общим весом 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.

Регистрация Rate

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

<?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:

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

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

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

В нашей функции мы будем искать метод доставки, который был выбран. Если этот метод — наш метод 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 );

Уведомление Checkout

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

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

Давайте добавим нашу функцию к этому действию:

<?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 );

}

ttp://joxi.ru/krDpvGLfEZQazr

Generic selectors
Exact matches only
Search in title
Search in content
Search in posts
Search in pages
Filter by Categories
=) Home Work
CSS
JavaScript
Word Press

Интеркасса (API)

Доллар

покупка  $ 1 | 27.53 грн
продажа $ 1 | 24.7 грн

Евро

покупка  € 1 | 30.59 грн
продажа € 1 | 27.33 грн