Кастомный экспорт заказов MiniShop2
Всем привет! Давно хотел поделиться данным кейсом, который «валяется на полке».
Спросите, а зачем? Есть же готовые компоненты… Ну, вы же знаете, я не сторонник платных решений, да и зачем покупать «самолёт», когда нужна «телега».
Накидал несколько сниппетов, которыми можно вывести все заказы сайта…
Сразу напишу, решение сырое, требует доработки, но уже сейчас может помочь страждущим сделать экспорт и при этом, если руки позволяют, доработать его индивидуально под проект как надо.
Сниппет getOrders получает все заказы сайта:
Чанк tpl.Order:
Сниппет msOrdersProducts — получает товары заказа:
Чанк tpl.order_products_row:
Сниппет getOrderAddress — получает данные о покупателе:
Чанк tpl.OrderAddress:
Данная статья, по большей части является пока что заметкой, где время от времени я буду дополнять информацию и дорабатывать код. Ну а пока что, это хоть какое то решение, которое позволит достичь поставленных задач от заказчиков по вопросу выгрузки заказов…
P.S. Что бы скачивался CSV файл, создаём новый тип содержимого с таким форматом, создаём ресурс без шаблона и с этим типом содержимого, ну и вызываем getOrders в content
P.P.S. Если на выводе получаете пустой файл, значит в заказах есть смайлы и ваша БД не utf8mb4, лучше поправить…
Спросите, а зачем? Есть же готовые компоненты… Ну, вы же знаете, я не сторонник платных решений, да и зачем покупать «самолёт», когда нужна «телега».
Накидал несколько сниппетов, которыми можно вывести все заказы сайта…
Сразу напишу, решение сырое, требует доработки, но уже сейчас может помочь страждущим сделать экспорт и при этом, если руки позволяют, доработать его индивидуально под проект как надо.
Сниппет getOrders получает все заказы сайта:
<?php
$tpl = $modx->getOption('tpl',$scriptProperties,'tpl.Order');
$q = $modx->newQuery('msOrder');
$results = $modx-> getIterator('msOrder', $q);
foreach ($results as $result) {
$resultArray = $result->toArray();
$output .= $modx->getChunk($tpl,$resultArray)."\n";
}
$output= "ID заказа;Номер заказа;Статус;Способ доставки;Способ оплаты;Дата заказа;Стоимость заказа;Товары;Получатель;Телефон;Комментарий\n".$output;
$user_agent = getenv("HTTP_USER_AGENT");
if(strpos($user_agent, "Win") !== FALSE) {
$output = iconv("UTF-8", "CP1251", $output);
} elseif(strpos($user_agent, "Mac") !== FALSE) {
$output = iconv("UTF-8", "macCyrillic", $output);
}
return $output;
Чанк tpl.Order:
[[+id]];[[+num]];[[+status:is=`1`:then=`Новый`]][[+status:is=`2`:then=`Оплачен`]][[+status:is=`3`:then=`Отправлен`]][[+status:is=`4`:then=`Отменён`]];[[+delivery:is=`1`:then=`Самовывоз`]][[+delivery:is=`2`:then=`Купить в 1 клик`]];[[+payment:is=`1`:then=`Оплата наличными`]];[[+createdon:strtotime:RusDate=`%j %month %Yг. в %H:%m`]];[[+cost]];[[!msOrdersProducts?order=`[[+id]]`&tpl=`tpl.order_products_row`]];[[!getOrderAddress?userid=`[[+user_id]]`&tpl=`tpl.OrderAddress`]]
Сниппет msOrdersProducts — получает товары заказа:
<?php
// выводит товары заказа.
$tpl = $modx->getOption('tpl',$scriptProperties,'tpl.order_products_row'); // если товар найден
$tpl_empty = $modx->getOption('tpl',$scriptProperties,'tpl.order_row_empty'); // если товар не найден
// ищем товар по id заказа
$q = $modx->prepare("SELECT * FROM ".$modx->getOption('table_prefix')."ms2_order_products WHERE order_id=".$order);
$q->execute();
$results = $q->fetchAll(PDO::FETCH_ASSOC);
$output;
// перебором либо выводим нужный заказ, либо оповещаем что его уже нет
foreach ($results as $result) {
$res = $modx->getObject('modResource', array('pagetitle'=>$result['name']));
if ($res) {
$resArray = $res->toArray();
$output .= $modx->getChunk($tpl,$resArray);
} else {
$prodName = $modx->setPlaceholder('name', $result['name']);
$output .= $modx->getChunk($tpl_empty);
}
}
return $output;
Чанк tpl.order_products_row:
[[+pagetitle]] |
Сниппет getOrderAddress — получает данные о покупателе:
<?php
$userID = $modx->getOption('userid', $scriptProperties);
$tpl = $modx->getOption('tpl', $scriptProperties, 'tpl.OrderAddress');
$output = '';
$q = $modx->prepare("SELECT * FROM ".$modx->getOption('table_prefix')."ms2_order_addresses WHERE user_id=".$userID);
$q->execute();
$results = $q->fetchAll(PDO::FETCH_ASSOC);
foreach ($results as $result) {
$output = $modx->getChunk($tpl, $result);
}
return $output;
Чанк tpl.OrderAddress:
[[+receiver]];[[+phone]];[[+comment:strip]]
Данная статья, по большей части является пока что заметкой, где время от времени я буду дополнять информацию и дорабатывать код. Ну а пока что, это хоть какое то решение, которое позволит достичь поставленных задач от заказчиков по вопросу выгрузки заказов…
P.S. Что бы скачивался CSV файл, создаём новый тип содержимого с таким форматом, создаём ресурс без шаблона и с этим типом содержимого, ну и вызываем getOrders в content
P.P.S. Если на выводе получаете пустой файл, значит в заказах есть смайлы и ваша БД не utf8mb4, лучше поправить…
Комментарии: 1
Позволю себе несколько замечаний.
1. Если заказов много — такой сниппет не сможет выполнить свою работу. Лучше вешать задачу на планировщик
2. Использование getCollection. Это не лучший вариант. Этот метод загружает в ОЗУ сразу всю коллекцию объектов заказа, что не лучшим образом отражается на производительности и ресурсах. Лучше использовать итератор через метод getIterator. Такой метод загружает в память только список объектов, при переборе по очереди достает из базы информацию. Этот метод существенно быстрее работает и кушает меньше ресурсов. К слову итератор это не изобретение MODX. Это паттерн PHP. Да и не только PHP — он почти во всех языках используется.
3. Это что за странная конструкция такая?
4. Использовать getChunk я бы рекомендовал так:
5. Не ошибка. Даже не предупреждение. Скорее глаз режет.
Использование прямых SQL конструкций.
Мы же в MODX работаем. Желательно использовать конструктор запроса. newQuery — его не просто так придумали. Помимо универсальности запроса, не привязанного к конкретной СУБД — это еще и выглядит красиво, аккуратно, профессионально. Сразу видно, что человек знает свое рабочее место.
1. Если заказов много — такой сниппет не сможет выполнить свою работу. Лучше вешать задачу на планировщик
2. Использование getCollection. Это не лучший вариант. Этот метод загружает в ОЗУ сразу всю коллекцию объектов заказа, что не лучшим образом отражается на производительности и ресурсах. Лучше использовать итератор через метод getIterator. Такой метод загружает в память только список объектов, при переборе по очереди достает из базы информацию. Этот метод существенно быстрее работает и кушает меньше ресурсов. К слову итератор это не изобретение MODX. Это паттерн PHP. Да и не только PHP — он почти во всех языках используется.
3. Это что за странная конструкция такая?
$modx->getOption('table_prefix')."ms2_order_addresses
Зачем так? Почему? Есть же гораздо более корректный метод обращения к таблице$modx->getTableName('msOrderAddress');
Так-то люди вполне могут переименовать таблицу, просто указав нужное имя в модельке. И приведенный метод гарантировано выдаст нужную таблицу. 4. Использовать getChunk я бы рекомендовал так:
$pdoTools = $modx->getService('pdoTools');
$pdoTools->getChunk('name', $params);
Этот вариант, в отличие от $modx->getChunk обработает конструкции и MODX и феном.5. Не ошибка. Даже не предупреждение. Скорее глаз режет.
Использование прямых SQL конструкций.
Мы же в MODX работаем. Желательно использовать конструктор запроса. newQuery — его не просто так придумали. Помимо универсальности запроса, не привязанного к конкретной СУБД — это еще и выглядит красиво, аккуратно, профессионально. Сразу видно, что человек знает свое рабочее место.
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.