+7 495 008 8452
  • Загрузка
Выберите ваш цвет

Создание собственных интеграций на базе модуля импорта

Есть вопросы, которые вы не смогли решить по нашим публикациям самостоятельно? Ждем ваше обращение в нашей службе техподдержки!

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

В данной статье размещён пример пользовательского класса, реализующего импорт данных из сервиса ads-api.ru. В нём отражены основные программные элементы, необходимые для подключения класса к функционалу модуля импорта.

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

<?php

/**
 * Пример дополнительной интеграции для модуля "Универсальный импорт" (acrit.import)
 * Помещается в директорию /local (или в любую поддиректорию данной директории)
 * Подключается в файле /bitrix/init.php или /local/init.php
 * Пример подключения:
 * include_once($_SERVER['DOCUMENT_ROOT'].'/local/lib/import_example.php') ;
 * ---
 * Интеграция с сервисом ads-api.ru
 */

namespace Acrit\Import;

\Bitrix\Main\Loader::includeModule('acrit.import');

class ImportRestAdsapiru extends Import
{
    private $source_login;
    private $source_token;

	/**
	 * Заполнение полей класса авторизационными данными из профиля
	 * (вспомогательная функция данного класса)
	 */
    public function fillAuthData() {
        if (!$this->arProfile['SOURCE_LOGIN'] || !$this->arProfile['SOURCE_KEY']) {
            throw new \Exception('Не указаны данные источника');
        }
        $this->source_login = $this->arProfile['SOURCE_LOGIN'];
        $this->source_token = $this->arProfile['SOURCE_KEY'];
    }

	/**
	 * Получение субпараметров ads-api.ru
	 * (обязательная функция модуля)
	 */
    public function fieldsPreParams() {
        $arFieldsParams = array(
            'title' => 'Параметры выборки'
        );
        $arFieldsParams['fields']['section'] = array(
            'DB_FIELD' => 'PARAM_1',
            'TYPE' => 'number',
            'DEFAULT' => '0',
            'LABEL' => 'Категория из ads-api.ru',
            'PLACEHOLDER' => '',
            'HINT' => '',
        );
        $arFieldsParams['fields']['limit'] = array(
            'DB_FIELD' => 'PARAM_2',
            'TYPE' => 'number',
            'DEFAULT' => '0',
            'LABEL' => 'Количество загружаемых позиций',
            'PLACEHOLDER' => '',
            'HINT' => '',
        );
        return $arFieldsParams;
    }

	/**
	 *
	 * (вспомогательная функция данного класса)
	 */
    protected function fieldsGetParams($obParams, $arFieldsPath, &$arSourceFields) {
        $l = count($arFieldsPath);
        foreach ($obParams as $obParam) {
            $arFieldsPath[$l] = array(
                'key' => $obParam->param,
                'title' => $obParam->title
            );
            // Добавляем значение в массив полей профиля
            $arTitles = array();
            foreach ($arFieldsPath as $arLevel) {
                $arTitles[] = $arLevel['title'];
            }
            $k = $arFieldsPath[$l]['key'];
            $arSourceFields[$k] = array(
                'ID' => $k,
                'NAME' => implode('. ', $arTitles),
                'EXAMPLE' => '',
            );
            // Обходим все субпараметры
            foreach ($obParam->values as $obValue) {
                if ($obValue->subparams) {
                    $this->fieldsGetParams($obValue->subparams, $arFieldsPath, $arSourceFields);
                }
            }
        }
        return $arFieldsPath;
    }

	/**
	 * Получение списка полей для второго шага в профиле импорта
	 * (обязательная функция модуля)
	 */
    public function fields() {
        $arSourceFields = array();
        $this->fillAuthData();
        $category_id = (int)$this->arProfile['SOURCE_PARAM_1'];
        if ($category_id) {
            // Список основных параметров
            $arAdsFields = array(
                "id" => "Идентификатор записи",
                "url" => "Url объявления на сайте-источнике",
                "title" => "Заголовок",
                "price" => "Цена",
                "time" => "Дата и время добавления объявления/обновления в систему. Время московское",
                "phone" => "Телефон",
                "phone_operator" => "Название мобильного оператора",
                "person" => "Персона для контактов, автор объявления",
                "contactname" => "Контактное лицо",
                "person_type" => "Тип персоны для контактов",
                "person_type_id" => "ID типа персоны для контактов",
                "city" => "Регион и Город вместе",
                "metro" => "Метро или район",
                "address" => "Адрес",
                "description" => "Описание объявления",
                "nedvigimost_type" => "Тип недвижимости: Продам, Сдам, Куплю или Сниму",
                "nedvigimost_type_id" => "ID типа недвижимости: 1 - Продам, 2 - Сдам, 3 - Куплю или 4 - Сниму",
                "avitoid" => "ID объявления на сайте-источнике",
                "source" => "Сайт-источник",
                "source_id" => "ID cайта-источника в нашей системе",
                "images" => "Картинки",
                "params" => "Дополнительные параметры объявления",
                "cat1_id" => "ID категории первого уровня",
                "cat2_id" => "ID категории второго уровня",
                "cat1" => "Название категории первого уровня",
                "cat2" => "Название категории второго уровня",
                "coords" => "Объект, содержащий координаты объявления, поля lat и lng",
                "region" => "Только название региона",
                "city1" => "Только название города",
                "param_xxx" => "Дополнительный параметр с кодом xxx",
                "count_ads_same_phone" => "Количество объявлений с тем же номером",
                "phone_protected" => "Защищен ли телефон",
            );
            foreach ($arAdsFields as $k => $name) {
                $arSourceFields[$k] = array(
                    'ID' => $k,
                    'NAME' => $name,
                    'EXAMPLE' => '',
                );
            }
            // Получаем дополнительные параметры
            $str = file_get_contents($this->arProfile['SOURCE'] . "/main/apigetparams?user=" . urlencode($this->source_login) .
                "&token=" . urlencode($this->source_token) .
                "&category_id=" . $category_id);
            $obResp = json_decode($str);
            $arFieldsPath = array();
            $this->fieldsGetParams($obResp->data, $arFieldsPath, $arSourceFields);
        }
        return $arSourceFields;
    }

	/**
	 * Подсчёт общего количества импортируемых элементов
	 * (обязательная функция модуля)
	 */
    public function count() {
        $count = 0;
        $load_limit = (int)$this->arProfile['SOURCE_PARAM_2'];
        if ($load_limit) {
            $count = $load_limit;
        }
        else {
            $this->fillAuthData();
            $category_id = (int)$this->arProfile['SOURCE_PARAM_1'];
            if ($category_id) {
                $query = $this->arProfile['SOURCE'] . "/main/api?user=" . urlencode($this->source_login) .
                    "&token=" . urlencode($this->source_token) .
                    "&category_id=" . $category_id;
                $str = file_get_contents($query);
                $obResp = json_decode($str);
                if ($obResp) {
                    $count = count($obResp->data);
                }
                sleep(5);
            }
        }
        return $count;
    }

	/**
	 * Импорт очередной порции товаров (один шаг импорта)
	 * (обязательная функция модуля)
	 * $limit - количество импортируемых за данный шаг элементов
	 * $next_item - элемент, с которого должен начаться импорт
	 */
    public function import($type=self::STEP_NO, $limit=0, $next_item=0) {
        $load_limit = (int)$this->arProfile['SOURCE_PARAM_2'];
        if ($load_limit > 50) {
            $limit = 50;
        }
        else {
            $limit = $load_limit;
        }
        \CModule::IncludeModule('iblock');
        $this->fillAuthData();
        $category_id = (int)$this->arProfile['SOURCE_PARAM_1'];
        if ($category_id) {
            $query = $this->arProfile['SOURCE'] . "/main/api?user=" . urlencode($this->source_login) .
                "&token=" . urlencode($this->source_token) .
                "&category_id=" . $category_id;
            if ($next_item) {
                $query .= "&startid=" . $next_item;
            }
            if ($type == self::STEP_BY_COUNT && $limit) {
                $query .= "&limit=" . ($limit + 1); // Последний элемент получаем только для стартового ID следующей итерации
            }
            $str = file_get_contents($query);
            $obResp = json_decode($str);
            $i = 0;
            if ($obResp->error) {
                throw new \Exception($obResp->error.' [Code '.$obResp->code.']');
            }
            if (!empty($obResp->data)) {
                foreach ($obResp->data as $obItem) {
                    $arRow = (array)$obItem;
                    $arRow['coords'] = (array)$arRow['coords'];
                    foreach ($arRow['images'] as $k => $obImage) {
                        $arRow['images'][$k] = $obImage->imgurl;
                    }
                    $arRow['params'] = (array)$arRow['params'];
                    $next_item = $arRow['id'];
                    if ($type == self::STEP_BY_COUNT && $limit && $i >= $limit) {
                        break;
                    }
                    // Отправляем данные позиции в инфоблок
                    $this->saveIBData($arRow, $next_item);
                    $i++;
                }
            }
            sleep(5);
        }
        return $next_item;
    }

	/**
	 * Добавление интеграции в меню модуля (на первом шаге настройки профиля)
	 * (обязательная функция модуля)
	 */
    static public function OnGetImportTypesHandler($arTypes) {
        $arTypes['rest'] = array(
            'name' => 'REST API ads-api.ru',
            'source_types' => array('oauth'),
            'file_ext' => 'rest_api',
            'class' => 'ImportRestAdsapiru',
        );
        return $arTypes;
    }
}



Назад в раздел



Часто задаваемые вопросы по модулям экспорта

Видео плейлист по настройке модулей экспорта