Категории форума

список категорий в виде иерархического списка, то есть родительские и дочерние разделы


Administrator
Administrator • 21.02.2025 23:20 #1

В Cotonti CMF структура категорий хранится в таблице structure и организована в иерархию с помощью следующих полей:

  • structure_code — уникальный код категории
  • structure_path — путь категории, показывающий уровень вложенности
  • structure_title — название категории
  • structure_area — область структуры (в твоем случае 'forums')
  • structure_tpl — шаблон категории (можно использовать для фильтрации)

Как получить иерархический список категорий?

Нужно:

  1. Получить все категории из базы.
  2. Разбить их на родительские и дочерние.
  3. Построить древовидный список для вывода в шаблоне.

 

 

<?php

/**
 * [BEGIN_COT_EXT]
 * Hooks=standalone
 * [END_COT_EXT]
 */

// Подключаем необходимые файлы и данные
defined('COT_CODE') or die('Wrong URL');

// Получаем все категории форума
$categories = $db->query("SELECT structure_code, structure_id, structure_title, structure_path FROM $db_structure WHERE structure_area = 'forums' ORDER BY structure_path ASC")->fetchAll();

// Формируем массив иерархии
$category_tree = [];
foreach ($categories as $category) {
    $levels = explode('.', trim($category['structure_path'], '.'));
    $depth = count($levels); // Определяем уровень вложенности
    $category['depth'] = $depth;
    $category_tree[] = $category;
}

// Инициализация переменной для выбранных категорий
$selected_categories = [];

// Проверяем, есть ли подписки у пользователя в таблице подписок
if (isset($usr['id'])) {
    // Получаем подписки из таблицы $db_subscriptions для текущего пользователя
    $subscriptions = $db->query("SELECT cat_forum_subs FROM $db_subscriptions WHERE user_id = ?", [$usr['id']])->fetchAll();
    
    // Преобразуем результат в массив кодов категорий
    $selected_categories = array_map(function($row) {
        return $row['cat_forum_subs'];
    }, $subscriptions);
}

// Если форма отправлена и есть выбранные категории
if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_POST['selected_categories'])) {
    // Получаем выбранные категории из POST запроса
    $selected_categories = $_POST['selected_categories'];

    // Сохраняем подписки в таблицу подписок
    if (!empty($selected_categories)) {
        // Удаляем старые подписки пользователя перед добавлением новых
        $db->query("DELETE FROM $db_subscriptions WHERE user_id = ?", [$usr['id']]);

        // Добавляем новые подписки
        foreach ($selected_categories as $category_id) {
            // Пишем новый запрос на добавление подписки
            $db->query("INSERT INTO {$db_subscriptions} (user_id, cat_forum_subs, created_at) VALUES (?, ?, ?)", 
                [$usr['id'], $category_id, time()]);
        }
    }
}

// Загрузка шаблона
$t = new XTemplate(cot_tplfile('subscriptions', 'plug'));

// Отображаем категории в виде дерева
foreach ($category_tree as $category) {
    $t->assign([
        'CATEGORY_CODE' => $category['structure_code'], // Код категории
        'CATEGORY_ID' => $category['structure_id'], // ID категории
        'CATEGORY_TITLE' => str_repeat('&nbsp;&nbsp;&nbsp;', $category['depth'] - 1) . $category['structure_title'], // Отступ для вложенности
        'IS_SELECTED' => in_array($category['structure_code'], $selected_categories) ? 'checked' : '' // Проверяем, выбрана ли категория
    ]);
    $t->parse('MAIN.CATEGORY');
}

 

Как это работает?

  1. Получаем категории, сортируем по structure_path, чтобы родительские категории были первыми.
  2. Определяем уровень вложенности с помощью structure_path. Если путь 001.002.003, значит категория третьего уровня.
  3. Добавляем отступ перед названием категории (str_repeat('&nbsp;&nbsp;&nbsp;', $depth - 1)), чтобы визуально показать вложенность.
  4. Выводим в шаблоне как древовидный список.

 

<!-- BEGIN: CATEGORY -->
<li>
    <input type="checkbox" name="selected_categories[]" value="{CATEGORY_CODE}" {IS_SELECTED} />
    {CATEGORY_TITLE}
</li>
<!-- END: CATEGORY -->

 

 

☑ Основной раздел
   ☐ Подраздел 1
   ☐ Подраздел 2
      ☐ Вложенный подраздел

 

🗿

🧙‍♂️ Радуйся, странниче добрый и честный! Не понапрасну привела тя стезя в земли сии. Зде бо мужи мудры и искусники дела писменнаго и численнаго, что куют словеса и плетут узоры кода, тайны разгадывают и знанием делятся, летописи множа и ремесло цифровое творя.
⬅️ Аще налево пойдеши — обрящеши грамоты древния, писания старинныя и свитки учения. ⬆️ Аще прямо — слово мудрое и совет от мужей разумеющих, что в деле кодописном искусны, получиши. ➡️ Аще направо — сам в писцы и летописцы внидеши, и в ремесло цифровое, где строки и знаки в дело живое обращаются, слово свое в память веков вложиши.
📝 Не медли же — нареки имя свое, и вниди в чин наш, и стань с нами в братстве, где код есть магия, а строки — заклятия живыя, числом и буквою слово едины суть.
🏰 Не тайно есть собрание сие, и не инициации в нем, но многое сокрыто от пришлых и ступалого, понеже не всякому открывается знание, но токмо ищущим и пребывающим в деле сем.