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

Тема в разделе "DLE", создана пользователем danneo, 17 ноя 2013.

Информация :
Актуальная версия DataLife Engine 11.2
( Final Release v.11.2 | Скачать DataLife Engine | Скачать 11.2 demo )
Нужно ли обновляться | Как обновиться | Изменения в шаблонах
> Нет русских символов <
[Приватная тема DLE (Все подробности в ЛС к модератору раздела)]

Версии 11.1 и ниже - уязвимы!

Локализации | F.A.Q. | Внешний вид
Правила раздела | Правила форума
Обсуждение хайда карается баном!
В каждом сообщении указывайте версию DLE, которого они касаются!
Модераторы: killoff
  1. danneo

    danneo Честный

    Регистр.:
    13 ноя 2007
    Сообщения:
    1.445
    Симпатии:
    113
    Подскажите, пожалуйста, как можно вывести все записи из тех категорий, которые являются вложенными той, в которой нахожусь.
    Т.е., если брать функционал ДЛЕ, то это уже реализовано - вывод новостей из вложенных категорий.
    Но найти этот функционал не могу (может не понимаю просто).
    Модуль свой. 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).
    Или может есть другой способ?
     
  2. Горбушка

    Горбушка Ищу её...

    Регистр.:
    2 май 2008
    Сообщения:
    3.113
    Симпатии:
    2.130
    Правильно
    Выбрать список всех категорий и пройтись по нему рекурсивно. Т.е. построить дерево категорий в виде массива.
    Пример кода. Взято не из ДЛЕ, но очень похоже.
    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'] . " &raquo; " $list;
            
    $parent_id $cat_info[$parent_id]['parentid'];

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

        }

        return 
    $list;
    }
    P.s. функции достаточно запустить и их алгоритм становится сразу понятным.
     
    Последнее редактирование: 17 ноя 2013
    danneo нравится это.
  3. danneo

    danneo Честный

    Регистр.:
    13 ноя 2007
    Сообщения:
    1.445
    Симпатии:
    113
    возникла другая проблема :)
    у записи есть несколько категорий, например, "3,4,5" (записано в поле таблицы категорий)
    Соответственно, при формировании SQL запроса формируется условие WHERE category IN ('5,6,7') - это все дочерние категории выбранной категории.
    Получается, что сравнивается со строкой. Если одно значение в поле таблицы, то все ок. А если у записи несколько категорий, то не такой способ не рабочий.
    С какой стороны подходить, даже не знаю.
     
  4. Горбушка

    Горбушка Ищу её...

    Регистр.:
    2 май 2008
    Сообщения:
    3.113
    Симпатии:
    2.130
    Несколько категорий из которых надо сделать выбор? А кто мешает вызвать функцию get_sub_cats() для нескольких категорий и объединить результат через implode(',', $cats) ?

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

    При этом для получения родителя для статьи с несколькими категориями, то выбирается первая категория из списка и вызывается get_categories(), либо вызывается последовательно для каждого ID в списке.
     
    danneo нравится это.
  5. danneo

    danneo Честный

    Регистр.:
    13 ноя 2007
    Сообщения:
    1.445
    Симпатии:
    113
    я чего то все равно не догоняю. Вот получившийся запрос (упрощенный:(
    Код:
    SELECT
      *
    FROM dle_post_zap
    WHERE dle_post_zap.category REGEXP '[[:<:]](1,4,5,6)[[:>:]]'
    Но ничего не выводит.
    1,4,5,6 - это все категории, которые родительские по отношению к той, в которой нахожусь.
     
  6. Горбушка

    Горбушка Ищу её...

    Регистр.:
    2 май 2008
    Сообщения:
    3.113
    Симпатии:
    2.130
    Ещё раз...
    Имеем статью, которая опубликована сразу в 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"...
     
  7. danneo

    danneo Честный

    Регистр.:
    13 ноя 2007
    Сообщения:
    1.445
    Симпатии:
    113
    ну вроде как заработало.
    просто дело в том, что категории не в той таблице, что у ДЛЕ, и функции свои пишу. Вот и не понял...

    Подскажи, пожалуйста, еще по такому вопросу... из этой же области (категорий)...
    Вывел статистику у каждой категории, в скобках, сколько записей в категории. Работает только у окончательной категории, без мультикатегорий.
    Но т.к. они вложенные, да и в поле у записей id категорий указаны через запятую, так просто не вывести.
    Запрос (упрощенный) :
    Код:
    SELECT *
      (SELECT COUNT(*)     
          FROM dle_post_zap
          WHERE dle_post_zap.category = dle_category.id
        ) AS cnt_cat
    FROM dle_category
    
    Как его нужно модифицировать, чтобы все сработало?
     
    Последнее редактирование модератором: 17 ноя 2013
  8. Горбушка

    Горбушка Ищу её...

    Регистр.:
    2 май 2008
    Сообщения:
    3.113
    Симпатии:
    2.130
    У тебя $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 полный дамп таблицы категорий =)
     
  9. danneo

    danneo Честный

    Регистр.:
    13 ноя 2007
    Сообщения:
    1.445
    Симпатии:
    113
    дак это выводит описание категории. А я то про статистику у категории. Чтобы в названии категории в скобках выводилось кол-во записей этой категории, с учетом ее всех дочерних.
    Например, Машины (35), Цветы (5)
    Да и проблема в том, что это мой модуль, не ДЛЕ. Записи - это не новости (отдельная таблица, как и категории). Поэтому не всегда можно использовать встроенные в ДЛЕ функции. Но это ладно, по аналогии можно сделать. Это так, к слову.
     
  10. Горбушка

    Горбушка Ищу её...

    Регистр.:
    2 май 2008
    Сообщения:
    3.113
    Симпатии:
    2.130
    Тут дело не в том, что нельзя использовать функции ДЛЕ. Я тебе даю код не из ДЛЕ, но очень похожий. Тебе надо просто переименовать их и всё...

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