8 дек. 2017 г., 20:21

Сортировка по нескольким значениям

Добрый Вечер!
Подскажите пожалуйста, как в расширяющем процессоре сделать сортировку по нескольким значениям? Аналогию вот этого:
SELECT * FROM page ORDER BY FIELD(season, "весна","лето","осень","зима")
по одному значению получилось:
$this->setDefaultProperties(array( 'sort' => 'proizv.value ="Decoriis" ', ...
А вот так уже не идет
$this->setDefaultProperties(array( 'sort' => 'proizv.value ="Decoriis","Berlinoyal" ', ...
И как можно остальные записи сортировать по другому полю?
Посоветуйте, где справку по этому вопросу почитать...
> 'sort' => 'proizv.value ="Decoriis","Berlinoyal" ',

это скорее походит на фильтр
Если нужна фильтрация, то стоит делать так:
$q->where(['proizv.value:in'=>[ "Decoriis", "Berlinoyal" ] ]);

При задании сортировки указываются поля, по которым нужно сортировать выборку. Никакие значения там не указываются. Чтобы быстрее понять xpdo очень рекомендую ознакомиться с основами SQL - он построен на них. Иначе очень трудно будет :)
Sql я знаю, поэтому и привожу рабочий пример от туда, мне нужно его переложить на xpdo .С одним значением у меня это работает
'sort' => 'proizv.value ="Decoriis" ',
значит можно сделать и несколько значений, только пока не знаю правильный синтаксис...
А остальные строки мне отбрасывать не нужно, фильтрацию я уже сделала выше. Мне их надо вывести следом, но уже сортировать по другому по полю.
По-русски задача звучит так:
Вывести список товаров таком виде: сначала приоритетных производителей, затем остальные по дате поступления на склад.

'sort' => 'proizv.value ="Decoriis" ',
Это у вас буквально sort => true|false
Если proizv.value = 'Decoriis', то это true, все остальное - false. То есть вы сортируете на Да и Нет. Сделайте $q->prepare(); $q->toSQL() и посмотрите какой у вас конечный SQL получается. Саша вам правильно говорит: вы не так запрос строите.
Если вам надо аналог этого сделать SELECT * FROM page ORDER BY FIELD(season, "весна","лето","осень","зима"), то пробуйте так:
$this->setDefaultProperties(array( 'sort' => "FIELD(proizv.value, 'Decoriis','Berlinoyal')", 'dir' => "desc",



$this->setDefaultProperties(array( 'sort' => "FIELD(proizv.value, 'Decoriis','Berlinoyal')", 'dir' => "desc",
именно так не получилось. в запросе ничего не меняется
Добавила в функцию
public function prepareQueryBeforeCount(xPDOQuery $c)
вот так
$c->sortby('FIELD(`proizv`.`value`,"Калитва","СКОВО" ) ');
в запросе видны изменения
... ORDER BY FIELD(`proizv`.`value`,"Калитва","СКОВО" ) ASC
а на фронте - нет.
Решила проверить как ведет себя запрос через phpmyAdmin. Оказалось, запрос верный, только нужные результаты в конце списка. Изменила порядок сортировки на DESC - все стало как надо.
Но теперь я никак не могу найти откуда идет ASC в запросе на сайте. Сама я его не дописывала... Через передачу параметра процессору
{assign var=params value=['dir' => "Desc"
не получается. Стала искать в наследуемых классах, добралась до site/web/resources/getdata.class.php изменила
'sort' => "{$this->classKey}.menuindex", 'dir' => 'DESC',
Но ничего не помогает... Ума не проложу, где это сидит
Как еще попробовать?
В своем конечном процессоре в методе initialize пропишите
parent::initialize(); print '<pre>'; print_r($this->properties); return true;
и посмотрите с какими параметрами в итоге инициируется процессор. Если какие-то сортировки добавлены после этого, то в большинстве случаев это косяк.
Пропишите отладку и в методах prepareQueryBeforeQuery и prepareQueryAfterCount, а так же в setSelection, если он есть. Я ничего не могу так сказать, точек костыльных вхождений очень много. Я в своих процессорах не переопределяю логику MODX-процессоров относительно параметров сортировки, так что по умолчанию все должно работать как есть.

Можете попробовать крайний случай. В prepareQueryBeforeCount выполнить $this->unsetProperty("sort"); $this->unsetProperty("dir"); и прописать свою сортировку непосредственно в объект запроса в методе prepareQueryAfterCount.

Николай! я в отчаянии...
Удалось получить входные параметры, но не в методе initialize, а в prepareQueryBeforeQuery
Array ( [start] => 0 [limit] => 15 [sort] => modResource.menuindex [dir] => DESC [combo] => [query] => [cache] => [cache_lifetime] => 0 [cache_prefix] => getdata/ [current] => [page] => [getPage] => 1 [getPageParamsSet] => getPage [includeTVs] => 1 [showhidden] => [showunpublished] => [summary] => [makeLinks] => [image_url_schema] => false [new1] => [hot] => [category_id] => 6532 [base_currency_id] => 79 )


как я и писала ранее сортировка идет по менюИндекс, но в запросе на выходе это не видно:
... AND `Product`.`sm_price` <> '0' AND `modResource`.`parent` IN (6532) ) ORDER BY FIELD(`proizv`.`value`,"Калитва","СКОВО" ) ASC
Следуя Вашему совету, убрала сортировку в методе prepareQueryBeforeCount :
// $c->sortby('FIELD(`proizv`.`value`,"Калитва","СКОВО" ) '); $this->unsetProperty("sort"); $this->unsetProperty("dir");
и добавила
public function prepareQueryAfterCount(xPDOQuery $c) { $c->sortby('FIELD(`proizv`.`value`,"Калитва","СКОВО" ) Desc '); $c->prepare(); print '<div><pre>'.$c->toSQL().'</pre></div>'; return $c; }
вот что получается :
.. AND `Product`.`sm_price` <> '0' AND `modResource`.`parent` IN (6532) ) ORDER BY FIELD(`proizv`.`value`,"Калитва","СКОВО" ) Desc ASC
это как понимать? почему ASC остается и просто дописывается Desc ( и даже моим регистром)

В вашем случае надо так:
$c->sortby('FIELD(`proizv`.`value`,"Калитва","СКОВО" )', 'Desc');
DESC/ASC должно вторым параметром передаваться. Если второй параметр не передан, по умолчанию используется ASC


Ура! все получилось.
Спасибо, Николай за науку и терпение.
Как получу барыж от заказчика, поделюсь))

Добавить комментарий