Файл footer.php в Cotonti

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

Основное назначение файла footer.php

Файл footer.php в системе Cotonti CMF выполняет ключевую роль в формировании нижней части веб-страницы (футера). Его задачи включают:

  1. Подготовка данных для шаблона футера:

    • Передача информации, такой как время генерации страницы, статистика SQL-запросов, отладочные данные (в режиме разработки) и нижняя строка (например, копирайт).
  2. Подключение плагинов и хуков:

    • Хуки (footer.first, footer.main, footer.tags, footer.last) позволяют расширять функционал футера без необходимости изменять основной код.
  3. Интеграция редакторов:

    • Автоматическое подключение визуальных редакторов для текстовых полей на странице, если они активированы.
  4. Режим отладки:

    • Включение режима разработчика, вывод подробной информации о SQL-запросах и времени их выполнения.
  5. Обработка шаблонов:

    • Выбор и обработка подходящего шаблона для футера в зависимости от текущего модуля, плагина или режима (административного, пользовательского).

Суть содержания кода

Код файла организован следующим образом:

  1. Проверка на отображение футера:

    • Код исполняется только в том случае, если в глобальных настройках включён вывод футера.
  2. Подключение хуков:

    • Выполняются внешние скрипты, которые добавляют или изменяют функционал футера.
  3. Обработка шаблона футера:

    • Определяется тип и базовый шаблон футера.
    • Шаблон подгружается с использованием XTemplate, и ему передаются необходимые данные (например, копирайт, статистика, время генерации страницы).
  4. Обработка режимов (пользователь/гость):

    • Отдельные данные и блоки шаблона генерируются для авторизованных пользователей и гостей.
  5. Режим разработчика:

    • Если включён режим разработки, код выводит детальную информацию о времени выполнения страницы и SQL-запросах.
  6. Финальная обработка:

    • Шаблон футера парсится и выводится в браузер.

Характеристика стиля PHP

  1. Стиль кодирования:

    • Используется объектно-ориентированный подход для работы с шаблонами через класс XTemplate.
    • Код организован в виде блоков с комментариями, что облегчает его чтение и расширение.
  2. Модульность:

    • Код активно использует хуки и плагины, позволяя расширять функционал без изменения ядра.
  3. Инкапсуляция данных:

    • Используются глобальные переменные и пространства имён, такие как Cot::$out и Cot::$cfg, что позволяет централизовать управление данными и настройками.
  4. Гибкость:

    • Код предусматривает разные режимы работы (административный, пользовательский, гость, режим разработчика), делая его универсальным для различных сценариев.
  5. Обработка условий:

    • Широкое использование конструкций if-else и тернарного оператора для настройки функционала в зависимости от ситуации.
  6. Шаблонный движок:

    • Основная нагрузка на форматирование и вывод данных возлагается на шаблонный движок XTemplate, что соответствует концепции разделения логики и представления (MVC).

Вывод

Файл footer.php — это фундаментальный элемент Cotonti CMF, отвечающий за вывод футера страницы, обработку хуков и плагинов, а также предоставление статистики и информации для отладки. Используемый стиль PHP характеризуется модульностью, гибкостью и хорошей структурой, что позволяет легко поддерживать и расширять код.

 

/**
 * @package Cotonti
 * @copyright (c) Cotonti Team
 * @license https://github.com/Cotonti/Cotonti/blob/master/License.txt
 */
// Заголовок комментария, указывающий на авторские права и лицензию для проекта Cotonti

defined('COT_CODE') or die('Wrong URL'); 
// Проверка, что код выполняется только в контексте Cotonti, иначе выводится ошибка "Wrong URL"

/* === Hook === */ 
// Начало блока хуков, чтобы расширения или плагины могли вмешиваться в процесс

foreach (cot_getextplugins('footer.first') as $pl) { 
    include $pl; 
} 
// Включение всех плагинов, привязанных к хуку 'footer.first' для добавления функционала в футер

/* ===== */ 
// Конец блока хуков

 

 

if (Cot::$sys['displayFooter']) {  // Проверка, нужно ли отображать футер
    $mtpl_type = (  // Определяем тип шаблона
        defined('COT_ADMIN')  // Если константа COT_ADMIN определена
        || (
            defined('COT_MESSAGE')  // Если определена константа COT_MESSAGE
            && $_SESSION['s_run_admin']  // И сессия активирована для админа
            && cot_auth('admin', 'any', 'R')  // И у пользователя есть права на чтение
        )
    ) ? 'core' : 'module';  // Если условия выполнены, тип шаблона — 'core', иначе — 'module'

    $mtpl_base = 'footer';  // Базовый шаблон футера
    if (Cot::$cfg['enablecustomhf']) {  // Если в конфигурации разрешена настройка пользовательского футера
        if (defined('COT_PLUG') && !empty($e)) {  // Если подключён плагин и не пусто в переменной $e
            $mtpl_base = ['footer', $e];  // Используем свой шаблон футера, основанный на плагине
        } elseif (!empty(Cot::$env['ext'])) {  // Если есть расширение в окружении
            $mtpl_base = ['footer', Cot::$env['ext']];  // Используем расширенный шаблон футера
        } elseif (!empty(Cot::$env['location'])) {  // Если задано местоположение
            $mtpl_base = ['footer', Cot::$env['location']];  // Используем шаблон футера для конкретного местоположения
        }
    }

    $t = new XTemplate(cot_tplfile($mtpl_base, $mtpl_type));  // Создаём новый объект шаблона с указанным файлом

    /* === Hook === */
    foreach (cot_getextplugins('footer.main') as $pl) {  // Вставляем плагины для футера
        include $pl;  // Подключаем файл плагина
    }
    /* ===== */

    // Назначаем данные для отображения в футере
    $t->assign([
        'FOOTER_COPYRIGHT'  => Cot::$out['copyright'],  // Копирайт
        'FOOTER_LOGSTATUS'  => Cot::$out['logstatus'],  // Статус логина
        'FOOTER_PMREMINDER' => !empty(Cot::$out['pmreminder']) ? Cot::$out['pmreminder'] : '',  // Напоминание о личных сообщениях
        'FOOTER_ADMINPANEL' => !empty(Cot::$out['adminpanel']) ? Cot::$out['adminpanel'] : '',  // Панель администратора
    ]);

    /* === Hook === */
    foreach (cot_getextplugins('footer.tags') as $pl) {  // Вставляем дополнительные теги для футера
        include $pl;  // Подключаем файл плагина
    }
    /* ===== */

    // Подключаем редакторы текста, если они есть
    if (
        (!empty($cot_textarea_count) || !empty($cot_turnOnEditor))  // Если есть текстовые области или включён редактор
        && !empty($cot_plugins['editor'])  // Если есть редакторы в плагинах
        && is_array($cot_plugins['editor'])  // Проверяем, что это массив
    ) {
        $parser = !empty(Cot::$sys['parser']) ? Cot::$sys['parser'] : Cot::$cfg['parser'];  // Определяем парсер
        if (!empty(Cot::$cfg['plugin'][$parser]['editor'])) {  // Если для парсера настроен редактор
            $editor = Cot::$cfg['plugin'][$parser]['editor'];  // Получаем редактор
            foreach ($cot_plugins['editor'] as $k) {  // Проходим по каждому плагину редактора
                if ($k['pl_code'] == $editor && cot_auth('plug', $k['pl_code'], 'R')) {  // Если код плагина совпадает и у пользователя есть права
                    $fileName = Cot::$cfg['plugins_dir'] . '/' . $k['pl_file'];  // Строим путь к файлу плагина
                    if (is_readable($fileName)) {  // Если файл плагина существует и читаем
                        include $fileName;  // Подключаем файл плагина
                        break;  // Останавливаем цикл после первого совпадения
                    }
                }
            }
        }
    }

    // Если нет пользовательских ресурсов для футера, присваиваем пустое значение
    if (empty(Cot::$out['footer_rc'])) {
        Cot::$out['footer_rc'] = '';  // Инициализируем пустую строку для футера
    }
    Cot::$out['footer_rc'] .= Resources::renderFooter();  // Добавляем пользовательские ресурсы футера

    $t->assign('FOOTER_RC', Cot::$out['footer_rc']);  // Присваиваем данные для футера

    if (Cot::$usr['id'] > 0) {  // Если пользователь авторизован
        $t->parse('FOOTER.USER');  // Обрабатываем блок для авторизованных пользователей
    } else {
        $t->parse('FOOTER.GUEST');  // Обрабатываем блок для гостей
    }

    // Если включён режим отладки
    if (Cot::$cfg['debug_mode']) {
        $cotHooksFired[] = 'footer.last';  // Добавляем хук для последнего этапа футера
        $cotHooksFired[] = 'output';  // Хук для вывода
        $cotHooksFired[] = 'shutdown';  // Хук для завершения работы
        Cot::$out['hooks'] = '<ol>';  // Создаём список хуков
        foreach ($cotHooksFired as $hook) {  // Для каждого хука
            Cot::$out['hooks'] .= '<li>' . $hook . '</li>';  // Добавляем хук в список
        }
        Cot::$out['hooks'] .= '</ol>';  // Закрываем список
        $t->assign('FOOTER_HOOKS', Cot::$out['hooks']);  // Присваиваем данные для вывода хуков
    }

    // Статистика времени создания страницы
    $i = explode(' ', microtime());  // Получаем текущее время
    Cot::$sys['endtime'] = $i[1] + $i[0];  // Время окончания
    Cot::$sys['creationtime'] = round(Cot::$sys['endtime'] - Cot::$sys['starttime'], 5);  // Время выполнения страницы

    Cot::$out['creationtime'] = (!Cot::$cfg['disablesysinfos']) ? Cot::$L['foo_created'].' '.cot_declension(Cot::$sys['creationtime'],
            $Ls['Seconds'], $onlyword = false, $canfrac = true) : '';  // Отображение времени создания страницы
    Cot::$out['sqlstatistics'] = (Cot::$cfg['showsqlstats'])
        ? Cot::$L['foo_sqltotal'] . ': '
        . cot_declension(round(Cot::$db->timeCount, 3), $Ls['Seconds'], $onlyword = false, $canfrac = true)
        . ' - ' . Cot::$L['foo_sqlqueries'] . ': ' . Cot::$db->count
        . ' - ' . Cot::$L['foo_sqlaverage'] . ': '
        . cot_declension(
            round((Cot::$db->timeCount / Cot::$db->count), 5),
            $Ls['Seconds'],
            $onlyword = false,
            $canfrac = true
        )
        : '';  // Статистика запросов в базе данных
    Cot::$out['bottomline'] = Cot::$cfg['bottomline'];  // Добавляем нижнюю строку конфигурации
    Cot::$out['bottomline'] .= (Cot::$cfg['keepcrbottom']) ? Cot::$out['copyright'] : '';  // Добавляем копирайт в нижнюю строку

    // Режим разработки и статистика SQL-запросов
    if (Cot::$cfg['devmode'] && cot_auth('admin', 'a', 'A')) {
        Cot::$out['devmode'] = "<h4>Dev-mode :</h4><table><tr><td><em>SQL query</em></td><td><em>Duration</em></td><td><em>Timeline</em></td><td><em>Execution stack<br />(file[line]: function)</em></td><td><em>Query</em></td></tr>";  // Старт таблицы отладки
        Cot::$out['devmode'] .= "<tr><td colspan=\"2\">BEGIN</td>";  // Начало таблицы
        Cot::$out['devmode'] .= "<td style=\"text-align:right;\">0.000 ms</td><td>&nbsp;</td></tr>";
        $tdStyle = 'vertical-align: top; padding: 0 10px 10px 0';  // Стиль для ячеек таблицы
        if (is_array(Cot::$sys['devmode']['queries'])) {  // Если есть запросы для отладки
            foreach (Cot::$sys['devmode']['queries'] as $k => $i) {  // Проходим по каждому запросу
                Cot::$out['devmode'] .= "<tr><td style=\"vertical-align: top\">#".$i[0]." &nbsp;</td>";  // Запрос
                Cot::$out['devmode'] .= "<td style=\"text-align:right; {$tdStyle}\">".sprintf("%.3f", round($i[1] * 1000, 3))." ms</td>";  // Время выполнения запроса
                Cot::$out['devmode'] .= "<td style=\"text-align:right; {$tdStyle}\">".sprintf("%.3f",
                        round(Cot::$sys['devmode']['timeline'][$k] * 1000, 3))." ms</td>";  // Время по таймлайну
                Cot::$out['devmode'] .= "<td style=\"text-align:left; {$tdStyle}\">".nl2br(htmlspecialchars($i[3]))."</td>";  // Стек вызовов
                Cot::$out['devmode'] .= "<td style=\"text-align:left; {$tdStyle}\">".htmlspecialchars($i[2])."</td></tr>";  // Запрос SQL
            }
        }
        Cot::$out['devmode'] .= "<tr><td colspan=\"2\">END</td>";  // Конец таблицы
        Cot::$out['devmode'] .= "<td style=\"text-align:right;\">".sprintf("%.3f", Cot::$sys['creationtime']).  // Время выполнения страницы
            " ms</td><td>&nbsp;</td></tr>";
        Cot::$out['devmode'] .= "</table><br />Total: " . round(Cot::$db->timeCount, 4) . "s - Queries:"  // Итоговая информация по времени и запросам
            . Cot::$db->count
            . " - Average: " . round((Cot::$db->timeCount / Cot::$db->count), 5) . "s/q";
    }

    // Присваиваем данные для нижней строки
$t->assign([
    'FOOTER_BOTTOMLINE' => Cot::$out['bottomline'],  // Присваиваем нижнюю строку из конфигурации
    'FOOTER_CREATIONTIME' => Cot::$out['creationtime'],  // Присваиваем время создания страницы
    'FOOTER_SQLSTATISTICS' => Cot::$out['sqlstatistics'],  // Присваиваем статистику SQL-запросов
    'FOOTER_DEVMODE' => isset(Cot::$out['devmode']) ? Cot::$out['devmode'] : '',  // Присваиваем данные о режиме разработки, если он активен
]);

    $t->parse('FOOTER');  // Обрабатываем шаблон футера
    $t->out('FOOTER');  // Выводим футер
}

/* === Hook === */
foreach (cot_getextplugins('footer.last') as $pl) {  // Вставляем плагины для последнего этапа футера
    include $pl;  // Подключаем файл плагина
}
/* ===== */

 

7 minutes read Administrator

Comments (0)

No comments yet
Only registered users can post new comments

Content author

Administrator

Offline

Administrator

Last logged: 2026-07-05 18:32

  • Page published: 2025-01-24 14:29
  • Last update: 2025-01-24 14:32

Similar pages

HTML-шаблон footer.tpl в Cotonti
1 Анализ шаблона подвала сайта в админке Cotonti CMF ("footer.tpl"): Основное назначение шаблона