Функция cot_load_structure в Cotonti

Подробное разбор функции cot_load_structure

Функция cot_load_structure загружает полную структуру категорий в массив и готовит его для использования в дальнейшем. Это довольно сложная функция, которая взаимодействует с базой данных, использует хуки для расширений и обрабатывает данные для отображения в различных областях сайта. Давайте рассмотрим её поэтапно.

Код функции

/**
 * Loads complete category structure into array
 */
function cot_load_structure()
{
    global $db_structure, $cot_extrafields, $structure;

    if (function_exists('cot_load_structure_custom')) {
        return cot_load_structure_custom();
    }

    $structure = [];
    if (defined('COT_UPGRADE')) {
        $sql = Cot::$db->query('SELECT * FROM ' . $db_structure . ' ORDER BY structure_path ASC');
        $row['structure_area'] = 'page';
    } else {
        $sql = Cot::$db->query('SELECT * FROM ' . Cot::$db->structure .
            ' ORDER BY structure_area ASC, structure_path ASC');
    }

    /* == Hook: Part 1 ==*/
    $extp = cot_getextplugins('structure');
    /* ================= */

    $path = []; // code path tree
    $tpath = []; // title path tree
    $tpls = []; // tpl codes tree

    $separator = Cot::$cfg['separator'] === strip_tags(Cot::$cfg['separator'])
        ? ' ' . Cot::$cfg['separator'] . ' '
        : ' / ';

    foreach ($sql->fetchAll() as $row) {
        $last_dot = mb_strrpos($row['structure_path'], '.');

        $row['structure_tpl'] = empty($row['structure_tpl']) ? $row['structure_code'] : $row['structure_tpl'];

        if ($last_dot > 0) {
            $path1 = mb_substr($row['structure_path'], 0, $last_dot);
            $path[$row['structure_path']] = $path[$path1] . '.' . $row['structure_code'];
            $tpath[$row['structure_path']] = $tpath[$path1] . $separator . $row['structure_title'];
            $parent_dot = mb_strrpos($path[$path1], '.');
            $parent = ($parent_dot > 0) ? mb_substr($path[$path1], $parent_dot + 1) : $path[$path1];
        } else {
            $path[$row['structure_path']] = $row['structure_code'];
            $tpath[$row['structure_path']] = $row['structure_title'];
            $parent = $row['structure_code']; // self
        }

        if ($row['structure_tpl'] == 'same_as_parent' && isset($tpls[$parent])) {
            $row['structure_tpl'] = $tpls[$parent];
        }

        $tpls[$row['structure_code']] = $row['structure_tpl'];

        $structure[$row['structure_area']][$row['structure_code']] = [
            'path' => $path[$row['structure_path']],
            'tpath' => $tpath[$row['structure_path']],
            'rpath' => $row['structure_path'],
            'id' => $row['structure_id'],
            'tpl' => $row['structure_tpl'],
            'title' => $row['structure_title'],
            'desc' => $row['structure_desc'],
            'icon' => $row['structure_icon'],
            'locked' => $row['structure_locked'],
            'count' => $row['structure_count'],
        ];

        if (is_array($cot_extrafields[$db_structure])) {
            foreach ($cot_extrafields[$db_structure] as $exfld) {
                $structure[$row['structure_area']][$row['structure_code']][$exfld['field_name']] =
                    $row['structure_'.$exfld['field_name']];
            }
        }

        /* == Hook: Part 2 ==*/
        foreach ($extp as $pl) {
            include $pl;
        }
        /* ================= */
    }
}


Описание работы функции

function cot_load_structure()
{
    global $db_structure, $cot_extrafields, $structure;

    if (function_exists('cot_load_structure_custom')) {
        return cot_load_structure_custom();
    }

    $structure = [];
    if (defined('COT_UPGRADE')) {
        $sql = Cot::$db->query('SELECT * FROM ' . $db_structure . ' ORDER BY structure_path ASC');
        $row['structure_area'] = 'page';
    } else {
        $sql = Cot::$db->query('SELECT * FROM ' . Cot::$db->structure . ' ORDER BY structure_area ASC, structure_path ASC');
    }
    


    
Проверка на наличие функции cot_load_structure_custom:

if (function_exists('cot_load_structure_custom')) {
    return cot_load_structure_custom();
}

Перед основной логикой, если существует пользовательская функция cot_load_structure_custom(), то будет вызвана она, а вся остальная логика пропущена. Это может быть использовано для кастомных реализаций загрузки структуры.

Инициализация переменных:

global $db_structure, $cot_extrafields, $structure;
$structure = [];



Глобальные переменные:
$db_structure — имя таблицы базы данных, в которой хранится структура.
$cot_extrafields — массив дополнительных полей.
$structure — основной массив, который будет содержать всю загруженную структуру категорий.
Переменная $structure инициализируется как пустой массив.

Запрос к базе данных:

В зависимости от того, обновляется ли система (COT_UPGRADE), выбирается один из двух SQL-запросов:
Если система обновляется, то запрос на выборку всех данных из таблицы структуры с сортировкой по пути структуры.
В противном случае, используется другой запрос, который сортирует данные сначала по типу области (structure_area), затем по пути структуры (structure_path).


Подключение плагинов через хук:


 

$extp = cot_getextplugins('structure');


Получаем список плагинов для структуры через хук cot_getextplugins('structure'). Этот хук позволяет плагинам вмешиваться в процесс загрузки структуры.


Подготовка переменных для обработки:

$path = []; // кодовый путь
$tpath = []; // путь по заголовкам
$tpls = []; // дерево шаблонов
$separator = Cot::$cfg['separator'] === strip_tags(Cot::$cfg['separator']) ? ' ' . Cot::$cfg['separator'] . ' ' : ' / '; //
Переменные для хранения путей:
$path // — будет хранить путь по кодам категорий.
$tpath // — будет хранить путь по заголовкам.
$tpls — // будет хранить шаблоны для каждой категории.
$separator // — разделитель, который будет использоваться между уровнями категорий в пути. 

Если конфигурация Cotonti позволяет, то используется заданный символ-разделитель. В противном случае используется стандартный разделитель ' / '.

Основной цикл обработки данных

foreach ($sql->fetchAll() as $row) {
    $last_dot = mb_strrpos($row['structure_path'], '.');

    $row['structure_tpl'] = empty($row['structure_tpl']) ? $row['structure_code'] : $row['structure_tpl'];

    if ($last_dot > 0) {
        $path1 = mb_substr($row['structure_path'], 0, $last_dot);
        $path[$row['structure_path']] = $path[$path1] . '.' . $row['structure_code'];
        $tpath[$row['structure_path']] = $tpath[$path1] . $separator . $row['structure_title'];
        $parent_dot = mb_strrpos($path[$path1], '.');
        $parent = ($parent_dot > 0) ? mb_substr($path[$path1], $parent_dot + 1) : $path[$path1];
    } else {
        $path[$row['structure_path']] = $row['structure_code'];
        $tpath[$row['structure_path']] = $row['structure_title'];
        $parent = $row['structure_code']; // self
    }

    if ($row['structure_tpl'] == 'same_as_parent' && isset($tpls[$parent])) {
        $row['structure_tpl'] = $tpls[$parent];
    }

    $tpls[$row['structure_code']] = $row['structure_tpl'];

    $structure[$row['structure_area']][$row['structure_code']] = [
        'path' => $path[$row['structure_path']],
        'tpath' => $tpath[$row['structure_path']],
        'rpath' => $row['structure_path'],
        'id' => $row['structure_id'],
        'tpl' => $row['structure_tpl'],
        'title' => $row['structure_title'],
        'desc' => $row['structure_desc'],
        'icon' => $row['structure_icon'],
        'locked' => $row['structure_locked'],
        'count' => $row['structure_count'],
    ];


    


Обработка структуры:

Для каждой строки данных, полученной из базы данных, выполняется обработка пути структуры (structure_path):
Определяется, есть ли в пути точка (указывает на наличие подкатегорий).
Строятся различные пути для текущей категории:

$path — путь по кодам.
$tpath — путь по заголовкам.


Шаблоны:

Если категория имеет свой шаблон, он сохраняется в массиве $tpls. Если шаблон равен 'same_as_parent', то будет использован шаблон родительской категории.


Сохранение данных о структуре:

Для каждой категории создается запись в массиве $structure, которая включает различные параметры:
path — путь по кодам.
tpath — путь по заголовкам.
rpath — оригинальный путь из базы данных.
И другие параметры, такие как ID, описание, иконка и т.д.


Дополнительные поля:

if (is_array($cot_extrafields[$db_structure])) {
    foreach ($cot_extrafields[$db_structure] as $exfld) {
        $structure[$row['structure_area']][$row['structure_code']][$exfld['field_name']] = $row['structure_'.$exfld['field_name']];
    }
}


 


Если для структуры предусмотрены дополнительные поля, они добавляются в массив structure для каждой категории.

Хуки плагинов:

foreach ($extp as $pl) {
    include $pl;
}


 


После загрузки и обработки всех данных функция включает плагины, которые могут вмешиваться в процесс обработки структуры через хук structure.


Заключение:
Функция cot_load_structure выполняет несколько важных задач:

Загружает все категории и их структуру из базы данных.
Строит пути категорий и заголовков для использования на сайте.
Обрабатывает шаблоны и дополнительные поля для категорий.
Использует хуки для расширений, позволяя плагинам вмешиваться в процесс.
Эта функция является важной частью работы с категориями и страницами в Cotonti, обеспечивая правильную организацию данных для дальнейшего использования в шаблонах и интерфейсах сайта.

 

5 минут чтения Administrator

Комментарии (0)

Комментарии отсутствуют
Добавление комментариев доступно только зарегистрированным пользователям

Автор контента

Administrator

Оффлайн

Administrator

Последняя авторизация: 05.07.2026 18:32

  • Страница размещена: 21.01.2025 14:25
  • Последнее обновление: 21.01.2025 14:26