Файл footer.php в Cotonti
отвечает за вывод футера страницы, обработку хуков и плагинов, а также предоставление статистики и информации для отладки.
Основное назначение файла footer.php
Файл footer.php в системе Cotonti CMF выполняет ключевую роль в формировании нижней части веб-страницы (футера). Его задачи включают:
-
Подготовка данных для шаблона футера:
- Передача информации, такой как время генерации страницы, статистика SQL-запросов, отладочные данные (в режиме разработки) и нижняя строка (например, копирайт).
-
Подключение плагинов и хуков:
- Хуки (
footer.first,footer.main,footer.tags,footer.last) позволяют расширять функционал футера без необходимости изменять основной код.
- Хуки (
-
Интеграция редакторов:
- Автоматическое подключение визуальных редакторов для текстовых полей на странице, если они активированы.
-
Режим отладки:
- Включение режима разработчика, вывод подробной информации о SQL-запросах и времени их выполнения.
-
Обработка шаблонов:
- Выбор и обработка подходящего шаблона для футера в зависимости от текущего модуля, плагина или режима (административного, пользовательского).
Суть содержания кода
Код файла организован следующим образом:
-
Проверка на отображение футера:
- Код исполняется только в том случае, если в глобальных настройках включён вывод футера.
-
Подключение хуков:
- Выполняются внешние скрипты, которые добавляют или изменяют функционал футера.
-
Обработка шаблона футера:
- Определяется тип и базовый шаблон футера.
- Шаблон подгружается с использованием
XTemplate, и ему передаются необходимые данные (например, копирайт, статистика, время генерации страницы).
-
Обработка режимов (пользователь/гость):
- Отдельные данные и блоки шаблона генерируются для авторизованных пользователей и гостей.
-
Режим разработчика:
- Если включён режим разработки, код выводит детальную информацию о времени выполнения страницы и SQL-запросах.
-
Финальная обработка:
- Шаблон футера парсится и выводится в браузер.
Характеристика стиля PHP
-
Стиль кодирования:
- Используется объектно-ориентированный подход для работы с шаблонами через класс
XTemplate. - Код организован в виде блоков с комментариями, что облегчает его чтение и расширение.
- Используется объектно-ориентированный подход для работы с шаблонами через класс
-
Модульность:
- Код активно использует хуки и плагины, позволяя расширять функционал без изменения ядра.
-
Инкапсуляция данных:
- Используются глобальные переменные и пространства имён, такие как
Cot::$outиCot::$cfg, что позволяет централизовать управление данными и настройками.
- Используются глобальные переменные и пространства имён, такие как
-
Гибкость:
- Код предусматривает разные режимы работы (административный, пользовательский, гость, режим разработчика), делая его универсальным для различных сценариев.
-
Обработка условий:
- Широкое использование конструкций
if-elseи тернарного оператора для настройки функционала в зависимости от ситуации.
- Широкое использование конструкций
-
Шаблонный движок:
- Основная нагрузка на форматирование и вывод данных возлагается на шаблонный движок
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> </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]." </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> </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; // Подключаем файл плагина
}
/* ===== */
Comments (0)
Content author
Offline
Administrator
Last logged: 2026-07-05 18:32
- Page published: 2025-01-24 14:29
- Last update: 2025-01-24 14:32