Уроки

Экспорт заказов из MiniShop2 в таблицу Excel формат CSV.

Привет всем интересующимся в раздел «Для разработчиков» писать не могу рейтинг низкий, поэтому сюда. Не нашел готового простого решения, есть заметки «Кастомный экспорт заказов MiniShop2», но там нужно создавай два сниппета, три чанка, один ресурс, зачем так много если можно обойтись одним сниппетом и одним ресурсом, лень двигатель прогресса + не люблю много снипетов, чанков, шаблонов и бла бла бла. Да есть платные решения, но это для новичков больше и зачем платить больше если можно сделать самому. История как обычно нафиг не нужно пока клиент не попросил выгружать статистику по заказам в таблицу Эксель, чтобы ему было удобно ее фильтровать и вообще работать с данными так удобнее и привычнее. Сразу скажу часть информацию взял в инете у других авторов, так что если кто-то узнал свой код не обижайтесь, мне нужно было решение я его сделал теперь делюсь своими наработками так сказать.

Создаем сниппет например getOrders
<?php
// Сниппет getOrders - выгрузка заказов miniShop2 в CSV

// Устанавливаем заголовки для скачивания CSV файла
header('Content-type: text/csv; charset=UTF-8');
header('Content-Disposition: attachment; filename="orders_export_' . date('Y-m-d_H-i') . '.csv"');

// Создаем итератор для заказов (экономнее памяти, чем getCollection)
$c = $modx->newQuery('msOrder');
$c->sortby('createdon', 'DESC'); // Сортировка по дате создания
$iterator = $modx->getIterator('msOrder', $c);

// Открываем поток вывода
$output = fopen('php://output', 'w');
// Добавляем BOM для корректного отображения кириллицы в Excel
fwrite($output, "\xEF\xBB\xBF");

// Заголовки столбцов CSV
fputcsv($output, [
    'ID заказа',
    'Номер заказа', 
    'Статус',
    'Стоимость',
    'Способ доставки',
    'Дата создания',
    'Покупатель',
    'Телефон',
    //'Email',
    'Город',
    'Адрес доставки',
    //'Комментарий'
], ';');

// Получаем все статусы заказов для преобразования ID в названия
$statuses = [];
$statusQuery = $modx->newQuery('msOrderStatus');
$statusCollection = $modx->getCollection('msOrderStatus', $statusQuery);
foreach ($statusCollection as $status) {
    $statusData = $status->toArray();
    $statuses[$statusData['id']] = $statusData['name'];
}

// Получаем все способы доставки для преобразования ID в названия
$deliveries = [];
$deliveryQuery = $modx->newQuery('msDelivery');
$deliveryCollection = $modx->getCollection('msDelivery', $deliveryQuery);
foreach ($deliveryCollection as $delivery) {
    $deliveryData = $delivery->toArray();
    $deliveries[$deliveryData['id']] = $deliveryData['name'];
}

// Обходим каждый заказ
foreach ($iterator as $order) {
    $orderArray = $order->toArray();
    
    // Получаем адрес заказа
    $addressData = [
        'receiver' => '',
        'phone' => '',
        //'email' => '',
        'city' => '',
        'street' => '',
        'building' => '',
        'room' => '',
        //'comment' => ''
    ];
    
    // Ищем адрес по order_id (для новых версий miniShop2)
    $address = $modx->getObject('msOrderAddress', ['order_id' => $orderArray['id']]);
    if (!$address) {
        // Если не нашли по order_id, ищем по user_id (для старых версий)
        $address = $modx->getObject('msOrderAddress', ['user_id' => $orderArray['user_id']]);
    }
    
    if ($address) {
        $addressArray = $address->toArray();
        $addressData = array_merge($addressData, $addressArray);
    }
    
    // Преобразуем ID статуса в название
    $statusName = isset($statuses[$orderArray['status']]) ? $statuses[$orderArray['status']] : 'Неизвестно';
    
    // Преобразуем ID способа доставки в название
    $deliveryName = isset($deliveries[$orderArray['delivery']]) ? $deliveries[$orderArray['delivery']] : 'Неизвестно';
    
    // Формируем полный адрес
    $fullAddress = '';
    if (!empty($addressData['street'])) {
        $fullAddress = $addressData['street'];
        if (!empty($addressData['building'])) {
            $fullAddress .= ', д.' . $addressData['building'];
        }
        if (!empty($addressData['room'])) {
            $fullAddress .= ', кв.' . $addressData['room'];
        }
    }
    
    // Формируем строку с данными
    $row = [
        $orderArray['id'],
        $orderArray['num'],
        $statusName,
        $orderArray['cost'],
        $deliveryName, // Способ доставки
        $orderArray['createdon'],
        $addressData['receiver'],
        $addressData['phone'], // Телефон отдельным столбцом
        //$addressData['email'],
        $addressData['city'],
        $fullAddress,
        //$addressData['comment']
    ];
    
    fputcsv($output, $row, ';');
}

fclose($output);
@session_write_close();
exit();
Далее создаем ресурс и внутри этого ресурса просто вызываем данный сниппет
[[!getOrders]]
При открытие ресурса на фронте будет предложено скачать файл типа orders_export_2025-10-2213-34.csv дата и время подставляется автоматически. Далее можно открывать в любом редакторе CSV файлов.
З.Ы. Если кто сделает на кнопку «Cкачать» в админке minishop2 буду очень благодарен. Дорабатывайте, оптимизируйте самое главное делайте лучше чем есть. Всем спасибо за внимание.
Вячеслав
Вчера в 14:08
modx.pro
50
0

Плашка о использовании cookie файлов на сайте

Всем привет! Учитывая актуальность вопроса, решил выложить код всплывающей плашки…
Как уже многие знают, РКН всех поставил на уши по поводу обработки персональных данных посетителей наших сайтов, поэтому добавляем плашку, что бы наши заказчики спали спокойно и не боялись штрафов)


Денис Усманов
29 мая 2025, 08:19
modx.pro
1
3 323
+6

Как организовать вывод отзывов с тегами в PageBlocks

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

Основная идея

— Создаем две отдельные таблицы: Теги и Отзывы.
— Каждому отзыву можно привязать один или несколько тегов.
— В настройках блока указываем, какие теги использовать для фильтрации отзывов.
— На фронтенде выводим только те отзывы, у которых есть выбранные теги.

Aleksandr Huz
29 апреля 2025, 16:50
modx.pro
1
1 423
+6

Генерация карты сайта в PageBlocks

Карта сайта (sitemap.xml) помогает поисковым системам быстро находить все страницы вашего сайта. Если страниц очень много, карты можно разбивать на несколько частей: новости, товары, статьи и т.д., а в основной карте давать ссылки на каждую из них. Такой подход облегчает индексирование и ускоряет появление новых страниц в поиске.

Aleksandr Huz
29 апреля 2025, 16:39
modx.pro
1 329
+5

pbStudio: Подключаем мультиязычность в PageBlocks

Введение


PageBlocks поддерживает мультиязычность без контекстов. Достаточно указать языки, задать поля для перевода и, при необходимости, подключить автоперевод — остальное сделает PageBlocks.

Навигация по урокам:
Aleksandr Huz
20 апреля 2025, 15:25
modx.pro
1
1 769
+6

pbStudio: Портфолио, Услуги и Контакты



Продолжаем разработку нашего сайта. В этом уроке мы завершим работу над всеми страницами.

Aleksandr Huz
19 апреля 2025, 11:05
modx.pro
1 354
+6

pbStudio: Чистый контроллер или FetchIt — два способа обработки форм



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

Aleksandr Huz
18 апреля 2025, 08:42
modx.pro
1
1 223
+6

pbStudio: Меню и страница «О нас»



Aleksandr Huz
17 апреля 2025, 10:27
modx.pro
1 101
+8

pbStudio: Создаём сайт с PageBlocks – настройка и главная страница

В этом уроке мы установим MODX, настроим необходимые компоненты и системные параметры для работы с PageBlocks. Затем создадим главную страницу и добавим на неё два блока. Это часть серии уроков, в которых мы пошагово создадим полноценный сайт для студии с использованием PageBlocks.



Aleksandr Huz
16 апреля 2025, 12:45
modx.pro
3
4 188
+11

PageBlocks. Выводим SEO-карточки

Задача: Вывести в ресурсе SEO-карточки из других ресурсов.
Пример:

Aleksandr Huz
14 февраля 2025, 11:31
modx.pro
3
1 878
+12