Женим mFilter2 и msListOrders

Выводим заказы miniShop2, фильтруем с помощью mFilter2.


Необходимые компоненты
msListOrders
mSearch2
— протестировать на демо сайте
Установка
— Подключите наш репозиторий
— Установите msListOrders — это компонент для вывода заказов minishop
— Установите mSearch2 — это компонент для поиска и фильтрация данных

Для тестирования можно использовать наш хостинг, на нём эти дополнения можно выбрать прямо при создании сайта.

Вывод заказов
{'!mSearchForm'|snippet:[
'autocomplete' => 0
]}

{set $ids = ' '}
{if $.request.query}
    {set $ids = '!pdoResources'|snippet:[
    'class' => 'msOrder',
    'sortby' => 'id',
    'returnIds' => 1,
    'where' => [
        'num:LIKE' => '%'~$.request.query~'%'
    ]
    ]}
{/if}

{'!mFilter2'|snippet:[
'class' => 'msOrder',
'element' => 'msListOrdersFilterWrapper',
'resources' => $ids,
'sortAliases' => [
'order' => 'msOrder',
'user' => 'modUserProfile'
],
'minQuery' => 1,
'limit' => 5,
'actions' => 'view',
'sort' => 'order|createdon:desc,order|id:desc',
'showLog' => 0,
'filters' => '
    order|status:status,
    order|delivery:delivery,
    order|payment:payment,
    orderuser|city
',

'tplOuter' => 'tpl.mFilter2.orders.outer',
'tplFilter.outer.order|status' => 'tpl.mFilter2.filter.select',
'tplFilter.row.order|status' => 'tpl.mFilter2.filter.option',
'tplFilter.outer.order|delivery' => 'tpl.mFilter2.filter.select',
'tplFilter.row.order|delivery' => 'tpl.mFilter2.filter.option',
'tplFilter.outer.order|payment' => 'tpl.mFilter2.filter.select',
'tplFilter.row.order|payment' => 'tpl.mFilter2.filter.option',
'tplFilter.outer.orderuser|city' => 'tpl.mFilter2.filter.select',
'tplFilter.row.orderuser|city' => 'tpl.mFilter2.filter.option',
]}

Чанк tpl.mFilter2.orders.outer
<div class="row msearch2" id="mse2_mfilter">
    <div class="span3 col-md-3">
        <form action="[[~[[*id]]]]" method="post" id="mse2_filters">
            [[+filters]]
            
            [[+filters:isnot=``:then=`
            <button type="reset" class="btn btn-default hidden">[[%mse2_reset]]</button>
            <button type="submit" class="btn btn-success pull-right hidden">[[%mse2_submit]]</button>
            <div class="clearfix"></div>
            `]]
        </form>

        

        <div>[[%mse2_limit]]
            <select name="mse_limit" id="mse2_limit">
                <option value="10" [[+limit:is=`10`:then=`selected`]]>10</option>
                <option value="25" [[+limit:is=`25`:then=`selected`]]>25</option>
                <option value="50" [[+limit:is=`50`:then=`selected`]]>50</option>
                <option value="100" [[+limit:is=`100`:then=`selected`]]>100</option>
            </select>
        </div>
    </div>

    <div class="span9 col-md-9">
        <h3>[[%mse2_filter_total]] <span id="mse2_total">[[+total:default=`0`]]</span></h3>

        <div class="row">
            <div id="mse2_sort" class="span5 col-md-5">
                [[%mse2_sort]]
                <a href="#" data-sort="order|createdon" data-dir="[[+mse2_sort:is=`order|createdon:desc`:then=`desc`]]" data-default="desc" class="sort">Дата создания <span></span></a>

                <a href="#" data-sort="order|id" data-dir="[[+mse2_sort:is=`order|id:desc`:then=`desc`]]" data-default="desc" class="sort">Идентификатор <span></span></a>
            </div>

            [[+tpls:notempty=`
            <div id="mse2_tpl" class="span4 col-md-4">
                <a href="#" data-tpl="0" class="[[+tpl0]]">[[%mse2_chunk_default]]</a> /
                <a href="#" data-tpl="1" class="[[+tpl1]]">[[%mse2_chunk_alternate]]</a>
            </div>
            `]]
        </div>

        <div id="mse2_selected_wrapper">
            <div id="mse2_selected">[[%mse2_selected]]:
                <span></span>
            </div>
        </div>

        <div id="mse2_results">
            [[+results]]
        </div>

        <div class="mse2_pagination">
            [[!+page.nav]]
        </div>

    </div>
</div>

Сниппет msListOrdersFilterWrapper
<?php

/** @var array $scriptProperties */
if (!empty($resources)) {
    if (!empty($where)) {
        if (is_string($where)) {
            $where = json_decode($where, true);
        }
    } else {
        $where = array();
    }

    $where['id:IN'] = is_string($resources) ? array_map('trim', explode(',', $resources)) : $resources;
    if (!empty($where)) {
        $scriptProperties['where'] = json_encode($where);
    }
}

return $modx->runSnippet('msListOrders', $scriptProperties);

Метод фильтрации
Создаем кастомный метод фильтрации customfilter.class.php
в папке
core/components/msearch2/custom/filters/
вставляем следующий код
<?php

class CustomFiltersHandler extends mse2FiltersHandler
{
    public function getOrderValues(array $fields, array $ids)
    {
        $filters = array();
        $q = $this->modx->newQuery('msOrder');
        $q->where(array('id:IN' => $ids));
        $q->select('id,' . implode(',', $fields));
        $tstart = microtime(true);
        if ($q->prepare() && $q->stmt->execute()) {
            $this->modx->queryTime += microtime(true) - $tstart;
            $this->modx->executedQueries++;
            while ($row = $q->stmt->fetch(PDO::FETCH_ASSOC)) {
                foreach ($row as $k => $v) {
                    $v = str_replace('"', '"', trim($v));
                    if ($k === 'id') {
                        continue;
                    } else if (isset($filters[$k][$v])) {
                        $filters[$k][$v][$row['id']] = $row['id'];
                    } else {
                        $filters[$k][$v] = array($row['id'] => $row['id']);
                    }
                }
            }
        } else {
            $this->modx->log(modX::LOG_LEVEL_ERROR, "[mSearch2] Error on get filter params.\nQuery: " . $q->toSQL() .
                "\nResponse: " . print_r($q->stmt->errorInfo(), 1)
            );
        }

        return $filters;
    }

    public function buildStatusFilter(array $values, $name = '')
    {
        $ids = array_keys($values);
        if (empty($ids) || (count($ids) < 2 && empty($this->config['showEmptyFilters']))) {
            return array();
        }

        $results = array();
        $q = $this->modx->newQuery('msOrderStatus', array('id:IN' => $ids));
        $q->select('id,name');
        $tstart = microtime(true);
        if ($q->prepare() && $q->stmt->execute()) {
            $this->modx->queryTime += microtime(true) - $tstart;
            $this->modx->executedQueries++;
            $statuses = array();
            while ($row = $q->stmt->fetch(PDO::FETCH_ASSOC)) {
                $statuses[$row['id']] = $row['name'];
            }
            foreach ($values as $id => $ids) {
                $title = !isset($statuses[$id]) ? $this->modx->lexicon('mse2_filter_boolean_no') : $statuses[$id];
                $results[$title] = array(
                    'title'     => $title,
                    'value'     => $id,
                    'type'      => 'status',
                    'resources' => $ids,
                );
            }
        }

        return $this->sortFilters($results, 'statuses', array('name' => $name));
    }

    public function buildDeliveryFilter(array $values, $name = '')
    {
        $ids = array_keys($values);
        if (empty($ids) || (count($ids) < 2 && empty($this->config['showEmptyFilters']))) {
            return array();
        }

        $results = array();
        $q = $this->modx->newQuery('msDelivery', array('id:IN' => $ids));
        $q->select('id,name');
        $tstart = microtime(true);
        if ($q->prepare() && $q->stmt->execute()) {
            $this->modx->queryTime += microtime(true) - $tstart;
            $this->modx->executedQueries++;
            $deliveries = array();
            while ($row = $q->stmt->fetch(PDO::FETCH_ASSOC)) {
                $deliveries[$row['id']] = $row['name'];
            }
            foreach ($values as $id => $ids) {
                $title = !isset($deliveries[$id]) ? $this->modx->lexicon('mse2_filter_boolean_no') : $deliveries[$id];
                $results[$title] = array(
                    'title'     => $title,
                    'value'     => $id,
                    'type'      => 'delivery',
                    'resources' => $ids,
                );
            }
        }

        return $this->sortFilters($results, 'statuses', array('name' => $name));
    }

    public function buildPaymentFilter(array $values, $name = '')
    {
        $ids = array_keys($values);
        if (empty($ids) || (count($ids) < 2 && empty($this->config['showEmptyFilters']))) {
            return array();
        }

        $results = array();
        $q = $this->modx->newQuery('msPayment', array('id:IN' => $ids));
        $q->select('id,name');
        $tstart = microtime(true);
        if ($q->prepare() && $q->stmt->execute()) {
            $this->modx->queryTime += microtime(true) - $tstart;
            $this->modx->executedQueries++;
            $payments = array();
            while ($row = $q->stmt->fetch(PDO::FETCH_ASSOC)) {
                $payments[$row['id']] = $row['name'];
            }
            foreach ($values as $id => $ids) {
                $title = !isset($payments[$id]) ? $this->modx->lexicon('mse2_filter_boolean_no') : $payments[$id];
                $results[$title] = array(
                    'title'     => $title,
                    'value'     => $id,
                    'type'      => 'payment',
                    'resources' => $ids,
                );
            }
        }

        return $this->sortFilters($results, 'statuses', array('name' => $name));
    }

    public function getUserValues(array $fields, array $ids)
    {

        $filters = array();
        $q = $this->modx->newQuery('modUser');
        $q->leftJoin('modUserProfile', 'Profile');
        $q->where(array('modUser.id:IN' => $ids));
        $q->select('modUser.id,' . $this->modx->getSelectColumns('modUserProfile', 'Profile', '', $fields));

        $tstart = microtime(true);
        if ($q->prepare() && $q->stmt->execute()) {
            $this->modx->queryTime += microtime(true) - $tstart;
            $this->modx->executedQueries++;
            while ($row = $q->stmt->fetch(PDO::FETCH_ASSOC)) {
                foreach ($row as $k => $v) {
                    $v = str_replace('"', '"', trim($v));
                    if ($k === 'id') {
                        continue;
                    } else if (isset($filters[$k][$v])) {
                        $filters[$k][$v][$row['id']] = $row['id'];
                    } else {
                        $filters[$k][$v] = array($row['id'] => $row['id']);
                    }
                }
            }
        } else {
            $this->modx->log(modX::LOG_LEVEL_ERROR, "[mSearch2] Error on get filter params.\nQuery: " . $q->toSQL() .
                "\nResponse: " . print_r($q->stmt->errorInfo(), 1));
        }

        return $filters;
    }

    public function getOrderUserValues(array $fields, array $ids)
    {

        $filters = array();

        $q = $this->modx->newQuery('msOrder');
        $q->leftJoin('modUser', 'User');
        $q->leftJoin('modUserProfile', 'UserProfile');

        $q->where(array('msOrder.id:IN' => $ids));
        $q->select('msOrder.id,' . $this->modx->getSelectColumns('modUserProfile', 'UserProfile', '', $fields));

        $tstart = microtime(true);
        if ($q->prepare() && $q->stmt->execute()) {
            $this->modx->queryTime += microtime(true) - $tstart;
            $this->modx->executedQueries++;
            while ($row = $q->stmt->fetch(PDO::FETCH_ASSOC)) {

                foreach ($row as $k => $v) {
                    $v = str_replace('"', '"', trim($v));
                    if ($k === 'id') {
                        continue;
                    } else if (isset($filters[$k][$v])) {
                        $filters[$k][$v][$row['id']] = $row['id'];
                    } else {
                        $filters[$k][$v] = array($row['id'] => $row['id']);
                    }
                }
            }
        } else {
            $this->modx->log(modX::LOG_LEVEL_ERROR, "[mSearch2] Error on get filter params.\nQuery: " . $q->toSQL() .
                "\nResponse: " . print_r($q->stmt->errorInfo(), 1));
        }

        return $filters;
    }

}
не забываем прописать настройку mse2_filters_handler_class = CustomFiltersHandler

PS. Всем спасибо за внимание.
— протестировать на демо сайте
— купить дополнение в modstore.pro
Володя
28 июля 2018, 15:07
modx.pro
17
2 559
+16
Поблагодарить автора Отправить деньги

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

Andrey
29 июля 2018, 16:14
0
Оч полезно! Как то кажется спрашивал уже на счет того как и «подружить», определенно в закладки!
    Karpunin Alexey
    04 августа 2018, 01:08
    0
    Спасибо вам большое!!! )))
      vrm13
      08 ноября 2018, 21:46
      0
      доброго вечера. Нашёл, как мне кажется, небольшой баг, компонент куплен больше года назад, в поддержку написать не могу.
      Просто немного неудобно при отладке отчищать лог ошибок. Хочу вывести на страницу полный список всех заказов пользователей через mslistorders и pdopage. Если в сниппете showLog=1 то в лог ошибок модекса вываливается весь полученный массив array (… при тысяче заказов это забивает лог на 10мб одна перезагрузка страницы.

      [2018-11-08 23:38:55] (ERROR @ /core/components/mslistorders/model/mslistorders/mslistorders.class.php : 336) [mslistorders]
      [2018-11-08 23:38:55] (ERROR @ /core/components/mslistorders/model/mslistorders/mslistorders.class.php : 338 Array
      (
          [total] => Array
              (.........
      вот эти строки. если я правильно понял, ошибки ведь нет, просто showLog отправляет ещё и в журнал ошибок вместо простого вывода на фронтэнд у менеджера.
        Володя
        09 ноября 2018, 11:18
        0
        Доброе утро.
        нет никакого бага, уберите showLog из параметров вызова сниппета и все.
          vrm13
          09 ноября 2018, 11:32
          0
          да, конечно убрал. Видимо я не правильно понял как работает showLog, думал это только печать на экран, но не запись в журнал.
        Артем
        20 марта 2019, 09:29
        0
        Добрый день!
        Тоже в техподдержку не могу написать, куплен давно.
        Обновил модуль. Теперь в списке заказов при нажатии на Повторить заказ в корзину ничего не падает и выпадает ошибка в консоль
          Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
          6