Разработка плагина доставки Shop-Script

Содержание...

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

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

В качестве примера посмотрите исходный код плагина доставки «Почта России» (GitHub-репозиторий).

Плагины доставки реализованы на уровне ядра фреймворка, а не конкретного приложения. Это позволяет использовать функциональность таких плагинов любому установленному приложению (например, Shop-Script).

Исходный код плагинов доставки находится в директории wa-plugins/shipping/. Каждый плагин представляет собой отдельную поддиректорию с реализацией класса, унаследованного от базового класса waShipping. Наименование поддиректории с файлами плагина является его уникальным идентификатором, который используется в формировании правильного имени класса плагина. Ниже приведен пример таких наименований для некоторого плагина с идентификатором myshipping:

wa-plugins/shipping/myshipping/lib/myshippingShipping.class.php

<?php
 
class myshippingShipping extends waShipping 
{ 
    ... 
}

Помимо основного класса, производного от waShipping, для работы плагина также требуются конфигурационные файлы, которые, как в приложениях и плагинах, размещаются в поддиректории lib/config/. Подробное описание конфигурационных файлов см. ниже.

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

Методы

В методах основного класса плагина для получения значений полей настроек плагина, описанных в конфигурационном файле lib/config/settings.php, используйте доступ к приватному полю вида $this->field_name. Вместо field_name указывайте идентификатор поля настроек, значение которого необходимо получить.

Методы, реализация которых обязательна для любого плагина доставки

calculate()

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

Типы возвращаемых значений

Один вариант доставки

Массив с одним подмассивом элементов.

[
    'name' => '', //название варианта доставки, например, “Наземный  транспорт”, “Авиа”, “Express Mail” и т. д.
    'comment' => '', //необязательное описание варианта доставки
    'est_delivery' => '', //произвольная строка, содержащая  информацию о примерном времени доставки
    'currency' => $this->currency, //ISO3-код валюты, в которой рассчитана  стоимость  доставки
    'rate_min' => $this->cost, //минимальная граница стоимости, если стоимость рассчитана приблизительно
    'rate_max' => $this->cost, //максимальная граница стоимости, если стоимость рассчитана приблизительно
    'rate' => $this->cost, //точная стоимость доставки
    'type' => ..., //один из типов доставки waShipping::TYPE_TODOOR, waShipping::TYPE_PICKUP или waShipping::TYPE_POST
    'delivery_date' => ..., //дата доставки или интервал дат доставки в формате SQL DATETIME
    'service' => ..., //название службы доставки для указания компании, выполняющей фактическую доставку
],

В зависимости от типа доставки, указанного в элементе 'type', в массиве должен присутствовать также элемент с ключом 'custom_data' с массивом дополнительных данных о возвращаемом варианте доставки:

  • waShipping::TYPE_PICKUP:
    • id string: идентификатор
    • lat float: широта координат
    • lng float: долгота координат
    • name string: название — извлекается из поля name варианта доставки либо поля name способа доставки и варианта доставки
    • description string: HTML-описание
    • way string: описание пути
    • additional string: дополнительное HTML-описание
    • timezone string: временная зона
    • schedule string|array: расписание работы в виде строки HTML-кода либо массива данных для отдельных дней недели:
      • type string: обозначение типа дня — рабочий (workday) и выходной (weekend)
      • start_work string: время начала работы в формате SQL DATETIME
      • end_work string: время окончания работы в формате SQL DATETIME
      • additional string: дополнительное описание для этого дня, максимум 64 символа
    • payment array: поддерживаемые способы оплаты в виде массива с ключами из числа констант waShipping::PAYMENT_TYPE_*
    • photos array: массив URL изображений пункта выдачи либо массив подмассивов с ключами uri (URL изображения), title (заголовок), description (описание)
    • storage int: срок хранения заказа в днях
    • intervals array: доступные интервалы времени доставки в виде массива; ключи массива: строки с обозначением интервала в часах и минутах, значения массива: подмассивы с номерами дней недели; например:
      [
          `10:00-18:00` => [0,1,2,3,4], //с понедельника по пятницу доставка с 10:00 до 18:00
          `10:00-15:00` => [5],         // в субботу доставка с 10:00 по 15:00
      ]
  • waShipping::TYPE_TODOOR:
    • id string: идентификатор
    • intervals array: доступные интервалы времени доставки
Несколько вариантов доставки

Массив с несколькими подмассивами.

[
    'variant_1' => [
        'name' => ...,
        'comment' => ...,
        'est_delivery' => ...,
        'currency' => ...,
        'rate_min' => ...,
        'rate_max' => ...,
        'rate' => ...,
        'type' => ..., //один из типов доставки waShipping::TYPE_TODOOR, waShipping::TYPE_PICKUP или waShipping::TYPE_POST
    ],
        'variant_2' => [
        'name' => ...,
        'comment' => ...,
        'est_delivery' => ...,
        'currency' => ...,
        'rate_min' => ...,
        'rate_max' => ...,
        'rate' => ...,
        'type' => ...,
    ],
    ...
],
Сообщение о невозможности рассчитать стоимость доставки для указанного адреса

Массив с одним подмассивом, содержащим пустую стоимость доставки и сообщение для покупателя. Плагин доставки должен предложить покупателю поля для изменения адреса доставки.

[
    'rate' => null,
    'comment' => '...',
],
Сообщение о невозможности рассчитать стоимость доставки

Строка с сообщением для покупателя.

'...'

data-атрибуты вариантов доставки

Метод calculate() может возвращать дополнительные data-атрибуты для вариантов доставки. Эти атрибуты могут использоваться JavaScript-кодом плагина в бекенде приложения при редактировании заказа для обновления стоимости доставки при изменении значений дополнительных полей, сформированных плагином.

Чтобы добавить такие дополнительные data-атрибуты, для каждого элемента массива, возвращаемого методом calculate(), нужно определить подмассив с ключом 'custom_data'. В качестве ключей подмассива нужно использовать ключи data-атрибутов, а в качестве значений подмассива — значения для этих атрибутов.

Пример
[
    'variant_id_1' => [
        'name' => '...',
        'est_delivery' => '...',
        'currency' => '...',
        'rate' => '...',
        'custom_data' => [
            'some-attribute' => 'какое-то значение атрибута',
            'another-attribute' => 'значение другого атрибута',
            '...' => '...',
        ],
    ],
    ...
],

allowedCurrency()

Возвращает строку или массив со списком ISO3-кодов валют, для которых плагин может рассчитывать стоимость доставки.

allowedWeightUnit()

Возвращает строковый идентификатор или массив идентификаторов поддерживаемых плагином единиц измерения веса отправления.

Методы, реализация которых необязательна и зависит от логики конкретного плагина

tracking($tracking_id = null)

Этот метод должен вернуть строку (допускается использование HTML-тегов), в которой может содержаться информация о текущем статусе отправления. Например, ссылку на страницу трассировки отправления на сайте службы доставки. Или же информацию о статусе отправления, если API службы доставки позволяет его получить.

Параметр $tracking_id — необязательный идентификатор отправления, полученный от пользователя. Результат, возвращаемый методом, предназначен для отображения покупателю на странице просмотра заказа.

getPrintForms(waOrder $order = null)

Возвращает список поддерживаемых печатных форм в виде ассоциативного массива следующего вида:

[
    key1 => [
        'name'        => '...',
        'description' => '...',
    ],
    key2 => [
        'name'        => '...',
        'description' => '...',
],
    ...
]

key — произвольный уникальный (в рамках данного плагина) идентификатор печатной формы;
name — наименование печатной формы;
description — описание печатной формы.

displayPrintForm($id, waOrder $order, $params = [])

Печать формы по указанному идентификатору (в качестве идентификатора используется ключ ассоциативного массива, возвращаемого методом getPrintForms()). Содержание и внешний вид каждой формы реализуются с помощью отдельного шаблона, хранящегося в поддиректории плагина templates/. Метод должен вернуть HTML-код сформированной печатной формы.

allowedAddress()

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

[
    [
        'country' => ...,
        'region'  => ...,
    ]
]

В качестве значения каждого из элементов может быть либо строка (единичное значение), либо массив строк (список идентификаторов разрешенных стран либо регионов). Если ограничивать доставку по отдельным регионам не нужно, то элемент 'region' можно не указывать.

requestedAddressFields()

Возвращает список полей адреса доставки, которые должны запрашиваться у покупателя при выборе способа доставки (когда срабатывает код плагина доставки). Метод должен вернуть либо false (не запрашивать поля адреса доставки), либо [] (запрашивать все поля адреса), либо массив со структурой, пример которой показан ниже:

return [
    'field_id_1' => ...,
    'field_id_2' => ...,
    ...
];

Вместо ключей массива вида field_id_* нужно указать идентификаторы полей адреса: 'country', 'region', 'city', 'zip', 'street' или любого другого пользовательского поля (если есть). Для элементов массива допустимы следующие значения:

  • [] — поле запрашивается
  • ['cost' => true] — поле запрашивается, и его значение является необходимым для расчета стоимости доставки
  • ['hidden' => true, 'value' => ...] — поле является скрытым и содержит значение, указанное в параметре 'value'
  • ['cost' => true, 'hidden' => true, 'value' => ...] — сочетание двух предыдущих вариантов
  • false — поле не запрашивается

requestedAddressFieldsForService($service)

Переопределив этот метод в классе плагина, вы сможете возвращать дополнительные поля адреса для выбранного варианта доставки, указанного в аргументе $service. Если поле обязательно для расчета стоимости доставки, для него нужно указать параметр $field['cost']=true, а если поле обязательно для ввода, для него укажите $field['required']=true.

Конфигурационные файлы

plugin.php

Файл plugin.php является главным конфигурационным файлом плагина доставки и предназначен для хранения базовой информации о плагине: названия, описания, версии и т. д. Формат файла:

<?php
    
return [
    'name' => ...,
    'description' => ...,
    'icon' => ...,
    'logo' => ...,
    'vendor' => ...,
    'version' => ...,
    'external' => true, //необязательный параметр
    'external_tracking' => true, //необязательный параметр
    'services_by_type' => true, //необязательный параметр
    'type' => ..., //необязательный параметр
];

Описания полей

  • name: наименование плагина; если в файле локализации плагина есть строка с ключом, совпадающим с указанным названием, то название будет локализовано автоматически;
  • description: описание плагина; если в файле локализации плагина есть строка с ключом, совпадающим с указанным описание, то описание будет локализовано автоматически;
  • icon: путь к файлу иконки плагина относительно директории с файлами плагина, например: img/russianpost16.png (указан путь к иконке стандартного размера 16х16 пикселей);
  • logo: путь к файлу логотипа плагина относительно директории с файлами плагина, например: img/russianpost.png (указан путь к логотипу стандартного размера для плагина доставки — 60х32 пикселя);
  • vendor: числовой идентификатор разработчика, его необходимо скопировать из своего аккаунта разработчика в Центре заказчика Webasyst;
  • version: строковое обозначение версии плагина, например: '1.0.0';
  • external: флаг, заставляющий запросы в PHP-коде плагина к внешним ресурсам (например, с помощью curl) выполняться в отдельном AJAX-запросе для увеличения отзывчивости страницы выбора способа доставки,
  • external_tracking: флаг, заставляющий запрос статуса отправления выполняться в отдельном AJAX-запросе для увеличения отзывчивости страницы с информацией о заказе в бекенде приложения;
  • services_by_type: флаг, обозначающий, что плагин умеет возвращать варианты доставки в зависимости от типа доставки, выбранного пользователем;
  • type: необязательный параметр, значением которого может быть одна из констант waShipping::TYPE_TODOOR, waShipping::TYPE_PICKUP или waShipping::TYPE_POST, если плагин умеет возвращать варианты доставки только одного типа.

settings.php

Файл settings.php используется для автоматического формирования интерфейса настроек плагина доставки в бекенде приложения, которое использует такой плагин. См. подробное описание файла настроек плагина.

requirements.php

Файл requirements.php используется для указания дополнительных системных требований, специфичных для работы конкретного плагина (например, наличие дополнительных расширений или отдельных параметров конфигурации PHP, установленных приложений Webasyst). См. подробное описание правил оформления системных требований продукта.

Использование дополнительных полей при оформлении и редактировании заказа

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

Чтобы предлагать дополнительные поля, в плагине необходимо реализовать публичный метод customFields(), который должен вернуть массив с конфигурацией полей. Пример реализации этого метода:

public function customFields(waOrder $order)
{
    if (!$this->getAdapter()->getAppProperties('custom_fields')) {
        //если приложение не поддерживает дополнительные поля, не показываем их ни во фронтенде, ни в бекенде
        return [];
    }
   //проверка текущего окружения
    if (wa()->getEnv() === 'backend') {
        //проверка поддержки приложением возможности редактирования дополнительных полей плагинов доставки в бекенде
        if (!$this->getAdapter()->getAppProperties('backend_custom_fields')) {
            //если приложение не поддерживает редактирование дополнительных полей, то поля не показываем
            return [];
        }
    }

    // получение значений дополнительных элементов, если они ранее уже были заполнены
    $shipping_params = $order->shipping_params;
    return [
        'field1' => [
            'value'        => $default_field_value, //значение по умолчанию, если необходимо
            'title'        => _wp('First field name'),
            'control_type' => waHtmlControl::INPUT,
        ],
        'field2' => [
            'value'        => $default_field_value, //значение по умолчанию, если необходимо
            'title'        => _wp('Second field name'),
            'control_type' => 'MyShippingPluginControl', //идентификатор пользовательского элемента формы
        ],
        //...
    ];
}

Валидация значений, введённых в дополнительные поля

Если покупатель ввёл недопустимое значение в дополнительное поле, можно заблокировать оформление заказа и показать покупателю сообщение об ошибке. Для этого добавьте в массив данных поля элемент с ключом 'errors' — он должен содержать подмассив со списком дополнительных полей, которые должны быть отмечены как заполненные неверно. Ключами подмассива должны быть имена дополнительных полей массива, а значениями — локализованные сообщения об ошибках для этих полей.

if (!strlen(trim($order->shipping_params['myfield']))) {
    $myfield_errors = [
        'myfield' => $this->_w('This field must be filled in.'),
    ];
}

$fields['myfield'] = [
    'value'        => '',
    'title'        => $this->_w('My field'),
    'control_type' => waHtmlControl::INPUT,
    'errors'       => $myfield_errors,
];

Собственные элементы форм

В качестве значения параметра 'control_type' можно указать строковый идентификатор пользовательского элемента формы (который может представлять из себя любой фрагмент HTML- и JavaScript-кода).

Для реализации пользовательского элемента формы необходимо следующее:

  1. Добавьте в класс плагина публичный метод, возвращающий строку HTML-кода пользовательского элемента.
  2. В начале метода customFields() выполните вызов следующего вида:

    $this->registerControl('MyShippingPluginControl', [$this, 'myShippingPluginControl']);

    В этом примере 'MyShippingPluginControl' в качестве первого аргумента метода registerControl() является идентификатором пользовательского элемента формы, а 'myShippingPluginControl' — именем метода, в котором реализован этот элемент формы.

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

Если изменение значения дополнительного поля должно сразу же динамически влиять на пересчет стоимости доставки, то в массиве конфигурации для этого поля нужно указать подмассив 'data' с элементом 'affects-rate' => true.

Пример
[
    'value'            => ifset($shipping_params['some_custom_field']),
    'title'            => _wp('Custom field name'),
    'control_type'     => waHtmlControl::SELECT,
    'description'      => '...',
    'options'          => [...],
    'data'             => [
        'affects-rate' => true,
    ],
]

Изменение значения дополнительного поля на стоимость доставки должно быть реализовано с помощью JavaScript-логики, которая должна при действиях пользователя взаимодействовать c основными полями плагина доставки. Эту JavaScript-логику нужно оформить в виде пользовательского элемента формы с использованием метода registerControl().

Чтобы получить значение дополнительного поля, нужно вызвать метод getPackageProperty($field) системного родительского класса плагина доставки. В качестве аргумента метод принимает строковый идентификатор дополнительного поля, сформированного с помощью метода customFields().

Пример
$shipping_params = $this->getPackageProperty('param_name');

Значения дополнительных полей отображаются на странице просмотра заказа в бекенде приложения вместе с названиями полей. Название поля извлекается из элемента 'title', указанного в конфигурации дополнительного поля, которую возвращает метод customFields().

Для каждого варианта доставки можно предлагать пользователю дополнительные поля — с помощью метода customFieldsForService(waOrder $order, $service). По умолчанию этот метод возвращает тот же результат, что и метод customFields(). При необходимости можно его переопределить в классе плагина, чтобы возвращать дополнительные элементы формы, — также с использованием инструментов класса waHtmlControl.

Для типа доставки waShipping::TYPE_TODOOR рекомендуется использовать дополнительное поле с ключом desired_delivery и типом waHtmlControl::DATETIME. Введенные пользователем данные будут доступны для просмотра и редактирования. Если изменение значения дополнительного поля должно приводить к автоматическому перерасчету стоимости доставки, для него нужно указать параметр $field['data']['affects-rate'] = true.

Запрос желаемой даты и времени доставки

Для выбора запрашиваемых у клиента элементов времени/даты и настройки доступных интервалов времени доставки в конфигурационном файле настроек settings.php нужно использовать элемент формы с ключом desired_delivery и идентификатором элемента настроек DeliveryIntervalControl:

'desired_delivery' => [
    'title'        => 'Preferred delivery time',
    'control_type' => 'DeliveryIntervalControl',
    'minutes'      => true,
],

Параметр 'minutes' обозначает необходимость указывать минуты в настройках интервалов времени доставки.

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

public function customFields(waOrder $order)
{
    $fields = parent::customFields($order);

    $this->registerControl('CustomDeliveryIntervalControl');
    $setting = $this->getSettings('customer_interval');

    if (!empty($setting['interval']) || !empty($setting['date'])) {
        if (!strlen($this->delivery_time)) {
            $from = time();
        } else {
            $from = strtotime(preg_replace('@,.+$@', '', $this->delivery_time));
        }
        $offset = max(0, ceil(($from - time()) / (24 * 3600)));
        $fields['desired_delivery'] = [
            'value'        => null,
            'title'        => $this->_w('Preferred delivery time'),
            'control_type' => 'CustomDeliveryIntervalControl',
            'params'       => [
                'date'      => empty($setting['date']) ? null : ifempty($offset, 0),
                'interval'  => ifset($setting['interval']),
                'intervals' => ifset($setting['intervals']),
            ],
        ];
    }
    return $fields;
}
Возможность запрашивать у клиента желаемую дату и время доставки должна поддерживаться приложением, с которым используется плагин. В случае с Shop-Script версия приложения должна быть не ниже 7.2.4.114.

Взаимодействие формы выбора доставки во фронтенде с плагином

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

$url_params = [
    'action_id' => 'foo', //в этом примере будет вызван публичный метод плагина с именем 'fooAction', который должен сформировать полноценный ответ на AJAX-запрос
    'plugin_id' => $this->key,
];
wa()->getRouteUrl(sprintf('%s/frontend/shippingPlugin', $this->app_id), $url_params, true);

Статус отправления

Плагин доставки оперирует отправлениями. Отправление — это экземпляр класса waOrder. Оно может находиться в одном из нескольких статусов, которые обозначаются константами класса waShipping:

  • waShipping::STATE_DRAFT — отправление формируется или редактируется
  • waShipping::STATE_READY — отправление сформировано и готово к отправке
  • waShipping::STATE_SHIPPING — отправление передается службе доставки
  • waShipping::STATE_CANCELED — отправление отменено

Для изменения или получения статуса отправления используйте следующие методы класса waShipping.

setPackageState (waOrder $order, $state, $params = [])

Переводит отправление в указанный статус и возвращает результат в одном из следующих форматов:

  • null — плагин не поддерживает этот статус.
  • string — одну строку с описанием ошибки для записи ее приложением в историю обработки заказа; HTML-теги допустимы, но не экранируется.
  • array[string] — ассоциативный массив с данными, которые будут сохранены приложением в элемент shipping_data в информации о заказе. Исключение: 'view_data' — строка для отображения в истории обработки заказа. HTML-теги допустимы, но не экранируются.

getStateFields ($state, waOrder $order = null, $params = [])

Возвращает массив полей веб-формы, которые должен заполнить пользователь при переводе отправления в указанный статус $state.

Значения заполненных полей копируются в аргумент $params['shipping_data'] при вызове метода setPackageState().

getAdapter()->getAppProperties ($property_name = null)

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

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

  • 'desired_date' — желаемая дата доставки
  • 'draft' — передача данных о черновике отправления
  • 'ready' — подтверждение данных отправления
  • 'shipping' — запрос на отправку отправления
  • 'cancel' — отмена отправления

Срок готовности отправления к передаче в службу доставки

При расчете стоимости доставки плагину доступен срок готовности заказа к передаче в службу доставки — его можно получить с помощью вызова

/** @var string $departure_datetime SQL DATETIME */
$departure_datetime = $this->getPackageProperty('departure_datetime');

Передача габаритов отправления

Для каждого элемента отправления указываются габариты в полях height, width, length, если они определены для элемента и приложение поддерживает передачу габаритов. Их можно получить с помощью метода $this->getItems(). Параметры total_height, total_width и total_length доступны в том случае, если приложение рассчитало общие габариты отправления. Их можно получить с помощью метода $this->getPackageProperty().

Размерность габаритов отправления

Для того чтобы определить единицу измерения габаритов отправления, переопределите метод allowedLinearUnit() — он должен вернуть одну из следующих единиц:

  • m — метр
  • cm — сантиметр
  • mm — мм
  • in — дюйм
  • ft — фут
  • km — километр
  • mi — миля

Проверка поддержки приложением передачи габаритов

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

$this->getAdapter()->getAppProperties('dimensions')

Значения, которые возвращает этот метод:

  • (string): идентификатор плагина расчёта габаритов заказа, если приложение поддерживает эту функциональность, она настроена и также настроен плагин.
  • true: приложение поддерживает функциональность, она настроена, но не настроен плагин.
  • false: приложение поддерживает функциональность, но она не настроена.
  • null: приложение не поддерживает функциональность.

Полезные методы

Базовый системный класс плагинов доставки waShipping предоставляет несколько полезных методов, которые можно использовать в основном классе плагина.

getAddress ($field = null)

Возвращает либо полный массив информации об адресе получателя, либо только значение указанного поля адреса, например, 'country', 'region', 'city', 'zip', 'street' или любого другого пользовательского поля (если есть).

getItems()

Возвращает массив с информацией о заказанных товарах.

getTotalPrice()

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

getTotalWeight()

Возвращает общий вес отправления.

Контроллеры и экшены

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

  • waJsonActions
  • waJsonController
  • waLongActionController
  • waSystemPluginActions
  • waSystemPluginAction

Обращение к собственным контроллерам плагина можно использовать, например, на странице настроек.

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

Готовый URL для выполнения запроса к собственному контроллеру удобно получать с помощью метода основного класса плагина getInteractionUrl($action = 'default', $module = 'backend').

Файлы HTML-шаблонов экшенов должны размещаться в директории templates/actions/[module]/[Module][Action].html.

Произвольные PHP-классы плагина

Для подключения произвольных классов плагина с использованием системного механизма автозагрузки файлы классов должны размещаться в директории lib/classes/ и именоваться по правилу shipping[Plugin_id][Class_name].class.php. Имена классов в таких файлах должны именоваться по правилу shipping[Plugin_id][Class_name]. Здесь [Plugin_id] — идентификатор плагина, [Class_name] — произвольная часть имени класса на усмотрение разработчика.

База данных

Общие настройки плагина

Общие для всех приложений настройки плагина можно хранить в таблице wa_app_settings. Сохранять и читать такие значения можно с помощью методов:

  • setGeneralSettings($name, $value)
  • getGeneralSettings($name = null, $default = '')

Такие настройки сохраняются в таблицу со значениями поля app_id в формате webasyst.shipping.[id]. Здесь [id] — это идентификатор плагина.

В качестве идентификаторов настроек нельзя использовать некоторые зарезервированные значения:

  • update_time — используется механизмом метаобновлений;
  • sync_time — используется механизмом выполнения задач по расписанию;
  • sync_success_time — используется механизмом выполнения задач по расписанию;
  • sync_failure_time — используется механизмом выполнения задач по расписанию.

Собственные таблицы плагина

Именовать таблицы плагина доставки нужно с использованием префикса wa_shipping_%plugin_id%.

Описывать структуру таблиц нужно в файле lib/config/db.php, как и для приложений и плагинов для них.

Для работы с собственной таблицей в плагине можно использовать класс waSystemPluginModel — дочерний класс waModel. В этом случае можно не оформлять самостоятельные классы моделей для каждой из таблиц плагина. С помощью метода setPlugin(waSystemPlugin $plugin, $table = null) этого класса удобно получить экземпляр waModel с указанием имени таблицы и сразу работать с данными в этой таблице.

Но если вам нужны собственные методы, которых нет в waModel, то этот способ не подойдёт — в этом случае нужно оформлять собственные классы моделей. Свои классы можно наследовать и от waSystemPluginModel.

В основном классе плагина есть метод getModel($table = null). Если в него передать имя таблицы, то он вернёт экземпляр класса для этой таблицы — если такой класс модели есть в плагине — или экземпляр waSystemPluginModel для указанной таблицы. В качестве имени таблицы нужно передать только часть имени после обязательного префикса.

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

Хранение данных в файлах

Плагины доставки могут хранить собственные данные в директории wa-data/. Для работы с такими файлами можно использовать новые методы основного класса:

  • getDataPath($path = null, $public = false, $create = true) — получение пути к файлам;
  • getDataUrl($path = null, $absolute = false) — получение URL файлов.

Задачи по расписанию

Код для поддержки задач по расписанию разделён на три части:

  1. Контроллер приложения, который вызывает метод runSync() для каждого экземпляра настроек плагина.
  2. «Обвязка» в методе runSync() базового класса waShipping, которая использует методы syncRequired() и handleSync($result), определяющие необходимость выполнения задачи и обрабатывающие результаты её выполнения. При необходимости эти методы можно переопределить в основном классе плагина доставки.
  3. Метод основного класса плагина плагина sync(), который реализует логику выполняемой задачи.

Информация о выполнении задач отображается на экране настроек плагина. В частности, если приложение не поддерживает запуск задач по расписанию, то показывается соответствующее предупреждение. Если метод получения настроек плагина getSettingsHtml() переопределён, то для удобства можно использовать логику отображения информации о выполнении задач в методе getNoticeHtml().

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

php cli.php shop shipping

Параметры конфигурационных файлов плагина

  • Описание возможностей плагина в файле plugin.php:
    • sync — флаг поддержки обновляемых справочников или кешируемых данных; может быть булевым или содержать рекомендуемый интервал обновления данных.
  • Описание поддержки функциональности приложением в файле плагина app.php:
    • sync — запуск обновления данных плагинов доставки и статусов отправлений по расписанию.
    • rights — требуемый вид прав пользователя для взаимодействия с плагином через его контроллеры. Если поле пустое или отсутствует, то требуются административные права к приложению. Для приложения shop необходим идентификатор прав доступа settings, который даёт пользователю доступ к настройкам приложения и плагинов оплаты и доставки.
  • Описания адресов (URL) для callback-уведомлений плагинов доставки размещаются в файле guide.php.

Метаобновления

Файлы метаобновлений должны размещаться в директории lib/updates/.