• DONATE to NULLED!
    Форуму и его команде можно помочь, мотивировать модераторов разделов.
    Помогите модератору этого раздела killoff лично.

Помощь Как вывести все записи из вложенных категорий?

danneo

Честный
Регистрация
13 Ноя 2007
Сообщения
1.526
Реакции
121
Подскажите, пожалуйста, как можно вывести все записи из тех категорий, которые являются вложенными той, в которой нахожусь.
Т.е., если брать функционал ДЛЕ, то это уже реализовано - вывод новостей из вложенных категорий.
Но найти этот функционал не могу (может не понимаю просто).
Модуль свой. DLE 10.0
Например, нахожусь в категории catid=5. У нее есть вложенные catid=8,9,10.
А записи прикреплены именно к catid=8,9,10.
Поэтому, находясь в catid=5, их не видно.
Как я понимаю, нужно построить строку со значениями всеми вложенными catid. Т.е. получить сначала строку вида "8,9,10".
А затем в SQL запрос добавить параметр, вида:
SELECT * FROM post_zap WHERE category IN('8,9,10').
В правильном направлении думаю?
Но возникает проблема, как построить эту строку?
Есть файл кэша категорий, в нем массив всех параметров всех категорий.
Как построить строку в обратном направлении, в строну родителя, я знаю. А вот, как обратно, не знаю.
Конкретно, как получить все элементы массива (где parentid = 5).
Или может есть другой способ?
 
В правильном направлении думаю?
Правильно
Но возникает проблема, как построить эту строку?
Выбрать список всех категорий и пройтись по нему рекурсивно. Т.е. построить дерево категорий в виде массива.
Пример кода. Взято не из ДЛЕ, но очень похоже.
PHP:
    $cat_info = array ();

    $db->query ( "SELECT * FROM `test` ORDER BY posi ASC" );
    while ( $row = $db->get_row () ) {

    	$cat_info[$row['id']] = array ();

    	foreach ( $row as $key => $value ) {
    		$cat_info[$row['id']][$key] = stripslashes ( $value );
    	}

    }
Функция получения ID дочерних категорий:
PHP:
function get_sub_cats($id, $subcategory = '') {

	global $cat_info;
	$subfound = array ();

	if( $subcategory == '' ) $subcategory = $id;

	foreach ( $cat_info as $cats ) {
		if( $cats['parentid'] == $id ) {
			$subfound[] = $cats['id'];
		}
	}

	foreach ( $subfound as $parentid ) {
		$subcategory .= "|" . $parentid;
		$subcategory = get_sub_cats( $parentid, $subcategory );
	}

	return $subcategory;

}
Получение родителя (пути от категории до рут-категории:(
PHP:
function get_categories($id) {

	global $cat_info, $conf;

	if( ! $id ) return;

	$parent_id = $cat_info[$id]['parentid'];

	$cat_info[$id]['name'];

	while ( $parent_id ) {
		
		$cat_info[$parent_id]['name'] . " » " . $list;
		$parent_id = $cat_info[$parent_id]['parentid'];

		if( $cat_info[$parent_id]['parentid'] == $cat_info[$parent_id]['id'] ) break;

	}

	return $list;
}
P.s. функции достаточно запустить и их алгоритм становится сразу понятным.
 
Последнее редактирование:
возникла другая проблема :)
у записи есть несколько категорий, например, "3,4,5" (записано в поле таблицы категорий)
Соответственно, при формировании SQL запроса формируется условие WHERE category IN ('5,6,7') - это все дочерние категории выбранной категории.
Получается, что сравнивается со строкой. Если одно значение в поле таблицы, то все ок. А если у записи несколько категорий, то не такой способ не рабочий.
С какой стороны подходить, даже не знаю.
 
Несколько категорий из которых надо сделать выбор? А кто мешает вызвать функцию get_sub_cats() для нескольких категорий и объединить результат через implode(',', $cats) ?

Запрос же на выборку делается WHERE `cat` IN ($cat_list) если каждая статья может быть только в 1 категории и WHERE `cat` regexp '[[:<:]](" . $cat_list . ")[[:>:]]' если есть мультикатегории, т.е. статья разом может быть в нескольких категориях.

При этом для получения родителя для статьи с несколькими категориями, то выбирается первая категория из списка и вызывается get_categories(), либо вызывается последовательно для каждого ID в списке.
 
я чего то все равно не догоняю. Вот получившийся запрос (упрощенный:(
Код:
SELECT
  *
FROM dle_post_zap
WHERE dle_post_zap.category REGEXP '[[:<:]](1,4,5,6)[[:>:]]'
Но ничего не выводит.
1,4,5,6 - это все категории, которые родительские по отношению к той, в которой нахожусь.
 
Ещё раз...
Имеем статью, которая опубликована сразу в 1 и 4 категории, в category значение: 1,4
Имеем категорию 1, у которой дочерние 2 и 3
Вызываем функцию get_sub_cats(1); - она возвращает нам "1|2|3"
Делаем запрос SELECT * FROM dle_post_zap WHERE dle_post_zap.category REGEXP '[[:<:]](1|2|3)[[:>:]]' - получаем новости, находящиеся в категориях 1, 2 и 3, включая нашу статью из категории "1,4"...
 
ну вроде как заработало.
просто дело в том, что категории не в той таблице, что у ДЛЕ, и функции свои пишу. Вот и не понял...

Подскажи, пожалуйста, еще по такому вопросу... из этой же области (категорий)...
Вывел статистику у каждой категории, в скобках, сколько записей в категории. Работает только у окончательной категории, без мультикатегорий.
Но т.к. они вложенные, да и в поле у записей id категорий указаны через запятую, так просто не вывести.
Запрос (упрощенный) :
Код:
SELECT *
  (SELECT COUNT(*)     
      FROM dle_post_zap
      WHERE dle_post_zap.category = dle_category.id
    ) AS cnt_cat
FROM dle_category
Как его нужно модифицировать, чтобы все сработало?
 
Последнее редактирование модератором:
У тебя $cat_info уже содержит информацию по всем категориям. Запросы в эту таблицу больше не нужны.
echo $cat_info[id][desc] - всё...
Очень грубо код будет выглядеть так (1 - родитель, 2 и 3 - подкатегории:(
PHP:
$cats = get_sub_cats(1);
$cats = explode('|', $cats);
foreach ( $cats as $value) {
        echo $cat_info[$value]['desc'];
}
Где desc - описание, 1 - ID твоей категории, $cat_info унаследована из кода, который я давал выше. На выходе получишь вывод описания всех категорий по очереди...

И всё, никакие запросы больше делать не надо. У тебя и так в $cat_info полный дамп таблицы категорий =)
 
дак это выводит описание категории. А я то про статистику у категории. Чтобы в названии категории в скобках выводилось кол-во записей этой категории, с учетом ее всех дочерних.
Например, Машины (35), Цветы (5)
Да и проблема в том, что это мой модуль, не ДЛЕ. Записи - это не новости (отдельная таблица, как и категории). Поэтому не всегда можно использовать встроенные в ДЛЕ функции. Но это ладно, по аналогии можно сделать. Это так, к слову.
 
Да и проблема в том, что это мой модуль, не ДЛЕ. Записи - это не новости (отдельная таблица, как и категории). Поэтому не всегда можно использовать встроенные в ДЛЕ функции. Но это ладно, по аналогии можно сделать. Это так, к слову.
Тут дело не в том, что нельзя использовать функции ДЛЕ. Я тебе даю код не из ДЛЕ, но очень похожий. Тебе надо просто переименовать их и всё...

Что касается статистики - сори, глаза закрываются, не так прочитал... Выводить количество в целом, плохая идея - весьма высокая нагрузка на БД. Но уменьшить её можно введя поле count в таблице с категориями и добавлять туда +1 при занесении статьи... Дальше остаётся контролировать этот счётчик. Не самый приятный способ, но нагрузка в разы меньше.
 
Назад
Сверху