Форум русской поддержки Joomla!® CMS
09.12.2016, 13:47:24 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
   
   Начало   Поиск Joomla 3.0 FAQ Joomla 2.5 FAQ Joomla 1.5 FAQ Правила форума Новости Joomla Реклама Войти Регистрация Помощь  
Страниц: [1]   Вниз
  Добавить закладку  |  Печать  
Автор

Решение: K2 получить материалы по тегу

 (Прочитано 444 раз)
0 Пользователей и 1 Гость смотрят эту тему.
d0ublezer0
Давно я тут
****

Репутация: +29/-0
Offline Offline

Сообщений: 317

Javaхарлал Неру


« : 17.01.2016, 20:09:35 »

мне была нужна такая функциональность: по определенному тегу выбрать все материалы из определенного раздела категорий со всеми вложенными категориями.
Такого решения я не нашел, более того, раз многие об этом спрашивают, но ответов нет, я понял, что решения готового тоже нет.
Написал сам. Делюсь.
Код
<?php
$GLOBALS['db'] = JFactory::getDBO(); // получаем объект базы данных
 
JLoader::register('modK2ToolsHelper', JPATH_ROOT . '/modules/mod_k2_tools/helper.php');  // подключаем помощника от модуля K2Tools
$GLOBALS['tag_cats'] = modK2ToolsHelper::getCategoryChildren(25); // собираем все дочерние для указанной категории материалов
$GLOBALS['tag_cats'] = @array_unique($GLOBALS['tag_cats']); // делаем список уникальным
$GLOBALS['tag_cats']=implode(",",$GLOBALS['tag_cats']); // склеиваем все категории
JLoader::register('K2HelperRoute', JPATH_ROOT . '/components/com_k2/helpers/route.php '); // подключаем роутер K2
 
function getItemsByTag($tags){
   $tags=array_map('trim', explode(',', $tags)); // разбираем теги на части и чистим их
   $tags="'".implode("','",$tags)."'"; // заново склеиваем теги для совместимости с MySQL
 
   $query="SELECT #__k2_items.id, #__k2_items.title, #__k2_items.alias,#__k2_items.catid, #__k2_categories.alias AS cat_alias
   FROM (#__k2_tags INNER JOIN (#__k2_tags_xref LEFT JOIN #__k2_items ON #__k2_tags_xref.itemID = #__k2_items.id) ON #__k2_tags.id = #__k2_tags_xref.tagID) LEFT JOIN #__k2_categories ON #__k2_items.catid = #__k2_categories.id
   WHERE (((#__k2_tags.name) in ($tags)) AND ((#__k2_items.catid) In ("
.$GLOBALS['tag_cats'].")) AND (#__k2_items.published = 1))";
 
   $GLOBALS['db']->setQuery($query);  // выполняем запрос к базе
   $items = $GLOBALS['db']->loadAssocList("id"); // собираем объекты из ответа
 
   if (count($items)>0){ // если результат не пустой
       ?>
       <ul class="fp-items-by-tag">
           <?
           foreach ($items as $item){ // для каждого материала создаем ссылку в списке
               $link = K2HelperRoute::getItemRoute($item["id"].':'.urlencode($item["alias"]), $item["catid"].':'.urlencode($item["cat_alias"]));
               ?><li><a href="<?=urldecode(JRoute::_($link));?>"><?=$item["title"]?></a></li><?  
           }
 
           ?>
       </ul>
       <?}
}
?>
Т.е. указав родительскую категорию, внутри которой нужно искать, мы можем вызывать функцию getItemsByTag("теги, по которым выполнять поиск, разделенные запятыми, или один тег")  - она выведет список со ссылками на материалы, соответствующие этому тегу.

Решение не претендует на уникальность и универсальность, но нужную мне задачу решает.

Может кому будет полезно..
« Последнее редактирование: 17.01.2016, 20:14:04 от d0ublezer0 » Записан
benelli
Захожу иногда
**

Репутация: +0/-0
Offline Offline

Сообщений: 18


« Ответ #1 : 01.08.2016, 00:10:59 »

Полезно, только не понятно чайникам как это применить на практике (куда вставлять код и как это использовать когда материалов в которых надо вывести подобные выборки десятки).
Записан
benelli
Захожу иногда
**

Репутация: +0/-0
Offline Offline

Сообщений: 18


« Ответ #2 : 31.08.2016, 14:20:10 »

Ап! Тема очень актуальна!
Записан
d0ublezer0
Давно я тут
****

Репутация: +29/-0
Offline Offline

Сообщений: 317

Javaхарлал Неру


« Ответ #3 : 31.08.2016, 14:44:27 »

Ап! Тема очень актуальна!
А готовое решение с комментариями из первого сообщения почему не подходит?
Записан
benelli
Захожу иногда
**

Репутация: +0/-0
Offline Offline

Сообщений: 18


« Ответ #4 : 31.08.2016, 14:49:05 »

А готовое решение с комментариями из первого сообщения почему не подходит?
Я не понимаю куда этот код надо установить. И если верно понял, то надо прямо в коде указывать из каких категорий брать материалы и с какими тегами? Как быть если таких указаний на сайте надо сделать множество?
Записан
Septdir
Живу я здесь
******

Репутация: +36/-3
Offline Offline

Пол: Мужской
Сообщений: 841


Skype: septdir


« Ответ #5 : 08.09.2016, 21:13:07 »

А зачем такой геморой? Ну варианта 2.
Первый: Написать плагин( может займусь).
Второй: для нетерпиливых:

1. Заходите в файл /components/com_k2/models/itemlist.php
2.В нем находите 242 строку (пред ней повыше весть case: tag)
Код
JArrayHelper::toInteger($categories);
 
3. Добавляете перед этим одну строку
Код
$categories = $this->getCategoryTree($categories);
Должно получится так
Код
if (is_array($categories))
{
$categories = $this->getCategoryTree($categories);
JArrayHelper::toInteger($categories);
$query .= " AND c.id IN(".implode(',', $categories).")";
}
 

Итого если у вас пункт меню типа Тэг и там выбрана категория или категории то всегда будут выводиться материалы из дочерних категорий.

P.S Функция getCategoryTree позволяете получить древо категорий тоишь родителя которого вы указали и все вложенные категории. Она весьма полезна так что я ее частенько храню в хелпере
Записан
benelli
Захожу иногда
**

Репутация: +0/-0
Offline Offline

Сообщений: 18


« Ответ #6 : 11.09.2016, 22:32:29 »

А зачем такой геморой? Ну варианта 2.
Первый: Написать плагин( может займусь).
Второй: для нетерпиливых:

1. Заходите в файл /components/com_k2/models/itemlist.php
2.В нем находите 242 строку (пред ней повыше весть case: tag)
Код
JArrayHelper::toInteger($categories);
 
3. Добавляете перед этим одну строку
Код
$categories = $this->getCategoryTree($categories);
Должно получится так
Код
if (is_array($categories))
{
$categories = $this->getCategoryTree($categories);
JArrayHelper::toInteger($categories);
$query .= " AND c.id IN(".implode(',', $categories).")";
}
 

Итого если у вас пункт меню типа Тэг и там выбрана категория или категории то всегда будут выводиться материалы из дочерних категорий.

P.S Функция getCategoryTree позволяете получить древо категорий тоишь родителя которого вы указали и все вложенные категории. Она весьма полезна так что я ее частенько храню в хелпере
Не помогает это решение. Нет ни каких изменений по сравнению со стандартным отображением.
« Последнее редактирование: 11.09.2016, 22:37:14 от benelli » Записан
Septdir
Живу я здесь
******

Репутация: +36/-3
Offline Offline

Пол: Мужской
Сообщений: 841


Skype: septdir


« Ответ #7 : 12.09.2016, 13:12:14 »

Не помогает это решение. Нет ни каких изменений по сравнению со стандартным отображением.
Значит не туда добавили ибо я проверил =). Там ниже еще есть когда категории строчное значение имеют. Ну да какие изменения должны быть, просто выводится все материалы и родителя и дочерней категории
Записан
benelli
Захожу иногда
**

Репутация: +0/-0
Offline Offline

Сообщений: 18


« Ответ #8 : 12.09.2016, 13:28:31 »

Значит не туда добавили ибо я проверил =). Там ниже еще есть когда категории строчное значение имеют. Ну да какие изменения должны быть, просто выводится все материалы и родителя и дочерней категории
А почему вы добавили изменения в itemlist ? Надо вывести материалы по тегу в другом материале, а не в списке материалов в категории.
Записан
Septdir
Живу я здесь
******

Репутация: +36/-3
Offline Offline

Пол: Мужской
Сообщений: 841


Skype: septdir


« Ответ #9 : 12.09.2016, 14:34:01 »

А почему вы добавили изменения в itemlist ? Надо вывести материалы по тегу в другом материале, а не в списке материалов в категории.
Ну потому что все списки получаются в model itemlist.php Тема была про то как получить список материалов, а не список материалов в самом материале. Хотя даже в самом материале список получаться там же просто функция другая
Фактически в этой функции другая логика и связки с категориями в принципе ибо связь идет сугубо то тэгам, но если хотите, сделать это не на много сложнее.
1. Заходите в файл /components/com_k2/models/itemlist.php
2.В нем находите функцию
Код
function getRelatedItems($itemID, $tags, $params)
3. В функции находите строчку (955 строка примерно)
Код
		$query .= " AND i.trash = 0
AND c.published = 1 "
;
 
И пред ней добавляете
Код
		$categories = $this->getCategoryTree($params->get('categories'));
JArrayHelper::toInteger($categories);
$query .= " AND c.id IN(".implode(',', $categories).")";
 
Должно получиться так
Код
		$categories = $this->getCategoryTree($params->get('categories'));
JArrayHelper::toInteger($categories);
$query .= " AND c.id IN(".implode(',', $categories).")";
$query .= " AND i.trash = 0
AND c.published = 1 "
;
 
Итого в материале при вызове ($this->relatedItems) вы будете получить массив материалов в которых содержаться данные тэги, а так же категории равна категории данного материала и всех вложенных. Но плагином такое не реализовать скорее всего, только кодом
Записан
benelli
Захожу иногда
**

Репутация: +0/-0
Offline Offline

Сообщений: 18


« Ответ #10 : 12.09.2016, 18:51:21 »

Ну потому что все списки получаются в model itemlist.php Тема была про то как получить список материалов, а не список материалов в самом материале. Хотя даже в самом материале список получаться там же просто функция другая
Фактически в этой функции другая логика и связки с категориями в принципе ибо связь идет сугубо то тэгам, но если хотите, сделать это не на много сложнее.
1. Заходите в файл /components/com_k2/models/itemlist.php
2.В нем находите функцию
Код
function getRelatedItems($itemID, $tags, $params)
3. В функции находите строчку (955 строка примерно)
Код
		$query .= " AND i.trash = 0
AND c.published = 1 "
;
 
И пред ней добавляете
Код
		$categories = $this->getCategoryTree($params->get('categories'));
JArrayHelper::toInteger($categories);
$query .= " AND c.id IN(".implode(',', $categories).")";
 
Должно получиться так
Код
		$categories = $this->getCategoryTree($params->get('categories'));
JArrayHelper::toInteger($categories);
$query .= " AND c.id IN(".implode(',', $categories).")";
$query .= " AND i.trash = 0
AND c.published = 1 "
;
 
Итого в материале при вызове ($this->relatedItems) вы будете получить массив материалов в которых содержаться данные тэги, а так же категории равна категории данного материала и всех вложенных. Но плагином такое не реализовать скорее всего, только кодом
Получается вот такая фигня:
Ошибка: 1064
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ') AND i.trash = 0 AND c.published = 1 AND c.access IN(1,1) AND c.trash =' at line 5 SQL=SELECT i.*, c.alias as categoryalias FROM #__k2_items as i LEFT JOIN #__k2_categories c ON c.id = i.catid WHERE i.published = 1 AND ( i.publish_up = '0000-00-00 00:00:00' OR i.publish_up <= '2016-09-12 14:47:23' ) AND ( i.publish_down = '0000-00-00 00:00:00' OR i.publish_down >= '2016-09-12 14:47:23' ) AND i.access IN(1,1) AND c.id IN() AND i.trash = 0 AND c.published = 1 AND c.access IN(1,1) AND c.trash = 0 AND (i.id) IN (96,50,311,309,94,310,93,46,349,316,498,384,385,317,318,315,367,95,522,47,312,348,386,499,521,270,528,527,387,45,313,369,526) ORDER BY i.created DESC LIMIT 0, 20

https://yadi.sk/i/3WWu2EHCv59XA

А плагин и не нужен, если это сделает код)
« Последнее редактирование: 12.09.2016, 18:57:37 от benelli » Записан
benelli
Захожу иногда
**

Репутация: +0/-0
Offline Offline

Сообщений: 18


« Ответ #11 : 12.09.2016, 18:59:49 »

ID сообщаются в ошибке как раз тех материалов, у которых есть нужный тег (при чем не только из требуемой категории, а из всех. Я проверил.)
Записан
Septdir
Живу я здесь
******

Репутация: +36/-3
Offline Offline

Пол: Мужской
Сообщений: 841


Skype: septdir


« Ответ #12 : 13.09.2016, 00:51:41 »

ID сообщаются в ошибке как раз тех материалов, у которых есть нужный тег (при чем не только из требуемой категории, а из всех. Я проверил.)
Включите отображение ошибок, в режим разработчик php и выложите текст ошибки. У вас не передается масиив с id категорий. Укажите версию движка, версию k2 ибо У Joomla 3.6.2 и k2 v 2.7.1 все норм.
закомоените строчку
Код
$query .= " AND c.id IN(".implode(',', $categories).")";
И если включены ошибки и от они есть  то они вылезут.
Проверьте в каком месте не получаются id
Код
print_r($params->get('categories'));
Или после JArrayHelper::toInteger($categories);
Код
print_r($categories);
« Последнее редактирование: 13.09.2016, 01:09:02 от Septdir » Записан
d0ublezer0
Давно я тут
****

Репутация: +29/-0
Offline Offline

Сообщений: 317

Javaхарлал Неру


« Ответ #13 : 20.10.2016, 09:26:01 »

P.S Функция getCategoryTree позволяете получить древо категорий тоишь родителя которого вы указали и все вложенные категории. Она весьма полезна так что я ее частенько храню в хелпере
Этот "геморрой", как вы выразились, вызван незнанием мной матчасти.
Естественно код с getCategoryTree гораздо удобнее, спасибо за наводку.
Записан
Страниц: [1]   Вверх
  Добавить закладку  |  Печать  
 
Перейти в:  

Powered by SMF 1.1.21 | SMF © 2006, Simple Machines

Joomlaforum.ru is not affiliated with or endorsed by the Joomla! Project or Open Source Matters.
The Joomla! name and logo is used under a limited license granted by Open Source Matters
the trademark holder in the United States and other countries.

LiveInternet