[miniShop2] Кнопка печати заказа из бек-энда


Часто приходится реализовывать максимально простую распечатку заказа из бек-энда для админов. Делается это в 3 простых и лёгких шага!

Дисклеймер


Сразу оговорюсь, что данное решение никак не может конкурировать с компонентом orderPrint, ибо последний куда более функционален:
— множество шаблонов документов,
— генерация PDF-документа,
— использование компонента с фронта,
— поддержка miniShop2, Shopkeeper,
— и т.д.

Решение


Как говорил выше, данное решение состоит из 3 шагов, а если быть точнее, из PHP файла, плагина и чанка.

Шаг 1

Создаём файл /assets/custom/ms2print.php с таким содержимым:
<?php
/** @var modX $modx */
if (!isset($modx)) {
    define('MODX_API_MODE', true);
    require_once dirname(dirname(dirname(__FILE__))) . '/index.php';
    $modx->getService('error', 'error.modError');
    $modx->getRequest();
    $modx->setLogLevel(modX::LOG_LEVEL_ERROR);
    $modx->setLogTarget('FILE');
    $modx->error->message = null;
    $modx->lexicon->load('default');
}
$ctx = !empty($_REQUEST['ctx']) ? $_REQUEST['ctx'] : $modx->context->get('key');
if ($ctx != $modx->context->get('key')) {
    $modx->switchContext($ctx);
}
$pdoTools = $modx->getService('pdoTools');

$order_id = (int)$_REQUEST['order'];
if (empty($order_id) || !$order = $modx->getObject('msOrder', ['id' => $order_id])) {
    $response = 'Заказ не найден!';
} elseif ($order->user_id != $modx->user->id && !$modx->user->hasSessionContext('mgr')) {
    $response = 'У вас нет прав на просмотр заказа!';
} else {
    $params = [
        'order' => $order->toArray(),
        'user' => !empty($order->UserProfile) ? $order->UserProfile->toArray() : [],
        'address' => !empty($order->Address) ? $order->Address->toArray() : [],
        'delivery' => !empty($order->Delivery) ? $order->Delivery->toArray() : [],
        'payment' => !empty($order->Payment) ? $order->Payment->toArray() : [],
        'products' => [],
    ];
    /** @var msOrderProduct $product */
    foreach ($order->Products as $product) {
        $params['products'][] = array_merge($product->toArray(), [
            'article' => $product->Product->Data->get('article'),
        ]);
    }
    $response = $pdoTools->getChunk('tpl.msGetOrder.print', $params);
}
@session_write_close();
exit($response);
К этому файлу мы будем обращаться для получения нашего заказа на печать.

Шаг 2

Создаём плагин на событие msOnManagerCustomCssJs с кодом:
<?php
$controller->addHtml("<script>
    Ext.ComponentMgr.onAvailable('minishop2-window-order-update', function () {
        var w = this;
        var order_id = w.record['id'] || 0;
        w['buttonAlign'] = 'left';
        w['buttons'].unshift({
            id: w['id'] + '-button-check',
            text: 'Распечатать',
            cls: 'primary-button',
            handler: function (btn) {
                window.open('/assets/custom/ms2print.php?order=' + order_id, '_blank').focus();
            },
            scope: w,
        }, '->');
    });
</script>");
Здесь мы внедряем нашу кнопку «Распечатать» в модальное окно заказа.

Шаг 3

Создаём чанк tpl.msGetOrder.print и выводим в нём все возможные переменные, чтобы понимать, с чем работать при создании шаблона на печать:
{$order | print}
{$user | print}
{$address | print}
{$delivery | print}
{$payment | print}
{$products | print}

Итого


Конечно, пытливый ум доработает это решение и для работы на фронте, но в любом случае оно будет уступать вышеупомянутому компоненту.
Павел Гвоздь
09 января 2019, 21:54
modx.pro
29
2 727
+24
Поблагодарить автора Отправить деньги

Комментарии: 4

Игорь
31 мая 2021, 19:10
0
Здравствуйте.
Полезное решение.
Не могу только понять, а как в плагин на событие msOnManagerCustomCssJs добавить код для вывода 2-х кнопок… т.е. что бы получилось примерно следующее: кнопки «Распечатать по форме1» и «Распечатать по форме2»?
    Игорь
    31 мая 2021, 21:53
    +1
    вроде сообразил
    <?php
    $controller->addHtml("<script>
        Ext.ComponentMgr.onAvailable('minishop2-window-order-update', function () {
            var w = this;
            var order_id = w.record['id'] || 0;
            w['buttonAlign'] = 'left';
            w['buttons'].unshift({
                id: w['id'] + '-button-check',
                text: 'Распечатать',
                cls: 'primary-button',
                handler: function (btn) {
                    window.open('/assets/custom/ms2print.php?order=' + order_id, '_blank').focus();
                },
                scope: w,
            },{
                id: w['id'] + '-button-check' + '2',
                text: 'Распечатать2',
                cls: 'primary-button',
                handler: function (btn) {
                    window.open('/assets/custom/ms2print2.php?order=' + order_id, '_blank').focus();
                },
                scope: w,
            },
            
            
            '->');
        });
    </script>");
      Павел Гвоздь
      01 июня 2021, 07:31
      0
      Только зачем делать 2 php файла, когда правильнее через 1 всё сделать? Готов поспорить, что 80% кода в этих файлах дублируется.
        Игорь
        01 июня 2021, 09:22
        0
        Полностью согласен. Там получается дублируется всё, кроме названия чанка с шаблоном формы… Только я не знаю как это реализовать.
    Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
    4