pdoResources сортировка по TV Решено

Дополнение: pdoResources

Здравствуйте.
Вывожу ресурсы с помощью 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, 19:22    Александр   
1    454 0

Комментарии (4)

  1. Александр 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, а не то, которое установлено по умолчанию.
    1. Володя 22 января 2017, 21:55 # +2
      просто укажи
      &sortby=`COALESCE(clock.price,9999999999)`
      
      1. Александр 22 января 2017, 22:15 # 0
        Володя, спасибо большое!!! Это работает)
        Пол интернета перерыл и не нашёл этого решения. Надеюсь, кому-то тоже будет полезным.
        1. Володя 22 января 2017, 22:15 # 0
          на здоровье!
      Вы должны авторизоваться, чтобы оставлять комментарии.