pdoResources сортировка по TV

Здравствуйте.
Вывожу ресурсы с помощью pdoResource:
[[!getPage@CategoryAndCollectionPagination?
                &elementClass=`modSnippet`
                &element=`pdoResources`
                &parents=`[[*id]]`
                &sortby=`clock.price`
                &sortdir=`ASC`
                &hideContainers=`1`
                &depth=`2`
                &limit=`[[#1910.tv.clocksQuantity]]`
                &tpl=`clock-item`
                &includeContent=`0`
                &showHidden=`1`
                &includeTVs=`clock.photo,clock.ref,clock.collection,clock.price,clock.currency,clock.available`
                &pageLimit=`3`
                &pageNavVar=`page.nav`
                
                &cache=`true`
                &cache_key=``
                &cache_expires=`31536000`
]]

При этом не у всех ресурсов TV clock.price (тип число) заполнено. Но ресурсы с незаполненными clock.price тоже нужно выводить.

Что в итоге получаю:
Товар
Товар
Товар
Товар 100руб.
Товар 200руб.
Товар 300руб.

Что нужно получить:
Товар 100руб.
Товар 200руб.
Товар 300руб.
Товар
Товар
Товар

Понимаю, что пустое значение clock.price равно 0, в итоге ресурсы со значением clock.price 0 выводятся до остальных ресурсов. Но не понимаю, как сделать сортировку как мне надо. Если кто сталкивался с такой задачей или знает, как это выполнить, прошу подсказать.
Александр
21 января 2017, 16:22
1
1 121
0

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

Александр
22 января 2017, 21:44
0
Написал сниппет, который будет возвращать отсортированные id ресурсов:
<?php
$where = array(
    'template' => 4,
    'published' => 1,
    'deleted' => 0,
    'isfolder' => 0
);
$output = [];
$resources = $modx -> getCollection('modResource', $where);
foreach ($resources as $id => $resource) {
    $output[$id] = $resource -> getTVValue($sortedByTV) ? $resource -> getTVValue($sortedByTV) : 999999999999;
}
asort($output);
$output = implode(",", array_keys($output));
return $output;
pdoResource теперь выглядит так:
[[!getPage@CategoryAndCollectionPagination?
                &elementClass=`modSnippet`
                &element=`pdoResources`
                &parents=`[[*id]]`
		&resources=`[[getSortedByTVResourcesIds? &sortedByTV=`clock.price`]]`
                &sortby=``
                &sortdir=`ASC`
                &hideContainers=`1`
                &depth=`2`
                &limit=`[[#1910.tv.clocksQuantity]]`
                &tpl=`clock-item`
                &includeContent=`0`
                &showHidden=`0`
                &includeTVs=`clock.photo,clock.ref,clock.collection,clock.price,clock.currency,clock.available`
                &pageLimit=`3`
                &pageNavVar=`page.nav`
                
                &cache=`true`
                &cache_key=``
                &cache_expires=`31536000`
]]
Но это какое-то неправильное решение. Сниппет работает 6 сек. (около 2к ресурсов)! Так ведь не должно быть. Плюс при открытии любой подкатегории $output всегда будет возвращать все ресурсы (около 2к), а не только те, которые относятся к этой подкатегории.

Наверняка есть нормальное решение в пару строчек с нормальной скоростью работы. Подскажите, пожалуйста, кто сталкивался.

Пробовал добавить для TV (по которому нужна сортировка) значение по умолчанию, например 999999999, чтобы ресурс с таким значением TV всегда был в конце, но это не работает. Такие ресурсы всё равно сортируются вначале, видимо из-за того, что пустое значение в БД — null, а не то, которое установлено по умолчанию.
Володя
22 января 2017, 21:55
2
+2
просто укажи
&sortby=`COALESCE(clock.price,9999999999)`
    Александр
    22 января 2017, 22:15
    0
    Володя, спасибо большое!!! Это работает)
    Пол интернета перерыл и не нашёл этого решения. Надеюсь, кому-то тоже будет полезным.
      Володя
      22 января 2017, 22:15
      0
      на здоровье!