Pull to refresh

Разбираемся с REST API Prestashop

Reading time 5 min
Views 26K

На днях была получена задача сделать импорт товаров в Prestashop. С данной CMS дела ранее не имел, а посему стал искать привычные API для добавления/изменения товаров. Каково же было мое удивление когда я их не нашел, ну или не сильно искал. Решение описанное здесь не подходило однозначно, так как требовалась работа с комбинациями товара, и кучей других параметров. Замечу что вариант изменения файлов ядра или создания кучи файлов переопределяющих системные классы были отброшены сразу. И тут я обратил внимание на REST API, оно как я понял появилось недавно, и информации по нему мало, но это показалось мне лучшим вариантом. Замечу что в данном материале я не ставлю цель повторить описанное в документации, а лишь упорядочить информацию и дополнить некоторые моменты.

Активация REST интерфейса в магазине

Активация довольно подробно описана на сайте с документацией, поэтому особенно задерживаться не будем на этом моменте. Главное не забыть активировать ЧПУ, иначе ничего работать не будет. После активации проверить работу API можно по ссылке yoursite.ru/api/.

Основная концепция

Общение с магазином происходит целиком и полностью на языке XML, исключая случай загрузки картинки, который мы рассмотрим ниже. Система API построена по принципу CRUD (Create, Read, Update, Delete) что в переводе в язык запросов HTTP дает нам следующее:

Большая часть общения с магазином будет происходить через класс PSWebServiceLibrary написанный одним из членов сообщества. Скачать его можно по ссылке, или найти на страницах документации.
Список всех возможных методов, и пояснение типов переменных лежит тут doc.prestashop.com, по сути это самый необходимый документ из всей документации, однако пройдя по ссылке yoursite.ru/api/ и введя в качестве логина созданный ранее ключ доступа можно походить ссылкам указанных в атрибуте «xlink:href», и наглядно просмотреть структуру API.

Создание элементов

Для создания любого элемента структуры магазина (далее возьмем для примера товар) нам сначала необходимо получить заготовку XML документа. Для этого к ссылке списка товаров необходимо дописать ?schema=synopsis. Ниже приведен пример создания товара через класс PSWebServiceLibrary:
//Создаем обьект класса указав url магазина и созданный секретный ключ из админки
$webService = new PrestaShopWebservice($shop_url, $secret_key, $debug);
//Обратите внимание, метод products без ?schema=synopsis выводит список товаров
$xml_product = $webService->get(array('resource' => 'products?schema=synopsis'));
//После получения заготовки заполняем поля XML
$resources_product = $new_product->children()->children();
$resources_product->name->language[0][0] =  "Test product";
$resources_product->link_rewrite->language[0][0] = "tstproduct";
$resources_product->active = 1;
$resources_product->available_for_order = 1;
$resources_product->show_price = 1;
$resources_product->out_of_stock = 2;//Если товара нет на складе, действие по умолчанию
//Если не указать категорию, товар не будет виден в админке, это важно
$resources_product->associations->categories->category[0]->id = 1;
//Отправляем заполненную заготовку на добавление
$created_product = $webService->add(array('resource' => 'products', 'postXml' => $new_product->asXML()));

В переменной $created_product у нас оказывается XML карточка товара в случае успеха, или карточка с описанием ошибки. Это утверждение верно для создания любых элементов кроме картинок.
Если просмотреть дебаг вывод то можно увидеть что класс лезет за заготовкой по адресу yoursite.ru/api/products/?schema=synopsis методом GET а добавляет товар методом POST по адресу yoursite.ru/api/products/.

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

К сожалению для загрузки картинок в классе PSWebServiceLibrary нет готового метода, поэтому пришлось приколхозить собственный. По хорошему его надо бы внести в вышеупомянутый класс, но на это не было ни сил ни времени. Поэтому загружать картинки мы будем сами. Также URL загрузки картинок не просто /api/images/ как например в случае с товарами (/api/products/) а, если это картинка товара, /api/images/products/$product_id/. Эта особенность была выявлена опытным путем.
Код загрузки картинки для товара:
$ch = curl_init(); 
curl_setopt($ch, CURLOPT_URL, $shop_url."api/images/products/".$product_id."/"); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
curl_setopt($ch, CURLOPT_USERPWD, $secret_key.":");
curl_setopt($ch, CURLOPT_TIMEOUT, 60); 
curl_setopt($ch, CURLOPT_POSTFIELDS, array('image' => '@my_image.png'));
$response= curl_exec($ch); 

В переменной $response у нас в итоге окажется или картинка которую мы загружали, или XML карточка ошибки. Здесь необходимо сделать проверку на ошибку загрузки путем проверки кода ответа сервера, или текста ответа.
Необходимо заметить что невозможно получить id загруженной картинки, для этого я сразу же после загрузки картинки делал выборку всех картинок указанного товара (/api/images/products/$product_id/) и та у которой наибольший id, и есть наша.

Редактирование элементов

Редактирование происходит практически так же как и создание, за исключением того что вначале мы получаем не заготовку карточки товара, а сам товар. После модификации полей мы просто меняем метод класса PSWebServiceLibrary с add на edit с такими же параметрами.
$product = $webService->get(array('resource' => 'products', 'id' => $product_id));
$mod_product = $webService->edit(array('resource' => 'products', 'id' => $product_id, 'putXml' => $product->asXML()));


Удаление элементов

Удаление происходит по синтаксису аналогичному методу get но только с помощью метода delete
$webService->delete(array('resource' => 'products', 'id' => $product_id));

В ответ ничего возвращено не будет.

Отлов ошибок

Если мы используем класс PSWebServiceLibrary то каждый вызов его методов необходимо оборачивать в блок try...catch так как при ошибки сервера он сгенерирует Fatal error типа PrestaShopWebserviceException. Подробнее ниже:
try {
  //Создаем обьект класса указав url магазина и созданный секретный ключ из админки
  $webService = new PrestaShopWebservice($shop_url, $secret_key, $debug);
  //Получаем список товаров
  $products = $webService->get( array( 'resource' => 'products' ) );
} catch ( PrestaShopWebserviceException $ex ) {
  $trace = $ex->getTrace(); //Получаем информацию об ошибке
  $errorCode = $trace[ 0 ][ 'args' ][ 0 ]; //Получаем код ошибки
  if ( $errorCode == 401 ) //Выводим сообщение на экран
    echo 'Bad auth key';
  else
    echo 'Other error : <br />' . $ex->getMessage();
}


Фильтры, сортировка, лимиты

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

Подводные камни

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

P.S.: Если у кого то остались вопросы, с радостью отвечу и дополню материал.
Tags:
Hubs:
+3
Comments 0
Comments Leave a comment

Articles