Доставка

Способы доставки – часть модуля «Интернет-магазин».

Модуль описывает работу с сервисами доставки. Используется в корзине магазина в виде подключения.

Подключение

Подключаемая часть – файл modules/delivery/delivery.inc.php. В нем описан класс Delivery_inc. В модуле к объекту класса можно обратиться через переменную $this->diafan->_delivery. Экземпляр класса создается при первом вызове переменной.

Методы

array get_all (integer &$select_delivery_id, float $summ) – Получает список способов доставки.

  • integer $select_delivery_id: выбранный способ доставки
  • float $summ: стоимость товаров в корзине

array order (integer $select_delivery_id, float $summ) – Результат выбора сервиса доставки при оформлении заказа.

  • integer $select_delivery_id: выбранный способ доставки
  • float $summ: стоимость товаров в корзине

void set_history (string $status, float $summ, string $service, string $service_id, string|array $data) – Запись в историю заказов.

  • string $status: статус заказа на доставку
  • float $summ: стоимость доставки
  • string $service: служба доставки
  • string $service_id: идентификатор заказа в системе службы доставки
  • string|array $data: данные о заказе, используемые бэкендом

array|boolaen false get_history (string $service) – Получает данные о заказе на доставку для выбранного способа доставки.

  • string $service: служба доставки

void done (integer $order_id) – Окончание оформления заказа.

  • integer $order_id

void set_status (integer $order_id, integer $status_id) – Действие при смене статуса заказа.

  • integer $order_id
  • integer $status_id

Структура бэкенда

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

Для этого нужно разработать несколько файлов стандартной структуры, учитывающие особенности сервиса доставки. И разместить папку с этими файлами в папку delivery/backend. Далее создать метод доставки, в котором в качестве службы доставки указать созданный бэкенд.

Модуль доставки (или бэкенд) должен иметь уникальное название латинскими буквами (по примеру boxberry, sdek, dpd и др.). Для примера будем использовать название myservice.

В папке delivery/backend/myservice могут находиться следующий файлы:

  • delivery.myservice.admin.php
  • delivery.myservice.model.php
  • delivery.myservice.view.php
  • delivery.myservice.js
  • delivery.myservice.action.php
  • delivery.myservice.php

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

Рассмотрим структуру стандартных файлов

delivery.myservice.admin.php

Файл содержит настройки службы доставки, подгружаемые при добавлении метода доставки.

Структура файла:

Пример:

// ошибка 404 при прямом вызове файлов
if (! defined('DIAFAN'))
{
    
$path = __FILE__;
    while(!
file_exists($path.'/includes/404.php'))
    {
        
$parent = dirname($path);
        if(
$parent == $path) exit;
        
$path = $parent;
    }
    include
$path.'/includes/404.php';
}

class
Delivery_myservice_admin
{
    public
$config;
    private
$diafan;

    public function
__construct(&$diafan)
    {
            
$this->diafan = &$diafan;
            
$this->config = array(
                
"name" => 'Название метода, выводимое администратору',
                
// настройки службы
                // ключи этого массива - название настроек латинскими буквами
                
"params" => array(
                    
// можно указать просто текстовое описание настройки
                    // тогда она будет редактироваться как строка
                    
'param1' => 'Название первой настройки',

                    
// можно указать массив данных, тогда есть возможность
                    // задать тип данных и подсказку
                    // доступны следующие типы: text - строка, checkbox - галочка
                    
'param2' => array(
                        
// название второй настройки
                        
'name' => 'Выводить карту',
                        
// тип - галочка
                        
'type' => 'checkbox',
                        
// подсказка
                        
'help' => 'Если настройка не включена, то выводим пункты вывоза списком',
                    ),

                    
// можно определить свою функцию для вывода поля и его сохранения
                    
'param3' => 'Название третьей настройки',
                )
            );
    }

    
/**
     * Своя функция на редактирования настройки param3
     *
     * @return void
     */
    
public function edit_variable_param3()
    {
        echo
'<div class="unit tr_delivery" delivery="myservice" style="display:none">
            <div class="infofield">Название поля</div>
            Значение поля
        </div>'
;
    }

    
/**
     * Своя функция на сохранение настройки param3
     *
     * @return void
     */
    
public function save_variable_param3()
    {
        
// сохраняет данные
    
}
}

delivery.myservice.model.php

Файл подготавливает данные о службе доставки для списка способов доставки в корзине магазина.

В файле генерируются данные, а затем они подставляются в шаблон delivery.myservice.view.php.

Пример:

// ошибка 404 при прямом вызове файлов
if (! defined('DIAFAN'))
{
    
$path = __FILE__;
    while(!
file_exists($path.'/includes/404.php'))
    {
        
$parent = dirname($path);
        if(
$parent == $path) exit;
        
$path = $parent;
    }
    include
$path.'/includes/404.php';
}

class
Delivery_myservice_model implements Delivery_model_interface
{
    
/*
     * Подключает способ доставки. Данные о заказе и способе доставки, переданные аргументом могут быть дополнены и использованы в дальнейшем в шаблоне бэкенда
     *
     * @param array $result данные о заказе (высота, ширина, длина, сумма, вес), идентификационный номер способа доставки ("id"), настройки способа доставки (array "params")
     * @return array
     */
    
public function get(&$result)
    {}

    
/*
     * Получает стоимость доставки
     *
     * @param array $params настройки способа доставки
     * @return mixed
     */
    
public function calculate($params)
    {}

    
/*
     * Получает данные, введенные пользователем в интерфейсе службы доставки
     *
     * @param array $params настройки способа доставки
     * @return mixed
     */
    
public function get_info($params)
    {}
}

Переменная $params — это массив настроек службы доставки, описанных в файле delivery.myservice.admin.php.

Пример:

// из нашего пример массив $params будет следующим
$params = array(
    
'param1' => '...',
    
'param2' => 1|0,
    
'param3' => '...',
);

Функция get() инициирует подключение бэкенда службы доставки. Функция принимает массив $result по ссылке. Это значит, что все, что будет дописано в массив $result внутри функции будет в нём сохранено. Чтобы $result было доступно в других функциях бэкенда нужно в функции get() сделать запись:

$this->result = $result;

В дальнейшем этот массив будет принят в шаблоне службы доставки delivery.myservice.view.php.

Функция get_info() возвращает информацию, введенную пользователем, которая потом будет сохранена в заказе. Это может быть город или адрес доставки, пункт выдачи заказа. Специфика этой информации определяется службой доставки. Обычно выбор сохраняется в сессию (это происходит в файле delivery.myservice.action.php) и затем из переменной сессии функция get_info() извлекает записанные данные и возвращает в подходящем формате.

Функция calculate() возвращает стоимость доставки. Для рассчета функция обращается к сервису доставки по API. В этой функции доступны все настройки из файла delivery.myservice.admin.php через массив $params. Если данных для рассчета стоимости недостаточно, например, не выбран ПВЗ, функция должна возвратить false. Если доставка не доступна по каким-то причинам, например, способ доставки не доступен для выбранного города, функция дожна вернуть NULL. Пользователь увидит сообщение об ошибке, предлагающее выбрать дополнительные опции доставки или другой способ доставки, и не сможет продолжить оформление заказа пока функция возвращает false или NULL.

Данные о заказе будут доступны через $this->result, если сделана соответствующая запись в функции get() (смотрите выше).

Какие же данные о заказе доступны?

  • $this->result['weight'] – вес;
  • $this->result['width'] – ширина;
  • $this->result['length'] – длина;
  • $this->result['height'] – высота;
  • $this->result['summ'] – стоимость.

delivery.myservice.view.php

Шаблон службы доставки. Данные для шаблона генерируются в файле delivery.myservice.model.php, функции get(). Шаблон выводится только в том случае, если пользователь выбрал службу доставки.

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

delivery.myservice.js

При наличии этот JS-файл автоматически подключается к шаблону delivery.myservice.view.php. В файле может быть написано:

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

delivery.myservice.action.php

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

  • module_name = delivery
  • backend = служба_доставки
  • action = метод_обработки

Обычно эти данные посылает JS-скрипт вместо с выбором пользователя как реакция на действия пользователя.

Пример:

Пользователь определил свой город в модуле myservice. В файле delivery.myservice.js будет обработка выбора:

$("select[name=myservice_city]").change(function(){
        $.
ajax({
                
data: {
                        
module: "delivery",
                        
backend: "myservice",
                        
action: "city",
                        
city: $("select[name=myservice_city]").val(),
                },
                
type: "POST",
                
dataType: "json",
                
success: function(result){
                        $(
'.js_cart_table_form').submit();
                },
        });
});

В файле delivery.myservice.action.php тогда будет записан этот выбор в сессию. Затем обновится корзина, будет пересчитана стоимость доставки с учетом выбора пользователя, записанного в сессии:

<?php
// ошибка 404 при прямом вызове файлов
if (! defined('DIAFAN'))
{
    
$path = __FILE__;
    while(!
file_exists($path.'/includes/404.php'))
    {
        
$parent = dirname($path);
        if(
$parent == $path) exit;
        
$path = $parent;
    }
    include
$path.'/includes/404.php';
}

class
Delivery_myservice_action extends Action
{
    public function
city()
    {
        
$_SESSION["myservice_city"] = $this->diafan->filter($_POST, "int", "myservice_city"]);
        
$this->result["result"] = "success";
    }

}

delivery.myservice.php

(Начиная с версии 6.0.11.10)

Если способ доставки требует служебный адрес для прямого обращения, то можно создать файл delivery.myservice.php. Он доступен по адресу https://site.ru/delivery/get/myservice/. В файле доступна все привычное окружение DIAFAN.CMS.

Готовые интеграции

В DIAFAN.CMS в стандартную сборку по умолчанию не включены модули доставки. Их можно скачать и установить отдельно.

Дополнения

Ваши комментарии и дополнения
02 декабря 2019 г. , редакция: 02 декабря 2019 г.
Касательно delivery.myservice.admin.php.

Для того, чтобы подвесить свою функцию на редактирование и сохранение поля param3, недостаточно сделать так, как в примере:
Код
// можно определить свою функцию для вывода поля и его сохранения
'param3' => 'Название третьей настройки',


Следует делать вот так:
Код
// можно определить свою функцию для вывода поля и его сохранения
'param3' => array(
// название третьей настройки
'name' => 'Название третьей настройки',
// тип - функция
'type' => 'function',
),


Подробнее см. /adm/includes/edit_functions.php, функция edit_variable_backend().
03 декабря 2019 г.
Касательно delivery.myservice.action.php.

Оказывается, есть требования к именованиям функций: названия должны состоять из строчных букв и подчеркиваний согласно регулярному выражению '/[^a-z0-9\_]+/'. Например:
Код
class Delivery_myservice_action extends Action
{
public function set_city()
{
// Это будет работать
}

public function setCity()
{
// А вот это не будет работать - никакого lowerCamelCase, только хардкор!
}
}

Подробнее см. delivery.php, функцию action().
24 марта 2020 г.
В примере в файле delivery.myservice.model.php модель реализует интерфейс Delivery_model_interface. Но в последней версии Диафана (6.0.12.5) интерфейс с таким именем не найден. Что делать?
24 марта 2020 г.
Код
В примере в файле delivery.myservice.model.php модель реализует интерфейс Delivery_model_interface. Но в последней версии Диафана (6.0.12.5) интерфейс с таким именем не найден

Ну как это "не найден"? В файле /modules/delivery/delivery.inc.php интерфейс заявлен
24 марта 2020 г.
Цитата
Ну как это "не найден"? В файле /modules/delivery/delivery.inc.php интерфейс заявлен


Прошу прощения! Оказалось, что не последняя версия Диафана стоит.

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