Привет, друпал.ру. Давно не писал тут гадостей, погряз в "не друпалом единым", решил вот че-нить да накатать (вдруг ввиду отсутствия активности аккаунт удалят). Ввиду того, что мозгов нехватает ченить полезное для всех написать - выкладываю маленький высер, ориентированный чисто на новичков, о котором меня 2 раза спрашивали местные нубы за последний месяц.
Представим типичную задачу (на примере Drupal 6.x + Ubercart 2.x + views 2.x) - вывести тизеры товаров с пагинацией, отсортированные по цене. В пару секунд решается средствами views.
Но! У некторых товаров нет цены (точнее она равна нулю), т.к. заказчик еще не получил прайс-лист, а товары решил выложить. Для таких товаров в качестве цены заказчик указал "0". Вместо цены "0" и кнопки "Купить" в шаблонах рисуем красивую ссылку на "Уточнить цену", ведущую на страницу контактов и вопрос решен. Только вот views эти самые товары выведет первыми при сортировке по цене по возрастанию, а хочется их вывести наоборот последними, они как бы в "резерве". Поставить в качестве фильтра "цена > 0" - не выведет вообще. А нужно вывести последними.
На помощь приходит hook_views_query_alter из Views API и конструкция IF() из MySQL, которые помогут нам динамически изменить сортировку.
Создаем новый модуль и в нем вставляем этот самый хук.
На входе хук принимает два аргумента. Первый - полный объект текущего view. Второй - объект запроса.
Первый аргумент нам понадобится, чтобы узнать, что мы имеем дело имено с нужным нам представлением, второй - будем модифицировать.
Допустим в качестве имя представления у нас catalog_view, а в качестве текущей сортировки views uc_products_sell_price ASC
<?php
function ИМЯМОДУЛЯ_views_query_alter(&$view, &$query) {
//Ограничиваем использование только для catalog_view
if ($view->name == 'catalog_view') {
//Подменяем стандартным SQL-синтаксисом цену 0 на 99999999, которая точно будет самая высокая
$query->orderby[0] = 'if(uc_products_sell_price = 0, 9999999, uc_products_sell_price) ASC';
//Посмотрите через var_dump или print_r содержимое $query->orderby
//если у вас несколько фильтров сортировки - чтобы переопределить именно нужный вам.
}
}
?>
Ну собственно все.
Теперь покажутся товары, сортированные по возрастанию по цене, начиная с тех, у которых цена выше 0, остальные попадут в конец выборки.
Этим же хуком можно реализовать пользовательскую сортировку на основе $_GET-параметров, которая нужна на любом интернет магазине без дополнительных модулей. У меня работает не на одном сайте.
Ну а дальше можно играться любыми параметрами.
Пример работы - Тыц, идем на последнюю страницу и видим "уточнить стоимость".
Комментарии
Подскажите, как это же сделать в седьмом друпале?