Не нравятся результаты поиска? Попробуйте другой поиск!
DLE FAQ » Все вопросы » Хаки » Как изменить вывод custom по нескольким тегам?

Как изменить вывод custom по нескольким тегам?


     24.06.2019    Все вопросы » Хаки    1232

вопрос
Здравствуйте, {custom tags="новости,шаблоны"} выведет все новости, которые содержат ключевые слова из облака тегов "новости" и "шаблоны".
Как сделать, чтобы выводило только те новости, у которых не один из этих, а оба эти тега присутствуют одновременно?

Ответил: LazyDev


Открыть файл /engine/modules/functions.php найти код
if( preg_match( "#tags=['\"](.+?)['\"]#i", $param_str, $match ) ) {
Выше вставить
if (preg_match("#and-tags=['\"](.+?)['\"]#i", $param_str, $match)) {
	$tempArray = [];
	$match[1] = explode(',', trim($match[1]));
	$oldMySQL = version_compare($db->mysql_version, '5.5.3', '<') == 1 ? false : true;
	
	foreach ($match[1] as $value) {
		$value = $db->safesql(trim($value));
		if ($value) {
			if ($oldMySQL) {
				$tempArray[] = "tags REGEXP '[[:<:]](" . $value  . ")[[:>:]]'";
			} else {
				$tempArray[] = "tags REGEXP '([[:punct:]]|^)(" . $value . ")([[:punct:]]|$)'";
			}
		}
	}
	
	if ($tempArray) {
		$where[] = implode(' AND ', $tempArray);
	}
	unset($tempArray);
}

В {custom} использовать
and-tags="тег,кофе"

11 комментариев

Mau
Юзер

Mau - 24 июня 2019 21:35 -

Как я понимаю, нужно править engine/modules/functions.php?

if( preg_match( "#tags=['\"](.+?)['\"]#i", $param_str, $match ) ) {

			$temp_array = array();
			
			$match[1] = explode (',', trim($match[1]));
			
			foreach ($match[1] as $value) {
				$value = $db->safesql(trim($value));
				if( $value ) $temp_array[] = "tag='{$value}'";
			}
			
			if ( count($temp_array) ) {
	
				$temp_array = implode(" OR ", $temp_array);
				
				$db->query ( "SELECT news_id FROM " . PREFIX . "_tags WHERE {$temp_array}" );

				$temp_array = array ();
				
				while ( $row = $db->get_row () ) {
					
					if (!in_array($row['news_id'], $temp_array)) $temp_array[] = $row['news_id'];
				
				}
				
				if (count ( $temp_array )) {
					
					$where[] = "id IN ('" . implode("','", $temp_array) . "')";
				
				} else $where[] = "id IN ('0')";
				
			}
			
		}

Mau
Юзер

Mau - 24 июня 2019 23:47 -

Спасибо, скажите, а эту строчку можно изменять? Похоже из-за нее отказывается правильно работать.
$oldMySQL = version_compare($db->mysql_version, '5.5.3', '<');

LazyDev
PHP-developer

LazyDev - 24 июня 2019 23:55 -

Mau,
1. Скиньте свой код custom.
2. Что значит отказывается правильно работать?

Мой блог: LazyDev.pro

Помогаю с решением проблем на платной основе.

Mau
Юзер

Mau - 25 июня 2019 00:12 -

{custom available="global" sort="desk" cache="yes" and-tags="чай,кофе,шоколад"}
, когда я вывожу один тег - "чай", показывается всего одна новость, хотя их три, а если прописать несколько тегов сразу, как выше, то вообще ничего не показывает, хотя новости, где прописаны все три тега присутствуют.
В этой строчке сменил знак '<' на '>' и все стало работать как надо.
$oldMySQL = version_compare($db->mysql_version, '5.5.3', '<');

LazyDev
PHP-developer

LazyDev - 25 июня 2019 00:28 -

Mau, Замените
$oldMySQL = version_compare($db->mysql_version, '5.5.3', '<');
На
$oldMySQL = version_compare($db->mysql_version, '5.5.3', '<') == 1 ? false : true;

Мой блог: LazyDev.pro

Помогаю с решением проблем на платной основе.

Mau
Юзер

Mau - 25 июня 2019 00:34 -

Спасибо еще раз, все работает!

homa152
Юзер

homa152 - 27 октября 2024 21:30 -

Добавлю касаемо обновления архитектуры MySQL
При добавлении хака с версии MySQL 8.0, возможно появление ошибки: 3685. Неверный аргумент для регулярного выражения.

Можно пофиксить самостоятельно внеся корректировки в сам хак из панели админа.

Строку:
$tempArray[] = "tags REGEXP '[[:<:]](" . $value  . ")[[:>:]]'";


Заменить на:
$tempArray[] = "tags REGEXP '\\\\b(" . $value  . ")\\\\b'";


Согласно справочному руководству MySQL 8.0 / ... / Регулярные выражения, «MySQL поддерживает регулярные выражения с помощью международных компонентов для Unicode (ICU)».

То есть, вместо "[[:<:]] и [[:>:]]", нужно использовать: "\b"

TeraMoune
Эксперт

TeraMoune - 27 октября 2024 22:32 -

Напротив нужно использовать [[:punct:]] вместо скобок, про это написано в документации на которую вы ссылаетесь. А \b означает границу слова и не способен правильно отображать результаты. Граница слова это когда выражение будет находить отдельные слова. Например новость имеет теги (Социальная сеть, Блокировка) и tags REGEXP '\\b(сеть)\\b' найдёт новость с тегом Социальная сеть, а так же Рыбацкая сеть и в принципе найдёт все новости где присутствует слово "Сеть" и будет много лишних результатов, а не только нужные.

В хаке как раз присутствует проверка на старую версию и новую mysql и в каждом случае используется тот вариант который является валидным для используемой версии.

Тестовый репозиторий установки плагинов: teramoune

homa152
Юзер

homa152 - 27 октября 2024 23:20 -

Я буквально 2 часа назад столкнулся с проблемами при установке этого хака, проблема была именно в ошибке 3685, сайт не просто переставал работать, использовалась стандартная заглушка при критических ошибках MySQL исправить получилось методом описанным выше, для версия до 8 хак работает исправно, но выше, требуется доработка, так как синтаксис считается ошибочным, вы можете проверить самостоятельно.

В статье также указано, что важно использовать экранирование, собственно, что и указано в методе по исправлению ошибки.
Статья по решению проблемы

homa152
Юзер

homa152 - 27 октября 2024 23:33 -

Если вы готовы предложить какое-то решение для исправление проблемы 3685, отлично. Иначе к сожалению на последних версиях MySQL хак не рабочий, согласно вашему трактату.

TeraMoune
Эксперт

TeraMoune - 28 октября 2024 01:05 -

Я же написал, продублирую: нужно использовать [[:punct:]]

И проблема в условии проверяющее версию mysql, можно поменять местами true и false, изменить знак меньше на больше или вовсе убрать код строки с version_compare и оставить ту строку кода $tempArray[] где используется [[:punct:]].

В статье также указано, что важно использовать экранирование, собственно, что и указано в методе по исправлению ошибки.
Статья по решению проблемы

Там у человека совершенно другое условие поиска. Он не теги ищет которые строго разделены запятыми, он просто слова ищет и ему как раз подойдёт граница слова. И это когда-то давно поиск был разделяя по границе слова, теперь есть character_class и используется другой метод. Но это не отменяет того, что вы нашли вопрос и решение которое никак не связано с темой новости поиска новостей с наличием тегов.

Тестовый репозиторий установки плагинов: teramoune

Чтобы комментировать - войдите или зарегистрируйтесь на сайте

Похожие вопросы

наверх