Интересный способ получить список категорий бренда в Drupal

Ну почему?

Получение списка категорий бренда - с виду довольно тривиальная задача, но при её решении всплывают подводные камни. Давайте разберёмся: как правило, в интернет-магазинах товары классифицируются как минимум по двум словарям - каталог и бренд. Например, товар под названием "мобильный телефон" относится к термину "мобильные телефоны" из словаря "каталог" и к термину "Завод имени Ленина" из словаря "производители". Довольно часто заказчик ставит перед разработчиком задачу отобразить на странице производителя все категории, в которых у производителя есть товары. Т.е. на странице "Завод имени Ленина" необходимо отобразить ссылки на разделы "мобильные телефоны", "холодильники", "ядерные боеголовки". Любой, кто знаком с друпалом, но не сталкивался с решением этой задачи, с ходу скажет, что это решается за 1 минуту через Views. Однако, на самом деле всё не так просто. Сразу напрашивается алгоритм - выводим материалы, с контекстным фильтром по бренду, отображаем только поле "Каталог" и дело якобы в шляпе. Но ведь товаров могут быть тысячи, поэтому категории многократно продублируются, а поскольку вьюс сделан по нодам, то ни уникальность запроса, ни агрегация нам не помогут. Не поможет также и группировка полей, т.к. помимо поля группировки, надо вывести ещё что-нибудь. Можно конечно же раздраконить шаблон представления, убрать оттуда вывод $rows, оставить только заголовки, но это костыль, ведь вьюс всё равно будет собирать тысячи товаров, которые не будет выводить.

Именно поэтому я решил, что оптимально будет написать свой запрос в базу, чтобы получить айдишники нужных терминов, а далее уже как-нибудь их обработать - либо вывести кодом, либо передать айдишники во views, и там уже настроить вывод, как душе угодно. Сам запрос делается в таблицу taxonomy_index, а для того, чтобы получить термины другого словаря, мы просто приджойним эту таблицу к самой себе. Собственно, код:

<?php
 
 
// Select terms
 
$query = db_select('taxonomy_index', 'ti');
 
$query->innerJoin('taxonomy_index', 'ti2', 'ti.nid=ti2.nid');
 
// Если вам не нужно название термина, то эту строку можно пропустить
 
$query->innerJoin('taxonomy_term_data', 'td', 'td.tid=ti2.tid');
 
$query->fields('ti2', array('tid'));
 
// и эту тоже
 
$query->fields('td', array('name'));
 
$query->condition('ti.tid', $args[0]);
 
$query->condition('ti2.tid', $args[0], '<>');
 
$query->distinct();
 
$terms = $query->execute()->fetchAll();
?>

Приведённый код я использовал в своём Custom Ctools content type, поэтому аргумент с айдишником бренда указан как $args[0], естественно, вы можете использовать это и в другом контексте, например, в кастомном модуле, блоке, шаблоне и т.д. Из полученных айдишников я сгенерировал ссылки вида catalog/%category/%brand, которые ведут на страницы с вьюсами с двумя контекстными фильтрами, чтобы показать товары, относящиеся одновременно и к указанной категории, и к бренду.

В общем, берите  и пользуйтесь, а если у вас есть другие способы решения этой задачи, то готов услышать вас в комментариях.

Поделиться: